From 99c5ea5368b2a58c6e93d4c76fccf5707c9469f8 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Wed, 29 Apr 2009 20:03:09 +0400 Subject: [PATCH 01/96] 6660539: Introspector shares cache of mutable BeanInfo between AppContexts Reviewed-by: peterz --- .../classes/java/beans/Introspector.java | 29 ++++++-- .../java/beans/Introspector/Test6660539.java | 68 +++++++++++++++++++ 2 files changed, 90 insertions(+), 7 deletions(-) create mode 100644 jdk/test/java/beans/Introspector/Test6660539.java diff --git a/jdk/src/share/classes/java/beans/Introspector.java b/jdk/src/share/classes/java/beans/Introspector.java index 6a50cbe7f7d..2a49db1794c 100644 --- a/jdk/src/share/classes/java/beans/Introspector.java +++ b/jdk/src/share/classes/java/beans/Introspector.java @@ -1,5 +1,5 @@ /* - * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2009 Sun Microsystems, Inc. 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 @@ -45,6 +45,7 @@ import java.util.EventListener; import java.util.List; import java.util.WeakHashMap; import java.util.TreeMap; +import sun.awt.AppContext; import sun.reflect.misc.ReflectUtil; /** @@ -111,8 +112,8 @@ public class Introspector { // Static Caches to speed up introspection. private static Map declaredMethodCache = Collections.synchronizedMap(new WeakHashMap()); - private static Map beanInfoCache = - Collections.synchronizedMap(new WeakHashMap()); + + private static final Object BEANINFO_CACHE = new Object(); private Class beanClass; private BeanInfo explicitBeanInfo; @@ -175,10 +176,18 @@ public class Introspector { if (!ReflectUtil.isPackageAccessible(beanClass)) { return (new Introspector(beanClass, null, USE_ALL_BEANINFO)).getBeanInfo(); } - BeanInfo bi = (BeanInfo)beanInfoCache.get(beanClass); + Map, BeanInfo> map; + synchronized (BEANINFO_CACHE) { + map = (Map, BeanInfo>) AppContext.getAppContext().get(BEANINFO_CACHE); + if (map == null) { + map = Collections.synchronizedMap(new WeakHashMap, BeanInfo>()); + AppContext.getAppContext().put(BEANINFO_CACHE, map); + } + } + BeanInfo bi = map.get(beanClass); if (bi == null) { bi = (new Introspector(beanClass, null, USE_ALL_BEANINFO)).getBeanInfo(); - beanInfoCache.put(beanClass, bi); + map.put(beanClass, bi); } return bi; } @@ -351,7 +360,10 @@ public class Introspector { */ public static void flushCaches() { - beanInfoCache.clear(); + Map map = (Map) AppContext.getAppContext().get(BEANINFO_CACHE); + if (map != null) { + map.clear(); + } declaredMethodCache.clear(); } @@ -374,7 +386,10 @@ public class Introspector { if (clz == null) { throw new NullPointerException(); } - beanInfoCache.remove(clz); + Map map = (Map) AppContext.getAppContext().get(BEANINFO_CACHE); + if (map != null) { + map.remove(clz); + } declaredMethodCache.remove(clz); } diff --git a/jdk/test/java/beans/Introspector/Test6660539.java b/jdk/test/java/beans/Introspector/Test6660539.java new file mode 100644 index 00000000000..b0678a5a04b --- /dev/null +++ b/jdk/test/java/beans/Introspector/Test6660539.java @@ -0,0 +1,68 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6660539 + * @summary Tests changeable BeanInfo cache in different application contexts + * @author Sergey Malenkov + */ + +import sun.awt.SunToolkit; + +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; + +public class Test6660539 implements Runnable { + private static final String NAME = "$$$"; + + public static void main(String[] args) throws Exception { + for (PropertyDescriptor pd : getPropertyDescriptors()) { + pd.setDisplayName(NAME); + } + ThreadGroup group = new ThreadGroup(NAME); + Thread thread = new Thread(group, new Test6660539()); + thread.start(); + thread.join(); + } + + public void run() { + SunToolkit.createNewAppContext(); + for (PropertyDescriptor pd : getPropertyDescriptors()) { + if (pd.getDisplayName().equals(NAME)) + throw new Error("shared BeanInfo cache"); + } + } + + private static PropertyDescriptor[] getPropertyDescriptors() { + try { + BeanInfo info = Introspector.getBeanInfo(Test6660539.class); + return info.getPropertyDescriptors(); + } + catch (IntrospectionException exception) { + throw new Error("unexpected", exception); + } + } +} From de6e2fb6e267b377c94c9179cd474d1689b4a0e6 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Wed, 29 Apr 2009 20:55:13 +0400 Subject: [PATCH 02/96] 6777487: Encoder allows reading private variables with certain names Reviewed-by: peterz --- .../share/classes/java/beans/MetaData.java | 83 ++++++++++--------- .../beans/XMLEncoder/6777487/TestBox.java | 52 ++++++++++++ .../6777487/TestCheckedCollection.java | 48 +++++++++++ .../XMLEncoder/6777487/TestCheckedList.java | 48 +++++++++++ .../XMLEncoder/6777487/TestCheckedMap.java | 49 +++++++++++ .../6777487/TestCheckedRandomAccessList.java | 48 +++++++++++ .../XMLEncoder/6777487/TestCheckedSet.java | 48 +++++++++++ .../6777487/TestCheckedSortedMap.java | 49 +++++++++++ .../6777487/TestCheckedSortedSet.java | 48 +++++++++++ .../beans/XMLEncoder/6777487/TestEncoder.java | 60 ++++++++++++++ .../beans/XMLEncoder/6777487/TestEnumMap.java | 47 +++++++++++ .../beans/XMLEncoder/6777487/TestEnumSet.java | 47 +++++++++++ 12 files changed, 589 insertions(+), 38 deletions(-) create mode 100644 jdk/test/java/beans/XMLEncoder/6777487/TestBox.java create mode 100644 jdk/test/java/beans/XMLEncoder/6777487/TestCheckedCollection.java create mode 100644 jdk/test/java/beans/XMLEncoder/6777487/TestCheckedList.java create mode 100644 jdk/test/java/beans/XMLEncoder/6777487/TestCheckedMap.java create mode 100644 jdk/test/java/beans/XMLEncoder/6777487/TestCheckedRandomAccessList.java create mode 100644 jdk/test/java/beans/XMLEncoder/6777487/TestCheckedSet.java create mode 100644 jdk/test/java/beans/XMLEncoder/6777487/TestCheckedSortedMap.java create mode 100644 jdk/test/java/beans/XMLEncoder/6777487/TestCheckedSortedSet.java create mode 100644 jdk/test/java/beans/XMLEncoder/6777487/TestEncoder.java create mode 100644 jdk/test/java/beans/XMLEncoder/6777487/TestEnumMap.java create mode 100644 jdk/test/java/beans/XMLEncoder/6777487/TestEnumSet.java diff --git a/jdk/src/share/classes/java/beans/MetaData.java b/jdk/src/share/classes/java/beans/MetaData.java index defd196457e..75c3945106d 100644 --- a/jdk/src/share/classes/java/beans/MetaData.java +++ b/jdk/src/share/classes/java/beans/MetaData.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2009 Sun Microsystems, Inc. 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 @@ -333,31 +333,6 @@ abstract class java_util_Collections extends PersistenceDelegate { return (oldC.size() == newC.size()) && oldC.containsAll(newC); } - static Object getPrivateField(final Object instance, final String name) { - return AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { - Class type = instance.getClass(); - while ( true ) { - try { - Field field = type.getDeclaredField(name); - field.setAccessible(true); - return field.get( instance ); - } - catch (NoSuchFieldException exception) { - type = type.getSuperclass(); - if (type == null) { - throw new IllegalStateException("Could not find field " + name, exception); - } - } - catch (Exception exception) { - throw new IllegalStateException("Could not get value " + type.getName() + '.' + name, exception); - } - } - } - } ); - } - static final class EmptyList_PersistenceDelegate extends java_util_Collections { protected Expression instantiate(Object oldInstance, Encoder out) { return new Expression(oldInstance, Collections.class, "emptyList", null); @@ -498,7 +473,7 @@ abstract class java_util_Collections extends PersistenceDelegate { static final class CheckedCollection_PersistenceDelegate extends java_util_Collections { protected Expression instantiate(Object oldInstance, Encoder out) { - Object type = getPrivateField(oldInstance, "type"); + Object type = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedCollection.type"); List list = new ArrayList((Collection) oldInstance); return new Expression(oldInstance, Collections.class, "checkedCollection", new Object[]{list, type}); } @@ -506,7 +481,7 @@ abstract class java_util_Collections extends PersistenceDelegate { static final class CheckedList_PersistenceDelegate extends java_util_Collections { protected Expression instantiate(Object oldInstance, Encoder out) { - Object type = getPrivateField(oldInstance, "type"); + Object type = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedCollection.type"); List list = new LinkedList((Collection) oldInstance); return new Expression(oldInstance, Collections.class, "checkedList", new Object[]{list, type}); } @@ -514,7 +489,7 @@ abstract class java_util_Collections extends PersistenceDelegate { static final class CheckedRandomAccessList_PersistenceDelegate extends java_util_Collections { protected Expression instantiate(Object oldInstance, Encoder out) { - Object type = getPrivateField(oldInstance, "type"); + Object type = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedCollection.type"); List list = new ArrayList((Collection) oldInstance); return new Expression(oldInstance, Collections.class, "checkedList", new Object[]{list, type}); } @@ -522,7 +497,7 @@ abstract class java_util_Collections extends PersistenceDelegate { static final class CheckedSet_PersistenceDelegate extends java_util_Collections { protected Expression instantiate(Object oldInstance, Encoder out) { - Object type = getPrivateField(oldInstance, "type"); + Object type = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedCollection.type"); Set set = new HashSet((Set) oldInstance); return new Expression(oldInstance, Collections.class, "checkedSet", new Object[]{set, type}); } @@ -530,7 +505,7 @@ abstract class java_util_Collections extends PersistenceDelegate { static final class CheckedSortedSet_PersistenceDelegate extends java_util_Collections { protected Expression instantiate(Object oldInstance, Encoder out) { - Object type = getPrivateField(oldInstance, "type"); + Object type = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedCollection.type"); SortedSet set = new TreeSet((SortedSet) oldInstance); return new Expression(oldInstance, Collections.class, "checkedSortedSet", new Object[]{set, type}); } @@ -538,8 +513,8 @@ abstract class java_util_Collections extends PersistenceDelegate { static final class CheckedMap_PersistenceDelegate extends java_util_Collections { protected Expression instantiate(Object oldInstance, Encoder out) { - Object keyType = getPrivateField(oldInstance, "keyType"); - Object valueType = getPrivateField(oldInstance, "valueType"); + Object keyType = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedMap.keyType"); + Object valueType = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedMap.valueType"); Map map = new HashMap((Map) oldInstance); return new Expression(oldInstance, Collections.class, "checkedMap", new Object[]{map, keyType, valueType}); } @@ -547,8 +522,8 @@ abstract class java_util_Collections extends PersistenceDelegate { static final class CheckedSortedMap_PersistenceDelegate extends java_util_Collections { protected Expression instantiate(Object oldInstance, Encoder out) { - Object keyType = getPrivateField(oldInstance, "keyType"); - Object valueType = getPrivateField(oldInstance, "valueType"); + Object keyType = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedMap.keyType"); + Object valueType = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedMap.valueType"); SortedMap map = new TreeMap((SortedMap) oldInstance); return new Expression(oldInstance, Collections.class, "checkedSortedMap", new Object[]{map, keyType, valueType}); } @@ -570,7 +545,7 @@ class java_util_EnumMap_PersistenceDelegate extends PersistenceDelegate { } private static Object getType(Object instance) { - return java_util_Collections.getPrivateField(instance, "keyType"); + return MetaData.getPrivateFieldValue(instance, "java.util.EnumMap.keyType"); } } @@ -589,7 +564,7 @@ class java_util_EnumSet_PersistenceDelegate extends PersistenceDelegate { } private static Object getType(Object instance) { - return java_util_Collections.getPrivateField(instance, "elementType"); + return MetaData.getPrivateFieldValue(instance, "java.util.EnumSet.elementType"); } } @@ -1280,7 +1255,7 @@ class javax_swing_Box_PersistenceDelegate extends DefaultPersistenceDelegate { private Integer getAxis(Object object) { Box box = (Box) object; - return (Integer) java_util_Collections.getPrivateField(box.getLayout(), "axis"); + return (Integer) MetaData.getPrivateFieldValue(box.getLayout(), "javax.swing.BoxLayout.axis"); } } @@ -1363,6 +1338,7 @@ final class sun_swing_PrintColorUIResource_PersistenceDelegate extends Persisten } class MetaData { + private static final Map fields = Collections.synchronizedMap(new WeakHashMap()); private static Hashtable internalPersistenceDelegates = new Hashtable(); private static PersistenceDelegate nullPersistenceDelegate = new NullPersistenceDelegate(); @@ -1501,4 +1477,35 @@ class MetaData { return null; } } + + static Object getPrivateFieldValue(Object instance, String name) { + Field field = fields.get(name); + if (field == null) { + int index = name.lastIndexOf('.'); + final String className = name.substring(0, index); + final String fieldName = name.substring(1 + index); + field = AccessController.doPrivileged(new PrivilegedAction() { + public Field run() { + try { + Field field = Class.forName(className).getDeclaredField(fieldName); + field.setAccessible(true); + return field; + } + catch (ClassNotFoundException exception) { + throw new IllegalStateException("Could not find class", exception); + } + catch (NoSuchFieldException exception) { + throw new IllegalStateException("Could not find field", exception); + } + } + }); + fields.put(name, field); + } + try { + return field.get(instance); + } + catch (IllegalAccessException exception) { + throw new IllegalStateException("Could not get value of the field", exception); + } + } } diff --git a/jdk/test/java/beans/XMLEncoder/6777487/TestBox.java b/jdk/test/java/beans/XMLEncoder/6777487/TestBox.java new file mode 100644 index 00000000000..1287f4414b5 --- /dev/null +++ b/jdk/test/java/beans/XMLEncoder/6777487/TestBox.java @@ -0,0 +1,52 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6777487 + * @summary Tests private field access for BoxLayout + * @author Sergey Malenkov + */ + +import java.awt.FlowLayout; +import javax.swing.Box; +import javax.swing.BoxLayout; + +public final class TestBox { + private static final Integer OBJECT = Integer.valueOf(-123); + + public static void main(String[] args) { + TestEncoder.test( + new Box(BoxLayout.LINE_AXIS), + new Box(BoxLayout.PAGE_AXIS) { + @Override + public FlowLayout getLayout() { + return new FlowLayout() { + private final Object axis = OBJECT; + }; + } + }, + OBJECT + ); + } +} diff --git a/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedCollection.java b/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedCollection.java new file mode 100644 index 00000000000..805f05f4299 --- /dev/null +++ b/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedCollection.java @@ -0,0 +1,48 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6777487 + * @summary Tests private field access for CheckedCollection + * @author Sergey Malenkov + */ + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public final class TestCheckedCollection { + private static final Object OBJECT = new Object(); + + public static void main(String[] args) { + List list = Collections.emptyList(); + TestEncoder.test( + Collections.checkedCollection(list, String.class), + new ArrayList() { + private final Object type = OBJECT; + }, + OBJECT + ); + } +} diff --git a/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedList.java b/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedList.java new file mode 100644 index 00000000000..69d6ca9c8ba --- /dev/null +++ b/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedList.java @@ -0,0 +1,48 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6777487 + * @summary Tests private field access for CheckedList + * @author Sergey Malenkov + */ + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public final class TestCheckedList { + private static final Object OBJECT = new Object(); + + public static void main(String[] args) { + List list = Collections.emptyList(); + TestEncoder.test( + Collections.checkedList(list, String.class), + new ArrayList() { + private final Object type = OBJECT; + }, + OBJECT + ); + } +} diff --git a/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedMap.java b/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedMap.java new file mode 100644 index 00000000000..7105782b179 --- /dev/null +++ b/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedMap.java @@ -0,0 +1,49 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6777487 + * @summary Tests private field access for CheckedMap + * @author Sergey Malenkov + */ + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +public final class TestCheckedMap { + private static final Object OBJECT = new Object(); + + public static void main(String[] args) { + Map map = Collections.emptyMap(); + TestEncoder.test( + Collections.checkedMap(map, String.class, String.class), + new HashMap() { + private final Object keyType = OBJECT; + private final Object valueType = OBJECT; + }, + OBJECT + ); + } +} diff --git a/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedRandomAccessList.java b/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedRandomAccessList.java new file mode 100644 index 00000000000..5141bc80620 --- /dev/null +++ b/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedRandomAccessList.java @@ -0,0 +1,48 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6777487 + * @summary Tests private field access for CheckedRandomAccessList + * @author Sergey Malenkov + */ + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public final class TestCheckedRandomAccessList { + private static final Object OBJECT = new Object(); + + public static void main(String[] args) { + List list = new ArrayList(); + TestEncoder.test( + Collections.checkedList(list, String.class), + new ArrayList() { + private final Object type = OBJECT; + }, + OBJECT + ); + } +} diff --git a/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedSet.java b/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedSet.java new file mode 100644 index 00000000000..d4dd04160b0 --- /dev/null +++ b/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedSet.java @@ -0,0 +1,48 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6777487 + * @summary Tests private field access for CheckedSet + * @author Sergey Malenkov + */ + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +public final class TestCheckedSet { + private static final Object OBJECT = new Object(); + + public static void main(String[] args) { + Set set = Collections.emptySet(); + TestEncoder.test( + Collections.checkedSet(set, String.class), + new HashSet() { + private final Object type = OBJECT; + }, + OBJECT + ); + } +} diff --git a/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedSortedMap.java b/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedSortedMap.java new file mode 100644 index 00000000000..f39e7e2e060 --- /dev/null +++ b/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedSortedMap.java @@ -0,0 +1,49 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6777487 + * @summary Tests private field access for CheckedSortedMap + * @author Sergey Malenkov + */ + +import java.util.Collections; +import java.util.SortedMap; +import java.util.TreeMap; + +public final class TestCheckedSortedMap { + private static final Object OBJECT = new Object(); + + public static void main(String[] args) { + SortedMap map = new TreeMap(); + TestEncoder.test( + Collections.checkedSortedMap(map, String.class, String.class), + new TreeMap() { + private final Object keyType = OBJECT; + private final Object valueType = OBJECT; + }, + OBJECT + ); + } +} diff --git a/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedSortedSet.java b/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedSortedSet.java new file mode 100644 index 00000000000..f49c6ea3d94 --- /dev/null +++ b/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedSortedSet.java @@ -0,0 +1,48 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6777487 + * @summary Tests private field access for CheckedSortedSet + * @author Sergey Malenkov + */ + +import java.util.Collections; +import java.util.SortedSet; +import java.util.TreeSet; + +public final class TestCheckedSortedSet { + private static final Object OBJECT = new Object(); + + public static void main(String[] args) { + SortedSet set = new TreeSet(); + TestEncoder.test( + Collections.checkedSortedSet(set, String.class), + new TreeSet() { + private final Object type = OBJECT; + }, + OBJECT + ); + } +} diff --git a/jdk/test/java/beans/XMLEncoder/6777487/TestEncoder.java b/jdk/test/java/beans/XMLEncoder/6777487/TestEncoder.java new file mode 100644 index 00000000000..a06289c8738 --- /dev/null +++ b/jdk/test/java/beans/XMLEncoder/6777487/TestEncoder.java @@ -0,0 +1,60 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +import java.beans.Expression; +import java.beans.XMLEncoder; + +final class TestEncoder extends XMLEncoder { + private Expression expression; + + private TestEncoder() { + super(System.out); + } + + @Override + public void writeExpression(Expression expression) { + if (this.expression == null) { + this.expression = expression; + } + super.writeExpression(expression); + } + + public static void test(Object provider, Object object, Object value) { + System.setSecurityManager(new SecurityManager()); + + TestEncoder encoder = new TestEncoder(); + encoder.setPersistenceDelegate( + object.getClass(), + encoder.getPersistenceDelegate(provider.getClass())); + encoder.writeObject(object); + encoder.close(); + + if (encoder.expression != null) { + for (Object argument : encoder.expression.getArguments()) { + if (value.equals(argument)) { + throw new Error("Found private value!"); + } + } + } + } +} diff --git a/jdk/test/java/beans/XMLEncoder/6777487/TestEnumMap.java b/jdk/test/java/beans/XMLEncoder/6777487/TestEnumMap.java new file mode 100644 index 00000000000..1d046c63e88 --- /dev/null +++ b/jdk/test/java/beans/XMLEncoder/6777487/TestEnumMap.java @@ -0,0 +1,47 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6777487 + * @summary Tests private field access for EnumMap + * @author Sergey Malenkov + */ + +import java.util.EnumMap; +import java.util.HashMap; + +public final class TestEnumMap { + private static final Object OBJECT = new Object(); + + public static void main(String[] args) { + TestEncoder.test( + new EnumMap(Point.class), + new HashMap() { + private final Object keyType = OBJECT; + }, + OBJECT); + } + + public enum Point { X, Y, Z } +} diff --git a/jdk/test/java/beans/XMLEncoder/6777487/TestEnumSet.java b/jdk/test/java/beans/XMLEncoder/6777487/TestEnumSet.java new file mode 100644 index 00000000000..b9f518d9979 --- /dev/null +++ b/jdk/test/java/beans/XMLEncoder/6777487/TestEnumSet.java @@ -0,0 +1,47 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6777487 + * @summary Tests private field access for EnumSet + * @author Sergey Malenkov + */ + +import java.util.EnumSet; +import java.util.HashSet; + +public final class TestEnumSet { + private static final Object OBJECT = new Object(); + + public static void main(String[] args) { + TestEncoder.test( + EnumSet.noneOf(Point.class), + new HashSet() { + private final Object elementType = OBJECT; + }, + OBJECT); + } + + public enum Point { X, Y, Z } +} From d663bac9312a84730da246fa8fcd8ce080e220fd Mon Sep 17 00:00:00 2001 From: Peter Zhelezniakov Date: Tue, 5 May 2009 12:07:37 +0400 Subject: [PATCH 03/96] 6837293: Reapply fix for 6588003 to JDK7 Reviewed-by: alexp --- .../classes/javax/swing/text/LayoutQueue.java | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/text/LayoutQueue.java b/jdk/src/share/classes/javax/swing/text/LayoutQueue.java index 38fd665c40e..f1d73ffc0d8 100644 --- a/jdk/src/share/classes/javax/swing/text/LayoutQueue.java +++ b/jdk/src/share/classes/javax/swing/text/LayoutQueue.java @@ -25,6 +25,7 @@ package javax.swing.text; import java.util.Vector; +import sun.awt.AppContext; /** * A queue of text layout tasks. @@ -35,10 +36,10 @@ import java.util.Vector; */ public class LayoutQueue { - Vector tasks; - Thread worker; + private static final Object DEFAULT_QUEUE = new Object(); - static LayoutQueue defaultQueue; + private Vector tasks; + private Thread worker; /** * Construct a layout queue. @@ -51,10 +52,15 @@ public class LayoutQueue { * Fetch the default layout queue. */ public static LayoutQueue getDefaultQueue() { - if (defaultQueue == null) { - defaultQueue = new LayoutQueue(); + AppContext ac = AppContext.getAppContext(); + synchronized (DEFAULT_QUEUE) { + LayoutQueue defaultQueue = (LayoutQueue) ac.get(DEFAULT_QUEUE); + if (defaultQueue == null) { + defaultQueue = new LayoutQueue(); + ac.put(DEFAULT_QUEUE, defaultQueue); + } + return defaultQueue; } - return defaultQueue; } /** @@ -63,7 +69,9 @@ public class LayoutQueue { * @param q the new queue. */ public static void setDefaultQueue(LayoutQueue q) { - defaultQueue = q; + synchronized (DEFAULT_QUEUE) { + AppContext.getAppContext().put(DEFAULT_QUEUE, q); + } } /** From b23fe07b43057fcb66d2a463e8e8371ce6b2069c Mon Sep 17 00:00:00 2001 From: Jean-Christophe Collet Date: Tue, 5 May 2009 11:02:51 +0200 Subject: [PATCH 04/96] 6801497: Proxy is assumed to be immutable but is non-final Cloned the proxy instance when necessary Reviewed-by: chegar --- jdk/src/share/classes/java/net/Socket.java | 13 +++++++++---- jdk/src/share/classes/java/net/URL.java | 8 +++++--- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/jdk/src/share/classes/java/net/Socket.java b/jdk/src/share/classes/java/net/Socket.java index e0769176af3..110a6a5f1a9 100644 --- a/jdk/src/share/classes/java/net/Socket.java +++ b/jdk/src/share/classes/java/net/Socket.java @@ -114,9 +114,14 @@ class Socket implements java.io.Closeable { * @since 1.5 */ public Socket(Proxy proxy) { - if (proxy != null && proxy.type() == Proxy.Type.SOCKS) { + // Create a copy of Proxy as a security measure + if (proxy == null) { + throw new IllegalArgumentException("Invalid Proxy"); + } + Proxy p = proxy == Proxy.NO_PROXY ? Proxy.NO_PROXY : new Proxy(proxy.type(), proxy.address()); + if (p.type() == Proxy.Type.SOCKS) { SecurityManager security = System.getSecurityManager(); - InetSocketAddress epoint = (InetSocketAddress) proxy.address(); + InetSocketAddress epoint = (InetSocketAddress) p.address(); if (security != null) { if (epoint.isUnresolved()) security.checkConnect(epoint.getHostName(), @@ -125,10 +130,10 @@ class Socket implements java.io.Closeable { security.checkConnect(epoint.getAddress().getHostAddress(), epoint.getPort()); } - impl = new SocksSocketImpl(proxy); + impl = new SocksSocketImpl(p); impl.setSocket(this); } else { - if (proxy == Proxy.NO_PROXY) { + if (p == Proxy.NO_PROXY) { if (factory == null) { impl = new PlainSocketImpl(); impl.setSocket(this); diff --git a/jdk/src/share/classes/java/net/URL.java b/jdk/src/share/classes/java/net/URL.java index bb934d9b745..73818e960d8 100644 --- a/jdk/src/share/classes/java/net/URL.java +++ b/jdk/src/share/classes/java/net/URL.java @@ -1004,16 +1004,18 @@ public final class URL implements java.io.Serializable { throw new IllegalArgumentException("proxy can not be null"); } + // Create a copy of Proxy as a security measure + Proxy p = proxy == Proxy.NO_PROXY ? Proxy.NO_PROXY : new Proxy(proxy.type(), proxy.address()); SecurityManager sm = System.getSecurityManager(); - if (proxy.type() != Proxy.Type.DIRECT && sm != null) { - InetSocketAddress epoint = (InetSocketAddress) proxy.address(); + if (p.type() != Proxy.Type.DIRECT && sm != null) { + InetSocketAddress epoint = (InetSocketAddress) p.address(); if (epoint.isUnresolved()) sm.checkConnect(epoint.getHostName(), epoint.getPort()); else sm.checkConnect(epoint.getAddress().getHostAddress(), epoint.getPort()); } - return handler.openConnection(this, proxy); + return handler.openConnection(this, p); } /** From 2453a64fc4954f7a2b13cf20f13583cc542fa0a3 Mon Sep 17 00:00:00 2001 From: Anthony Petrov Date: Tue, 5 May 2009 17:47:04 +0400 Subject: [PATCH 05/96] 6805231: Security Warning Icon is missing in Windows 2000 Prof from Jdk build 6u12 The icon becomes layered only when the fading-out effect is being performed. Reviewed-by: art, dcherepanov --- .../windows/native/sun/windows/awt_Window.cpp | 36 ++++++++++++++----- .../windows/native/sun/windows/awt_Window.h | 3 ++ 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/jdk/src/windows/native/sun/windows/awt_Window.cpp b/jdk/src/windows/native/sun/windows/awt_Window.cpp index 88bcd8ecc45..3e31a1c8db8 100644 --- a/jdk/src/windows/native/sun/windows/awt_Window.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Window.cpp @@ -524,7 +524,7 @@ void AwtWindow::CreateWarningWindow(JNIEnv *env) RegisterWarningWindowClass(); warningWindow = ::CreateWindowEx( - WS_EX_NOACTIVATE | WS_EX_LAYERED, + WS_EX_NOACTIVATE, GetWarningWindowClassName(), warningString, WS_POPUP, @@ -536,7 +536,7 @@ void AwtWindow::CreateWarningWindow(JNIEnv *env) NULL // lParam ); if (warningWindow == NULL) { - //XXX: actually this is bad... We didn't manage to create the widow. + //XXX: actually this is bad... We didn't manage to create the window. return; } @@ -836,6 +836,19 @@ void AwtWindow::RepaintWarningWindow() ::ReleaseDC(warningWindow, hdc); } +void AwtWindow::SetLayered(HWND window, bool layered) +{ + const LONG ex_style = ::GetWindowLong(window, GWL_EXSTYLE); + ::SetWindowLong(window, GWL_EXSTYLE, layered ? + ex_style | WS_EX_LAYERED : ex_style & ~WS_EX_LAYERED); +} + +bool AwtWindow::IsLayered(HWND window) +{ + const LONG ex_style = ::GetWindowLong(window, GWL_EXSTYLE); + return ex_style & WS_EX_LAYERED; +} + void AwtWindow::StartSecurityAnimation(AnimationKind kind) { if (!IsUntrusted()) { @@ -858,8 +871,14 @@ void AwtWindow::StartSecurityAnimation(AnimationKind kind) ::SetLayeredWindowAttributes(warningWindow, RGB(0, 0, 0), 0xFF, LWA_ALPHA); + AwtWindow::SetLayered(warningWindow, false); ::RedrawWindow(warningWindow, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); + } else if (securityAnimationKind == akPreHide) { + // Pre-hiding means fading-out. We have to make the window layered. + // Note: Some VNC clients do not support layered windows, hence + // we dynamically turn it on and off. See 6805231. + AwtWindow::SetLayered(warningWindow, true); } } @@ -2528,8 +2547,6 @@ void AwtWindow::SetTranslucency(BYTE opacity, BOOL opaque) HWND hwnd = GetHWnd(); - LONG ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE); - if (opaque != old_opaque) { ::EnterCriticalSection(&contentBitmapCS); if (hContentBitmap != NULL) { @@ -2541,21 +2558,22 @@ void AwtWindow::SetTranslucency(BYTE opacity, BOOL opaque) if (opaque && opacity == 0xff) { // Turn off all the effects - ::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style & ~WS_EX_LAYERED); + AwtWindow::SetLayered(hwnd, false); + // Ask the window to repaint itself and all the children RedrawWindow(); } else { // We're going to enable some effects - if (!(ex_style & WS_EX_LAYERED)) { - ::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style | WS_EX_LAYERED); + if (!AwtWindow::IsLayered(hwnd)) { + AwtWindow::SetLayered(hwnd, true); } else { if ((opaque && opacity < 0xff) ^ (old_opaque && old_opacity < 0xff)) { // _One_ of the modes uses the SetLayeredWindowAttributes. // Need to reset the style in this case. // If both modes are simple (i.e. just changing the opacity level), // no need to reset the style. - ::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style & ~WS_EX_LAYERED); - ::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style | WS_EX_LAYERED); + AwtWindow::SetLayered(hwnd, false); + AwtWindow::SetLayered(hwnd, true); } } diff --git a/jdk/src/windows/native/sun/windows/awt_Window.h b/jdk/src/windows/native/sun/windows/awt_Window.h index bf43150a7e8..40da9979bcd 100644 --- a/jdk/src/windows/native/sun/windows/awt_Window.h +++ b/jdk/src/windows/native/sun/windows/awt_Window.h @@ -332,6 +332,9 @@ private: void RepositionSecurityWarning(JNIEnv *env); + static void SetLayered(HWND window, bool layered); + static bool IsLayered(HWND window); + public: void UpdateSecurityWarningVisibility(); static bool IsWarningWindow(HWND hWnd); From dfb6852a1624bfa42b89ad993ec832bfab0b5d89 Mon Sep 17 00:00:00 2001 From: Anthony Petrov Date: Tue, 5 May 2009 17:56:31 +0400 Subject: [PATCH 06/96] 6818787: It is possible to reposition the security icon too far from the border of the window on X11 The constraints for the position of the icon are moved to the shared code Reviewed-by: art, dcherepanov --- jdk/src/share/classes/java/awt/Window.java | 54 ++++++++++++++++--- .../windows/native/sun/windows/awt_Window.cpp | 25 --------- 2 files changed, 47 insertions(+), 32 deletions(-) diff --git a/jdk/src/share/classes/java/awt/Window.java b/jdk/src/share/classes/java/awt/Window.java index 01d9ff59d00..faff2758726 100644 --- a/jdk/src/share/classes/java/awt/Window.java +++ b/jdk/src/share/classes/java/awt/Window.java @@ -3593,16 +3593,56 @@ public class Window extends Container implements Accessible { // ****************** END OF MIXING CODE ******************************** - // This method gets the window location/size as reported by the native - // system since the locally cached values may represent outdated data. - // NOTE: this method is invoked on the toolkit thread, and therefore - // is not supposed to become public/user-overridable. + /** + * Limit the given double value with the given range. + */ + private static double limit(double value, double min, double max) { + value = Math.max(value, min); + value = Math.min(value, max); + return value; + } + + /** + * Calculate the position of the security warning. + * + * This method gets the window location/size as reported by the native + * system since the locally cached values may represent outdated data. + * + * The method is used from the native code, or via AWTAccessor. + * + * NOTE: this method is invoked on the toolkit thread, and therefore is not + * supposed to become public/user-overridable. + */ private Point2D calculateSecurityWarningPosition(double x, double y, double w, double h) { - return new Point2D.Double( - x + w * securityWarningAlignmentX + securityWarningPointX, - y + h * securityWarningAlignmentY + securityWarningPointY); + // The position according to the spec of SecurityWarning.setPosition() + double wx = x + w * securityWarningAlignmentX + securityWarningPointX; + double wy = y + h * securityWarningAlignmentY + securityWarningPointY; + + // First, make sure the warning is not too far from the window bounds + wx = Window.limit(wx, + x - securityWarningWidth - 2, + x + w + 2); + wy = Window.limit(wy, + y - securityWarningHeight - 2, + y + h + 2); + + // Now make sure the warning window is visible on the screen + Rectangle screenBounds = graphicsConfig.getBounds(); + Insets screenInsets = + Toolkit.getDefaultToolkit().getScreenInsets(graphicsConfig); + + wx = Window.limit(wx, + screenBounds.x + screenInsets.left, + screenBounds.x + screenBounds.width - screenInsets.right + - securityWarningWidth); + wy = Window.limit(wy, + screenBounds.y + screenInsets.top, + screenBounds.y + screenBounds.height - screenInsets.bottom + - securityWarningHeight); + + return new Point2D.Double(wx, wy); } static { diff --git a/jdk/src/windows/native/sun/windows/awt_Window.cpp b/jdk/src/windows/native/sun/windows/awt_Window.cpp index 3e31a1c8db8..39f61bb7543 100644 --- a/jdk/src/windows/native/sun/windows/awt_Window.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Window.cpp @@ -707,31 +707,6 @@ void AwtWindow::CalculateWarningWindowBounds(JNIEnv *env, LPRECT rect) env->DeleteLocalRef(point2D); - //Make sure the warning is not far from the window bounds - x = max(x, windowBounds.left - (int)warningWindowWidth - 2); - x = min(x, windowBounds.right + (int)warningWindowWidth + 2); - - y = max(y, windowBounds.top - (int)warningWindowHeight - 2); - y = min(y, windowBounds.bottom + (int)warningWindowHeight + 2); - - // Now make sure the warning window is visible on the screen - HMONITOR hmon = MonitorFromWindow(GetHWnd(), MONITOR_DEFAULTTOPRIMARY); - DASSERT(hmon != NULL); - - RECT monitorBounds; - RECT monitorInsets; - - MonitorBounds(hmon, &monitorBounds); - if (!AwtToolkit::GetScreenInsets(m_screenNum, &monitorInsets)) { - ::ZeroMemory(&monitorInsets, sizeof(monitorInsets)); - } - - x = max(x, monitorBounds.left + monitorInsets.left); - x = min(x, monitorBounds.right - monitorInsets.right - (int)warningWindowWidth); - - y = max(y, monitorBounds.top + monitorInsets.top); - y = min(y, monitorBounds.bottom - monitorInsets.bottom - (int)warningWindowHeight); - rect->left = x; rect->top = y; rect->right = rect->left + warningWindowWidth; From f6e8569c858067188a8d84e91d91dafa4aaa0a71 Mon Sep 17 00:00:00 2001 From: Artem Ananiev Date: Wed, 6 May 2009 15:17:22 +0400 Subject: [PATCH 07/96] 6656586: Cursor.predefined is protected static mutable (findbugs) Reviewed-by: hawtin, igor --- jdk/src/share/classes/java/awt/Cursor.java | 21 ++++++-- .../PredefinedPrivate/PredefinedPrivate.java | 49 +++++++++++++++++++ 2 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 jdk/test/java/awt/Cursor/PredefinedPrivate/PredefinedPrivate.java diff --git a/jdk/src/share/classes/java/awt/Cursor.java b/jdk/src/share/classes/java/awt/Cursor.java index cc1b20b999a..0187eac69b9 100644 --- a/jdk/src/share/classes/java/awt/Cursor.java +++ b/jdk/src/share/classes/java/awt/Cursor.java @@ -118,8 +118,18 @@ public class Cursor implements java.io.Serializable { */ public static final int MOVE_CURSOR = 13; + /** + * @deprecated As of JDK version 1.7, the {@link #getPredefinedCursor()} + * method should be used instead. + */ + @Deprecated protected static Cursor predefined[] = new Cursor[14]; + /** + * This field is a private replacement for 'predefined' array. + */ + private final static Cursor[] predefinedPrivate = new Cursor[14]; + /* Localization names and default values */ static final String[][] cursorProperties = { { "AWT.DefaultCursor", "Default Cursor" }, @@ -253,10 +263,15 @@ public class Cursor implements java.io.Serializable { if (type < Cursor.DEFAULT_CURSOR || type > Cursor.MOVE_CURSOR) { throw new IllegalArgumentException("illegal cursor type"); } - if (predefined[type] == null) { - predefined[type] = new Cursor(type); + Cursor c = predefinedPrivate[type]; + if (c == null) { + predefinedPrivate[type] = c = new Cursor(type); } - return predefined[type]; + // fill 'predefined' array for backwards compatibility. + if (predefined[type] == null) { + predefined[type] = c; + } + return c; } /** diff --git a/jdk/test/java/awt/Cursor/PredefinedPrivate/PredefinedPrivate.java b/jdk/test/java/awt/Cursor/PredefinedPrivate/PredefinedPrivate.java new file mode 100644 index 00000000000..a4ba1daaca4 --- /dev/null +++ b/jdk/test/java/awt/Cursor/PredefinedPrivate/PredefinedPrivate.java @@ -0,0 +1,49 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6656586 + * @summary Test that Cursor.predefined array is not used in +Cursor.getPredefinedCursor() method + * @author Artem Ananiev + * @run main PredefinedPrivate + */ + +import java.awt.*; + +public class PredefinedPrivate { + public static void main(String args[]) { + new MyCursor(); + if (Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR) instanceof MyCursor) { + throw new RuntimeException("Test FAILED: getPredefinedCursor() returned modified cursor"); + } + } +} + +class MyCursor extends Cursor { + public MyCursor() { + super(DEFAULT_CURSOR); + Cursor.predefined[DEFAULT_CURSOR] = this; + } +} From ec41d4d0e931bf22dbfbcda44d506c9a44a3091d Mon Sep 17 00:00:00 2001 From: Eamonn McManus Date: Thu, 7 May 2009 10:44:45 +0200 Subject: [PATCH 08/96] 6736293: OpenType checks can be bypassed through finalizer resurrection Reviewed-by: hawtin --- jdk/src/share/classes/java/awt/Window.java | 2 ++ .../openmbean/OpenMBeanAttributeInfoSupport.java | 8 ++++---- .../classes/javax/management/openmbean/OpenType.java | 5 +++++ 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/jdk/src/share/classes/java/awt/Window.java b/jdk/src/share/classes/java/awt/Window.java index faff2758726..920b499c9a3 100644 --- a/jdk/src/share/classes/java/awt/Window.java +++ b/jdk/src/share/classes/java/awt/Window.java @@ -3629,6 +3629,8 @@ public class Window extends Container implements Accessible { y + h + 2); // Now make sure the warning window is visible on the screen + GraphicsConfiguration graphicsConfig = + getGraphicsConfiguration_NoClientCode(); Rectangle screenBounds = graphicsConfig.getBounds(); Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(graphicsConfig); diff --git a/jdk/src/share/classes/javax/management/openmbean/OpenMBeanAttributeInfoSupport.java b/jdk/src/share/classes/javax/management/openmbean/OpenMBeanAttributeInfoSupport.java index 3ad03ef58ae..f2f86e1bf72 100644 --- a/jdk/src/share/classes/javax/management/openmbean/OpenMBeanAttributeInfoSupport.java +++ b/jdk/src/share/classes/javax/management/openmbean/OpenMBeanAttributeInfoSupport.java @@ -690,7 +690,7 @@ public class OpenMBeanAttributeInfoSupport private static T convertFromString(String s, OpenType openType) { Class c; try { - c = cast(Class.forName(openType.getClassName())); + c = cast(Class.forName(openType.safeGetClassName())); } catch (ClassNotFoundException e) { throw new NoClassDefFoundError(e.toString()); // can't happen } @@ -711,7 +711,7 @@ public class OpenMBeanAttributeInfoSupport } catch (Exception e) { final String msg = "Could not convert \"" + s + "\" using method: " + valueOf; - throw new IllegalArgumentException(msg); + throw new IllegalArgumentException(msg, e); } } @@ -728,7 +728,7 @@ public class OpenMBeanAttributeInfoSupport } catch (Exception e) { final String msg = "Could not convert \"" + s + "\" using constructor: " + con; - throw new IllegalArgumentException(msg); + throw new IllegalArgumentException(msg, e); } } @@ -757,7 +757,7 @@ public class OpenMBeanAttributeInfoSupport stringArrayClass = Class.forName(squareBrackets + "Ljava.lang.String;"); targetArrayClass = - Class.forName(squareBrackets + "L" + baseType.getClassName() + + Class.forName(squareBrackets + "L" + baseType.safeGetClassName() + ";"); } catch (ClassNotFoundException e) { throw new NoClassDefFoundError(e.toString()); // can't happen diff --git a/jdk/src/share/classes/javax/management/openmbean/OpenType.java b/jdk/src/share/classes/javax/management/openmbean/OpenType.java index 3f74c3cda60..b6d40d008c7 100644 --- a/jdk/src/share/classes/javax/management/openmbean/OpenType.java +++ b/jdk/src/share/classes/javax/management/openmbean/OpenType.java @@ -304,7 +304,12 @@ public abstract class OpenType implements Serializable { * @return the class name. */ public String getClassName() { + return className; + } + // A version of getClassName() that can only be called from within this + // package and that cannot be overridden. + String safeGetClassName() { return className; } From 10f62128a45fa6384621e57b86cc18475ee7fa27 Mon Sep 17 00:00:00 2001 From: Andrew Brygin Date: Fri, 8 May 2009 15:38:21 +0400 Subject: [PATCH 09/96] 6656625: ImageReaderSpi.STANDARD_INPUT_TYPE/ImageWriterSpi.STANDARD_OUTPUT_TYPE are mutable static (findbugs) Reviewed-by: prr --- .../sun/imageio/plugins/bmp/BMPImageReaderSpi.java | 2 +- .../sun/imageio/plugins/bmp/BMPImageWriterSpi.java | 3 ++- .../sun/imageio/plugins/gif/GIFImageReaderSpi.java | 2 +- .../sun/imageio/plugins/gif/GIFImageWriterSpi.java | 3 ++- .../imageio/plugins/jpeg/JPEGImageReaderSpi.java | 2 +- .../imageio/plugins/jpeg/JPEGImageWriterSpi.java | 3 ++- .../sun/imageio/plugins/png/PNGImageReaderSpi.java | 2 +- .../sun/imageio/plugins/png/PNGImageWriterSpi.java | 3 ++- .../imageio/plugins/wbmp/WBMPImageReaderSpi.java | 2 +- .../imageio/plugins/wbmp/WBMPImageWriterSpi.java | 3 ++- .../classes/javax/imageio/spi/ImageReaderSpi.java | 9 ++++++++- .../classes/javax/imageio/spi/ImageWriterSpi.java | 13 ++++++++++--- 12 files changed, 33 insertions(+), 14 deletions(-) diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageReaderSpi.java b/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageReaderSpi.java index 9cea55911f7..2966a4b883c 100644 --- a/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageReaderSpi.java +++ b/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageReaderSpi.java @@ -51,7 +51,7 @@ public class BMPImageReaderSpi extends ImageReaderSpi { entensions, mimeType, "com.sun.imageio.plugins.bmp.BMPImageReader", - STANDARD_INPUT_TYPE, + new Class[] { ImageInputStream.class }, writerSpiNames, false, null, null, null, null, diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageWriterSpi.java b/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageWriterSpi.java index f5e322e01da..4ae73d4c897 100644 --- a/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageWriterSpi.java +++ b/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageWriterSpi.java @@ -32,6 +32,7 @@ import java.awt.image.SinglePixelPackedSampleModel; import javax.imageio.spi.ImageWriterSpi; import javax.imageio.spi.ServiceRegistry; import javax.imageio.spi.IIORegistry; +import javax.imageio.stream.ImageOutputStream; import javax.imageio.ImageWriter; import javax.imageio.ImageTypeSpecifier; import javax.imageio.IIOException; @@ -55,7 +56,7 @@ public class BMPImageWriterSpi extends ImageWriterSpi { entensions, mimeType, "com.sun.imageio.plugins.bmp.BMPImageWriter", - STANDARD_OUTPUT_TYPE, + new Class[] { ImageOutputStream.class }, readerSpiNames, false, null, null, null, null, diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageReaderSpi.java b/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageReaderSpi.java index 0dc0a40a6d7..3832b1eb923 100644 --- a/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageReaderSpi.java +++ b/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageReaderSpi.java @@ -60,7 +60,7 @@ public class GIFImageReaderSpi extends ImageReaderSpi { suffixes, MIMETypes, readerClassName, - STANDARD_INPUT_TYPE, + new Class[] { ImageInputStream.class }, writerSpiNames, true, GIFStreamMetadata.nativeMetadataFormatName, diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageWriterSpi.java b/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageWriterSpi.java index 796e3b2a458..42b81e4c8b8 100644 --- a/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageWriterSpi.java +++ b/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageWriterSpi.java @@ -31,6 +31,7 @@ import java.util.Locale; import javax.imageio.ImageTypeSpecifier; import javax.imageio.ImageWriter; import javax.imageio.spi.ImageWriterSpi; +import javax.imageio.stream.ImageOutputStream; import com.sun.imageio.plugins.common.PaletteBuilder; public class GIFImageWriterSpi extends ImageWriterSpi { @@ -59,7 +60,7 @@ public class GIFImageWriterSpi extends ImageWriterSpi { suffixes, MIMETypes, writerClassName, - STANDARD_OUTPUT_TYPE, + new Class[] { ImageOutputStream.class }, readerSpiNames, true, GIFWritableStreamMetadata.NATIVE_FORMAT_NAME, diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReaderSpi.java b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReaderSpi.java index 13327e3ea9c..25aabe32e90 100644 --- a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReaderSpi.java +++ b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReaderSpi.java @@ -46,7 +46,7 @@ public class JPEGImageReaderSpi extends ImageReaderSpi { JPEG.suffixes, JPEG.MIMETypes, "com.sun.imageio.plugins.jpeg.JPEGImageReader", - STANDARD_INPUT_TYPE, + new Class[] { ImageInputStream.class }, writerSpiNames, true, JPEG.nativeStreamMetadataFormatName, diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriterSpi.java b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriterSpi.java index 717b4360794..02fade632ed 100644 --- a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriterSpi.java +++ b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriterSpi.java @@ -28,6 +28,7 @@ package com.sun.imageio.plugins.jpeg; import javax.imageio.spi.ImageWriterSpi; import javax.imageio.spi.ServiceRegistry; import javax.imageio.spi.IIORegistry; +import javax.imageio.stream.ImageOutputStream; import javax.imageio.ImageWriter; import javax.imageio.ImageTypeSpecifier; import javax.imageio.IIOException; @@ -49,7 +50,7 @@ public class JPEGImageWriterSpi extends ImageWriterSpi { JPEG.suffixes, JPEG.MIMETypes, "com.sun.imageio.plugins.jpeg.JPEGImageWriter", - STANDARD_OUTPUT_TYPE, + new Class[] { ImageOutputStream.class }, readerSpiNames, true, JPEG.nativeStreamMetadataFormatName, diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageReaderSpi.java b/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageReaderSpi.java index 44ee5b80101..6576b83df58 100644 --- a/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageReaderSpi.java +++ b/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageReaderSpi.java @@ -60,7 +60,7 @@ public class PNGImageReaderSpi extends ImageReaderSpi { suffixes, MIMETypes, readerClassName, - STANDARD_INPUT_TYPE, + new Class[] { ImageInputStream.class }, writerSpiNames, false, null, null, diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageWriterSpi.java b/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageWriterSpi.java index 0dabd881816..4f69fcd70de 100644 --- a/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageWriterSpi.java +++ b/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageWriterSpi.java @@ -34,6 +34,7 @@ import javax.imageio.ImageTypeSpecifier; import javax.imageio.metadata.IIOMetadataFormat; import javax.imageio.metadata.IIOMetadataFormatImpl; import javax.imageio.spi.ImageWriterSpi; +import javax.imageio.stream.ImageOutputStream; public class PNGImageWriterSpi extends ImageWriterSpi { @@ -61,7 +62,7 @@ public class PNGImageWriterSpi extends ImageWriterSpi { suffixes, MIMETypes, writerClassName, - STANDARD_OUTPUT_TYPE, + new Class[] { ImageOutputStream.class }, readerSpiNames, false, null, null, diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/wbmp/WBMPImageReaderSpi.java b/jdk/src/share/classes/com/sun/imageio/plugins/wbmp/WBMPImageReaderSpi.java index 2d882ab6b2c..7e5e6e61e0e 100644 --- a/jdk/src/share/classes/com/sun/imageio/plugins/wbmp/WBMPImageReaderSpi.java +++ b/jdk/src/share/classes/com/sun/imageio/plugins/wbmp/WBMPImageReaderSpi.java @@ -51,7 +51,7 @@ public class WBMPImageReaderSpi extends ImageReaderSpi { entensions, mimeType, "com.sun.imageio.plugins.wbmp.WBMPImageReader", - STANDARD_INPUT_TYPE, + new Class[] { ImageInputStream.class }, writerSpiNames, true, null, null, null, null, diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/wbmp/WBMPImageWriterSpi.java b/jdk/src/share/classes/com/sun/imageio/plugins/wbmp/WBMPImageWriterSpi.java index 1da8420dc32..82106f981f5 100644 --- a/jdk/src/share/classes/com/sun/imageio/plugins/wbmp/WBMPImageWriterSpi.java +++ b/jdk/src/share/classes/com/sun/imageio/plugins/wbmp/WBMPImageWriterSpi.java @@ -28,6 +28,7 @@ package com.sun.imageio.plugins.wbmp; import javax.imageio.spi.ImageWriterSpi; import javax.imageio.spi.ServiceRegistry; import javax.imageio.spi.IIORegistry; +import javax.imageio.stream.ImageOutputStream; import javax.imageio.ImageWriter; import javax.imageio.ImageTypeSpecifier; import javax.imageio.IIOException; @@ -54,7 +55,7 @@ public class WBMPImageWriterSpi extends ImageWriterSpi { entensions, mimeType, "com.sun.imageio.plugins.wbmp.WBMPImageWriter", - STANDARD_OUTPUT_TYPE, + new Class[] { ImageOutputStream.class }, readerSpiNames, true, null, null, null, null, diff --git a/jdk/src/share/classes/javax/imageio/spi/ImageReaderSpi.java b/jdk/src/share/classes/javax/imageio/spi/ImageReaderSpi.java index 4f0b7fa6ac5..0de66188ba8 100644 --- a/jdk/src/share/classes/javax/imageio/spi/ImageReaderSpi.java +++ b/jdk/src/share/classes/javax/imageio/spi/ImageReaderSpi.java @@ -77,7 +77,10 @@ public abstract class ImageReaderSpi extends ImageReaderWriterSpi { * A single-element array, initially containing * ImageInputStream.class, to be returned from * getInputTypes. + * @deprecated Instead of using this field, directly create + * the equivalent array { ImageInputStream.class }. */ + @Deprecated public static final Class[] STANDARD_INPUT_TYPE = { ImageInputStream.class }; @@ -227,7 +230,11 @@ public abstract class ImageReaderSpi extends ImageReaderWriterSpi { throw new IllegalArgumentException ("inputTypes.length == 0!"); } - this.inputTypes = (Class[])inputTypes.clone(); + + this.inputTypes = (inputTypes == STANDARD_INPUT_TYPE) ? + new Class[] { ImageInputStream.class } : + inputTypes.clone(); + // If length == 0, leave it null if (writerSpiNames != null && writerSpiNames.length > 0) { this.writerSpiNames = (String[])writerSpiNames.clone(); diff --git a/jdk/src/share/classes/javax/imageio/spi/ImageWriterSpi.java b/jdk/src/share/classes/javax/imageio/spi/ImageWriterSpi.java index 324c5cd3d05..f3ff947a4f4 100644 --- a/jdk/src/share/classes/javax/imageio/spi/ImageWriterSpi.java +++ b/jdk/src/share/classes/javax/imageio/spi/ImageWriterSpi.java @@ -77,9 +77,12 @@ public abstract class ImageWriterSpi extends ImageReaderWriterSpi { /** * A single-element array, initially containing - * ImageInputStream.class, to be returned from - * getInputTypes. + * ImageOutputStream.class, to be returned from + * getOutputTypes. + * @deprecated Instead of using this field, directly create + * the equivalent array { ImageOutputStream.class }. */ + @Deprecated public static final Class[] STANDARD_OUTPUT_TYPE = { ImageOutputStream.class }; @@ -228,7 +231,11 @@ public abstract class ImageWriterSpi extends ImageReaderWriterSpi { throw new IllegalArgumentException ("outputTypes.length == 0!"); } - this.outputTypes = (Class[])outputTypes.clone(); + + this.outputTypes = (outputTypes == STANDARD_OUTPUT_TYPE) ? + new Class[] { ImageOutputStream.class } : + outputTypes.clone(); + // If length == 0, leave it null if (readerSpiNames != null && readerSpiNames.length > 0) { this.readerSpiNames = (String[])readerSpiNames.clone(); From 8fdb1d367a6988246045d77dba7ce3e9b4eab893 Mon Sep 17 00:00:00 2001 From: Andrew Brygin Date: Fri, 8 May 2009 15:57:33 +0400 Subject: [PATCH 10/96] 6657133: Mutable statics in imageio plugins (findbugs) Reviewed-by: prr --- .../com/sun/imageio/stream/StreamCloser.java | 44 +++++++++++++------ .../plugins/bmp/BMPImageWriteParam.java | 2 +- .../stream/FileCacheImageInputStream.java | 10 ++++- .../stream/FileCacheImageOutputStream.java | 10 ++++- jdk/src/share/lib/security/java.security | 2 +- .../share/lib/security/java.security-solaris | 2 +- .../share/lib/security/java.security-windows | 2 +- 7 files changed, 51 insertions(+), 21 deletions(-) diff --git a/jdk/src/share/classes/com/sun/imageio/stream/StreamCloser.java b/jdk/src/share/classes/com/sun/imageio/stream/StreamCloser.java index 03c6ce32364..96e5646f782 100644 --- a/jdk/src/share/classes/com/sun/imageio/stream/StreamCloser.java +++ b/jdk/src/share/classes/com/sun/imageio/stream/StreamCloser.java @@ -43,35 +43,35 @@ import javax.imageio.stream.ImageInputStream; */ public class StreamCloser { - private static WeakHashMap toCloseQueue; + private static WeakHashMap toCloseQueue; private static Thread streamCloser; - public static void addToQueue(ImageInputStream iis) { + public static void addToQueue(CloseAction ca) { synchronized (StreamCloser.class) { if (toCloseQueue == null) { toCloseQueue = - new WeakHashMap(); + new WeakHashMap(); } - toCloseQueue.put(iis, null); + toCloseQueue.put(ca, null); if (streamCloser == null) { final Runnable streamCloserRunnable = new Runnable() { public void run() { if (toCloseQueue != null) { synchronized (StreamCloser.class) { - Set set = + Set set = toCloseQueue.keySet(); // Make a copy of the set in order to avoid // concurrent modification (the is.close() // will in turn call removeFromQueue()) - ImageInputStream[] streams = - new ImageInputStream[set.size()]; - streams = set.toArray(streams); - for (ImageInputStream is : streams) { - if (is != null) { + CloseAction[] actions = + new CloseAction[set.size()]; + actions = set.toArray(actions); + for (CloseAction ca : actions) { + if (ca != null) { try { - is.close(); + ca.performAction(); } catch (IOException e) { } } @@ -106,10 +106,28 @@ public class StreamCloser { } } - public static void removeFromQueue(ImageInputStream iis) { + public static void removeFromQueue(CloseAction ca) { synchronized (StreamCloser.class) { if (toCloseQueue != null) { - toCloseQueue.remove(iis); + toCloseQueue.remove(ca); + } + } + } + + public static CloseAction createCloseAction(ImageInputStream iis) { + return new CloseAction(iis); + } + + public static final class CloseAction { + private ImageInputStream iis; + + private CloseAction(ImageInputStream iis) { + this.iis = iis; + } + + public void performAction() throws IOException { + if (iis != null) { + iis.close(); } } } diff --git a/jdk/src/share/classes/javax/imageio/plugins/bmp/BMPImageWriteParam.java b/jdk/src/share/classes/javax/imageio/plugins/bmp/BMPImageWriteParam.java index ec3acf2e9db..e11057f2a48 100644 --- a/jdk/src/share/classes/javax/imageio/plugins/bmp/BMPImageWriteParam.java +++ b/jdk/src/share/classes/javax/imageio/plugins/bmp/BMPImageWriteParam.java @@ -78,7 +78,7 @@ public class BMPImageWriteParam extends ImageWriteParam { super(locale); // Set compression types ("BI_RGB" denotes uncompressed). - compressionTypes = BMPConstants.compressionTypeNames; + compressionTypes = BMPConstants.compressionTypeNames.clone(); // Set compression flag. canWriteCompressed = true; diff --git a/jdk/src/share/classes/javax/imageio/stream/FileCacheImageInputStream.java b/jdk/src/share/classes/javax/imageio/stream/FileCacheImageInputStream.java index ad03d65c04d..1bff7746344 100644 --- a/jdk/src/share/classes/javax/imageio/stream/FileCacheImageInputStream.java +++ b/jdk/src/share/classes/javax/imageio/stream/FileCacheImageInputStream.java @@ -62,6 +62,10 @@ public class FileCacheImageInputStream extends ImageInputStreamImpl { /** The DisposerRecord that closes the underlying cache. */ private final DisposerRecord disposerRecord; + /** The CloseAction that closes the stream in + * the StreamCloser's shutdown hook */ + private final StreamCloser.CloseAction closeAction; + /** * Constructs a FileCacheImageInputStream that will read * from a given InputStream. @@ -96,7 +100,9 @@ public class FileCacheImageInputStream extends ImageInputStreamImpl { this.cacheFile = File.createTempFile("imageio", ".tmp", cacheDir); this.cache = new RandomAccessFile(cacheFile, "rw"); - StreamCloser.addToQueue(this); + + this.closeAction = StreamCloser.createCloseAction(this); + StreamCloser.addToQueue(closeAction); disposerRecord = new StreamDisposerRecord(cacheFile, cache); if (getClass() == FileCacheImageInputStream.class) { @@ -242,7 +248,7 @@ public class FileCacheImageInputStream extends ImageInputStreamImpl { stream = null; cache = null; cacheFile = null; - StreamCloser.removeFromQueue(this); + StreamCloser.removeFromQueue(closeAction); } /** diff --git a/jdk/src/share/classes/javax/imageio/stream/FileCacheImageOutputStream.java b/jdk/src/share/classes/javax/imageio/stream/FileCacheImageOutputStream.java index f6387125499..f079e8e81fa 100644 --- a/jdk/src/share/classes/javax/imageio/stream/FileCacheImageOutputStream.java +++ b/jdk/src/share/classes/javax/imageio/stream/FileCacheImageOutputStream.java @@ -48,6 +48,10 @@ public class FileCacheImageOutputStream extends ImageOutputStreamImpl { // Pos after last (rightmost) byte written private long maxStreamPos = 0L; + /** The CloseAction that closes the stream in + * the StreamCloser's shutdown hook */ + private final StreamCloser.CloseAction closeAction; + /** * Constructs a FileCacheImageOutputStream that will write * to a given outputStream. @@ -82,7 +86,9 @@ public class FileCacheImageOutputStream extends ImageOutputStreamImpl { this.cacheFile = File.createTempFile("imageio", ".tmp", cacheDir); this.cache = new RandomAccessFile(cacheFile, "rw"); - StreamCloser.addToQueue(this); + + this.closeAction = StreamCloser.createCloseAction(this); + StreamCloser.addToQueue(closeAction); } public int read() throws IOException { @@ -227,7 +233,7 @@ public class FileCacheImageOutputStream extends ImageOutputStreamImpl { cacheFile = null; stream.flush(); stream = null; - StreamCloser.removeFromQueue(this); + StreamCloser.removeFromQueue(closeAction); } public void flushBefore(long pos) throws IOException { diff --git a/jdk/src/share/lib/security/java.security b/jdk/src/share/lib/security/java.security index eadfe715b51..c2a07506c15 100644 --- a/jdk/src/share/lib/security/java.security +++ b/jdk/src/share/lib/security/java.security @@ -127,7 +127,7 @@ system.scope=sun.security.provider.IdentityDatabase # passed to checkPackageAccess unless the # corresponding RuntimePermission ("accessClassInPackage."+package) has # been granted. -package.access=sun. +package.access=sun.,com.sun.imageio. # # List of comma-separated packages that start with or equal this string diff --git a/jdk/src/share/lib/security/java.security-solaris b/jdk/src/share/lib/security/java.security-solaris index 58fbc9d15cd..05dfcb17728 100644 --- a/jdk/src/share/lib/security/java.security-solaris +++ b/jdk/src/share/lib/security/java.security-solaris @@ -128,7 +128,7 @@ system.scope=sun.security.provider.IdentityDatabase # passed to checkPackageAccess unless the # corresponding RuntimePermission ("accessClassInPackage."+package) has # been granted. -package.access=sun. +package.access=sun.,com.sun.imageio. # # List of comma-separated packages that start with or equal this string diff --git a/jdk/src/share/lib/security/java.security-windows b/jdk/src/share/lib/security/java.security-windows index 25de17d5247..062b85b63c3 100644 --- a/jdk/src/share/lib/security/java.security-windows +++ b/jdk/src/share/lib/security/java.security-windows @@ -128,7 +128,7 @@ system.scope=sun.security.provider.IdentityDatabase # passed to checkPackageAccess unless the # corresponding RuntimePermission ("accessClassInPackage."+package) has # been granted. -package.access=sun. +package.access=sun.,com.sun.imageio. # # List of comma-separated packages that start with or equal this string From 813ad65e9a7847816c206e194c4b8d297ed3ca17 Mon Sep 17 00:00:00 2001 From: Andrew Brygin Date: Fri, 8 May 2009 16:15:15 +0400 Subject: [PATCH 11/96] 6823373: [ZDI-CAN-460] Java Web Start JPEG header parsing needs more scruity Reviewed-by: igor --- .../sun/awt/splashscreen/splashscreen_jpeg.c | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/jdk/src/share/native/sun/awt/splashscreen/splashscreen_jpeg.c b/jdk/src/share/native/sun/awt/splashscreen/splashscreen_jpeg.c index 09d38fcb422..5d250e9e4b3 100644 --- a/jdk/src/share/native/sun/awt/splashscreen/splashscreen_jpeg.c +++ b/jdk/src/share/native/sun/awt/splashscreen/splashscreen_jpeg.c @@ -139,21 +139,45 @@ SplashDecodeJpeg(Splash * splash, struct jpeg_decompress_struct *cinfo) splash->width = cinfo->output_width; splash->height = cinfo->output_height; + + if (!SAFE_TO_ALLOC(splash->imageFormat.depthBytes, splash->width)) { + return 0; + } stride = splash->width * splash->imageFormat.depthBytes; + if (!SAFE_TO_ALLOC(stride, splash->height)) { + return 0; + } + if (!SAFE_TO_ALLOC(cinfo->output_width, cinfo->output_components)) { + return 0; + } + splash->frameCount = 1; splash->frames = (SplashImage *) malloc(sizeof(SplashImage) * splash->frameCount); + if (splash->frames == NULL) { + return 0; + } memset(splash->frames, 0, sizeof(SplashImage) * splash->frameCount); + splash->loopCount = 1; - splash->frames[0].bitmapBits = malloc(stride * splash->height); splash->frames[0].delay = 0; + splash->frames[0].bitmapBits = malloc(stride * splash->height); + if (splash->frames[0].bitmapBits == NULL) { + free(splash->frames); + return 0; + } rowStride = cinfo->output_width * cinfo->output_components; buffer = (*cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo, JPOOL_IMAGE, rowStride, 1); + if (buffer == NULL) { + free(splash->frames[0].bitmapBits); + free(splash->frames); + return 0; + } initFormat(&srcFormat, 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000); srcFormat.byteOrder = BYTE_ORDER_LSBFIRST; From ce7e28f3e6e44f6558968cb731d6fb5a90f29d9d Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Tue, 12 May 2009 16:32:34 +0100 Subject: [PATCH 12/96] 6801071: Remote sites can compromise user privacy and possibly hijack web sessions Reviewed-by: jccollet, hawtin --- jdk/make/sun/net/FILES_java.gmk | 1 + jdk/src/share/classes/java/net/Socket.java | 2 +- .../classes/java/net/SocksSocketImpl.java | 25 ++++++++--- jdk/src/share/classes/java/net/URL.java | 2 +- .../classes/sun/net/ApplicationProxy.java | 43 +++++++++++++++++++ .../www/protocol/http/HttpURLConnection.java | 18 +++++--- 6 files changed, 78 insertions(+), 13 deletions(-) create mode 100644 jdk/src/share/classes/sun/net/ApplicationProxy.java diff --git a/jdk/make/sun/net/FILES_java.gmk b/jdk/make/sun/net/FILES_java.gmk index 1ab771a37f1..00b6223b8da 100644 --- a/jdk/make/sun/net/FILES_java.gmk +++ b/jdk/make/sun/net/FILES_java.gmk @@ -24,6 +24,7 @@ # FILES_java = \ + sun/net/ApplicationProxy.java \ sun/net/InetAddressCachePolicy.java \ sun/net/URLCanonicalizer.java \ sun/net/NetworkClient.java \ diff --git a/jdk/src/share/classes/java/net/Socket.java b/jdk/src/share/classes/java/net/Socket.java index 110a6a5f1a9..39dfebd4180 100644 --- a/jdk/src/share/classes/java/net/Socket.java +++ b/jdk/src/share/classes/java/net/Socket.java @@ -118,7 +118,7 @@ class Socket implements java.io.Closeable { if (proxy == null) { throw new IllegalArgumentException("Invalid Proxy"); } - Proxy p = proxy == Proxy.NO_PROXY ? Proxy.NO_PROXY : new Proxy(proxy.type(), proxy.address()); + Proxy p = proxy == Proxy.NO_PROXY ? Proxy.NO_PROXY : sun.net.ApplicationProxy.create(proxy); if (p.type() == Proxy.Type.SOCKS) { SecurityManager security = System.getSecurityManager(); InetSocketAddress epoint = (InetSocketAddress) p.address(); diff --git a/jdk/src/share/classes/java/net/SocksSocketImpl.java b/jdk/src/share/classes/java/net/SocksSocketImpl.java index e73b6c9467e..4561b6e1e56 100644 --- a/jdk/src/share/classes/java/net/SocksSocketImpl.java +++ b/jdk/src/share/classes/java/net/SocksSocketImpl.java @@ -47,6 +47,9 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { private Socket cmdsock = null; private InputStream cmdIn = null; private OutputStream cmdOut = null; + /* true if the Proxy has been set programatically */ + private boolean applicationSetProxy; /* false */ + SocksSocketImpl() { // Nothing needed @@ -64,6 +67,7 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { // Use getHostString() to avoid reverse lookups server = ad.getHostString(); port = ad.getPort(); + applicationSetProxy = true; } } @@ -165,8 +169,7 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { throw (IOException) pae.getException(); } } else { - userName = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("user.name")); + userName = getUserName(); } } if (userName == null) @@ -267,8 +270,7 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { out.write((endpoint.getPort() >> 8) & 0xff); out.write((endpoint.getPort() >> 0) & 0xff); out.write(endpoint.getAddress().getAddress()); - String userName = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("user.name")); + String userName = getUserName(); try { out.write(userName.getBytes("ISO-8859-1")); } catch (java.io.UnsupportedEncodingException uee) { @@ -588,8 +590,7 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { out.write((super.getLocalPort() >> 8) & 0xff); out.write((super.getLocalPort() >> 0) & 0xff); out.write(addr1); - String userName = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("user.name")); + String userName = getUserName(); try { out.write(userName.getBytes("ISO-8859-1")); } catch (java.io.UnsupportedEncodingException uee) { @@ -1052,4 +1053,16 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { super.close(); } + private String getUserName() { + String userName = ""; + if (applicationSetProxy) { + try { + userName = System.getProperty("user.name"); + } catch (SecurityException se) { /* swallow Exception */ } + } else { + userName = java.security.AccessController.doPrivileged( + new sun.security.action.GetPropertyAction("user.name")); + } + return userName; + } } diff --git a/jdk/src/share/classes/java/net/URL.java b/jdk/src/share/classes/java/net/URL.java index 73818e960d8..33cfe039654 100644 --- a/jdk/src/share/classes/java/net/URL.java +++ b/jdk/src/share/classes/java/net/URL.java @@ -1005,7 +1005,7 @@ public final class URL implements java.io.Serializable { } // Create a copy of Proxy as a security measure - Proxy p = proxy == Proxy.NO_PROXY ? Proxy.NO_PROXY : new Proxy(proxy.type(), proxy.address()); + Proxy p = proxy == Proxy.NO_PROXY ? Proxy.NO_PROXY : sun.net.ApplicationProxy.create(proxy); SecurityManager sm = System.getSecurityManager(); if (p.type() != Proxy.Type.DIRECT && sm != null) { InetSocketAddress epoint = (InetSocketAddress) p.address(); diff --git a/jdk/src/share/classes/sun/net/ApplicationProxy.java b/jdk/src/share/classes/sun/net/ApplicationProxy.java new file mode 100644 index 00000000000..2c84e3649e3 --- /dev/null +++ b/jdk/src/share/classes/sun/net/ApplicationProxy.java @@ -0,0 +1,43 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.net; + +import java.net.Proxy; +import java.net.SocketAddress; + +/** + * Proxy wrapper class so that we can determine application set + * proxies by type. + */ +public final class ApplicationProxy extends Proxy { + private ApplicationProxy(Proxy proxy) { + super(proxy.type(), proxy.address()); + } + + public static ApplicationProxy create(Proxy proxy) { + return new ApplicationProxy(proxy); + } +} diff --git a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java index 6f3250b30eb..9f5d7303abc 100644 --- a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java +++ b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java @@ -575,12 +575,20 @@ public class HttpURLConnection extends java.net.HttpURLConnection { responses = new MessageHeader(); this.handler = handler; instProxy = p; - cookieHandler = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { + if (instProxy instanceof sun.net.ApplicationProxy) { + /* Application set Proxies should not have access to cookies + * in a secure environment unless explicitly allowed. */ + try { + cookieHandler = CookieHandler.getDefault(); + } catch (SecurityException se) { /* swallow exception */ } + } else { + cookieHandler = java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { public CookieHandler run() { - return CookieHandler.getDefault(); - } - }); + return CookieHandler.getDefault(); + } + }); + } cacheHandler = java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public ResponseCache run() { From 28848d3300bdbb324ab81bdf4b4d9d14d349ed1a Mon Sep 17 00:00:00 2001 From: Alex Menkov Date: Wed, 13 May 2009 13:52:52 +0400 Subject: [PATCH 13/96] 6657625: RmfFileReader/StandardMidiFileWriter.types are public mutable statics (findbugs) Reviewed-by: hawtin --- .../classes/com/sun/media/sound/StandardMidiFileWriter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jdk/src/share/classes/com/sun/media/sound/StandardMidiFileWriter.java b/jdk/src/share/classes/com/sun/media/sound/StandardMidiFileWriter.java index 533104fa707..fce29478ada 100644 --- a/jdk/src/share/classes/com/sun/media/sound/StandardMidiFileWriter.java +++ b/jdk/src/share/classes/com/sun/media/sound/StandardMidiFileWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2009 Sun Microsystems, Inc. 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 @@ -82,7 +82,7 @@ public class StandardMidiFileWriter extends MidiFileWriter { /** * MIDI parser types */ - public static final int types[] = { + private static final int types[] = { MIDI_TYPE_0, MIDI_TYPE_1 }; From 00b701fedae519097ea4f8c3b1f5f95c6d2cd117 Mon Sep 17 00:00:00 2001 From: Alex Menkov Date: Wed, 13 May 2009 14:32:14 +0400 Subject: [PATCH 14/96] 6738524: JDK13Services allows read access to system properties from untrusted code Reviewed-by: hawtin --- .../com/sun/media/sound/JDK13Services.java | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/jdk/src/share/classes/com/sun/media/sound/JDK13Services.java b/jdk/src/share/classes/com/sun/media/sound/JDK13Services.java index 2b588ceef8d..fd477285770 100644 --- a/jdk/src/share/classes/com/sun/media/sound/JDK13Services.java +++ b/jdk/src/share/classes/com/sun/media/sound/JDK13Services.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2009 Sun Microsystems, Inc. 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 @@ -41,6 +41,15 @@ import javax.sound.midi.spi.MidiFileWriter; import javax.sound.midi.spi.SoundbankReader; import javax.sound.midi.spi.MidiDeviceProvider; +import javax.sound.midi.Receiver; +import javax.sound.midi.Sequencer; +import javax.sound.midi.Synthesizer; +import javax.sound.midi.Transmitter; +import javax.sound.sampled.Clip; +import javax.sound.sampled.Port; +import javax.sound.sampled.SourceDataLine; +import javax.sound.sampled.TargetDataLine; + /** * JDK13Services uses the Service class in JDK 1.3 @@ -186,6 +195,16 @@ public class JDK13Services { If the property is not set, null is returned. */ private static synchronized String getDefaultProvider(Class typeClass) { + if (!SourceDataLine.class.equals(typeClass) + && !TargetDataLine.class.equals(typeClass) + && !Clip.class.equals(typeClass) + && !Port.class.equals(typeClass) + && !Receiver.class.equals(typeClass) + && !Transmitter.class.equals(typeClass) + && !Synthesizer.class.equals(typeClass) + && !Sequencer.class.equals(typeClass)) { + return null; + } String value; String propertyName = typeClass.getName(); value = JSSecurityManager.getProperty(propertyName); From 272f5e12f9e369834173681913c17b7e5c23a3c3 Mon Sep 17 00:00:00 2001 From: Alex Menkov Date: Wed, 13 May 2009 14:32:33 +0400 Subject: [PATCH 15/96] 6777448: JDK13Services.getProviders creates instances with full privileges [hawtin, alexp] Reviewed-by: hawtin, alexp --- .../sun/media/sound/JSSecurityManager.java | 55 +++++++++++-------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/jdk/src/share/classes/com/sun/media/sound/JSSecurityManager.java b/jdk/src/share/classes/com/sun/media/sound/JSSecurityManager.java index 253d22c1e93..064e5c4ba04 100644 --- a/jdk/src/share/classes/com/sun/media/sound/JSSecurityManager.java +++ b/jdk/src/share/classes/com/sun/media/sound/JSSecurityManager.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2009 Sun Microsystems, Inc. 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 @@ -283,28 +283,37 @@ class JSSecurityManager { static List getProviders(final Class providerClass) { - PrivilegedAction action = new PrivilegedAction() { - public Object run() { - List p = new ArrayList(); - Iterator ps = Service.providers(providerClass); - while (ps.hasNext()) { - try { - Object provider = ps.next(); - if (providerClass.isInstance(provider)) { - // $$mp 2003-08-22 - // Always adding at the beginning reverses the - // order of the providers. So we no longer have - // to do this in AudioSystem and MidiSystem. - p.add(0, provider); - } - } catch (Throwable t) { - //$$fb 2002-11-07: do not fail on SPI not found - if (Printer.err) t.printStackTrace(); - } } - return p; + List p = new ArrayList(); + // Service.providers(Class) just creates "lazy" iterator instance, + // so it doesn't require do be called from privileged section + final Iterator ps = Service.providers(providerClass); + + // the iterator's hasNext() method looks through classpath for + // the provider class names, so it requires read permissions + PrivilegedAction hasNextAction = new PrivilegedAction() { + public Boolean run() { + return ps.hasNext(); + } + }; + + while (AccessController.doPrivileged(hasNextAction)) { + try { + // the iterator's next() method creates instances of the + // providers and it should be called in the current security + // context + Object provider = ps.next(); + if (providerClass.isInstance(provider)) { + // $$mp 2003-08-22 + // Always adding at the beginning reverses the + // order of the providers. So we no longer have + // to do this in AudioSystem and MidiSystem. + p.add(0, provider); } - }; - List providers = (List) AccessController.doPrivileged(action); - return providers; + } catch (Throwable t) { + //$$fb 2002-11-07: do not fail on SPI not found + if (Printer.err) t.printStackTrace(); + } + } + return p; } } From 0681d1454c1758bbb76ba3073b2f4116a66109da Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Thu, 18 Jun 2009 14:08:07 +0400 Subject: [PATCH 16/96] 6660049: Synth Region.uiToRegionMap/lowerCaseNameMap are mutable statics Reviewed-by: hawtin --- .../javax/swing/plaf/synth/Region.java | 288 ++++++++++-------- .../javax/swing/plaf/synth/Test6660049.java | 123 ++++++++ 2 files changed, 287 insertions(+), 124 deletions(-) create mode 100644 jdk/test/javax/swing/plaf/synth/Test6660049.java diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/Region.java b/jdk/src/share/classes/javax/swing/plaf/synth/Region.java index c7de782ba59..1ecd999896d 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/Region.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/Region.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2009 Sun Microsystems, Inc. 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 @@ -24,8 +24,13 @@ */ package javax.swing.plaf.synth; -import javax.swing.*; -import java.util.*; +import sun.awt.AppContext; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import javax.swing.JComponent; +import javax.swing.UIDefaults; /** * A distinct rendering area of a Swing component. A component may @@ -67,8 +72,8 @@ import java.util.*; * @author Scott Violet */ public class Region { - private static final Map uiToRegionMap = new HashMap(); - private static final Map lowerCaseNameMap = new HashMap(); + private static final Object UI_TO_REGION_MAP_KEY = new Object(); + private static final Object LOWER_CASE_NAME_MAP_KEY = new Object(); /** * ArrowButton's are special types of buttons that also render a @@ -77,396 +82,433 @@ public class Region { * To bind a style to this Region use the name * ArrowButton. */ - public static final Region ARROW_BUTTON = new Region("ArrowButton", - "ArrowButtonUI"); + public static final Region ARROW_BUTTON = new Region("ArrowButton", false); /** * Button region. To bind a style to this Region use the name * Button. */ - public static final Region BUTTON = new Region("Button", - "ButtonUI"); + public static final Region BUTTON = new Region("Button", false); /** * CheckBox region. To bind a style to this Region use the name * CheckBox. */ - public static final Region CHECK_BOX = new Region("CheckBox", - "CheckBoxUI"); + public static final Region CHECK_BOX = new Region("CheckBox", false); /** * CheckBoxMenuItem region. To bind a style to this Region use * the name CheckBoxMenuItem. */ - public static final Region CHECK_BOX_MENU_ITEM = new Region( - "CheckBoxMenuItem", "CheckBoxMenuItemUI"); + public static final Region CHECK_BOX_MENU_ITEM = new Region("CheckBoxMenuItem", false); /** * ColorChooser region. To bind a style to this Region use * the name ColorChooser. */ - public static final Region COLOR_CHOOSER = new Region( - "ColorChooser", "ColorChooserUI"); + public static final Region COLOR_CHOOSER = new Region("ColorChooser", false); /** * ComboBox region. To bind a style to this Region use * the name ComboBox. */ - public static final Region COMBO_BOX = new Region( - "ComboBox", "ComboBoxUI"); + public static final Region COMBO_BOX = new Region("ComboBox", false); /** * DesktopPane region. To bind a style to this Region use * the name DesktopPane. */ - public static final Region DESKTOP_PANE = new Region("DesktopPane", - "DesktopPaneUI"); + public static final Region DESKTOP_PANE = new Region("DesktopPane", false); + /** * DesktopIcon region. To bind a style to this Region use * the name DesktopIcon. */ - public static final Region DESKTOP_ICON = new Region("DesktopIcon", - "DesktopIconUI"); + public static final Region DESKTOP_ICON = new Region("DesktopIcon", false); /** * EditorPane region. To bind a style to this Region use * the name EditorPane. */ - public static final Region EDITOR_PANE = new Region("EditorPane", - "EditorPaneUI"); + public static final Region EDITOR_PANE = new Region("EditorPane", false); /** * FileChooser region. To bind a style to this Region use * the name FileChooser. */ - public static final Region FILE_CHOOSER = new Region("FileChooser", - "FileChooserUI"); + public static final Region FILE_CHOOSER = new Region("FileChooser", false); /** * FormattedTextField region. To bind a style to this Region use * the name FormattedTextField. */ - public static final Region FORMATTED_TEXT_FIELD = new Region( - "FormattedTextField", "FormattedTextFieldUI"); + public static final Region FORMATTED_TEXT_FIELD = new Region("FormattedTextField", false); /** * InternalFrame region. To bind a style to this Region use * the name InternalFrame. */ - public static final Region INTERNAL_FRAME = new Region("InternalFrame", - "InternalFrameUI"); + public static final Region INTERNAL_FRAME = new Region("InternalFrame", false); + /** * TitlePane of an InternalFrame. The TitlePane typically * shows a menu, title, widgets to manipulate the internal frame. * To bind a style to this Region use the name * InternalFrameTitlePane. */ - public static final Region INTERNAL_FRAME_TITLE_PANE = - new Region("InternalFrameTitlePane", - "InternalFrameTitlePaneUI"); + public static final Region INTERNAL_FRAME_TITLE_PANE = new Region("InternalFrameTitlePane", false); /** * Label region. To bind a style to this Region use the name * Label. */ - public static final Region LABEL = new Region("Label", "LabelUI"); + public static final Region LABEL = new Region("Label", false); /** * List region. To bind a style to this Region use the name * List. */ - public static final Region LIST = new Region("List", "ListUI"); + public static final Region LIST = new Region("List", false); /** * Menu region. To bind a style to this Region use the name * Menu. */ - public static final Region MENU = new Region("Menu", "MenuUI"); + public static final Region MENU = new Region("Menu", false); /** * MenuBar region. To bind a style to this Region use the name * MenuBar. */ - public static final Region MENU_BAR = new Region("MenuBar", "MenuBarUI"); + public static final Region MENU_BAR = new Region("MenuBar", false); /** * MenuItem region. To bind a style to this Region use the name * MenuItem. */ - public static final Region MENU_ITEM = new Region("MenuItem","MenuItemUI"); + public static final Region MENU_ITEM = new Region("MenuItem", false); /** * Accelerator region of a MenuItem. To bind a style to this * Region use the name MenuItemAccelerator. */ - public static final Region MENU_ITEM_ACCELERATOR = new Region( - "MenuItemAccelerator"); + public static final Region MENU_ITEM_ACCELERATOR = new Region("MenuItemAccelerator", true); /** * OptionPane region. To bind a style to this Region use * the name OptionPane. */ - public static final Region OPTION_PANE = new Region("OptionPane", - "OptionPaneUI"); + public static final Region OPTION_PANE = new Region("OptionPane", false); /** * Panel region. To bind a style to this Region use the name * Panel. */ - public static final Region PANEL = new Region("Panel", "PanelUI"); + public static final Region PANEL = new Region("Panel", false); /** * PasswordField region. To bind a style to this Region use * the name PasswordField. */ - public static final Region PASSWORD_FIELD = new Region("PasswordField", - "PasswordFieldUI"); + public static final Region PASSWORD_FIELD = new Region("PasswordField", false); /** * PopupMenu region. To bind a style to this Region use * the name PopupMenu. */ - public static final Region POPUP_MENU = new Region("PopupMenu", - "PopupMenuUI"); + public static final Region POPUP_MENU = new Region("PopupMenu", false); /** * PopupMenuSeparator region. To bind a style to this Region * use the name PopupMenuSeparator. */ - public static final Region POPUP_MENU_SEPARATOR = new Region( - "PopupMenuSeparator", "PopupMenuSeparatorUI"); + public static final Region POPUP_MENU_SEPARATOR = new Region("PopupMenuSeparator", false); /** * ProgressBar region. To bind a style to this Region * use the name ProgressBar. */ - public static final Region PROGRESS_BAR = new Region("ProgressBar", - "ProgressBarUI"); + public static final Region PROGRESS_BAR = new Region("ProgressBar", false); /** * RadioButton region. To bind a style to this Region * use the name RadioButton. */ - public static final Region RADIO_BUTTON = new Region( - "RadioButton", "RadioButtonUI"); + public static final Region RADIO_BUTTON = new Region("RadioButton", false); /** * RegionButtonMenuItem region. To bind a style to this Region * use the name RadioButtonMenuItem. */ - public static final Region RADIO_BUTTON_MENU_ITEM = new Region( - "RadioButtonMenuItem", "RadioButtonMenuItemUI"); + public static final Region RADIO_BUTTON_MENU_ITEM = new Region("RadioButtonMenuItem", false); /** * RootPane region. To bind a style to this Region use * the name RootPane. */ - public static final Region ROOT_PANE = new Region("RootPane", - "RootPaneUI"); + public static final Region ROOT_PANE = new Region("RootPane", false); /** * ScrollBar region. To bind a style to this Region use * the name ScrollBar. */ - public static final Region SCROLL_BAR = new Region("ScrollBar", - "ScrollBarUI"); + public static final Region SCROLL_BAR = new Region("ScrollBar", false); + /** * Track of the ScrollBar. To bind a style to this Region use * the name ScrollBarTrack. */ - public static final Region SCROLL_BAR_TRACK = new Region("ScrollBarTrack"); + public static final Region SCROLL_BAR_TRACK = new Region("ScrollBarTrack", true); + /** * Thumb of the ScrollBar. The thumb is the region of the ScrollBar * that gives a graphical depiction of what percentage of the View is * currently visible. To bind a style to this Region use * the name ScrollBarThumb. */ - public static final Region SCROLL_BAR_THUMB = new Region("ScrollBarThumb"); + public static final Region SCROLL_BAR_THUMB = new Region("ScrollBarThumb", true); /** * ScrollPane region. To bind a style to this Region use * the name ScrollPane. */ - public static final Region SCROLL_PANE = new Region("ScrollPane", - "ScrollPaneUI"); + public static final Region SCROLL_PANE = new Region("ScrollPane", false); /** * Separator region. To bind a style to this Region use * the name Separator. */ - public static final Region SEPARATOR = new Region("Separator", - "SeparatorUI"); + public static final Region SEPARATOR = new Region("Separator", false); /** * Slider region. To bind a style to this Region use * the name Slider. */ - public static final Region SLIDER = new Region("Slider", "SliderUI"); + public static final Region SLIDER = new Region("Slider", false); + /** * Track of the Slider. To bind a style to this Region use * the name SliderTrack. */ - public static final Region SLIDER_TRACK = new Region("SliderTrack"); + public static final Region SLIDER_TRACK = new Region("SliderTrack", true); + /** * Thumb of the Slider. The thumb of the Slider identifies the current * value. To bind a style to this Region use the name * SliderThumb. */ - public static final Region SLIDER_THUMB = new Region("SliderThumb"); + public static final Region SLIDER_THUMB = new Region("SliderThumb", true); /** * Spinner region. To bind a style to this Region use the name * Spinner. */ - public static final Region SPINNER = new Region("Spinner", "SpinnerUI"); + public static final Region SPINNER = new Region("Spinner", false); /** * SplitPane region. To bind a style to this Region use the name * SplitPane. */ - public static final Region SPLIT_PANE = new Region("SplitPane", - "SplitPaneUI"); + public static final Region SPLIT_PANE = new Region("SplitPane", false); /** * Divider of the SplitPane. To bind a style to this Region * use the name SplitPaneDivider. */ - public static final Region SPLIT_PANE_DIVIDER = new Region( - "SplitPaneDivider"); + public static final Region SPLIT_PANE_DIVIDER = new Region("SplitPaneDivider", true); /** * TabbedPane region. To bind a style to this Region use * the name TabbedPane. */ - public static final Region TABBED_PANE = new Region("TabbedPane", - "TabbedPaneUI"); + public static final Region TABBED_PANE = new Region("TabbedPane", false); + /** * Region of a TabbedPane for one tab. To bind a style to this * Region use the name TabbedPaneTab. */ - public static final Region TABBED_PANE_TAB = new Region("TabbedPaneTab"); + public static final Region TABBED_PANE_TAB = new Region("TabbedPaneTab", true); + /** * Region of a TabbedPane containing the tabs. To bind a style to this * Region use the name TabbedPaneTabArea. */ - public static final Region TABBED_PANE_TAB_AREA = - new Region("TabbedPaneTabArea"); + public static final Region TABBED_PANE_TAB_AREA = new Region("TabbedPaneTabArea", true); + /** * Region of a TabbedPane containing the content. To bind a style to this * Region use the name TabbedPaneContent. */ - public static final Region TABBED_PANE_CONTENT = - new Region("TabbedPaneContent"); + public static final Region TABBED_PANE_CONTENT = new Region("TabbedPaneContent", true); /** * Table region. To bind a style to this Region use * the name Table. */ - public static final Region TABLE = new Region("Table", "TableUI"); + public static final Region TABLE = new Region("Table", false); /** * TableHeader region. To bind a style to this Region use * the name TableHeader. */ - public static final Region TABLE_HEADER = new Region("TableHeader", - "TableHeaderUI"); + public static final Region TABLE_HEADER = new Region("TableHeader", false); + /** * TextArea region. To bind a style to this Region use * the name TextArea. */ - public static final Region TEXT_AREA = new Region("TextArea", - "TextAreaUI"); + public static final Region TEXT_AREA = new Region("TextArea", false); /** * TextField region. To bind a style to this Region use * the name TextField. */ - public static final Region TEXT_FIELD = new Region("TextField", - "TextFieldUI"); + public static final Region TEXT_FIELD = new Region("TextField", false); /** * TextPane region. To bind a style to this Region use * the name TextPane. */ - public static final Region TEXT_PANE = new Region("TextPane", - "TextPaneUI"); + public static final Region TEXT_PANE = new Region("TextPane", false); /** * ToggleButton region. To bind a style to this Region use * the name ToggleButton. */ - public static final Region TOGGLE_BUTTON = new Region("ToggleButton", - "ToggleButtonUI"); + public static final Region TOGGLE_BUTTON = new Region("ToggleButton", false); /** * ToolBar region. To bind a style to this Region use * the name ToolBar. */ - public static final Region TOOL_BAR = new Region("ToolBar", "ToolBarUI"); + public static final Region TOOL_BAR = new Region("ToolBar", false); + /** * Region of the ToolBar containing the content. To bind a style to this * Region use the name ToolBarContent. */ - public static final Region TOOL_BAR_CONTENT = new Region("ToolBarContent"); + public static final Region TOOL_BAR_CONTENT = new Region("ToolBarContent", true); + /** * Region for the Window containing the ToolBar. To bind a style to this * Region use the name ToolBarDragWindow. */ - public static final Region TOOL_BAR_DRAG_WINDOW = new Region( - "ToolBarDragWindow", null, false); + public static final Region TOOL_BAR_DRAG_WINDOW = new Region("ToolBarDragWindow", false); /** * ToolTip region. To bind a style to this Region use * the name ToolTip. */ - public static final Region TOOL_TIP = new Region("ToolTip", "ToolTipUI"); + public static final Region TOOL_TIP = new Region("ToolTip", false); /** * ToolBar separator region. To bind a style to this Region use * the name ToolBarSeparator. */ - public static final Region TOOL_BAR_SEPARATOR = new Region( - "ToolBarSeparator", "ToolBarSeparatorUI"); + public static final Region TOOL_BAR_SEPARATOR = new Region("ToolBarSeparator", false); /** * Tree region. To bind a style to this Region use the name * Tree. */ - public static final Region TREE = new Region("Tree", "TreeUI"); + public static final Region TREE = new Region("Tree", false); + /** * Region of the Tree for one cell. To bind a style to this * Region use the name TreeCell. */ - public static final Region TREE_CELL = new Region("TreeCell"); + public static final Region TREE_CELL = new Region("TreeCell", true); /** * Viewport region. To bind a style to this Region use * the name Viewport. */ - public static final Region VIEWPORT = new Region("Viewport", "ViewportUI"); + public static final Region VIEWPORT = new Region("Viewport", false); + private static Map getUItoRegionMap() { + AppContext context = AppContext.getAppContext(); + Map map = (Map) context.get(UI_TO_REGION_MAP_KEY); + if (map == null) { + map = new HashMap(); + map.put("ArrowButtonUI", ARROW_BUTTON); + map.put("ButtonUI", BUTTON); + map.put("CheckBoxUI", CHECK_BOX); + map.put("CheckBoxMenuItemUI", CHECK_BOX_MENU_ITEM); + map.put("ColorChooserUI", COLOR_CHOOSER); + map.put("ComboBoxUI", COMBO_BOX); + map.put("DesktopPaneUI", DESKTOP_PANE); + map.put("DesktopIconUI", DESKTOP_ICON); + map.put("EditorPaneUI", EDITOR_PANE); + map.put("FileChooserUI", FILE_CHOOSER); + map.put("FormattedTextFieldUI", FORMATTED_TEXT_FIELD); + map.put("InternalFrameUI", INTERNAL_FRAME); + map.put("InternalFrameTitlePaneUI", INTERNAL_FRAME_TITLE_PANE); + map.put("LabelUI", LABEL); + map.put("ListUI", LIST); + map.put("MenuUI", MENU); + map.put("MenuBarUI", MENU_BAR); + map.put("MenuItemUI", MENU_ITEM); + map.put("OptionPaneUI", OPTION_PANE); + map.put("PanelUI", PANEL); + map.put("PasswordFieldUI", PASSWORD_FIELD); + map.put("PopupMenuUI", POPUP_MENU); + map.put("PopupMenuSeparatorUI", POPUP_MENU_SEPARATOR); + map.put("ProgressBarUI", PROGRESS_BAR); + map.put("RadioButtonUI", RADIO_BUTTON); + map.put("RadioButtonMenuItemUI", RADIO_BUTTON_MENU_ITEM); + map.put("RootPaneUI", ROOT_PANE); + map.put("ScrollBarUI", SCROLL_BAR); + map.put("ScrollPaneUI", SCROLL_PANE); + map.put("SeparatorUI", SEPARATOR); + map.put("SliderUI", SLIDER); + map.put("SpinnerUI", SPINNER); + map.put("SplitPaneUI", SPLIT_PANE); + map.put("TabbedPaneUI", TABBED_PANE); + map.put("TableUI", TABLE); + map.put("TableHeaderUI", TABLE_HEADER); + map.put("TextAreaUI", TEXT_AREA); + map.put("TextFieldUI", TEXT_FIELD); + map.put("TextPaneUI", TEXT_PANE); + map.put("ToggleButtonUI", TOGGLE_BUTTON); + map.put("ToolBarUI", TOOL_BAR); + map.put("ToolTipUI", TOOL_TIP); + map.put("ToolBarSeparatorUI", TOOL_BAR_SEPARATOR); + map.put("TreeUI", TREE); + map.put("ViewportUI", VIEWPORT); + context.put(UI_TO_REGION_MAP_KEY, map); + } + return map; + } - private String name; - private boolean subregion; - + private static Map getLowerCaseNameMap() { + AppContext context = AppContext.getAppContext(); + Map map = (Map) context.get(LOWER_CASE_NAME_MAP_KEY); + if (map == null) { + map = new HashMap(); + context.put(LOWER_CASE_NAME_MAP_KEY, map); + } + return map; + } static Region getRegion(JComponent c) { - return uiToRegionMap.get(c.getUIClassID()); + return getUItoRegionMap().get(c.getUIClassID()); } static void registerUIs(UIDefaults table) { - for (String key : uiToRegionMap.keySet()) { + for (Object key : getUItoRegionMap().keySet()) { table.put(key, "javax.swing.plaf.synth.SynthLookAndFeel"); } } + private final String name; + private final boolean subregion; - Region(String name) { - this(name, null, true); - } - - Region(String name, String ui) { - this(name, ui, false); + private Region(String name, boolean subregion) { + if (name == null) { + throw new NullPointerException("You must specify a non-null name"); + } + this.name = name; + this.subregion = subregion; } /** @@ -481,14 +523,10 @@ public class Region { * @param subregion Whether or not this is a subregion. */ protected Region(String name, String ui, boolean subregion) { - if (name == null) { - throw new NullPointerException("You must specify a non-null name"); - } - this.name = name; + this(name, subregion); if (ui != null) { - uiToRegionMap.put(ui, this); + getUItoRegionMap().put(ui, this); } - this.subregion = subregion; } /** @@ -514,16 +552,17 @@ public class Region { /** * Returns the name, in lowercase. + * + * @return lower case representation of the name of the Region */ String getLowerCaseName() { - synchronized(lowerCaseNameMap) { - String lowerCaseName = lowerCaseNameMap.get(this); - if (lowerCaseName == null) { - lowerCaseName = getName().toLowerCase(); - lowerCaseNameMap.put(this, lowerCaseName); - } - return lowerCaseName; + Map lowerCaseNameMap = getLowerCaseNameMap(); + String lowerCaseName = lowerCaseNameMap.get(this); + if (lowerCaseName == null) { + lowerCaseName = name.toLowerCase(Locale.ENGLISH); + lowerCaseNameMap.put(this, lowerCaseName); } + return lowerCaseName; } /** @@ -531,6 +570,7 @@ public class Region { * * @return name of the Region. */ + @Override public String toString() { return name; } diff --git a/jdk/test/javax/swing/plaf/synth/Test6660049.java b/jdk/test/javax/swing/plaf/synth/Test6660049.java new file mode 100644 index 00000000000..466453a8a60 --- /dev/null +++ b/jdk/test/javax/swing/plaf/synth/Test6660049.java @@ -0,0 +1,123 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6660049 6849518 + * @summary Tests the Region initialization + * @author Sergey Malenkov + */ + +import sun.awt.SunToolkit; + +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.SwingUtilities; +import javax.swing.plaf.synth.Region; +import javax.swing.plaf.synth.SynthLookAndFeel; + +public class Test6660049 implements Runnable { + public static void main(String[] args) { + SwingUtilities.invokeLater(new Test6660049( + javax.swing.JButton.class, + javax.swing.JCheckBox.class, + javax.swing.JCheckBoxMenuItem.class, + javax.swing.JColorChooser.class, + javax.swing.JComboBox.class, + javax.swing.JDesktopPane.class, + javax.swing.JEditorPane.class, + javax.swing.JFileChooser.class, + javax.swing.JFormattedTextField.class, + javax.swing.JInternalFrame.class, + javax.swing.JLabel.class, + javax.swing.JList.class, + javax.swing.JMenu.class, + javax.swing.JMenuBar.class, + javax.swing.JMenuItem.class, + javax.swing.JOptionPane.class, + javax.swing.JPanel.class, + javax.swing.JPasswordField.class, + javax.swing.JPopupMenu.class, + javax.swing.JProgressBar.class, + javax.swing.JRadioButton.class, + javax.swing.JRadioButtonMenuItem.class, + javax.swing.JRootPane.class, + javax.swing.JScrollBar.class, + javax.swing.JScrollPane.class, + javax.swing.JSeparator.class, + javax.swing.JSlider.class, + javax.swing.JSpinner.class, + javax.swing.JSplitPane.class, + javax.swing.JTabbedPane.class, + javax.swing.JTable.class, + javax.swing.JTextArea.class, + javax.swing.JTextField.class, + javax.swing.JTextPane.class, + javax.swing.JToggleButton.class, + javax.swing.JToolBar.class, + javax.swing.JToolTip.class, + javax.swing.JTree.class, + javax.swing.JViewport.class, + javax.swing.table.JTableHeader.class)); + } + + private final Class[] types; + private final Region region; + + private Test6660049(Class... types) { + this.types = types; + run(); + + this.region = new Region("Button", "ButtonUI", true) { + @Override + public String getName() { + throw new Error("6660049: exploit is available"); + } + }; + } + + public void run() { + if (this.region != null) { + SunToolkit.createNewAppContext(); + } + for (Class type : this.types) { + Region region = getRegion(type); + if (region == null) { + throw new Error("6849518: region is not initialized"); + } + } + getRegion(JButton.class).getName(); + } + + private static Region getRegion(Class type) { + try { + return SynthLookAndFeel.getRegion(type.newInstance()); + } + catch (IllegalAccessException exception) { + throw new Error("unexpected exception", exception); + } + catch (InstantiationException exception) { + throw new Error("unexpected exception", exception); + } + } +} From 6b90310fed55e58b749b5d4b1fbbdc67ef227eca Mon Sep 17 00:00:00 2001 From: Abhijit Saha Date: Mon, 22 Jun 2009 13:36:37 -0700 Subject: [PATCH 17/96] 6656610: AccessibleResourceBundle.getContents exposes mutable static (findbugs) Reviewed-by: hawtin --- .../accessibility/AccessibleResourceBundle.java | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/jdk/src/share/classes/javax/accessibility/AccessibleResourceBundle.java b/jdk/src/share/classes/javax/accessibility/AccessibleResourceBundle.java index b5f23e199fa..ec27c756bde 100644 --- a/jdk/src/share/classes/javax/accessibility/AccessibleResourceBundle.java +++ b/jdk/src/share/classes/javax/accessibility/AccessibleResourceBundle.java @@ -44,15 +44,11 @@ public class AccessibleResourceBundle extends ListResourceBundle { * localized display strings. */ public Object[][] getContents() { - return contents; - } + // The table holding the mapping between the programmatic keys + // and the display strings for the en_US locale. + return new Object[][] { - /** - * The table holding the mapping between the programmatic keys - * and the display strings for the en_US locale. - */ - static final Object[][] contents = { - // LOCALIZE THIS + // LOCALIZE THIS // Role names // { "application","application" }, // { "border","border" }, @@ -151,5 +147,6 @@ public class AccessibleResourceBundle extends ListResourceBundle { { "vertical","vertical" }, { "horizontal","horizontal" } // END OF MATERIAL TO LOCALIZE - }; + }; + } } From 68d0756ea67b3c8655a28193e6725e07d3b8554b Mon Sep 17 00:00:00 2001 From: Sean Mullan Date: Tue, 23 Jun 2009 13:54:36 -0400 Subject: [PATCH 18/96] 6824440: XML Signature HMAC issue Reviewed-by: asaha --- .../implementations/IntegrityHmac.java | 76 +++++++---- .../internal/dom/DOMHMACSignatureMethod.java | 53 ++++---- .../xml/internal/security/TruncateHMAC.java | 118 ++++++++++++++++++ ...enveloping-hmac-sha1-trunclen-0-attack.xml | 16 +++ ...enveloping-hmac-sha1-trunclen-8-attack.xml | 17 +++ .../xml/crypto/dsig/GenerationTests.java | 16 ++- .../xml/crypto/dsig/ValidationTests.java | 39 +++++- ...enveloping-hmac-sha1-trunclen-0-attack.xml | 16 +++ ...enveloping-hmac-sha1-trunclen-8-attack.xml | 17 +++ 9 files changed, 311 insertions(+), 57 deletions(-) create mode 100644 jdk/test/com/sun/org/apache/xml/internal/security/TruncateHMAC.java create mode 100644 jdk/test/com/sun/org/apache/xml/internal/security/signature-enveloping-hmac-sha1-trunclen-0-attack.xml create mode 100644 jdk/test/com/sun/org/apache/xml/internal/security/signature-enveloping-hmac-sha1-trunclen-8-attack.xml create mode 100644 jdk/test/javax/xml/crypto/dsig/data/signature-enveloping-hmac-sha1-trunclen-0-attack.xml create mode 100644 jdk/test/javax/xml/crypto/dsig/data/signature-enveloping-hmac-sha1-trunclen-8-attack.xml diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java index d3495bb567f..85cc9e38a68 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java @@ -60,8 +60,14 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { */ public abstract String engineGetURI(); + /** + * Returns the output length of the hash/digest. + */ + abstract int getDigestLength(); + /** Field _macAlgorithm */ private Mac _macAlgorithm = null; + private boolean _HMACOutputLengthSet = false; /** Field _HMACOutputLength */ int _HMACOutputLength = 0; @@ -115,14 +121,16 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { throws XMLSignatureException { try { - byte[] completeResult = this._macAlgorithm.doFinal(); - - if ((this._HMACOutputLength == 0) || (this._HMACOutputLength >= 160)) { + if (this._HMACOutputLengthSet && this._HMACOutputLength < getDigestLength()) { + if (log.isLoggable(java.util.logging.Level.FINE)) { + log.log(java.util.logging.Level.FINE, + "HMACOutputLength must not be less than " + getDigestLength()); + } + throw new XMLSignatureException("errorMessages.XMLSignatureException"); + } else { + byte[] completeResult = this._macAlgorithm.doFinal(); return MessageDigestAlgorithm.isEqual(completeResult, signature); } - byte[] stripped = IntegrityHmac.reduceBitLength(completeResult, - this._HMACOutputLength); - return MessageDigestAlgorithm.isEqual(stripped, signature); } catch (IllegalStateException ex) { throw new XMLSignatureException("empty", ex); } @@ -176,14 +184,15 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { protected byte[] engineSign() throws XMLSignatureException { try { - byte[] completeResult = this._macAlgorithm.doFinal(); - - if ((this._HMACOutputLength == 0) || (this._HMACOutputLength >= 160)) { - return completeResult; + if (this._HMACOutputLengthSet && this._HMACOutputLength < getDigestLength()) { + if (log.isLoggable(java.util.logging.Level.FINE)) { + log.log(java.util.logging.Level.FINE, + "HMACOutputLength must not be less than " + getDigestLength()); + } + throw new XMLSignatureException("errorMessages.XMLSignatureException"); + } else { + return this._macAlgorithm.doFinal(); } - return IntegrityHmac.reduceBitLength(completeResult, - this._HMACOutputLength); - } catch (IllegalStateException ex) { throw new XMLSignatureException("empty", ex); } @@ -361,6 +370,7 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { */ protected void engineSetHMACOutputLength(int HMACOutputLength) { this._HMACOutputLength = HMACOutputLength; + this._HMACOutputLengthSet = true; } /** @@ -376,12 +386,13 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { throw new IllegalArgumentException("element null"); } - Text hmaclength =XMLUtils.selectDsNodeText(element.getFirstChild(), - Constants._TAG_HMACOUTPUTLENGTH,0); + Text hmaclength =XMLUtils.selectDsNodeText(element.getFirstChild(), + Constants._TAG_HMACOUTPUTLENGTH,0); - if (hmaclength != null) { - this._HMACOutputLength = Integer.parseInt(hmaclength.getData()); - } + if (hmaclength != null) { + this._HMACOutputLength = Integer.parseInt(hmaclength.getData()); + this._HMACOutputLengthSet = true; + } } @@ -390,14 +401,13 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { * * @param element */ - public void engineAddContextToElement(Element element) - { + public void engineAddContextToElement(Element element) { if (element == null) { throw new IllegalArgumentException("null element"); } - if (this._HMACOutputLength != 0) { + if (this._HMACOutputLengthSet) { Document doc = element.getOwnerDocument(); Element HMElem = XMLUtils.createElementInSignatureSpace(doc, Constants._TAG_HMACOUTPUTLENGTH); @@ -436,6 +446,10 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { public String engineGetURI() { return XMLSignature.ALGO_ID_MAC_HMAC_SHA1; } + + int getDigestLength() { + return 160; + } } /** @@ -463,6 +477,10 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { public String engineGetURI() { return XMLSignature.ALGO_ID_MAC_HMAC_SHA256; } + + int getDigestLength() { + return 256; + } } /** @@ -490,6 +508,10 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { public String engineGetURI() { return XMLSignature.ALGO_ID_MAC_HMAC_SHA384; } + + int getDigestLength() { + return 384; + } } /** @@ -517,6 +539,10 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { public String engineGetURI() { return XMLSignature.ALGO_ID_MAC_HMAC_SHA512; } + + int getDigestLength() { + return 512; + } } /** @@ -544,6 +570,10 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { public String engineGetURI() { return XMLSignature.ALGO_ID_MAC_HMAC_RIPEMD160; } + + int getDigestLength() { + return 160; + } } /** @@ -571,5 +601,9 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { public String engineGetURI() { return XMLSignature.ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5; } + + int getDigestLength() { + return 128; + } } } diff --git a/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMHMACSignatureMethod.java b/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMHMACSignatureMethod.java index 5a9000c898c..482283b616e 100644 --- a/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMHMACSignatureMethod.java +++ b/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMHMACSignatureMethod.java @@ -19,7 +19,7 @@ * */ /* - * Copyright 2005-2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005-2009 Sun Microsystems, Inc. All rights reserved. */ /* * $Id: DOMHMACSignatureMethod.java,v 1.2 2008/07/24 15:20:32 mullan Exp $ @@ -58,6 +58,7 @@ public abstract class DOMHMACSignatureMethod extends DOMSignatureMethod { Logger.getLogger("org.jcp.xml.dsig.internal.dom"); private Mac hmac; private int outputLength; + private boolean outputLengthSet; /** * Creates a DOMHMACSignatureMethod with the specified params @@ -87,6 +88,7 @@ public abstract class DOMHMACSignatureMethod extends DOMSignatureMethod { ("params must be of type HMACParameterSpec"); } outputLength = ((HMACParameterSpec) params).getOutputLength(); + outputLengthSet = true; if (log.isLoggable(Level.FINE)) { log.log(Level.FINE, "Setting outputLength from HMACParameterSpec to: " @@ -101,6 +103,7 @@ public abstract class DOMHMACSignatureMethod extends DOMSignatureMethod { throws MarshalException { outputLength = new Integer (paramsElem.getFirstChild().getNodeValue()).intValue(); + outputLengthSet = true; if (log.isLoggable(Level.FINE)) { log.log(Level.FINE, "unmarshalled outputLength: " + outputLength); } @@ -135,23 +138,13 @@ public abstract class DOMHMACSignatureMethod extends DOMSignatureMethod { throw new XMLSignatureException(nsae); } } - if (log.isLoggable(Level.FINE)) { - log.log(Level.FINE, "outputLength = " + outputLength); + if (outputLengthSet && outputLength < getDigestLength()) { + throw new XMLSignatureException + ("HMACOutputLength must not be less than " + getDigestLength()); } hmac.init((SecretKey) key); si.canonicalize(context, new MacOutputStream(hmac)); byte[] result = hmac.doFinal(); - if (log.isLoggable(Level.FINE)) { - log.log(Level.FINE, "resultLength = " + result.length); - } - if (outputLength != -1) { - int byteLength = outputLength/8; - if (result.length > byteLength) { - byte[] truncated = new byte[byteLength]; - System.arraycopy(result, 0, truncated, 0, byteLength); - result = truncated; - } - } return MessageDigest.isEqual(sig, result); } @@ -171,18 +164,13 @@ public abstract class DOMHMACSignatureMethod extends DOMSignatureMethod { throw new XMLSignatureException(nsae); } } + if (outputLengthSet && outputLength < getDigestLength()) { + throw new XMLSignatureException + ("HMACOutputLength must not be less than " + getDigestLength()); + } hmac.init((SecretKey) key); si.canonicalize(context, new MacOutputStream(hmac)); - byte[] result = hmac.doFinal(); - if (outputLength != -1) { - int byteLength = outputLength/8; - if (result.length > byteLength) { - byte[] truncated = new byte[byteLength]; - System.arraycopy(result, 0, truncated, 0, byteLength); - result = truncated; - } - } - return result; + return hmac.doFinal(); } boolean paramsEqual(AlgorithmParameterSpec spec) { @@ -197,6 +185,11 @@ public abstract class DOMHMACSignatureMethod extends DOMSignatureMethod { return (outputLength == ospec.getOutputLength()); } + /** + * Returns the output length of the hash/digest. + */ + abstract int getDigestLength(); + static final class SHA1 extends DOMHMACSignatureMethod { SHA1(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException { @@ -211,6 +204,9 @@ public abstract class DOMHMACSignatureMethod extends DOMSignatureMethod { String getSignatureAlgorithm() { return "HmacSHA1"; } + int getDigestLength() { + return 160; + } } static final class SHA256 extends DOMHMACSignatureMethod { @@ -227,6 +223,9 @@ public abstract class DOMHMACSignatureMethod extends DOMSignatureMethod { String getSignatureAlgorithm() { return "HmacSHA256"; } + int getDigestLength() { + return 256; + } } static final class SHA384 extends DOMHMACSignatureMethod { @@ -243,6 +242,9 @@ public abstract class DOMHMACSignatureMethod extends DOMSignatureMethod { String getSignatureAlgorithm() { return "HmacSHA384"; } + int getDigestLength() { + return 384; + } } static final class SHA512 extends DOMHMACSignatureMethod { @@ -259,5 +261,8 @@ public abstract class DOMHMACSignatureMethod extends DOMSignatureMethod { String getSignatureAlgorithm() { return "HmacSHA512"; } + int getDigestLength() { + return 512; + } } } diff --git a/jdk/test/com/sun/org/apache/xml/internal/security/TruncateHMAC.java b/jdk/test/com/sun/org/apache/xml/internal/security/TruncateHMAC.java new file mode 100644 index 00000000000..ebb424de328 --- /dev/null +++ b/jdk/test/com/sun/org/apache/xml/internal/security/TruncateHMAC.java @@ -0,0 +1,118 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test %I% %E% + * @bug 6824440 + * @summary Check that Apache XMLSec APIs will not accept HMAC truncation + * lengths less than minimum bound + * @compile -XDignore.symbol.file TruncateHMAC.java + * @run main TruncateHMAC + */ + +import java.io.File; +import javax.crypto.SecretKey; +import javax.xml.parsers.DocumentBuilderFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import com.sun.org.apache.xml.internal.security.Init; +import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer; +import com.sun.org.apache.xml.internal.security.signature.XMLSignature; +import com.sun.org.apache.xml.internal.security.signature.XMLSignatureException; +import com.sun.org.apache.xml.internal.security.utils.Constants; + + +public class TruncateHMAC { + + private final static String DIR = System.getProperty("test.src", "."); + private static DocumentBuilderFactory dbf = null; + private static boolean atLeastOneFailed = false; + + public static void main(String[] args) throws Exception { + + Init.init(); + dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + dbf.setValidating(false); + validate("signature-enveloping-hmac-sha1-trunclen-0-attack.xml"); + validate("signature-enveloping-hmac-sha1-trunclen-8-attack.xml"); + generate_hmac_sha1_40(); + + if (atLeastOneFailed) { + throw new Exception + ("At least one signature did not validate as expected"); + } + } + + private static void validate(String data) throws Exception { + System.out.println("Validating " + data); + File file = new File(DIR, data); + + Document doc = dbf.newDocumentBuilder().parse(file); + NodeList nl = + doc.getElementsByTagNameNS(Constants.SignatureSpecNS, "Signature"); + if (nl.getLength() == 0) { + throw new Exception("Couldn't find signature Element"); + } + Element sigElement = (Element) nl.item(0); + XMLSignature signature = new XMLSignature + (sigElement, file.toURI().toString()); + SecretKey sk = signature.createSecretKey("secret".getBytes("ASCII")); + try { + System.out.println + ("Validation status: " + signature.checkSignatureValue(sk)); + System.out.println("FAILED"); + atLeastOneFailed = true; + } catch (XMLSignatureException xse) { + System.out.println(xse.getMessage()); + System.out.println("PASSED"); + } + } + + private static void generate_hmac_sha1_40() throws Exception { + System.out.println("Generating "); + + Document doc = dbf.newDocumentBuilder().newDocument(); + XMLSignature sig = new XMLSignature + (doc, null, XMLSignature.ALGO_ID_MAC_HMAC_SHA1, 40, + Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS); + try { + sig.sign(getSecretKey("secret".getBytes("ASCII"))); + System.out.println("FAILED"); + atLeastOneFailed = true; + } catch (XMLSignatureException xse) { + System.out.println(xse.getMessage()); + System.out.println("PASSED"); + } + } + + private static SecretKey getSecretKey(final byte[] secret) { + return new SecretKey() { + public String getFormat() { return "RAW"; } + public byte[] getEncoded() { return secret; } + public String getAlgorithm(){ return "SECRET"; } + }; + } +} diff --git a/jdk/test/com/sun/org/apache/xml/internal/security/signature-enveloping-hmac-sha1-trunclen-0-attack.xml b/jdk/test/com/sun/org/apache/xml/internal/security/signature-enveloping-hmac-sha1-trunclen-0-attack.xml new file mode 100644 index 00000000000..5008dae5193 --- /dev/null +++ b/jdk/test/com/sun/org/apache/xml/internal/security/signature-enveloping-hmac-sha1-trunclen-0-attack.xml @@ -0,0 +1,16 @@ + + + + + + 0 + + + + nz4GS0NbH2SrWlD/4fX313CoTzc= + + + + + some other text + diff --git a/jdk/test/com/sun/org/apache/xml/internal/security/signature-enveloping-hmac-sha1-trunclen-8-attack.xml b/jdk/test/com/sun/org/apache/xml/internal/security/signature-enveloping-hmac-sha1-trunclen-8-attack.xml new file mode 100644 index 00000000000..dfe0a0df9a5 --- /dev/null +++ b/jdk/test/com/sun/org/apache/xml/internal/security/signature-enveloping-hmac-sha1-trunclen-8-attack.xml @@ -0,0 +1,17 @@ + + + + + + 8 + + + + nz4GS0NbH2SrWlD/4fX313CoTzc= + + + + Qw== + + some other text + diff --git a/jdk/test/javax/xml/crypto/dsig/GenerationTests.java b/jdk/test/javax/xml/crypto/dsig/GenerationTests.java index ea4fd610e1e..13881966d32 100644 --- a/jdk/test/javax/xml/crypto/dsig/GenerationTests.java +++ b/jdk/test/javax/xml/crypto/dsig/GenerationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2009 Sun Microsystems, Inc. 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 @@ -23,9 +23,7 @@ /** * @test - * @bug 4635230 - * @bug 6283345 - * @bug 6303830 + * @bug 4635230 6283345 6303830 6824440 * @summary Basic unit tests for generating XML Signatures with JSR 105 * @compile -XDignore.symbol.file KeySelectors.java SignatureValidator.java * X509KeySelector.java GenerationTests.java @@ -248,8 +246,14 @@ public class GenerationTests { System.out.println("* Generating signature-enveloping-hmac-sha1-40.xml"); SignatureMethod hmacSha1 = fac.newSignatureMethod (SignatureMethod.HMAC_SHA1, new HMACParameterSpec(40)); - test_create_signature_enveloping(sha1, hmacSha1, null, - getSecretKey("secret".getBytes("ASCII")), sks, false); + try { + test_create_signature_enveloping(sha1, hmacSha1, null, + getSecretKey("secret".getBytes("ASCII")), sks, false); + } catch (Exception e) { + if (!(e instanceof XMLSignatureException)) { + throw e; + } + } System.out.println(); } diff --git a/jdk/test/javax/xml/crypto/dsig/ValidationTests.java b/jdk/test/javax/xml/crypto/dsig/ValidationTests.java index 0934de7e921..0604af9bbc5 100644 --- a/jdk/test/javax/xml/crypto/dsig/ValidationTests.java +++ b/jdk/test/javax/xml/crypto/dsig/ValidationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2009 Sun Microsystems, Inc. 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 @@ -23,9 +23,7 @@ /** * @test - * @bug 4635230 - * @bug 6365103 - * @bug 6366054 + * @bug 4635230 6365103 6366054 6824440 * @summary Basic unit tests for validating XML Signatures with JSR 105 * @compile -XDignore.symbol.file KeySelectors.java SignatureValidator.java * X509KeySelector.java ValidationTests.java @@ -42,6 +40,7 @@ import javax.xml.crypto.URIDereferencer; import javax.xml.crypto.URIReference; import javax.xml.crypto.URIReferenceException; import javax.xml.crypto.XMLCryptoContext; +import javax.xml.crypto.dsig.XMLSignatureException; import javax.xml.crypto.dsig.XMLSignatureFactory; /** @@ -68,7 +67,6 @@ public class ValidationTests { "signature-enveloping-dsa.xml", "signature-enveloping-rsa.xml", "signature-enveloping-hmac-sha1.xml", - "signature-enveloping-hmac-sha1-40.xml", "signature-external-dsa.xml", "signature-external-b64-dsa.xml", "signature-retrievalmethod-rawx509crt.xml", @@ -106,7 +104,6 @@ public class ValidationTests { KVKS, KVKS, SKKS, - SKKS, KVKS, KVKS, CKS, @@ -146,6 +143,36 @@ public class ValidationTests { atLeastOneFailed = true; } + System.out.println("Validating signature-enveloping-hmac-sha1-40.xml"); + try { + test_signature("signature-enveloping-hmac-sha1-40.xml", SKKS, false); + System.out.println("FAILED"); + atLeastOneFailed = true; + } catch (XMLSignatureException xse) { + System.out.println(xse.getMessage()); + System.out.println("PASSED"); + } + + System.out.println("Validating signature-enveloping-hmac-sha1-trunclen-0-attack.xml"); + try { + test_signature("signature-enveloping-hmac-sha1-trunclen-0-attack.xml", SKKS, false); + System.out.println("FAILED"); + atLeastOneFailed = true; + } catch (XMLSignatureException xse) { + System.out.println(xse.getMessage()); + System.out.println("PASSED"); + } + + System.out.println("Validating signature-enveloping-hmac-sha1-trunclen-8-attack.xml"); + try { + test_signature("signature-enveloping-hmac-sha1-trunclen-8-attack.xml", SKKS, false); + System.out.println("FAILED"); + atLeastOneFailed = true; + } catch (XMLSignatureException xse) { + System.out.println(xse.getMessage()); + System.out.println("PASSED"); + } + if (atLeastOneFailed) { throw new Exception ("At least one signature did not validate as expected"); diff --git a/jdk/test/javax/xml/crypto/dsig/data/signature-enveloping-hmac-sha1-trunclen-0-attack.xml b/jdk/test/javax/xml/crypto/dsig/data/signature-enveloping-hmac-sha1-trunclen-0-attack.xml new file mode 100644 index 00000000000..5008dae5193 --- /dev/null +++ b/jdk/test/javax/xml/crypto/dsig/data/signature-enveloping-hmac-sha1-trunclen-0-attack.xml @@ -0,0 +1,16 @@ + + + + + + 0 + + + + nz4GS0NbH2SrWlD/4fX313CoTzc= + + + + + some other text + diff --git a/jdk/test/javax/xml/crypto/dsig/data/signature-enveloping-hmac-sha1-trunclen-8-attack.xml b/jdk/test/javax/xml/crypto/dsig/data/signature-enveloping-hmac-sha1-trunclen-8-attack.xml new file mode 100644 index 00000000000..dfe0a0df9a5 --- /dev/null +++ b/jdk/test/javax/xml/crypto/dsig/data/signature-enveloping-hmac-sha1-trunclen-8-attack.xml @@ -0,0 +1,17 @@ + + + + + + 8 + + + + nz4GS0NbH2SrWlD/4fX313CoTzc= + + + + Qw== + + some other text + From d92c74443f73ee3c282a052d9e5027a5123621d1 Mon Sep 17 00:00:00 2001 From: Kumar Srinivasan Date: Mon, 22 Jun 2009 07:23:20 -0700 Subject: [PATCH 19/96] 6830335: Java JAR Pack200 Decompression Integer Overflow Vulnerability Fixes a potential vulnerability in the unpack200 logic, by adding extra checks, a back-port. Reviewed-by: asaha --- .../share/native/com/sun/java/util/jar/pack/unpack.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp b/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp index a6f4ca0c2c8..7ca65c5d61e 100644 --- a/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp +++ b/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp @@ -908,10 +908,12 @@ void cpool::init(unpacker* u_, int counts[NUM_COUNTS]) { // place a limit on future CP growth: int generous = 0; - generous += u->ic_count*3; // implicit name, outer, outer.utf8 - generous += 40; // WKUs, misc - generous += u->class_count; // implicit SourceFile strings - maxentries = nentries + generous; + generous = add_size(generous, u->ic_count); // implicit name + generous = add_size(generous, u->ic_count); // outer + generous = add_size(generous, u->ic_count); // outer.utf8 + generous = add_size(generous, 40); // WKUs, misc + generous = add_size(generous, u->class_count); // implicit SourceFile strings + maxentries = add_size(nentries, generous); // Note that this CP does not include "empty" entries // for longs and doubles. Those are introduced when From 7db63ef95fd14841554e4238ec151a73a2bb040d Mon Sep 17 00:00:00 2001 From: Naoto Sato Date: Tue, 30 Jun 2009 17:12:32 -0700 Subject: [PATCH 20/96] 6852429: IME should call ImmIsUIMessage() or DefWindowProc() when it receives WM_IME_SETCONTEX Reviewed-by: peytoia --- jdk/src/windows/native/sun/windows/awt_Component.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/jdk/src/windows/native/sun/windows/awt_Component.cpp b/jdk/src/windows/native/sun/windows/awt_Component.cpp index 3c20533de90..ba0fc9cdc99 100644 --- a/jdk/src/windows/native/sun/windows/awt_Component.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp @@ -3739,11 +3739,12 @@ void AwtComponent::SetCandidateWindow(int iCandType, int x, int y) MsgRouting AwtComponent::WmImeSetContext(BOOL fSet, LPARAM *lplParam) { - // This message causes native status window shown even it is disabled. So don't - // let DefWindowProc process this message if this IMC is disabled. + // If the Windows input context is disabled, do not let Windows + // display any UIs. HIMC hIMC = ImmGetContext(); if (hIMC == NULL) { - return mrConsume; + *lplParam = 0; + return mrDoDefault; } if (fSet) { From e4502f3b6fa5fc7bb678e0f02736bd2407883bca Mon Sep 17 00:00:00 2001 From: Sean Mullan Date: Wed, 8 Jul 2009 16:57:40 -0400 Subject: [PATCH 21/96] 6858484: If an invalid HMAC XML Signature is validated, all subsequent valid HMAC signatures are invalid Reviewed-by: asaha --- .../implementations/IntegrityHmac.java | 4 +++- .../xml/internal/security/TruncateHMAC.java | 24 +++++++++++++------ .../signature-enveloping-hmac-sha1.xml | 15 ++++++++++++ 3 files changed, 35 insertions(+), 8 deletions(-) create mode 100644 jdk/test/com/sun/org/apache/xml/internal/security/signature-enveloping-hmac-sha1.xml diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java index 85cc9e38a68..7231b069a18 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java @@ -106,7 +106,9 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { } public void reset() { - _HMACOutputLength=0; + _HMACOutputLength=0; + _HMACOutputLengthSet = false; + _macAlgorithm.reset(); } /** diff --git a/jdk/test/com/sun/org/apache/xml/internal/security/TruncateHMAC.java b/jdk/test/com/sun/org/apache/xml/internal/security/TruncateHMAC.java index ebb424de328..a77d02b84f9 100644 --- a/jdk/test/com/sun/org/apache/xml/internal/security/TruncateHMAC.java +++ b/jdk/test/com/sun/org/apache/xml/internal/security/TruncateHMAC.java @@ -23,7 +23,7 @@ /** * @test %I% %E% - * @bug 6824440 + * @bug 6824440 6858484 * @summary Check that Apache XMLSec APIs will not accept HMAC truncation * lengths less than minimum bound * @compile -XDignore.symbol.file TruncateHMAC.java @@ -56,8 +56,10 @@ public class TruncateHMAC { dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); dbf.setValidating(false); - validate("signature-enveloping-hmac-sha1-trunclen-0-attack.xml"); - validate("signature-enveloping-hmac-sha1-trunclen-8-attack.xml"); + validate("signature-enveloping-hmac-sha1-trunclen-0-attack.xml", false); + validate("signature-enveloping-hmac-sha1-trunclen-8-attack.xml", false); + // this one should pass + validate("signature-enveloping-hmac-sha1.xml", true); generate_hmac_sha1_40(); if (atLeastOneFailed) { @@ -66,7 +68,7 @@ public class TruncateHMAC { } } - private static void validate(String data) throws Exception { + private static void validate(String data, boolean pass) throws Exception { System.out.println("Validating " + data); File file = new File(DIR, data); @@ -83,11 +85,19 @@ public class TruncateHMAC { try { System.out.println ("Validation status: " + signature.checkSignatureValue(sk)); - System.out.println("FAILED"); - atLeastOneFailed = true; + if (!pass) { + System.out.println("FAILED"); + atLeastOneFailed = true; + } else { + System.out.println("PASSED"); + } } catch (XMLSignatureException xse) { System.out.println(xse.getMessage()); - System.out.println("PASSED"); + if (!pass) { + System.out.println("PASSED"); + } else { + System.out.println("FAILED"); + } } } diff --git a/jdk/test/com/sun/org/apache/xml/internal/security/signature-enveloping-hmac-sha1.xml b/jdk/test/com/sun/org/apache/xml/internal/security/signature-enveloping-hmac-sha1.xml new file mode 100644 index 00000000000..c0c8343a895 --- /dev/null +++ b/jdk/test/com/sun/org/apache/xml/internal/security/signature-enveloping-hmac-sha1.xml @@ -0,0 +1,15 @@ + + + + + + + + 7/XTsHaBSOnJ/jXD5v0zL6VKYsk= + + + + JElPttIT4Am7Q+MNoMyv+WDfAZw= + + some text + From dd76763423f427a552407f4a106fa4388bcaf130 Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Wed, 15 Jul 2009 10:25:01 +0100 Subject: [PATCH 22/96] 6846972: cannot access member of raw type when erasure change overriding into overloading Fix of 6400189 caused a nasty problem in method resolution Reviewed-by: jjg --- .../com/sun/tools/javac/comp/Resolve.java | 3 +- .../javac/generics/rawOverride/T6846972.java | 49 +++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 langtools/test/tools/javac/generics/rawOverride/T6846972.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java index bb62298119c..808fd9959ef 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -251,7 +251,8 @@ public class Resolve { return true; else { Symbol s2 = ((MethodSymbol)sym).implementation(site.tsym, types, true); - return (s2 == null || s2 == sym); + return (s2 == null || s2 == sym || + !types.isSubSignature(types.memberType(site, s2), types.memberType(site, sym))); } } //where diff --git a/langtools/test/tools/javac/generics/rawOverride/T6846972.java b/langtools/test/tools/javac/generics/rawOverride/T6846972.java new file mode 100644 index 00000000000..af39a2d7cd6 --- /dev/null +++ b/langtools/test/tools/javac/generics/rawOverride/T6846972.java @@ -0,0 +1,49 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6846972 + * @summary cannot access member of raw type when erasure change overriding into overloading + * @author mcimadamore + * @compile T6846972.java + */ + +import java.util.EnumMap; + +public class T6846972 { + + enum Suit { + CLUBS, DIAMONDS; + } + + static Object [] array = { + Suit.CLUBS, "value1", + Suit.DIAMONDS, "value2" + }; + + static void test() { + EnumMap map = new EnumMap(Suit.class); + map.put(array[0], array[1]); + } +} From c854c85621aa9bfa03f290835a7369d4108b3305 Mon Sep 17 00:00:00 2001 From: Sergey Groznyh Date: Wed, 15 Jul 2009 19:05:18 +0400 Subject: [PATCH 23/96] 6612541: api/javax_swing/text/LabelView/index.html#getXXX[LabelView0004] fails since JDK 7 b20 Reviewed-by: peterz --- jdk/src/share/classes/javax/swing/text/GlyphView.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/text/GlyphView.java b/jdk/src/share/classes/javax/swing/text/GlyphView.java index 364fd69e8ee..087e9201545 100644 --- a/jdk/src/share/classes/javax/swing/text/GlyphView.java +++ b/jdk/src/share/classes/javax/swing/text/GlyphView.java @@ -719,8 +719,9 @@ public class GlyphView extends View implements TabableView, Cloneable { checkPainter(); int p0 = getStartOffset(); int p1 = painter.getBoundedPosition(this, p0, pos, len); - return ((p1 > p0) && (getBreakSpot(p0, p1) != BreakIterator.DONE)) ? - View.ExcellentBreakWeight : View.BadBreakWeight; + return p1 == p0 ? View.BadBreakWeight : + getBreakSpot(p0, p1) != BreakIterator.DONE ? + View.ExcellentBreakWeight : View.GoodBreakWeight; } return super.getBreakWeight(axis, pos, len); } From ae2586d2c3656378e28e8e372836fd270f439bf3 Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Wed, 15 Jul 2009 17:01:47 +0100 Subject: [PATCH 24/96] 6860795: NullPointerException when compiling a negative java source Rich formatter shouldn't propagate visits on method symbols that have a null type Reviewed-by: jjg --- .../javac/util/RichDiagnosticFormatter.java | 3 +- .../javac/Diagnostics/6860795/T6860795.java | 34 +++++++++++++++++++ .../javac/Diagnostics/6860795/T6860795.out | 2 ++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 langtools/test/tools/javac/Diagnostics/6860795/T6860795.java create mode 100644 langtools/test/tools/javac/Diagnostics/6860795/T6860795.out diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java b/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java index 6d8538bf654..60e323f7bda 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java @@ -569,7 +569,8 @@ public class RichDiagnosticFormatter extends @Override public Void visitMethodSymbol(MethodSymbol s, Void ignored) { visit(s.owner, null); - typePreprocessor.visit(s.type); + if (s.type != null) + typePreprocessor.visit(s.type); return null; } }; diff --git a/langtools/test/tools/javac/Diagnostics/6860795/T6860795.java b/langtools/test/tools/javac/Diagnostics/6860795/T6860795.java new file mode 100644 index 00000000000..6480e0ff2b7 --- /dev/null +++ b/langtools/test/tools/javac/Diagnostics/6860795/T6860795.java @@ -0,0 +1,34 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6860795 + * @summary NullPointerException when compiling a negative java source + * @author mcimadamore + * @compile/fail/ref=T6860795.out -XDrawDiagnostics T6860795.java + */ + +class Test { + void foo(float x, int x) {} +} diff --git a/langtools/test/tools/javac/Diagnostics/6860795/T6860795.out b/langtools/test/tools/javac/Diagnostics/6860795/T6860795.out new file mode 100644 index 00000000000..f7ec1120afd --- /dev/null +++ b/langtools/test/tools/javac/Diagnostics/6860795/T6860795.out @@ -0,0 +1,2 @@ +T6860795.java:33:27: compiler.err.already.defined: x, foo +1 error From da30267d99edd4ab695bce12fd92e67f1241965a Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Thu, 16 Jul 2009 20:12:14 +0400 Subject: [PATCH 25/96] 6505027: terminateEditOnFocusLost making problems for table in JDesktopPane Reviewed-by: alexp --- .../classes/javax/swing/JInternalFrame.java | 31 ++-- .../swing/JInternalFrame/Test6505027.java | 136 ++++++++++++++++++ 2 files changed, 151 insertions(+), 16 deletions(-) create mode 100644 jdk/test/javax/swing/JInternalFrame/Test6505027.java diff --git a/jdk/src/share/classes/javax/swing/JInternalFrame.java b/jdk/src/share/classes/javax/swing/JInternalFrame.java index 837ffe49e4f..3079a26ebdc 100644 --- a/jdk/src/share/classes/javax/swing/JInternalFrame.java +++ b/jdk/src/share/classes/javax/swing/JInternalFrame.java @@ -26,13 +26,10 @@ package javax.swing; import java.awt.*; -import java.awt.event.*; import java.beans.PropertyVetoException; import java.beans.PropertyChangeEvent; -import java.util.EventListener; -import javax.swing.border.Border; import javax.swing.event.InternalFrameEvent; import javax.swing.event.InternalFrameListener; import javax.swing.plaf.*; @@ -40,7 +37,6 @@ import javax.swing.plaf.*; import javax.accessibility.*; import java.io.ObjectOutputStream; -import java.io.ObjectInputStream; import java.io.IOException; import java.lang.StringBuilder; import java.beans.PropertyChangeListener; @@ -1459,19 +1455,22 @@ public class JInternalFrame extends JComponent implements SwingUtilities2.compositeRequestFocus(getDesktopIcon()); } else { - // FocusPropertyChangeListener will eventually update - // lastFocusOwner. As focus requests are asynchronous - // lastFocusOwner may be accessed before it has been correctly - // updated. To avoid any problems, lastFocusOwner is immediately - // set, assuming the request will succeed. - lastFocusOwner = getMostRecentFocusOwner(); - if (lastFocusOwner == null) { - // Make sure focus is restored somewhere, so that - // we don't leave a focused component in another frame while - // this frame is selected. - lastFocusOwner = getContentPane(); + Component component = KeyboardFocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner(); + if ((component == null) || !SwingUtilities.isDescendingFrom(component, this)) { + // FocusPropertyChangeListener will eventually update + // lastFocusOwner. As focus requests are asynchronous + // lastFocusOwner may be accessed before it has been correctly + // updated. To avoid any problems, lastFocusOwner is immediately + // set, assuming the request will succeed. + setLastFocusOwner(getMostRecentFocusOwner()); + if (lastFocusOwner == null) { + // Make sure focus is restored somewhere, so that + // we don't leave a focused component in another frame while + // this frame is selected. + setLastFocusOwner(getContentPane()); + } + lastFocusOwner.requestFocus(); } - lastFocusOwner.requestFocus(); } } diff --git a/jdk/test/javax/swing/JInternalFrame/Test6505027.java b/jdk/test/javax/swing/JInternalFrame/Test6505027.java new file mode 100644 index 00000000000..218769003cb --- /dev/null +++ b/jdk/test/javax/swing/JInternalFrame/Test6505027.java @@ -0,0 +1,136 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6505027 + * @summary Tests focus problem inside internal frame + * @author Sergey Malenkov + */ + +import java.awt.AWTException; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Container; +import java.awt.KeyboardFocusManager; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import javax.swing.DefaultCellEditor; +import javax.swing.JComboBox; +import javax.swing.JDesktopPane; +import javax.swing.JFrame; +import javax.swing.JInternalFrame; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.JTextField; +import javax.swing.SwingUtilities; +import javax.swing.WindowConstants; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableColumn; + +public class Test6505027 implements Runnable { + + private static final boolean INTERNAL = true; + private static final boolean TERMINATE = true; + + private static final int WIDTH = 450; + private static final int HEIGHT = 200; + private static final int OFFSET = 10; + private static final long PAUSE = 2048L; + + private static final String[] COLUMNS = { "Size", "Shape" }; // NON-NLS + private static final String[] ITEMS = { "a", "b", "c", "d" }; // NON-NLS + private static final String KEY = "terminateEditOnFocusLost"; // NON-NLS + + public static void main(String[] args) { + SwingUtilities.invokeLater(new Test6505027()); + + Component component = null; + while (component == null) { + try { + Thread.sleep(PAUSE); + } + catch (InterruptedException exception) { + // ignore interrupted exception + } + component = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); + } + if (!component.getClass().equals(JComboBox.class)) { + throw new Error("unexpected focus owner: " + component); + } + SwingUtilities.getWindowAncestor(component).dispose(); + } + + private JTable table; + private Point point; + + public void run() { + if (this.table == null) { + JFrame main = new JFrame(); + main.setSize(WIDTH + OFFSET * 3, HEIGHT + OFFSET * 5); + main.setLocationRelativeTo(null); + main.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); + main.setVisible(true); + + Container container = main; + if (INTERNAL) { + JInternalFrame frame = new JInternalFrame(); + frame.setBounds(OFFSET, OFFSET, WIDTH, HEIGHT); + frame.setVisible(true); + + JDesktopPane desktop = new JDesktopPane(); + desktop.add(frame, new Integer(1)); + + container.add(desktop); + container = frame; + } + this.table = new JTable(new DefaultTableModel(COLUMNS, 2)); + if (TERMINATE) { + this.table.putClientProperty(KEY, Boolean.TRUE); + } + TableColumn column = this.table.getColumn(COLUMNS[1]); + column.setCellEditor(new DefaultCellEditor(new JComboBox(ITEMS))); + + container.add(BorderLayout.NORTH, new JTextField()); + container.add(BorderLayout.CENTER, new JScrollPane(this.table)); + + SwingUtilities.invokeLater(this); + } + else if (this.point == null) { + this.point = this.table.getCellRect(1, 1, false).getLocation(); + SwingUtilities.convertPointToScreen(this.point, this.table); + SwingUtilities.invokeLater(this); + } + else { + try { + Robot robot = new Robot(); + robot.mouseMove(this.point.x + 1, this.point.y + 1); + robot.mousePress(InputEvent.BUTTON1_MASK); + } + catch (AWTException exception) { + throw new Error("unexpected exception", exception); + } + } + } +} From 44904765cac436e041e31a1bb32b2e63a2641603 Mon Sep 17 00:00:00 2001 From: Peter Zhelezniakov Date: Fri, 17 Jul 2009 15:25:51 +0400 Subject: [PATCH 26/96] 6387360: Usage of package-private class as a parameter of a method (javax.swing.text.ParagraphView) Reviewed-by: malenkov --- .../classes/javax/swing/text/ParagraphView.java | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/text/ParagraphView.java b/jdk/src/share/classes/javax/swing/text/ParagraphView.java index c7f6bb09c3e..2b5f7826a08 100644 --- a/jdk/src/share/classes/javax/swing/text/ParagraphView.java +++ b/jdk/src/share/classes/javax/swing/text/ParagraphView.java @@ -174,23 +174,6 @@ public class ParagraphView extends FlowView implements TabExpander { return layoutPool.getView(index); } - /** - * Adjusts the given row if possible to fit within the - * layout span. By default this will try to find the - * highest break weight possible nearest the end of - * the row. If a forced break is encountered, the - * break will be positioned there. - *

- * This is meant for internal usage, and should not be used directly. - * - * @param r the row to adjust to the current layout - * span - * @param desiredSpan the current layout span >= 0 - * @param x the location r starts at - */ - protected void adjustRow(Row r, int desiredSpan, int x) { - } - /** * Returns the next visual position for the cursor, in * either the east or west direction. From e5047864cd1b701e2afdcfe2f87907dc7eedd650 Mon Sep 17 00:00:00 2001 From: Artem Ananiev Date: Fri, 17 Jul 2009 15:40:19 +0400 Subject: [PATCH 27/96] 6844297: java/awt/EventQueue/6638195/bug6638195.java test failed in jdk7 on Windows just on b59,passed on b57 Reviewed-by: bchristi, dcherepanov --- .../awt/EventQueue/6638195/bug6638195.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/jdk/test/java/awt/EventQueue/6638195/bug6638195.java b/jdk/test/java/awt/EventQueue/6638195/bug6638195.java index 9dc3b50b973..c4612391547 100644 --- a/jdk/test/java/awt/EventQueue/6638195/bug6638195.java +++ b/jdk/test/java/awt/EventQueue/6638195/bug6638195.java @@ -1,5 +1,5 @@ /* - * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2008-2009 Sun Microsystems, Inc. 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 @@ -23,7 +23,7 @@ /* @test * - * @bug 6638195 + * @bug 6638195 6844297 * @author Igor Kushnirskiy * @summary tests if EventQueueDelegate.Delegate is invoked. */ @@ -47,11 +47,22 @@ public class bug6638195 { } private static void runTest(MyEventQueueDelegate delegate) throws Exception { + // We need an empty runnable here, so the next event is + // processed with a new EventQueueDelegate. See 6844297 + // for details EventQueue.invokeLater( new Runnable() { public void run() { } }); + // The following event is expected to be processed by + // the EventQueueDelegate instance + EventQueue.invokeLater( + new Runnable() { + public void run() { + } + }); + // Finally, proceed on the main thread final CountDownLatch latch = new CountDownLatch(1); EventQueue.invokeLater( new Runnable() { @@ -60,7 +71,7 @@ public class bug6638195 { } }); latch.await(); - if (! delegate.allInvoked()) { + if (!delegate.allInvoked()) { throw new RuntimeException("failed"); } } @@ -125,6 +136,7 @@ public class bug6638195 { return objectMap; } + static class MyEventQueueDelegate implements EventQueueDelegate.Delegate { private volatile boolean getNextEventInvoked = false; private volatile boolean beforeDispatchInvoked = false; From 97bb9bff6fec0de4d29248cdea3d535c57666157 Mon Sep 17 00:00:00 2001 From: Vinnie Ryan Date: Fri, 17 Jul 2009 20:29:41 +0100 Subject: [PATCH 28/96] 6657619: DnsContext.debug is public static mutable (findbugs) Reviewed-by: alanb --- .../classes/com/sun/jndi/dns/DnsContext.java | 4 +- jdk/test/com/sun/jndi/dns/CheckAccess.java | 49 +++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 jdk/test/com/sun/jndi/dns/CheckAccess.java diff --git a/jdk/src/share/classes/com/sun/jndi/dns/DnsContext.java b/jdk/src/share/classes/com/sun/jndi/dns/DnsContext.java index a5c8f01f3c1..3b30bb96a6e 100644 --- a/jdk/src/share/classes/com/sun/jndi/dns/DnsContext.java +++ b/jdk/src/share/classes/com/sun/jndi/dns/DnsContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2009 Sun Microsystems, Inc. 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 @@ -922,7 +922,7 @@ public class DnsContext extends ComponentDirContext { //---------- Debugging - public static boolean debug = false; + private static final boolean debug = false; private static final void dprint(String msg) { if (debug) { diff --git a/jdk/test/com/sun/jndi/dns/CheckAccess.java b/jdk/test/com/sun/jndi/dns/CheckAccess.java new file mode 100644 index 00000000000..478575167a5 --- /dev/null +++ b/jdk/test/com/sun/jndi/dns/CheckAccess.java @@ -0,0 +1,49 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6657619 + * @summary DnsContext.debug is public static mutable (findbugs) + * @author Vincent Ryan + */ + +import java.lang.reflect.*; + +/* + * Check that the 'debug' class member is no longer publicly accessible. + */ +public class CheckAccess { + public static final void main(String[] args) throws Exception { + try { + Class clazz = Class.forName("com.sun.jndi.dns.DnsContext"); + Field field = clazz.getField("debug"); + if (Modifier.isPublic(field.getModifiers())) { + throw new Exception( + "class member 'debug' must not be publicly accessible"); + } + } catch (NoSuchFieldException e) { + // 'debug' is not publicly accessible, ignore exception + } + } +} From d12079f670e26bd0c26e80ace4f63b3308622396 Mon Sep 17 00:00:00 2001 From: Vinnie Ryan Date: Fri, 17 Jul 2009 20:43:53 +0100 Subject: [PATCH 29/96] 6657695: AbstractSaslImpl.logger is a static mutable (findbugs) Reviewed-by: alanb --- .../security/sasl/util/AbstractSaslImpl.java | 21 +++------ .../sun/security/sasl/util/CheckAccess.java | 46 +++++++++++++++++++ 2 files changed, 52 insertions(+), 15 deletions(-) create mode 100644 jdk/test/com/sun/security/sasl/util/CheckAccess.java diff --git a/jdk/src/share/classes/com/sun/security/sasl/util/AbstractSaslImpl.java b/jdk/src/share/classes/com/sun/security/sasl/util/AbstractSaslImpl.java index 9c24b55ecf6..ac6fa258632 100644 --- a/jdk/src/share/classes/com/sun/security/sasl/util/AbstractSaslImpl.java +++ b/jdk/src/share/classes/com/sun/security/sasl/util/AbstractSaslImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2009 Sun Microsystems, Inc. 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 @@ -48,10 +48,6 @@ import sun.misc.HexDumpEncoder; * @author Rosanna Lee */ public abstract class AbstractSaslImpl { - /** - * Logger for debug messages - */ - protected static Logger logger; // set in initLogger(); lazily loads logger protected boolean completed = false; protected boolean privacy = false; @@ -68,7 +64,6 @@ public abstract class AbstractSaslImpl { protected String myClassName; protected AbstractSaslImpl(Map props, String className) throws SaslException { - initLogger(); myClassName = className; // Parse properties to set desired context options @@ -325,19 +320,15 @@ public abstract class AbstractSaslImpl { } } - /** - * Sets logger field. - */ - private static synchronized void initLogger() { - if (logger == null) { - logger = Logger.getLogger(SASL_LOGGER_NAME); - } - } - // ---------------- Constants ----------------- private static final String SASL_LOGGER_NAME = "javax.security.sasl"; protected static final String MAX_SEND_BUF = "javax.security.sasl.sendmaxbuffer"; + /** + * Logger for debug messages + */ + protected static final Logger logger = Logger.getLogger(SASL_LOGGER_NAME); + // default 0 (no protection); 1 (integrity only) protected static final byte NO_PROTECTION = (byte)1; protected static final byte INTEGRITY_ONLY_PROTECTION = (byte)2; diff --git a/jdk/test/com/sun/security/sasl/util/CheckAccess.java b/jdk/test/com/sun/security/sasl/util/CheckAccess.java new file mode 100644 index 00000000000..9ac0674b15c --- /dev/null +++ b/jdk/test/com/sun/security/sasl/util/CheckAccess.java @@ -0,0 +1,46 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6657695 + * @summary AbstractSaslImpl.logger is a static mutable (findbugs) + * @author Vincent Ryan + */ + +import java.lang.reflect.*; + +/* + * Check that the 'logger' class member is immutable. + */ +public class CheckAccess { + public static final void main(String[] args) throws Exception { + Class clazz = + Class.forName("com.sun.security.sasl.util.AbstractSaslImpl"); + Field field = clazz.getDeclaredField("logger"); + if (! Modifier.isFinal(field.getModifiers())) { + throw new Exception( + "class member 'logger' must be immutable"); + } + } +} From b838a003268c302ddf5ae15cd78bef658c591375 Mon Sep 17 00:00:00 2001 From: Peter Zhelezniakov Date: Mon, 20 Jul 2009 13:33:09 +0400 Subject: [PATCH 30/96] 6857360: NimbusLAF: Menu indicator looks ugly with RTL orientation Reviewed-by: rupashka --- jdk/src/share/classes/javax/swing/plaf/nimbus/NimbusIcon.java | 2 ++ jdk/src/share/classes/sun/swing/MenuItemLayoutHelper.java | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/plaf/nimbus/NimbusIcon.java b/jdk/src/share/classes/javax/swing/plaf/nimbus/NimbusIcon.java index 921ca0ea74c..f96a03c9045 100644 --- a/jdk/src/share/classes/javax/swing/plaf/nimbus/NimbusIcon.java +++ b/jdk/src/share/classes/javax/swing/plaf/nimbus/NimbusIcon.java @@ -84,6 +84,8 @@ class NimbusIcon extends SynthIcon { translatex = 1; } } + } else if (c instanceof JMenu) { + flip = ! c.getComponentOrientation().isLeftToRight(); } if (g instanceof Graphics2D){ Graphics2D gfx = (Graphics2D)g; diff --git a/jdk/src/share/classes/sun/swing/MenuItemLayoutHelper.java b/jdk/src/share/classes/sun/swing/MenuItemLayoutHelper.java index 109d0c4022c..1f0281e9be3 100644 --- a/jdk/src/share/classes/sun/swing/MenuItemLayoutHelper.java +++ b/jdk/src/share/classes/sun/swing/MenuItemLayoutHelper.java @@ -718,10 +718,10 @@ public class MenuItemLayoutHelper { } private void alignRect(Rectangle rect, int alignment, int origWidth) { - if (alignment != SwingUtilities.LEFT) { + if (alignment == SwingConstants.RIGHT) { rect.x = rect.x + rect.width - origWidth; - rect.width = origWidth; } + rect.width = origWidth; } protected void layoutIconAndTextInLabelRect(LayoutResult lr) { From 4ba0a90189212113e138bd6723442cf640cbc8db Mon Sep 17 00:00:00 2001 From: Peter Zhelezniakov Date: Mon, 20 Jul 2009 13:34:54 +0400 Subject: [PATCH 31/96] 6849331: Nimbus L&F: AbstractRegionPainter's paint context is not initialized Reviewed-by: rupashka --- .../plaf/nimbus/AbstractRegionPainter.java | 50 +++++++++++++------ 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/plaf/nimbus/AbstractRegionPainter.java b/jdk/src/share/classes/javax/swing/plaf/nimbus/AbstractRegionPainter.java index bf29e15221d..f5762f0f0ef 100644 --- a/jdk/src/share/classes/javax/swing/plaf/nimbus/AbstractRegionPainter.java +++ b/jdk/src/share/classes/javax/swing/plaf/nimbus/AbstractRegionPainter.java @@ -227,10 +227,10 @@ public abstract class AbstractRegionPainter implements Painter { * * @param x an encoded x value (0...1, or 1...2, or 2...3) * @return the decoded x value + * @throws IllegalArgumentException + * if {@code x < 0} or {@code x > 3} */ protected final float decodeX(float x) { - if (ctx.canvasSize == null) return x; - if (x >= 0 && x <= 1) { return x * leftWidth; } else if (x > 1 && x < 2) { @@ -238,7 +238,7 @@ public abstract class AbstractRegionPainter implements Painter { } else if (x >= 2 && x <= 3) { return ((x-2) * rightWidth) + leftWidth + centerWidth; } else { - throw new AssertionError("Invalid x"); + throw new IllegalArgumentException("Invalid x"); } } @@ -248,10 +248,10 @@ public abstract class AbstractRegionPainter implements Painter { * * @param y an encoded y value (0...1, or 1...2, or 2...3) * @return the decoded y value + * @throws IllegalArgumentException + * if {@code y < 0} or {@code y > 3} */ protected final float decodeY(float y) { - if (ctx.canvasSize == null) return y; - if (y >= 0 && y <= 1) { return y * topHeight; } else if (y > 1 && y < 2) { @@ -259,7 +259,7 @@ public abstract class AbstractRegionPainter implements Painter { } else if (y >= 2 && y <= 3) { return ((y-2) * bottomHeight) + topHeight + centerHeight; } else { - throw new AssertionError("Invalid y"); + throw new IllegalArgumentException("Invalid y"); } } @@ -271,10 +271,10 @@ public abstract class AbstractRegionPainter implements Painter { * @param x an encoded x value of the bezier control point (0...1, or 1...2, or 2...3) * @param dx the offset distance to the anchor from the control point x * @return the decoded x location of the control point + * @throws IllegalArgumentException + * if {@code x < 0} or {@code x > 3} */ protected final float decodeAnchorX(float x, float dx) { - if (ctx.canvasSize == null) return x + dx; - if (x >= 0 && x <= 1) { return decodeX(x) + (dx * leftScale); } else if (x > 1 && x < 2) { @@ -282,7 +282,7 @@ public abstract class AbstractRegionPainter implements Painter { } else if (x >= 2 && x <= 3) { return decodeX(x) + (dx * rightScale); } else { - throw new AssertionError("Invalid x"); + throw new IllegalArgumentException("Invalid x"); } } @@ -294,10 +294,10 @@ public abstract class AbstractRegionPainter implements Painter { * @param y an encoded y value of the bezier control point (0...1, or 1...2, or 2...3) * @param dy the offset distance to the anchor from the control point y * @return the decoded y position of the control point + * @throws IllegalArgumentException + * if {@code y < 0} or {@code y > 3} */ protected final float decodeAnchorY(float y, float dy) { - if (ctx.canvasSize == null) return y + dy; - if (y >= 0 && y <= 1) { return decodeY(y) + (dy * topScale); } else if (y > 1 && y < 2) { @@ -305,7 +305,7 @@ public abstract class AbstractRegionPainter implements Painter { } else if (y >= 2 && y <= 3) { return decodeY(y) + (dy * bottomScale); } else { - throw new AssertionError("Invalid y"); + throw new IllegalArgumentException("Invalid y"); } } @@ -363,6 +363,15 @@ public abstract class AbstractRegionPainter implements Painter { * @param midpoints * @param colors * @return a valid LinearGradientPaint. This method never returns null. + * @throws NullPointerException + * if {@code midpoints} array is null, + * or {@code colors} array is null, + * @throws IllegalArgumentException + * if start and end points are the same points, + * or {@code midpoints.length != colors.length}, + * or {@code colors} is less than 2 in size, + * or a {@code midpoints} value is less than 0.0 or greater than 1.0, + * or the {@code midpoints} are not provided in strictly increasing order */ protected final LinearGradientPaint decodeGradient(float x1, float y1, float x2, float y2, float[] midpoints, Color[] colors) { if (x1 == x2 && y1 == y2) { @@ -384,6 +393,15 @@ public abstract class AbstractRegionPainter implements Painter { * @param midpoints * @param colors * @return a valid RadialGradientPaint. This method never returns null. + * @throws NullPointerException + * if {@code midpoints} array is null, + * or {@code colors} array is null + * @throws IllegalArgumentException + * if {@code r} is non-positive, + * or {@code midpoints.length != colors.length}, + * or {@code colors} is less than 2 in size, + * or a {@code midpoints} value is less than 0.0 or greater than 1.0, + * or the {@code midpoints} are not provided in strictly increasing order */ protected final RadialGradientPaint decodeRadialGradient(float x, float y, float r, float[] midpoints, Color[] colors) { if (r == 0f) { @@ -537,10 +555,10 @@ public abstract class AbstractRegionPainter implements Painter { this.maxVerticalScaleFactor = maxV; if (canvasSize != null) { - a = insets.left; - b = canvasSize.width - insets.right; - c = insets.top; - d = canvasSize.height - insets.bottom; + a = stretchingInsets.left; + b = canvasSize.width - stretchingInsets.right; + c = stretchingInsets.top; + d = canvasSize.height - stretchingInsets.bottom; this.canvasSize = canvasSize; this.inverted = inverted; if (inverted) { From da10005c86ffc6ea59c644d3473ea89fb196d25a Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Wed, 22 Jul 2009 12:21:31 +0400 Subject: [PATCH 32/96] 6802868: JInternalFrame is not maximized when maximized parent frame Reviewed-by: rupashka --- .../swing/plaf/basic/BasicDesktopIconUI.java | 15 +- .../plaf/basic/BasicInternalFrameUI.java | 42 +++-- .../swing/plaf/basic/DesktopIconMover.java | 168 ------------------ .../swing/JInternalFrame/Test6802868.java | 108 +++++++++++ 4 files changed, 136 insertions(+), 197 deletions(-) delete mode 100644 jdk/src/share/classes/javax/swing/plaf/basic/DesktopIconMover.java create mode 100644 jdk/test/javax/swing/JInternalFrame/Test6802868.java diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicDesktopIconUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicDesktopIconUI.java index 5ebb6289440..888b95aa021 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicDesktopIconUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicDesktopIconUI.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2009 Sun Microsystems, Inc. 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 @@ -32,9 +32,6 @@ import javax.swing.event.*; import javax.swing.border.*; import javax.swing.plaf.*; import java.beans.*; -import java.util.EventListener; -import java.io.Serializable; - /** * Basic L&F for a minimized window on a desktop. @@ -47,7 +44,6 @@ public class BasicDesktopIconUI extends DesktopIconUI { protected JInternalFrame.JDesktopIcon desktopIcon; protected JInternalFrame frame; - private DesktopIconMover desktopIconMover; /** * The title pane component used in the desktop icon. @@ -128,21 +124,12 @@ public class BasicDesktopIconUI extends DesktopIconUI { mouseInputListener = createMouseInputListener(); desktopIcon.addMouseMotionListener(mouseInputListener); desktopIcon.addMouseListener(mouseInputListener); - getDesktopIconMover().installListeners(); } protected void uninstallListeners() { desktopIcon.removeMouseMotionListener(mouseInputListener); desktopIcon.removeMouseListener(mouseInputListener); mouseInputListener = null; - getDesktopIconMover().uninstallListeners(); - } - - private DesktopIconMover getDesktopIconMover() { - if (desktopIconMover == null) { - desktopIconMover = new DesktopIconMover(desktopIcon); - } - return desktopIconMover; } protected void installDefaults() { diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicInternalFrameUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicInternalFrameUI.java index 383930533a2..551ab00d602 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicInternalFrameUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicInternalFrameUI.java @@ -27,16 +27,10 @@ package javax.swing.plaf.basic; import java.awt.*; import java.awt.event.*; -import java.awt.peer.LightweightPeer; - import javax.swing.*; -import javax.swing.border.*; import javax.swing.plaf.*; import javax.swing.event.*; - import java.beans.*; -import java.io.Serializable; - import sun.swing.DefaultLookup; import sun.swing.UIAction; @@ -55,6 +49,7 @@ public class BasicInternalFrameUI extends InternalFrameUI protected MouseInputAdapter borderListener; protected PropertyChangeListener propertyChangeListener; protected LayoutManager internalFrameLayout; + protected ComponentListener componentListener; protected MouseInputListener glassPaneDispatcher; private InternalFrameListener internalFrameListener; @@ -66,9 +61,9 @@ public class BasicInternalFrameUI extends InternalFrameUI protected BasicInternalFrameTitlePane titlePane; // access needs this private static DesktopManager sharedDesktopManager; + private boolean componentListenerAdded = false; private Rectangle parentBounds; - private DesktopIconMover desktopIconMover; private boolean dragging = false; private boolean resizing = false; @@ -209,17 +204,14 @@ public class BasicInternalFrameUI extends InternalFrameUI frame.getGlassPane().addMouseListener(glassPaneDispatcher); frame.getGlassPane().addMouseMotionListener(glassPaneDispatcher); } + componentListener = createComponentListener(); if (frame.getParent() != null) { parentBounds = frame.getParent().getBounds(); } - getDesktopIconMover().installListeners(); - } - - private DesktopIconMover getDesktopIconMover() { - if (desktopIconMover == null) { - desktopIconMover = new DesktopIconMover(frame); + if ((frame.getParent() != null) && !componentListenerAdded) { + frame.getParent().addComponentListener(componentListener); + componentListenerAdded = true; } - return desktopIconMover; } // Provide a FocusListener to listen for a WINDOW_LOST_FOCUS event, @@ -290,7 +282,11 @@ public class BasicInternalFrameUI extends InternalFrameUI * @since 1.3 */ protected void uninstallListeners() { - getDesktopIconMover().uninstallListeners(); + if ((frame.getParent() != null) && componentListenerAdded) { + frame.getParent().removeComponentListener(componentListener); + componentListenerAdded = false; + } + componentListener = null; if (glassPaneDispatcher != null) { frame.getGlassPane().removeMouseListener(glassPaneDispatcher); frame.getGlassPane().removeMouseMotionListener(glassPaneDispatcher); @@ -1228,6 +1224,15 @@ public class BasicInternalFrameUI extends InternalFrameUI } } + // Relocate the icon base on the new parent bounds. + if (icon != null) { + Rectangle iconBounds = icon.getBounds(); + int y = iconBounds.y + + (parentNewBounds.height - parentBounds.height); + icon.setBounds(iconBounds.x, y, + iconBounds.width, iconBounds.height); + } + // Update the new parent bounds for next resize. if (!parentBounds.equals(parentNewBounds)) { parentBounds = parentNewBounds; @@ -1399,6 +1404,9 @@ public class BasicInternalFrameUI extends InternalFrameUI // Cancel a resize in progress if the internal frame // gets a setClosed(true) or dispose(). cancelResize(); + if ((frame.getParent() != null) && componentListenerAdded) { + frame.getParent().removeComponentListener(componentListener); + } closeFrame(f); } } else if (JInternalFrame.IS_MAXIMUM_PROPERTY == prop) { @@ -1431,6 +1439,10 @@ public class BasicInternalFrameUI extends InternalFrameUI } else { parentBounds = null; } + if ((frame.getParent() != null) && !componentListenerAdded) { + f.getParent().addComponentListener(componentListener); + componentListenerAdded = true; + } } else if (JInternalFrame.TITLE_PROPERTY == prop || prop == "closable" || prop == "iconable" || prop == "maximizable") { diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/DesktopIconMover.java b/jdk/src/share/classes/javax/swing/plaf/basic/DesktopIconMover.java deleted file mode 100644 index deff4f27a5f..00000000000 --- a/jdk/src/share/classes/javax/swing/plaf/basic/DesktopIconMover.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 1997-2008 Sun Microsystems, Inc. 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. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package javax.swing.plaf.basic; - -import javax.swing.*; -import java.awt.*; -import java.awt.event.*; -import java.beans.*; - -/** - * DesktopIconMover is intended to move desktop icon - * when parent window is resized. - */ -class DesktopIconMover implements ComponentListener, PropertyChangeListener { - private Component parent; - private JInternalFrame frame; // if not null, DesktopIconMover(frame) - // constructor was used - private JInternalFrame.JDesktopIcon icon; - private Rectangle parentBounds; - private boolean componentListenerAdded = false; - - public DesktopIconMover(JInternalFrame frame) { - if (frame == null) { - throw new NullPointerException("Frame cannot be null"); - } - this.frame = frame; - this.icon = frame.getDesktopIcon(); - if (icon == null) { - throw new NullPointerException( - "frame.getDesktopIcon() cannot be null"); - } - this.parent = frame.getParent(); - if (this.parent != null) { - parentBounds = this.parent.getBounds(); - } - } - - public DesktopIconMover(JInternalFrame.JDesktopIcon icon) { - if (icon == null) { - throw new NullPointerException("Icon cannot be null"); - } - this.icon = icon; - this.parent = icon.getParent(); - if (this.parent != null) { - parentBounds = this.parent.getBounds(); - } - } - - public void installListeners() { - if (frame != null) { - frame.addPropertyChangeListener(this); - } else { - icon.addPropertyChangeListener(this); - } - addComponentListener(); - } - - public void uninstallListeners() { - if (frame != null) { - frame.removePropertyChangeListener(this); - } else { - icon.removePropertyChangeListener(this); - } - removeComponentListener(); - } - - public void propertyChange(PropertyChangeEvent evt) { - String propName = evt.getPropertyName(); - if ("ancestor".equals(propName)) { - Component newAncestor = (Component) evt.getNewValue(); - - // Remove component listener if parent is changing - Component probablyNewParent = getCurrentParent(); - if ((probablyNewParent != null) && - (!probablyNewParent.equals(parent))) { - removeComponentListener(); - parent = probablyNewParent; - } - - if (newAncestor == null) { - removeComponentListener(); - } else { - addComponentListener(); - } - - // Update parentBounds - if (parent != null) { - parentBounds = parent.getBounds(); - } else { - parentBounds = null; - } - } else if (JInternalFrame.IS_CLOSED_PROPERTY.equals(propName)) { - removeComponentListener(); - } - } - - private void addComponentListener() { - if (!componentListenerAdded && (parent != null)) { - parent.addComponentListener(this); - componentListenerAdded = true; - } - } - - private void removeComponentListener() { - if ((parent != null) && componentListenerAdded) { - parent.removeComponentListener(this); - componentListenerAdded = false; - } - } - - private Component getCurrentParent() { - if (frame != null) { - return frame.getParent(); - } else { - return icon.getParent(); - } - } - - public void componentResized(ComponentEvent e) { - if ((parent == null) || (parentBounds == null)) { - return; - } - - Rectangle parentNewBounds = parent.getBounds(); - if ((parentNewBounds == null) || parentNewBounds.equals(parentBounds)) { - return; - } - - // Move desktop icon only in up-down direction - int newIconY = icon.getLocation().y + - (parentNewBounds.height - parentBounds.height); - icon.setLocation(icon.getLocation().x, newIconY); - - parentBounds = parentNewBounds; - } - - public void componentMoved(ComponentEvent e) { - } - - public void componentShown(ComponentEvent e) { - } - - public void componentHidden(ComponentEvent e) { - } -} diff --git a/jdk/test/javax/swing/JInternalFrame/Test6802868.java b/jdk/test/javax/swing/JInternalFrame/Test6802868.java new file mode 100644 index 00000000000..74410df81fd --- /dev/null +++ b/jdk/test/javax/swing/JInternalFrame/Test6802868.java @@ -0,0 +1,108 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6802868 + * @summary JInternalFrame is not maximized when maximized parent frame + * @author Alexander Potochkin + */ + +import sun.awt.SunToolkit; + +import java.awt.Dimension; +import java.awt.Point; +import java.awt.Robot; +import java.awt.Toolkit; +import java.beans.PropertyVetoException; +import javax.swing.JDesktopPane; +import javax.swing.JFrame; +import javax.swing.JInternalFrame; +import javax.swing.SwingUtilities; + +public class Test6802868 { + static JInternalFrame jif; + static JFrame frame; + static Dimension size; + static Point location; + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + robot.setAutoDelay(20); + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + frame = new JFrame(); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + JDesktopPane jdp = new JDesktopPane(); + frame.getContentPane().add(jdp); + + jif = new JInternalFrame("Title", true, true, true, true); + jdp.add(jif); + jif.setVisible(true); + + frame.setSize(200, 200); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + + try { + jif.setMaximum(true); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + toolkit.realSync(); + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + size = jif.getSize(); + frame.setSize(300, 300); + } + }); + toolkit.realSync(); + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + if (jif.getSize().equals(size)) { + throw new RuntimeException("InternalFrame hasn't changed its size"); + } + try { + jif.setIcon(true); + } catch (PropertyVetoException e) { + e.printStackTrace(); + } + location = jif.getDesktopIcon().getLocation(); + frame.setSize(400, 400); + } + }); + toolkit.realSync(); + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + if (jif.getDesktopIcon().getLocation().equals(location)) { + throw new RuntimeException("JDesktopIcon hasn't moved"); + } + } + }); + } +} From 6293f73bd86a04cf3ab19f580549b1039a3e96ab Mon Sep 17 00:00:00 2001 From: Dmitry Cherepanov Date: Wed, 22 Jul 2009 13:00:11 +0400 Subject: [PATCH 33/96] 6859935: REGRESSION: Settings are missing in JCP/Advanced tab on windows Reviewed-by: art --- .../windows/classes/sun/awt/windows/WToolkit.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/jdk/src/windows/classes/sun/awt/windows/WToolkit.java b/jdk/src/windows/classes/sun/awt/windows/WToolkit.java index 6e12209f94c..9fcf3d67a8b 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WToolkit.java +++ b/jdk/src/windows/classes/sun/awt/windows/WToolkit.java @@ -886,14 +886,12 @@ public class WToolkit extends SunToolkit implements Runnable { * this should be done in lazilyLoadDesktopProperty() only. */ protected synchronized void initializeDesktopProperties() { - desktopProperties.put("DnD.Autoscroll.initialDelay", Integer.valueOf(50)); - desktopProperties.put("DnD.Autoscroll.interval", Integer.valueOf(50)); - - try { - desktopProperties.put("Shell.shellFolderManager", - Class.forName("sun.awt.shell.Win32ShellFolderManager2")); - } catch (ClassNotFoundException ex) { - } + desktopProperties.put("DnD.Autoscroll.initialDelay", + Integer.valueOf(50)); + desktopProperties.put("DnD.Autoscroll.interval", + Integer.valueOf(50)); + desktopProperties.put("Shell.shellFolderManager", + "sun.awt.shell.Win32ShellFolderManager2"); } /* From 8440a8dba3b2f7c732b12d8bcaaec3a7c91db207 Mon Sep 17 00:00:00 2001 From: Anthony Petrov Date: Thu, 23 Jul 2009 13:46:23 +0400 Subject: [PATCH 34/96] 6848424: java/awt/Frame/FrameSize/TestFrameSize.java needs improvement The test now thoroughly verifies the pack() method Reviewed-by: art, dcherepanov --- .../awt/Frame/FrameSize/TestFrameSize.java | 74 +++++++++++++------ 1 file changed, 51 insertions(+), 23 deletions(-) diff --git a/jdk/test/java/awt/Frame/FrameSize/TestFrameSize.java b/jdk/test/java/awt/Frame/FrameSize/TestFrameSize.java index b220ec5cc01..29a4399a609 100644 --- a/jdk/test/java/awt/Frame/FrameSize/TestFrameSize.java +++ b/jdk/test/java/awt/Frame/FrameSize/TestFrameSize.java @@ -1,5 +1,6 @@ /* * Copyright 2009 Red Hat, Inc. All Rights Reserved. + * Portions Copyright 2009 Sun Microsystems, Inc. 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 @@ -37,35 +38,62 @@ * Test fails if size of window is wrong */ -import java.awt.Dimension; -import java.awt.Frame; +import java.awt.*; public class TestFrameSize { - static Dimension desiredDimensions = new Dimension(200, 200); - static int ERROR_MARGIN = 15; - static Frame mainWindow; + static Dimension desiredDimensions = new Dimension(200, 200); + static Frame mainWindow; - public static void drawGui() { - mainWindow = new Frame(""); - mainWindow.setPreferredSize(desiredDimensions); - mainWindow.pack(); + private static Dimension getClientSize(Frame window) { + Dimension size = window.getSize(); + Insets insets = window.getInsets(); - Dimension actualDimensions = mainWindow.getSize(); - System.out.println("Desired dimensions: " + desiredDimensions.toString()); - System.out.println("Actual dimensions: " + actualDimensions.toString()); - if (Math.abs(actualDimensions.height - desiredDimensions.height) > ERROR_MARGIN) { - throw new RuntimeException("Incorrect widow size"); - } + System.out.println("getClientSize() for " + window); + System.out.println(" size: " + size); + System.out.println(" insets: " + insets); + + return new Dimension( + size.width - insets.left - insets.right, + size.height - insets.top - insets.bottom); + } + + public static void drawGui() { + mainWindow = new Frame(""); + mainWindow.setPreferredSize(desiredDimensions); + mainWindow.pack(); + + Dimension actualDimensions = mainWindow.getSize(); + System.out.println("Desired dimensions: " + desiredDimensions.toString()); + System.out.println("Actual dimensions: " + actualDimensions.toString()); + if (!actualDimensions.equals(desiredDimensions)) { + throw new RuntimeException("Incorrect widow size"); } - public static void main(String[] args) { - try { - drawGui(); - } finally { - if (mainWindow != null) { - mainWindow.dispose(); - } - } + // pack() guarantees to preserve the size of the client area after + // showing the window. + Dimension clientSize1 = getClientSize(mainWindow); + System.out.println("Client size before showing: " + clientSize1); + + mainWindow.setVisible(true); + + ((sun.awt.SunToolkit)Toolkit.getDefaultToolkit()).realSync(); + + Dimension clientSize2 = getClientSize(mainWindow); + System.out.println("Client size after showing: " + clientSize2); + + if (!clientSize2.equals(clientSize1)) { + throw new RuntimeException("Incorrect client area size."); } + } + + public static void main(String[] args) { + try { + drawGui(); + } finally { + if (mainWindow != null) { + mainWindow.dispose(); + } + } + } } From 653e2804122cdf24e86465d3da9839bfb699f6e2 Mon Sep 17 00:00:00 2001 From: Pavel Porvatov Date: Thu, 23 Jul 2009 17:56:53 +0400 Subject: [PATCH 35/96] 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out Reviewed-by: malenkov, peterz --- .../classes/javax/swing/JFileChooser.java | 7 +- .../swing/plaf/basic/BasicDirectoryModel.java | 10 +- .../classes/sun/awt/shell/ShellFolder.java | 60 +++- .../sun/awt/shell/ShellFolderManager.java | 10 +- jdk/src/share/classes/sun/swing/FilePane.java | 7 +- .../sun/awt/shell/Win32ShellFolder2.java | 292 +++++++++--------- .../awt/shell/Win32ShellFolderManager2.java | 91 ++++-- 7 files changed, 278 insertions(+), 199 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/JFileChooser.java b/jdk/src/share/classes/javax/swing/JFileChooser.java index 82c85fe9faa..8ba9c7c42af 100644 --- a/jdk/src/share/classes/javax/swing/JFileChooser.java +++ b/jdk/src/share/classes/javax/swing/JFileChooser.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2009 Sun Microsystems, Inc. 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 @@ -739,6 +739,11 @@ public class JFileChooser extends JComponent implements Accessible { dialog.show(); firePropertyChange("JFileChooserDialogIsClosingProperty", dialog, null); + + // Remove all components from dialog. The MetalFileChooserUI.installUI() method (and other LAFs) + // registers AWT listener for dialogs and produces memory leaks. It happens when + // installUI invoked after the showDialog method. + dialog.getContentPane().removeAll(); dialog.dispose(); dialog = null; return returnValue; diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java index 74f24b6eb7e..1e5d80f8ea2 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java @@ -1,5 +1,5 @@ /* - * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2009 Sun Microsystems, Inc. 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 @@ -232,6 +232,10 @@ public class BasicDirectoryModel extends AbstractListModel implements PropertyCh public void run0() { FileSystemView fileSystem = filechooser.getFileSystemView(); + if (isInterrupted()) { + return; + } + File[] list = fileSystem.getFiles(currentDirectory, filechooser.isFileHidingEnabled()); if (isInterrupted()) { @@ -268,8 +272,8 @@ public class BasicDirectoryModel extends AbstractListModel implements PropertyCh // To avoid loads of synchronizations with Invoker and improve performance we // execute the whole block on the COM thread - DoChangeContents doChangeContents = ShellFolder.getInvoker().invoke(new Callable() { - public DoChangeContents call() throws Exception { + DoChangeContents doChangeContents = ShellFolder.invoke(new Callable() { + public DoChangeContents call() { int newSize = newFileCache.size(); int oldSize = fileCache.size(); diff --git a/jdk/src/share/classes/sun/awt/shell/ShellFolder.java b/jdk/src/share/classes/sun/awt/shell/ShellFolder.java index d38fd98e030..cf3c7893384 100644 --- a/jdk/src/share/classes/sun/awt/shell/ShellFolder.java +++ b/jdk/src/share/classes/sun/awt/shell/ShellFolder.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2009 Sun Microsystems, Inc. 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 @@ -289,8 +289,8 @@ public abstract class ShellFolder extends File { // To avoid loads of synchronizations with Invoker and improve performance we // synchronize the whole code of the sort method once - getInvoker().invoke(new Callable() { - public Void call() throws Exception { + invoke(new Callable() { + public Void call() { // Check that we can use the ShellFolder.sortChildren() method: // 1. All files have the same non-null parent // 2. All files is ShellFolders @@ -330,8 +330,8 @@ public abstract class ShellFolder extends File { public void sortChildren(final List files) { // To avoid loads of synchronizations with Invoker and improve performance we // synchronize the whole code of the sort method once - getInvoker().invoke(new Callable() { - public Void call() throws Exception { + invoke(new Callable() { + public Void call() { Collections.sort(files, FILE_COMPARATOR); return null; @@ -501,18 +501,62 @@ public abstract class ShellFolder extends File { return invoker; } + /** + * Invokes the {@code task} which doesn't throw checked exceptions + * from its {@code call} method. If invokation is interrupted then Thread.currentThread().isInterrupted() will + * be set and result will be {@code null} + */ + public static T invoke(Callable task) { + try { + return invoke(task, RuntimeException.class); + } catch (InterruptedException e) { + return null; + } + } + + /** + * Invokes the {@code task} which throws checked exceptions from its {@code call} method. + * If invokation is interrupted then Thread.currentThread().isInterrupted() will + * be set and InterruptedException will be thrown as well. + */ + public static T invoke(Callable task, Class exceptionClass) + throws InterruptedException, E { + try { + return getInvoker().invoke(task); + } catch (Exception e) { + if (e instanceof RuntimeException) { + // Rethrow unchecked exceptions + throw (RuntimeException) e; + } + + if (e instanceof InterruptedException) { + // Set isInterrupted flag for current thread + Thread.currentThread().interrupt(); + + // Rethrow InterruptedException + throw (InterruptedException) e; + } + + if (exceptionClass.isInstance(e)) { + throw exceptionClass.cast(e); + } + + throw new RuntimeException("Unexpected error", e); + } + } + /** * Interface allowing to invoke tasks in different environments on different platforms. */ public static interface Invoker { /** - * Invokes a callable task. If the {@code task} throws a checked exception, - * it will be wrapped into a {@link RuntimeException} + * Invokes a callable task. * * @param task a task to invoke + * @throws Exception {@code InterruptedException} or an exception that was thrown from the {@code task} * @return the result of {@code task}'s invokation */ - T invoke(Callable task); + T invoke(Callable task) throws Exception; } /** diff --git a/jdk/src/share/classes/sun/awt/shell/ShellFolderManager.java b/jdk/src/share/classes/sun/awt/shell/ShellFolderManager.java index dc8901f7bc5..fe00063ffbb 100644 --- a/jdk/src/share/classes/sun/awt/shell/ShellFolderManager.java +++ b/jdk/src/share/classes/sun/awt/shell/ShellFolderManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2009 Sun Microsystems, Inc. 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 @@ -108,12 +108,8 @@ class ShellFolderManager { } private static class DirectInvoker implements ShellFolder.Invoker { - public T invoke(Callable task) { - try { - return task.call(); - } catch (Exception e) { - throw new RuntimeException(e); - } + public T invoke(Callable task) throws Exception { + return task.call(); } } } diff --git a/jdk/src/share/classes/sun/swing/FilePane.java b/jdk/src/share/classes/sun/swing/FilePane.java index eae3d5a0d60..4aa80522216 100644 --- a/jdk/src/share/classes/sun/swing/FilePane.java +++ b/jdk/src/share/classes/sun/swing/FilePane.java @@ -1,6 +1,5 @@ - /* - * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2009 Sun Microsystems, Inc. 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 @@ -905,8 +904,8 @@ public class FilePane extends JPanel implements PropertyChangeListener { @Override public void sort() { - ShellFolder.getInvoker().invoke(new Callable() { - public Void call() throws Exception { + ShellFolder.invoke(new Callable() { + public Void call() { DetailsTableRowSorter.super.sort(); return null; } diff --git a/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java b/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java index 716b56238cf..1b81007fe8e 100644 --- a/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java +++ b/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2009 Sun Microsystems, Inc. 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 @@ -29,7 +29,6 @@ import java.awt.Image; import java.awt.Toolkit; import java.awt.image.BufferedImage; import java.io.File; -import java.io.FileNotFoundException; import java.io.IOException; import java.util.*; import java.util.concurrent.*; @@ -185,8 +184,8 @@ final class Win32ShellFolder2 extends ShellFolder { boolean disposed; public void dispose() { if (disposed) return; - ShellFolder.getInvoker().invoke(new Callable() { - public Void call() throws Exception { + invoke(new Callable() { + public Void call() { if (relativePIDL != 0) { releasePIDL(relativePIDL); } @@ -224,7 +223,7 @@ final class Win32ShellFolder2 extends ShellFolder { */ private boolean isPersonal; - private static String composePathForCsidl(int csidl) throws IOException { + private static String composePathForCsidl(int csidl) throws IOException, InterruptedException { String path = getFileSystemPath(csidl); return path == null ? ("ShellFolder: 0x" + Integer.toHexString(csidl)) @@ -235,12 +234,13 @@ final class Win32ShellFolder2 extends ShellFolder { * Create a system special shell folder, such as the * desktop or Network Neighborhood. */ - Win32ShellFolder2(final int csidl) throws IOException { + Win32ShellFolder2(final int csidl) throws IOException, InterruptedException { // Desktop is parent of DRIVES and NETWORK, not necessarily // other special shell folders. super(null, composePathForCsidl(csidl)); - ShellFolder.getInvoker().invoke(new Callable() { - public Void call() throws Exception { + + invoke(new Callable() { + public Void call() throws InterruptedException { if (csidl == DESKTOP) { initDesktop(); } else { @@ -276,7 +276,7 @@ final class Win32ShellFolder2 extends ShellFolder { } return null; } - }); + }, InterruptedException.class); sun.java2d.Disposer.addRecord(this, disposer); } @@ -296,13 +296,13 @@ final class Win32ShellFolder2 extends ShellFolder { /** * Creates a shell folder with a parent and relative PIDL */ - Win32ShellFolder2(final Win32ShellFolder2 parent, final long relativePIDL) { + Win32ShellFolder2(final Win32ShellFolder2 parent, final long relativePIDL) throws InterruptedException { super(parent, - ShellFolder.getInvoker().invoke(new Callable() { - public String call() throws Exception { + invoke(new Callable() { + public String call() { return getFileSystemPath(parent.getIShellFolder(), relativePIDL); } - }) + }, RuntimeException.class) ); this.disposer.relativePIDL = relativePIDL; getAbsolutePath(); @@ -335,8 +335,8 @@ final class Win32ShellFolder2 extends ShellFolder { * drive (normally "C:\"). */ protected Object writeReplace() throws java.io.ObjectStreamException { - return ShellFolder.getInvoker().invoke(new Callable() { - public File call() throws Exception { + return invoke(new Callable() { + public File call() { if (isFileSystem()) { return new File(getPath()); } else { @@ -398,11 +398,11 @@ final class Win32ShellFolder2 extends ShellFolder { /** * Accessor for IShellFolder */ - public long getIShellFolder() { + private long getIShellFolder() { if (disposer.pIShellFolder == 0) { - disposer.pIShellFolder = - ShellFolder.getInvoker().invoke(new Callable() { - public Long call() throws Exception { + try { + disposer.pIShellFolder = invoke(new Callable() { + public Long call() { assert(isDirectory()); assert(parent != null); long parentIShellFolder = getParentIShellFolder(); @@ -421,7 +421,10 @@ final class Win32ShellFolder2 extends ShellFolder { } return pIShellFolder; } - }); + }, RuntimeException.class); + } catch (InterruptedException e) { + // Ignore error + } } return disposer.pIShellFolder; } @@ -505,18 +508,23 @@ final class Win32ShellFolder2 extends ShellFolder { } if (parent == rhs.parent || parent.equals(rhs.parent)) { - return pidlsEqual(getParentIShellFolder(), disposer.relativePIDL, rhs.disposer.relativePIDL); + try { + return pidlsEqual(getParentIShellFolder(), disposer.relativePIDL, rhs.disposer.relativePIDL); + } catch (InterruptedException e) { + return false; + } } return false; } - private static boolean pidlsEqual(final long pIShellFolder, final long pidl1, final long pidl2) { - return ShellFolder.getInvoker().invoke(new Callable() { - public Boolean call() throws Exception { - return (compareIDs(pIShellFolder, pidl1, pidl2) == 0); + private static boolean pidlsEqual(final long pIShellFolder, final long pidl1, final long pidl2) + throws InterruptedException { + return invoke(new Callable() { + public Boolean call() { + return compareIDs(pIShellFolder, pidl1, pidl2) == 0; } - }); + }, RuntimeException.class); } // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details @@ -539,14 +547,16 @@ final class Win32ShellFolder2 extends ShellFolder { * Return whether the given attribute flag is set for this object */ public boolean hasAttribute(final int attribute) { - return ShellFolder.getInvoker().invoke(new Callable() { - public Boolean call() throws Exception { + Boolean result = invoke(new Callable() { + public Boolean call() { // Caching at this point doesn't seem to be cost efficient return (getAttributes0(getParentIShellFolder(), getRelativePIDL(), attribute) & attribute) != 0; } }); + + return result != null && result; } /** @@ -561,32 +571,29 @@ final class Win32ShellFolder2 extends ShellFolder { private static native int getAttributes0(long pParentIShellFolder, long pIDL, int attrsMask); // Return the path to the underlying file system object + // Should be called from the COM thread private static String getFileSystemPath(final long parentIShellFolder, final long relativePIDL) { - return ShellFolder.getInvoker().invoke(new Callable() { - public String call() throws Exception { - int linkedFolder = ATTRIB_LINK | ATTRIB_FOLDER; - if (parentIShellFolder == Win32ShellFolderManager2.getNetwork().getIShellFolder() && - getAttributes0(parentIShellFolder, relativePIDL, linkedFolder) == linkedFolder) { + int linkedFolder = ATTRIB_LINK | ATTRIB_FOLDER; + if (parentIShellFolder == Win32ShellFolderManager2.getNetwork().getIShellFolder() && + getAttributes0(parentIShellFolder, relativePIDL, linkedFolder) == linkedFolder) { - String s = - getFileSystemPath(Win32ShellFolderManager2.getDesktop().getIShellFolder(), - getLinkLocation(parentIShellFolder, relativePIDL, false)); - if (s != null && s.startsWith("\\\\")) { - return s; - } - } - return getDisplayNameOf(parentIShellFolder, relativePIDL, SHGDN_FORPARSING); + String s = + getFileSystemPath(Win32ShellFolderManager2.getDesktop().getIShellFolder(), + getLinkLocation(parentIShellFolder, relativePIDL, false)); + if (s != null && s.startsWith("\\\\")) { + return s; } - }); + } + return getDisplayNameOf(parentIShellFolder, relativePIDL, SHGDN_FORPARSING); } // Needs to be accessible to Win32ShellFolderManager2 - static String getFileSystemPath(final int csidl) throws IOException { - return ShellFolder.getInvoker().invoke(new Callable() { - public String call() throws Exception { + static String getFileSystemPath(final int csidl) throws IOException, InterruptedException { + return invoke(new Callable() { + public String call() throws IOException { return getFileSystemPath0(csidl); } - }); + }, IOException.class); } // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details @@ -630,13 +637,14 @@ final class Win32ShellFolder2 extends ShellFolder { */ // Returns an IEnumIDList interface for an IShellFolder. The value // returned must be released using releaseEnumObjects(). - private long getEnumObjects(long pIShellFolder, final boolean includeHiddenFiles) { - final boolean isDesktop = (disposer.pIShellFolder == getDesktopIShellFolder()); - return ShellFolder.getInvoker().invoke(new Callable() { - public Long call() throws Exception { + private long getEnumObjects(final boolean includeHiddenFiles) throws InterruptedException { + return invoke(new Callable() { + public Long call() { + boolean isDesktop = disposer.pIShellFolder == getDesktopIShellFolder(); + return getEnumObjects(disposer.pIShellFolder, isDesktop, includeHiddenFiles); } - }); + }, RuntimeException.class); } // Returns an IEnumIDList interface for an IShellFolder. The value @@ -670,58 +678,62 @@ final class Win32ShellFolder2 extends ShellFolder { security.checkRead(getPath()); } - return ShellFolder.getInvoker().invoke(new Callable() { - public File[] call() throws Exception { - if (!isDirectory()) { - return null; - } - // Links to directories are not directories and cannot be parents. - // This does not apply to folders in My Network Places (NetHood) - // because they are both links and real directories! - if (isLink() && !hasAttribute(ATTRIB_FOLDER)) { - return new File[0]; - } + try { + return invoke(new Callable() { + public File[] call() throws InterruptedException { + if (!isDirectory()) { + return null; + } + // Links to directories are not directories and cannot be parents. + // This does not apply to folders in My Network Places (NetHood) + // because they are both links and real directories! + if (isLink() && !hasAttribute(ATTRIB_FOLDER)) { + return new File[0]; + } - Win32ShellFolder2 desktop = Win32ShellFolderManager2.getDesktop(); - Win32ShellFolder2 personal = Win32ShellFolderManager2.getPersonal(); + Win32ShellFolder2 desktop = Win32ShellFolderManager2.getDesktop(); + Win32ShellFolder2 personal = Win32ShellFolderManager2.getPersonal(); - // If we are a directory, we have a parent and (at least) a - // relative PIDL. We must first ensure we are bound to the - // parent so we have an IShellFolder to query. - long pIShellFolder = getIShellFolder(); - // Now we can enumerate the objects in this folder. - ArrayList list = new ArrayList(); - long pEnumObjects = getEnumObjects(pIShellFolder, includeHiddenFiles); - if (pEnumObjects != 0) { - long childPIDL; - int testedAttrs = ATTRIB_FILESYSTEM | ATTRIB_FILESYSANCESTOR; - do { - childPIDL = getNextChild(pEnumObjects); - boolean releasePIDL = true; - if (childPIDL != 0 && - (getAttributes0(pIShellFolder, childPIDL, testedAttrs) & testedAttrs) != 0) { - Win32ShellFolder2 childFolder; - if (Win32ShellFolder2.this.equals(desktop) - && personal != null - && pidlsEqual(pIShellFolder, childPIDL, personal.disposer.relativePIDL)) { - childFolder = personal; - } else { - childFolder = new Win32ShellFolder2(Win32ShellFolder2.this, childPIDL); - releasePIDL = false; + // If we are a directory, we have a parent and (at least) a + // relative PIDL. We must first ensure we are bound to the + // parent so we have an IShellFolder to query. + long pIShellFolder = getIShellFolder(); + // Now we can enumerate the objects in this folder. + ArrayList list = new ArrayList(); + long pEnumObjects = getEnumObjects(includeHiddenFiles); + if (pEnumObjects != 0) { + long childPIDL; + int testedAttrs = ATTRIB_FILESYSTEM | ATTRIB_FILESYSANCESTOR; + do { + childPIDL = getNextChild(pEnumObjects); + boolean releasePIDL = true; + if (childPIDL != 0 && + (getAttributes0(pIShellFolder, childPIDL, testedAttrs) & testedAttrs) != 0) { + Win32ShellFolder2 childFolder; + if (Win32ShellFolder2.this.equals(desktop) + && personal != null + && pidlsEqual(pIShellFolder, childPIDL, personal.disposer.relativePIDL)) { + childFolder = personal; + } else { + childFolder = new Win32ShellFolder2(Win32ShellFolder2.this, childPIDL); + releasePIDL = false; + } + list.add(childFolder); } - list.add(childFolder); - } - if (releasePIDL) { - releasePIDL(childPIDL); - } - } while (childPIDL != 0 && !Thread.currentThread().isInterrupted()); - releaseEnumObjects(pEnumObjects); + if (releasePIDL) { + releasePIDL(childPIDL); + } + } while (childPIDL != 0 && !Thread.currentThread().isInterrupted()); + releaseEnumObjects(pEnumObjects); + } + return Thread.currentThread().isInterrupted() + ? new File[0] + : list.toArray(new ShellFolder[list.size()]); } - return Thread.currentThread().isInterrupted() - ? new File[0] - : list.toArray(new ShellFolder[list.size()]); - } - }); + }, InterruptedException.class); + } catch (InterruptedException e) { + return new File[0]; + } } @@ -730,13 +742,13 @@ final class Win32ShellFolder2 extends ShellFolder { * * @return The child shellfolder, or null if not found. */ - Win32ShellFolder2 getChildByPath(final String filePath) { - return ShellFolder.getInvoker().invoke(new Callable() { - public Win32ShellFolder2 call() throws Exception { + Win32ShellFolder2 getChildByPath(final String filePath) throws InterruptedException { + return invoke(new Callable() { + public Win32ShellFolder2 call() throws InterruptedException { long pIShellFolder = getIShellFolder(); - long pEnumObjects = getEnumObjects(pIShellFolder, true); + long pEnumObjects = getEnumObjects(true); Win32ShellFolder2 child = null; - long childPIDL = 0; + long childPIDL; while ((childPIDL = getNextChild(pEnumObjects)) != 0) { if (getAttributes0(pIShellFolder, childPIDL, ATTRIB_FILESYSTEM) != 0) { @@ -753,7 +765,7 @@ final class Win32ShellFolder2 extends ShellFolder { releaseEnumObjects(pEnumObjects); return child; } - }); + }, InterruptedException.class); } private Boolean cachedIsLink; @@ -791,8 +803,8 @@ final class Win32ShellFolder2 extends ShellFolder { } private ShellFolder getLinkLocation(final boolean resolve) { - return ShellFolder.getInvoker().invoke(new Callable() { - public ShellFolder call() throws Exception { + return invoke(new Callable() { + public ShellFolder call() { if (!isLink()) { return null; } @@ -805,6 +817,8 @@ final class Win32ShellFolder2 extends ShellFolder { location = Win32ShellFolderManager2.createShellFolderFromRelativePIDL(getDesktop(), linkLocationPIDL); + } catch (InterruptedException e) { + // Return null } catch (InternalError e) { // Could be a link to a non-bindable object, such as a network connection // TODO: getIShellFolder() should throw FileNotFoundException instead @@ -816,19 +830,12 @@ final class Win32ShellFolder2 extends ShellFolder { } // Parse a display name into a PIDL relative to the current IShellFolder. - long parseDisplayName(final String name) throws FileNotFoundException { - try { - return ShellFolder.getInvoker().invoke(new Callable() { - public Long call() throws Exception { - return parseDisplayName0(getIShellFolder(), name); - } - }); - } catch (RuntimeException e) { - if (e.getCause() instanceof IOException) { - throw new FileNotFoundException("Could not find file " + name); + long parseDisplayName(final String name) throws IOException, InterruptedException { + return invoke(new Callable() { + public Long call() throws IOException { + return parseDisplayName0(getIShellFolder(), name); } - throw e; - } + }, IOException.class); } // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details @@ -846,8 +853,8 @@ final class Win32ShellFolder2 extends ShellFolder { public String getDisplayName() { if (displayName == null) { displayName = - ShellFolder.getInvoker().invoke(new Callable() { - public String call() throws Exception { + invoke(new Callable() { + public String call() { return getDisplayNameOf(getParentIShellFolder(), getRelativePIDL(), SHGDN_NORMAL); } @@ -867,8 +874,8 @@ final class Win32ShellFolder2 extends ShellFolder { if (folderType == null) { final long absolutePIDL = getAbsolutePIDL(); folderType = - ShellFolder.getInvoker().invoke(new Callable() { - public String call() throws Exception { + invoke(new Callable() { + public String call() { return getFolderType(absolutePIDL); } }); @@ -926,15 +933,12 @@ final class Win32ShellFolder2 extends ShellFolder { public static native int[] getFileChooserBitmapBits(); + // Should be called from the COM thread private long getIShellIcon() { if (pIShellIcon == -1L) { - pIShellIcon = - ShellFolder.getInvoker().invoke(new Callable() { - public Long call() throws Exception { - return getIShellIcon(getIShellFolder()); - } - }); + pIShellIcon = getIShellIcon(getIShellFolder()); } + return pIShellIcon; } @@ -988,8 +992,8 @@ final class Win32ShellFolder2 extends ShellFolder { Image icon = getLargeIcon ? largeIcon : smallIcon; if (icon == null) { icon = - ShellFolder.getInvoker().invoke(new Callable() { - public Image call() throws Exception { + invoke(new Callable() { + public Image call() { Image newIcon = null; if (isFileSystem()) { long parentIShellIcon = (parent != null) @@ -1113,8 +1117,8 @@ final class Win32ShellFolder2 extends ShellFolder { private static final int LVCFMT_CENTER = 2; public ShellFolderColumnInfo[] getFolderColumns() { - return ShellFolder.getInvoker().invoke(new Callable() { - public ShellFolderColumnInfo[] call() throws Exception { + return invoke(new Callable() { + public ShellFolderColumnInfo[] call() { ShellFolderColumnInfo[] columns = doGetColumnInfo(getIShellFolder()); if (columns != null) { @@ -1143,8 +1147,8 @@ final class Win32ShellFolder2 extends ShellFolder { } public Object getFolderColumnValue(final int column) { - return ShellFolder.getInvoker().invoke(new Callable() { - public Object call() throws Exception { + return invoke(new Callable() { + public Object call() { return doGetColumnValue(getParentIShellFolder(), getRelativePIDL(), column); } }); @@ -1163,8 +1167,8 @@ final class Win32ShellFolder2 extends ShellFolder { public void sortChildren(final List files) { // To avoid loads of synchronizations with Invoker and improve performance we // synchronize the whole code of the sort method once - getInvoker().invoke(new Callable() { - public Void call() throws Exception { + invoke(new Callable() { + public Void call() { Collections.sort(files, new ColumnComparator(getIShellFolder(), 0)); return null; @@ -1184,19 +1188,21 @@ final class Win32ShellFolder2 extends ShellFolder { // compares 2 objects within this folder by the specified column public int compare(final File o, final File o1) { - return ShellFolder.getInvoker().invoke(new Callable() { - public Integer call() throws Exception { + Integer result = invoke(new Callable() { + public Integer call() { if (o instanceof Win32ShellFolder2 - && o1 instanceof Win32ShellFolder2) { + && o1 instanceof Win32ShellFolder2) { // delegates comparison to native method return compareIDsByColumn(parentIShellFolder, - ((Win32ShellFolder2) o).getRelativePIDL(), - ((Win32ShellFolder2) o1).getRelativePIDL(), - columnIdx); + ((Win32ShellFolder2) o).getRelativePIDL(), + ((Win32ShellFolder2) o1).getRelativePIDL(), + columnIdx); } return 0; } }); + + return result == null ? 0 : result; } } } diff --git a/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java b/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java index 1586846357e..4471a3ec0da 100644 --- a/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java +++ b/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2009 Sun Microsystems, Inc. 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 @@ -58,10 +58,15 @@ public class Win32ShellFolderManager2 extends ShellFolderManager { } public ShellFolder createShellFolder(File file) throws FileNotFoundException { - return createShellFolder(getDesktop(), file); + try { + return createShellFolder(getDesktop(), file); + } catch (InterruptedException e) { + throw new FileNotFoundException("Execution was interrupted"); + } } - static Win32ShellFolder2 createShellFolder(Win32ShellFolder2 parent, File file) throws FileNotFoundException { + static Win32ShellFolder2 createShellFolder(Win32ShellFolder2 parent, File file) + throws FileNotFoundException, InterruptedException { long pIDL; try { pIDL = parent.parseDisplayName(file.getCanonicalPath()); @@ -77,7 +82,8 @@ public class Win32ShellFolderManager2 extends ShellFolderManager { return folder; } - static Win32ShellFolder2 createShellFolderFromRelativePIDL(Win32ShellFolder2 parent, long pIDL) { + static Win32ShellFolder2 createShellFolderFromRelativePIDL(Win32ShellFolder2 parent, long pIDL) + throws InterruptedException { // Walk down this relative pIDL, creating new nodes for each of the entries while (pIDL != 0) { long curPIDL = Win32ShellFolder2.copyFirstPIDLEntry(pIDL); @@ -108,7 +114,9 @@ public class Win32ShellFolderManager2 extends ShellFolderManager { try { desktop = new Win32ShellFolder2(DESKTOP); } catch (IOException e) { - desktop = null; + // Ignore error + } catch (InterruptedException e) { + // Ignore error } } return desktop; @@ -119,7 +127,9 @@ public class Win32ShellFolderManager2 extends ShellFolderManager { try { drives = new Win32ShellFolder2(DRIVES); } catch (IOException e) { - drives = null; + // Ignore error + } catch (InterruptedException e) { + // Ignore error } } return drives; @@ -132,8 +142,10 @@ public class Win32ShellFolderManager2 extends ShellFolderManager { if (path != null) { recent = createShellFolder(getDesktop(), new File(path)); } + } catch (InterruptedException e) { + // Ignore error } catch (IOException e) { - recent = null; + // Ignore error } } return recent; @@ -144,7 +156,9 @@ public class Win32ShellFolderManager2 extends ShellFolderManager { try { network = new Win32ShellFolder2(NETWORK); } catch (IOException e) { - network = null; + // Ignore error + } catch (InterruptedException e) { + // Ignore error } } return network; @@ -164,8 +178,10 @@ public class Win32ShellFolderManager2 extends ShellFolderManager { personal.setIsPersonal(); } } + } catch (InterruptedException e) { + // Ignore error } catch (IOException e) { - personal = null; + // Ignore error } } return personal; @@ -267,6 +283,9 @@ public class Win32ShellFolderManager2 extends ShellFolderManager { } } catch (IOException e) { // Skip this value + } catch (InterruptedException e) { + // Return empty result + return new File[0]; } } while (value != null); @@ -476,33 +495,39 @@ public class Win32ShellFolderManager2 extends ShellFolderManager { return comThread; } - public T invoke(Callable task) { - try { - if (Thread.currentThread() == comThread) { - // if it's already called from the COM - // thread, we don't need to delegate the task - return task.call(); - } else { - while (true) { - Future future = submit(task); + public T invoke(Callable task) throws Exception { + if (Thread.currentThread() == comThread) { + // if it's already called from the COM + // thread, we don't need to delegate the task + return task.call(); + } else { + Future future; - try { - return future.get(); - } catch (InterruptedException e) { - // Repeat the attempt - future.cancel(true); - } + try { + future = submit(task); + } catch (RejectedExecutionException e) { + throw new InterruptedException(e.getMessage()); + } + + try { + return future.get(); + } catch (InterruptedException e) { + future.cancel(true); + + throw e; + } catch (ExecutionException e) { + Throwable cause = e.getCause(); + + if (cause instanceof Exception) { + throw (Exception) cause; } + + if (cause instanceof Error) { + throw (Error) cause; + } + + throw new RuntimeException("Unexpected error", cause); } - } catch (Exception e) { - Throwable cause = (e instanceof ExecutionException) ? e.getCause() : e; - if (cause instanceof RuntimeException) { - throw (RuntimeException) cause; - } - if (cause instanceof Error) { - throw (Error) cause; - } - throw new RuntimeException(cause); } } } From b1c83646db18c63426a5a81aa8e31bee79ca5d52 Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Thu, 23 Jul 2009 11:37:44 -0700 Subject: [PATCH 36/96] 6863814: javap crashes when facing array class literals Reviewed-by: jjg --- .../tools/classfile/ExtendedAnnotation.java | 1 + .../typeAnnotations/ArrayClassLiterals.java | 182 ++++++++++++++++++ 2 files changed, 183 insertions(+) create mode 100644 langtools/test/tools/javap/typeAnnotations/ArrayClassLiterals.java diff --git a/langtools/src/share/classes/com/sun/tools/classfile/ExtendedAnnotation.java b/langtools/src/share/classes/com/sun/tools/classfile/ExtendedAnnotation.java index 252754884a2..85e49d6c926 100644 --- a/langtools/src/share/classes/com/sun/tools/classfile/ExtendedAnnotation.java +++ b/langtools/src/share/classes/com/sun/tools/classfile/ExtendedAnnotation.java @@ -357,6 +357,7 @@ public class ExtendedAnnotation { sb.append(type_index); break; case CLASS_LITERAL: + case CLASS_LITERAL_GENERIC_OR_ARRAY: sb.append(", offset = "); sb.append(offset); break; diff --git a/langtools/test/tools/javap/typeAnnotations/ArrayClassLiterals.java b/langtools/test/tools/javap/typeAnnotations/ArrayClassLiterals.java new file mode 100644 index 00000000000..ec93fb64aae --- /dev/null +++ b/langtools/test/tools/javap/typeAnnotations/ArrayClassLiterals.java @@ -0,0 +1,182 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +import java.io.*; +import com.sun.tools.classfile.*; + +/* + * @test ArrayClassLiterals + * @summary test that class literals array doesn't crash javap + */ + +public class ArrayClassLiterals { + public static void main(String[] args) throws Exception { + new ArrayClassLiterals().run(); + } + + public void run() throws Exception { + File javaFile = writeTestFile(); + File classFile = compileTestFile(javaFile); + + ClassFile cf = ClassFile.read(classFile); + test(cf); + for (Field f : cf.fields) { + test(cf, f); + } + for (Method m: cf.methods) { + test(cf, m); + } + + countAnnotations(); + + if (errors > 0) + throw new Exception(errors + " errors found"); + System.out.println("PASSED"); + } + + void test(ClassFile cf) { + test(cf, Attribute.RuntimeVisibleTypeAnnotations, true); + test(cf, Attribute.RuntimeInvisibleTypeAnnotations, false); + } + + void test(ClassFile cf, Method m) { + test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true); + test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false); + } + + void test(ClassFile cf, Field m) { + test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true); + test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false); + } + + // test the result of Attributes.getIndex according to expectations + // encoded in the method's name + void test(ClassFile cf, String name, boolean visible) { + int index = cf.attributes.getIndex(cf.constant_pool, name); + if (index != -1) { + Attribute attr = cf.attributes.get(index); + assert attr instanceof RuntimeTypeAnnotations_attribute; + RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; + all += tAttr.annotations.length; + if (visible) + visibles += tAttr.annotations.length; + else + invisibles += tAttr.annotations.length; + + for (ExtendedAnnotation anno : tAttr.annotations) + anno.position.toString(); + } + } + + // test the result of Attributes.getIndex according to expectations + // encoded in the method's name + void test(ClassFile cf, Method m, String name, boolean visible) { + int index = m.attributes.getIndex(cf.constant_pool, name); + if (index != -1) { + Attribute attr = m.attributes.get(index); + assert attr instanceof RuntimeTypeAnnotations_attribute; + RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; + all += tAttr.annotations.length; + if (visible) + visibles += tAttr.annotations.length; + else + invisibles += tAttr.annotations.length; + + for (ExtendedAnnotation anno : tAttr.annotations) + anno.position.toString(); + } + } + + // test the result of Attributes.getIndex according to expectations + // encoded in the method's name + void test(ClassFile cf, Field m, String name, boolean visible) { + int index = m.attributes.getIndex(cf.constant_pool, name); + if (index != -1) { + Attribute attr = m.attributes.get(index); + assert attr instanceof RuntimeTypeAnnotations_attribute; + RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; + all += tAttr.annotations.length; + if (visible) + visibles += tAttr.annotations.length; + else + invisibles += tAttr.annotations.length; + + for (ExtendedAnnotation anno : tAttr.annotations) + anno.position.toString(); + } + } + + File writeTestFile() throws IOException { + File f = new File("Testa.java"); + PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f))); + out.println("import java.util.*;"); + out.println("class Testa { "); + out.println(" @interface A { }"); + + out.println(" void test() {"); + out.println(" Object a = @A String.class;"); + out.println(" Object b = @A String @A [] @A [].class;"); + out.println(" }"); + out.println("}"); + + out.close(); + return f; + } + + File compileTestFile(File f) { + int rc = com.sun.tools.javac.Main.compile(new String[] { "-source", "1.7", "-g", f.getPath() }); + if (rc != 0) + throw new Error("compilation failed. rc=" + rc); + String path = f.getPath(); + return new File(path.substring(0, path.length() - 5) + ".class"); + } + + void countAnnotations() { + int expected_visibles = 0, expected_invisibles = 4; + int expected_all = expected_visibles + expected_invisibles; + + if (expected_all != all) { + errors++; + System.err.println("expected " + expected_all + + " annotations but found " + all); + } + + if (expected_visibles != visibles) { + errors++; + System.err.println("expected " + expected_visibles + + " visibles annotations but found " + visibles); + } + + if (expected_invisibles != invisibles) { + errors++; + System.err.println("expected " + expected_invisibles + + " invisibles annotations but found " + invisibles); + } + + } + + int errors; + int all; + int visibles; + int invisibles; +} From ae71131125c53f70d3469b49bdb72872dd048863 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Thu, 23 Jul 2009 14:15:58 -0700 Subject: [PATCH 37/96] 6863914: bug number missing from test Reviewed-by: tbell --- .../test/tools/javap/typeAnnotations/ArrayClassLiterals.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/langtools/test/tools/javap/typeAnnotations/ArrayClassLiterals.java b/langtools/test/tools/javap/typeAnnotations/ArrayClassLiterals.java index ec93fb64aae..f77480f3bb0 100644 --- a/langtools/test/tools/javap/typeAnnotations/ArrayClassLiterals.java +++ b/langtools/test/tools/javap/typeAnnotations/ArrayClassLiterals.java @@ -1,5 +1,5 @@ /* - * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Sun Microsystems, Inc. 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 @@ -26,6 +26,7 @@ import com.sun.tools.classfile.*; /* * @test ArrayClassLiterals + * @bug 6863814 * @summary test that class literals array doesn't crash javap */ From 604fce4d26065e49f6d997eba6b88273a7854066 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Fri, 24 Jul 2009 14:47:01 -0700 Subject: [PATCH 38/96] 6863746: javap should not scan ct.sym by default Reviewed-by: mcimadamore --- .../com/sun/tools/javap/JavapFileManager.java | 1 + .../com/sun/tools/javap/JavapTask.java | 9 ---- .../classes/com/sun/tools/javap/Options.java | 1 - langtools/test/tools/javap/T6863746.java | 52 +++++++++++++++++++ 4 files changed, 53 insertions(+), 10 deletions(-) create mode 100644 langtools/test/tools/javap/T6863746.java diff --git a/langtools/src/share/classes/com/sun/tools/javap/JavapFileManager.java b/langtools/src/share/classes/com/sun/tools/javap/JavapFileManager.java index 2a9e87e0476..85c40921e85 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/JavapFileManager.java +++ b/langtools/src/share/classes/com/sun/tools/javap/JavapFileManager.java @@ -44,6 +44,7 @@ import com.sun.tools.javac.util.Context; class JavapFileManager extends JavacFileManager { private JavapFileManager(Context context, Charset charset) { super(context, true, charset); + setIgnoreSymbolFile(true); } static JavapFileManager create(final DiagnosticListener dl, PrintWriter log, Options options) { diff --git a/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java b/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java index 77e88b79ab3..285f1b48347 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java +++ b/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java @@ -235,12 +235,6 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages { } }, - new Option(false, "-XDignore.symbol.file") { - void process(JavapTask task, String opt, String arg) { - task.options.ignoreSymbolFile = true; - } - }, - new Option(false, "-XDdetails") { void process(JavapTask task, String opt, String arg) { task.options.details = EnumSet.allOf(InstructionDetailWriter.Kind.class); @@ -477,9 +471,6 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages { throw new BadArgs("err.incompatible.options", sb); } - if (options.ignoreSymbolFile && fileManager instanceof JavapFileManager) - ((JavapFileManager) fileManager).setIgnoreSymbolFile(true); - if ((classes == null || classes.size() == 0) && !(noArgs || options.help || options.version || options.fullVersion)) { throw new BadArgs("err.no.classes.specified"); diff --git a/langtools/src/share/classes/com/sun/tools/javap/Options.java b/langtools/src/share/classes/com/sun/tools/javap/Options.java index ee70afa8a50..70f76060ebc 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/Options.java +++ b/langtools/src/share/classes/com/sun/tools/javap/Options.java @@ -88,5 +88,4 @@ public class Options { public boolean compat; // bug-for-bug compatibility mode with old javap public boolean jsr277; - public boolean ignoreSymbolFile; // file manager should ignore ct.sym } diff --git a/langtools/test/tools/javap/T6863746.java b/langtools/test/tools/javap/T6863746.java new file mode 100644 index 00000000000..cceaf0dc3be --- /dev/null +++ b/langtools/test/tools/javap/T6863746.java @@ -0,0 +1,52 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +import java.io.*; + +/* + * @test + * @bug 6863746 + * @summary javap should not scan ct.sym by default + */ + +public class T6863746 { + public static void main(String... args) throws Exception{ + new T6863746().run(); + } + + public void run() throws Exception { + String[] args = { "-c", "java.lang.Object" }; + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + int rc = com.sun.tools.javap.Main.run(args, pw); + pw.close(); + String out = sw.toString(); + System.out.println(out); + String[] lines = out.split("\n"); + // If ct.sym is being read, the output does not include + // Code attributes, so check for Code attributes as a + // way of detecting that ct.sym is not being used. + if (lines.length < 50 || out.indexOf("Code:") == -1) + throw new Exception("unexpected output from javap"); + } +} From 55dc8eb040a6a08b64747f49ab40505b89bbf9db Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Sun, 26 Jul 2009 21:27:11 -0700 Subject: [PATCH 39/96] 6381698: Warn of decommissioning of apt Reviewed-by: jjg --- langtools/make/build.properties | 2 +- .../sun/mirror/apt/AnnotationProcessor.java | 8 +++- .../apt/AnnotationProcessorEnvironment.java | 9 +++- .../apt/AnnotationProcessorFactory.java | 8 +++- .../apt/AnnotationProcessorListener.java | 7 +++ .../sun/mirror/apt/AnnotationProcessors.java | 6 +++ .../classes/com/sun/mirror/apt/Filer.java | 14 +++++- .../classes/com/sun/mirror/apt/Messager.java | 10 +++-- .../sun/mirror/apt/RoundCompleteEvent.java | 7 +++ .../sun/mirror/apt/RoundCompleteListener.java | 7 +++ .../com/sun/mirror/apt/RoundState.java | 7 +++ .../com/sun/mirror/apt/package-info.java | 38 ++++++++++++++++ .../classes/com/sun/mirror/apt/package.html | 42 ------------------ .../mirror/declaration/AnnotationMirror.java | 8 +++- .../AnnotationTypeDeclaration.java | 8 +++- .../AnnotationTypeElementDeclaration.java | 8 +++- .../mirror/declaration/AnnotationValue.java | 8 +++- .../mirror/declaration/ClassDeclaration.java | 8 +++- .../declaration/ConstructorDeclaration.java | 8 +++- .../sun/mirror/declaration/Declaration.java | 8 +++- .../declaration/EnumConstantDeclaration.java | 8 +++- .../mirror/declaration/EnumDeclaration.java | 8 +++- .../declaration/ExecutableDeclaration.java | 8 +++- .../mirror/declaration/FieldDeclaration.java | 8 +++- .../declaration/InterfaceDeclaration.java | 8 +++- .../mirror/declaration/MemberDeclaration.java | 8 +++- .../mirror/declaration/MethodDeclaration.java | 8 +++- .../com/sun/mirror/declaration/Modifier.java | 7 ++- .../declaration/PackageDeclaration.java | 8 +++- .../declaration/ParameterDeclaration.java | 8 +++- .../mirror/declaration/TypeDeclaration.java | 8 +++- .../declaration/TypeParameterDeclaration.java | 8 +++- .../sun/mirror/declaration/package-info.java | 40 +++++++++++++++++ .../com/sun/mirror/declaration/package.html | 44 ------------------- .../com/sun/mirror/type/AnnotationType.java | 8 +++- .../com/sun/mirror/type/ArrayType.java | 8 +++- .../com/sun/mirror/type/ClassType.java | 8 +++- .../com/sun/mirror/type/DeclaredType.java | 8 +++- .../classes/com/sun/mirror/type/EnumType.java | 8 +++- .../com/sun/mirror/type/InterfaceType.java | 8 +++- .../mirror/type/MirroredTypeException.java | 7 +++ .../mirror/type/MirroredTypesException.java | 7 +++ .../com/sun/mirror/type/PrimitiveType.java | 14 +++++- .../com/sun/mirror/type/ReferenceType.java | 8 +++- .../com/sun/mirror/type/TypeMirror.java | 8 +++- .../com/sun/mirror/type/TypeVariable.java | 8 +++- .../classes/com/sun/mirror/type/VoidType.java | 8 +++- .../com/sun/mirror/type/WildcardType.java | 8 +++- .../com/sun/mirror/type/package-info.java | 37 ++++++++++++++++ .../classes/com/sun/mirror/type/package.html | 42 ------------------ .../sun/mirror/util/DeclarationFilter.java | 8 +++- .../sun/mirror/util/DeclarationScanner.java | 8 +++- .../sun/mirror/util/DeclarationVisitor.java | 8 +++- .../sun/mirror/util/DeclarationVisitors.java | 7 +++ .../com/sun/mirror/util/Declarations.java | 8 +++- .../mirror/util/SimpleDeclarationVisitor.java | 8 +++- .../sun/mirror/util/SimpleTypeVisitor.java | 8 +++- .../mirror/util/SourceOrderDeclScanner.java | 7 +++ .../com/sun/mirror/util/SourcePosition.java | 11 ++++- .../com/sun/mirror/util/TypeVisitor.java | 8 +++- .../classes/com/sun/mirror/util/Types.java | 8 +++- .../com/sun/mirror/util/package-info.java | 37 ++++++++++++++++ .../classes/com/sun/mirror/util/package.html | 42 ------------------ .../classes/com/sun/tools/apt/comp/Apt.java | 1 + .../com/sun/tools/apt/comp/BootstrapAPF.java | 1 + .../com/sun/tools/apt/comp/PrintAP.java | 1 + .../com/sun/tools/apt/main/JavaCompiler.java | 1 + .../classes/com/sun/tools/apt/main/Main.java | 7 ++- .../com/sun/tools/apt/mirror/AptEnv.java | 2 +- .../AnnotationProcessorEnvironmentImpl.java | 1 + .../sun/tools/apt/mirror/apt/FilerImpl.java | 2 +- .../tools/apt/mirror/apt/MessagerImpl.java | 2 +- .../mirror/apt/RoundCompleteEventImpl.java | 1 + .../tools/apt/mirror/apt/RoundStateImpl.java | 1 + .../declaration/AnnotationMirrorImpl.java | 2 +- .../declaration/AnnotationProxyMaker.java | 2 +- .../AnnotationTypeDeclarationImpl.java | 2 +- .../AnnotationTypeElementDeclarationImpl.java | 2 +- .../declaration/AnnotationValueImpl.java | 2 +- .../declaration/ClassDeclarationImpl.java | 2 +- .../apt/mirror/declaration/Constants.java | 1 + .../ConstructorDeclarationImpl.java | 2 +- .../mirror/declaration/DeclarationImpl.java | 2 +- .../mirror/declaration/DeclarationMaker.java | 2 +- .../EnumConstantDeclarationImpl.java | 2 +- .../declaration/EnumDeclarationImpl.java | 2 +- .../ExecutableDeclarationImpl.java | 2 +- .../declaration/FieldDeclarationImpl.java | 2 +- .../declaration/InterfaceDeclarationImpl.java | 2 +- .../declaration/MemberDeclarationImpl.java | 2 +- .../declaration/MethodDeclarationImpl.java | 2 +- .../declaration/PackageDeclarationImpl.java | 2 +- .../declaration/ParameterDeclarationImpl.java | 2 +- .../declaration/TypeDeclarationImpl.java | 2 +- .../TypeParameterDeclarationImpl.java | 2 +- .../apt/mirror/type/AnnotationTypeImpl.java | 2 +- .../tools/apt/mirror/type/ArrayTypeImpl.java | 2 +- .../tools/apt/mirror/type/ClassTypeImpl.java | 2 +- .../apt/mirror/type/DeclaredTypeImpl.java | 2 +- .../tools/apt/mirror/type/EnumTypeImpl.java | 2 +- .../apt/mirror/type/InterfaceTypeImpl.java | 2 +- .../apt/mirror/type/PrimitiveTypeImpl.java | 2 +- .../sun/tools/apt/mirror/type/TypeMaker.java | 2 +- .../tools/apt/mirror/type/TypeMirrorImpl.java | 2 +- .../apt/mirror/type/TypeVariableImpl.java | 2 +- .../tools/apt/mirror/type/VoidTypeImpl.java | 2 +- .../apt/mirror/type/WildcardTypeImpl.java | 2 +- .../apt/mirror/util/DeclarationsImpl.java | 2 +- .../apt/mirror/util/SourcePositionImpl.java | 2 +- .../sun/tools/apt/mirror/util/TypesImpl.java | 2 +- .../sun/tools/apt/resources/apt.properties | 8 ++++ langtools/test/tools/apt/Basics/apt.sh | 3 +- langtools/test/tools/apt/Compile/compile.sh | 2 +- 113 files changed, 607 insertions(+), 260 deletions(-) create mode 100644 langtools/src/share/classes/com/sun/mirror/apt/package-info.java delete mode 100644 langtools/src/share/classes/com/sun/mirror/apt/package.html create mode 100644 langtools/src/share/classes/com/sun/mirror/declaration/package-info.java delete mode 100644 langtools/src/share/classes/com/sun/mirror/declaration/package.html create mode 100644 langtools/src/share/classes/com/sun/mirror/type/package-info.java delete mode 100644 langtools/src/share/classes/com/sun/mirror/type/package.html create mode 100644 langtools/src/share/classes/com/sun/mirror/util/package-info.java delete mode 100644 langtools/src/share/classes/com/sun/mirror/util/package.html diff --git a/langtools/make/build.properties b/langtools/make/build.properties index 52df7e9acd0..53dd569ebd6 100644 --- a/langtools/make/build.properties +++ b/langtools/make/build.properties @@ -68,7 +68,7 @@ javac.no.jdk.warnings = -XDignore.symbol.file=true # set the following to -version to verify the versions of javac being used javac.version.opt = # in time, there should be no exceptions to -Xlint:all -javac.lint.opts = -Xlint:all -Werror +javac.lint.opts = -Xlint:all,-deprecation -Werror # options for the task for javac javadoc.jls3.url=http://java.sun.com/docs/books/jls/ diff --git a/langtools/src/share/classes/com/sun/mirror/apt/AnnotationProcessor.java b/langtools/src/share/classes/com/sun/mirror/apt/AnnotationProcessor.java index 591793d8e0a..5175fd2fcaa 100644 --- a/langtools/src/share/classes/com/sun/mirror/apt/AnnotationProcessor.java +++ b/langtools/src/share/classes/com/sun/mirror/apt/AnnotationProcessor.java @@ -50,11 +50,17 @@ import java.util.Collection; * annotations of those types. It may freely examine any other program * elements in the course of its processing. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is {@link + * javax.annotation.processing.Processor}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface AnnotationProcessor { /** diff --git a/langtools/src/share/classes/com/sun/mirror/apt/AnnotationProcessorEnvironment.java b/langtools/src/share/classes/com/sun/mirror/apt/AnnotationProcessorEnvironment.java index bdd8277da88..0cd7db8770d 100644 --- a/langtools/src/share/classes/com/sun/mirror/apt/AnnotationProcessorEnvironment.java +++ b/langtools/src/share/classes/com/sun/mirror/apt/AnnotationProcessorEnvironment.java @@ -48,11 +48,17 @@ import com.sun.mirror.util.*; * provides a simple way to select just the items of interest * when a method returns a collection of declarations. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is {@link + * javax.annotation.processing.ProcessingEnvironment}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface AnnotationProcessorEnvironment { /** @@ -87,7 +93,6 @@ public interface AnnotationProcessorEnvironment { Filer getFiler(); - /** * Returns the declarations of the types specified when the * annotation processing tool was invoked. diff --git a/langtools/src/share/classes/com/sun/mirror/apt/AnnotationProcessorFactory.java b/langtools/src/share/classes/com/sun/mirror/apt/AnnotationProcessorFactory.java index a2169b1117c..b2b700635b6 100644 --- a/langtools/src/share/classes/com/sun/mirror/apt/AnnotationProcessorFactory.java +++ b/langtools/src/share/classes/com/sun/mirror/apt/AnnotationProcessorFactory.java @@ -42,11 +42,17 @@ import com.sun.mirror.declaration.AnnotationTypeDeclaration; * must provide a public no-argument constructor to be used by tools to * instantiate the factory. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is {@link + * javax.annotation.processing.Processor}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface AnnotationProcessorFactory { /** diff --git a/langtools/src/share/classes/com/sun/mirror/apt/AnnotationProcessorListener.java b/langtools/src/share/classes/com/sun/mirror/apt/AnnotationProcessorListener.java index 89b1e82a168..3c040e6be22 100644 --- a/langtools/src/share/classes/com/sun/mirror/apt/AnnotationProcessorListener.java +++ b/langtools/src/share/classes/com/sun/mirror/apt/AnnotationProcessorListener.java @@ -28,8 +28,15 @@ package com.sun.mirror.apt; /** * Superinterface for all annotation processor event listeners. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. This interface has no + * direct analog in the standardized API because the different round + * model renders it unnecessary. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ +@Deprecated +@SuppressWarnings("deprecation") public interface AnnotationProcessorListener extends java.util.EventListener {} diff --git a/langtools/src/share/classes/com/sun/mirror/apt/AnnotationProcessors.java b/langtools/src/share/classes/com/sun/mirror/apt/AnnotationProcessors.java index c3e8f9496e2..19885c315fa 100644 --- a/langtools/src/share/classes/com/sun/mirror/apt/AnnotationProcessors.java +++ b/langtools/src/share/classes/com/sun/mirror/apt/AnnotationProcessors.java @@ -31,10 +31,16 @@ import java.util.*; /** * Utilities to create specialized annotation processors. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. There is no direct analog + * of the functionality of this class in the standardized API. + * * @since 1.5 * @author Joseph D. Darcy * @author Scott Seligman */ +@Deprecated +@SuppressWarnings("deprecation") public class AnnotationProcessors { static class NoOpAP implements AnnotationProcessor { NoOpAP() {} diff --git a/langtools/src/share/classes/com/sun/mirror/apt/Filer.java b/langtools/src/share/classes/com/sun/mirror/apt/Filer.java index 4053a0e0dc6..e85bcda6d3b 100644 --- a/langtools/src/share/classes/com/sun/mirror/apt/Filer.java +++ b/langtools/src/share/classes/com/sun/mirror/apt/Filer.java @@ -51,11 +51,17 @@ import java.io.*; * be deleted. Any subsequent attempt to create the same file during * a run will fail. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is {@link + * javax.annotation.processing.Filer}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface Filer { /** @@ -140,7 +146,13 @@ public interface Filer { /** * Locations (subtrees within the file system) where new files are created. + * + * @deprecated All components of this API have been superseded by + * the standardized annotation processing API. The replacement + * for the functionality of this enum is {@link + * javax.tools.StandardLocation}. */ + @Deprecated enum Location { /** The location of new source files. */ SOURCE_TREE, diff --git a/langtools/src/share/classes/com/sun/mirror/apt/Messager.java b/langtools/src/share/classes/com/sun/mirror/apt/Messager.java index 37ab26ae2f2..e25e352436c 100644 --- a/langtools/src/share/classes/com/sun/mirror/apt/Messager.java +++ b/langtools/src/share/classes/com/sun/mirror/apt/Messager.java @@ -25,20 +25,24 @@ package com.sun.mirror.apt; - import com.sun.mirror.util.SourcePosition; - /** * A Messager provides the way for * an annotation processor to report error messages, warnings, and * other notices. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is {@link + * javax.annotation.processing.Messager}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface Messager { /** diff --git a/langtools/src/share/classes/com/sun/mirror/apt/RoundCompleteEvent.java b/langtools/src/share/classes/com/sun/mirror/apt/RoundCompleteEvent.java index a163b9d3f1a..aa94151a0ab 100644 --- a/langtools/src/share/classes/com/sun/mirror/apt/RoundCompleteEvent.java +++ b/langtools/src/share/classes/com/sun/mirror/apt/RoundCompleteEvent.java @@ -32,10 +32,17 @@ package com.sun.mirror.apt; * cannot meaningfully be serialized because all of the annotation * processing tool's internal state would potentially be needed. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. This class has no direct + * analog in the standardized API because the different round model + * renders it unnecessary. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ +@Deprecated +@SuppressWarnings("deprecation") public abstract class RoundCompleteEvent extends java.util.EventObject { private RoundState rs; diff --git a/langtools/src/share/classes/com/sun/mirror/apt/RoundCompleteListener.java b/langtools/src/share/classes/com/sun/mirror/apt/RoundCompleteListener.java index ae460d8f4c9..caefe36b1df 100644 --- a/langtools/src/share/classes/com/sun/mirror/apt/RoundCompleteListener.java +++ b/langtools/src/share/classes/com/sun/mirror/apt/RoundCompleteListener.java @@ -28,10 +28,17 @@ package com.sun.mirror.apt; /** * Listener for the completion of a round of annotation processing. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. This interface has no + * direct analog in the standardized API because the different round + * model renders it unnecessary. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ +@Deprecated +@SuppressWarnings("deprecation") public interface RoundCompleteListener extends AnnotationProcessorListener { /** * Invoked after all processors for a round have run to completion. diff --git a/langtools/src/share/classes/com/sun/mirror/apt/RoundState.java b/langtools/src/share/classes/com/sun/mirror/apt/RoundState.java index 956899d8574..b39bae2a174 100644 --- a/langtools/src/share/classes/com/sun/mirror/apt/RoundState.java +++ b/langtools/src/share/classes/com/sun/mirror/apt/RoundState.java @@ -28,10 +28,17 @@ package com.sun.mirror.apt; /** * Represents the status of a completed round of annotation processing. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is {@link + * javax.annotation.processing.RoundEnvironment}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ +@Deprecated +@SuppressWarnings("deprecation") public interface RoundState { /** * Returns true if this was the last round of annotation diff --git a/langtools/src/share/classes/com/sun/mirror/apt/package-info.java b/langtools/src/share/classes/com/sun/mirror/apt/package-info.java new file mode 100644 index 00000000000..b98d789189e --- /dev/null +++ b/langtools/src/share/classes/com/sun/mirror/apt/package-info.java @@ -0,0 +1,38 @@ +/* + * Copyright 2004 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * Classes used to communicate information between {@linkplain + * com.sun.mirror.apt.AnnotationProcessor annotation processors} and + * an annotation processing tool. + * + *

The {@code apt} tool and its associated API have been superseded + * by the standardized annotation processing API. The replacement for + * the functionality in this package is {@link + * javax.annotation.processing}. + * + * @since 1.5 + */ +package com.sun.mirror.apt; diff --git a/langtools/src/share/classes/com/sun/mirror/apt/package.html b/langtools/src/share/classes/com/sun/mirror/apt/package.html deleted file mode 100644 index 8330decfd8b..00000000000 --- a/langtools/src/share/classes/com/sun/mirror/apt/package.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - -Classes used to communicate information between -{@linkplain com.sun.mirror.apt.AnnotationProcessor annotation processors} -and an annotation processing tool. - -

Note that the apt tool and its associated APIs may be -changed or superseded in future j2se releases. - -@since 1.5 - - diff --git a/langtools/src/share/classes/com/sun/mirror/declaration/AnnotationMirror.java b/langtools/src/share/classes/com/sun/mirror/declaration/AnnotationMirror.java index 03b65de8600..f05e7c62cf2 100644 --- a/langtools/src/share/classes/com/sun/mirror/declaration/AnnotationMirror.java +++ b/langtools/src/share/classes/com/sun/mirror/declaration/AnnotationMirror.java @@ -38,11 +38,17 @@ import com.sun.mirror.util.SourcePosition; * ("=="). There is no guarantee that any particular * annotation will always be represented by the same object. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is {@link + * javax.lang.model.element.AnnotationMirror}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface AnnotationMirror { /** diff --git a/langtools/src/share/classes/com/sun/mirror/declaration/AnnotationTypeDeclaration.java b/langtools/src/share/classes/com/sun/mirror/declaration/AnnotationTypeDeclaration.java index ed7c14e94cb..dda20902bf5 100644 --- a/langtools/src/share/classes/com/sun/mirror/declaration/AnnotationTypeDeclaration.java +++ b/langtools/src/share/classes/com/sun/mirror/declaration/AnnotationTypeDeclaration.java @@ -32,11 +32,17 @@ import java.util.Collection; /** * Represents the declaration of an annotation type. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is included in {@link + * javax.lang.model.element.TypeElement}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface AnnotationTypeDeclaration extends InterfaceDeclaration { /** diff --git a/langtools/src/share/classes/com/sun/mirror/declaration/AnnotationTypeElementDeclaration.java b/langtools/src/share/classes/com/sun/mirror/declaration/AnnotationTypeElementDeclaration.java index 1864e36b845..2eae91e4335 100644 --- a/langtools/src/share/classes/com/sun/mirror/declaration/AnnotationTypeElementDeclaration.java +++ b/langtools/src/share/classes/com/sun/mirror/declaration/AnnotationTypeElementDeclaration.java @@ -29,11 +29,17 @@ package com.sun.mirror.declaration; /** * Represents an element of an annotation type. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is included in {@link + * javax.lang.model.element.ExecutableElement}. + * * @author Joe Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface AnnotationTypeElementDeclaration extends MethodDeclaration { /** diff --git a/langtools/src/share/classes/com/sun/mirror/declaration/AnnotationValue.java b/langtools/src/share/classes/com/sun/mirror/declaration/AnnotationValue.java index b4f9593262f..a71ae6d5de8 100644 --- a/langtools/src/share/classes/com/sun/mirror/declaration/AnnotationValue.java +++ b/langtools/src/share/classes/com/sun/mirror/declaration/AnnotationValue.java @@ -30,11 +30,17 @@ import com.sun.mirror.util.SourcePosition; /** * Represents a value of an annotation type element. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is {@link + * javax.lang.model.element.AnnotationValue}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface AnnotationValue { /** diff --git a/langtools/src/share/classes/com/sun/mirror/declaration/ClassDeclaration.java b/langtools/src/share/classes/com/sun/mirror/declaration/ClassDeclaration.java index 8d86c528314..08168036d7a 100644 --- a/langtools/src/share/classes/com/sun/mirror/declaration/ClassDeclaration.java +++ b/langtools/src/share/classes/com/sun/mirror/declaration/ClassDeclaration.java @@ -46,13 +46,19 @@ import com.sun.mirror.type.ClassType; * provides a simple way to select just the items of interest * when a method returns a collection of declarations. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is included in {@link + * javax.lang.model.element.TypeElement}. + * * @author Joseph D. Darcy * @author Scott Seligman * * @see ClassType * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface ClassDeclaration extends TypeDeclaration { /** diff --git a/langtools/src/share/classes/com/sun/mirror/declaration/ConstructorDeclaration.java b/langtools/src/share/classes/com/sun/mirror/declaration/ConstructorDeclaration.java index 11391f8f8a3..240f45d8165 100644 --- a/langtools/src/share/classes/com/sun/mirror/declaration/ConstructorDeclaration.java +++ b/langtools/src/share/classes/com/sun/mirror/declaration/ConstructorDeclaration.java @@ -29,10 +29,16 @@ package com.sun.mirror.declaration; /** * Represents a constructor of a class or interface. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is included in {@link + * javax.lang.model.element.ExecutableElement}. + * * @author Joe Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface ConstructorDeclaration extends ExecutableDeclaration { } diff --git a/langtools/src/share/classes/com/sun/mirror/declaration/Declaration.java b/langtools/src/share/classes/com/sun/mirror/declaration/Declaration.java index 1cffc6427d7..8c9e8d652dd 100644 --- a/langtools/src/share/classes/com/sun/mirror/declaration/Declaration.java +++ b/langtools/src/share/classes/com/sun/mirror/declaration/Declaration.java @@ -44,6 +44,11 @@ import com.sun.mirror.util.*; * method. There is no guarantee that any particular declaration will * always be represented by the same object. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is {@link + * javax.lang.model.element.Element}. + * * @author Joseph D. Darcy * @author Scott Seligman * @@ -51,7 +56,8 @@ import com.sun.mirror.util.*; * @see TypeMirror * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface Declaration { /** diff --git a/langtools/src/share/classes/com/sun/mirror/declaration/EnumConstantDeclaration.java b/langtools/src/share/classes/com/sun/mirror/declaration/EnumConstantDeclaration.java index 60f45b5e460..58db4fa437e 100644 --- a/langtools/src/share/classes/com/sun/mirror/declaration/EnumConstantDeclaration.java +++ b/langtools/src/share/classes/com/sun/mirror/declaration/EnumConstantDeclaration.java @@ -29,11 +29,17 @@ package com.sun.mirror.declaration; /** * Represents an enum constant declaration. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is included in {@link + * javax.lang.model.element.VariableElement}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface EnumConstantDeclaration extends FieldDeclaration { /** * {@inheritDoc} diff --git a/langtools/src/share/classes/com/sun/mirror/declaration/EnumDeclaration.java b/langtools/src/share/classes/com/sun/mirror/declaration/EnumDeclaration.java index c1026830a1d..96fa36b5944 100644 --- a/langtools/src/share/classes/com/sun/mirror/declaration/EnumDeclaration.java +++ b/langtools/src/share/classes/com/sun/mirror/declaration/EnumDeclaration.java @@ -32,11 +32,17 @@ import java.util.Collection; /** * Represents the declaration of an enum type. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is included in {@link + * javax.lang.model.element.TypeElement}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface EnumDeclaration extends ClassDeclaration { /** diff --git a/langtools/src/share/classes/com/sun/mirror/declaration/ExecutableDeclaration.java b/langtools/src/share/classes/com/sun/mirror/declaration/ExecutableDeclaration.java index e3b1b3d15ed..1a5d26c78f4 100644 --- a/langtools/src/share/classes/com/sun/mirror/declaration/ExecutableDeclaration.java +++ b/langtools/src/share/classes/com/sun/mirror/declaration/ExecutableDeclaration.java @@ -34,11 +34,17 @@ import com.sun.mirror.type.ReferenceType; /** * Represents a method or constructor of a class or interface. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is {@link + * javax.lang.model.element.ExecutableElement}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface ExecutableDeclaration extends MemberDeclaration { /** diff --git a/langtools/src/share/classes/com/sun/mirror/declaration/FieldDeclaration.java b/langtools/src/share/classes/com/sun/mirror/declaration/FieldDeclaration.java index 656dd89eab5..eb45a08e326 100644 --- a/langtools/src/share/classes/com/sun/mirror/declaration/FieldDeclaration.java +++ b/langtools/src/share/classes/com/sun/mirror/declaration/FieldDeclaration.java @@ -32,11 +32,17 @@ import com.sun.mirror.type.TypeMirror; /** * Represents a field of a type declaration. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is included in {@link + * javax.lang.model.element.VariableElement}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface FieldDeclaration extends MemberDeclaration { /** diff --git a/langtools/src/share/classes/com/sun/mirror/declaration/InterfaceDeclaration.java b/langtools/src/share/classes/com/sun/mirror/declaration/InterfaceDeclaration.java index 253371acb25..2f69d6d3e68 100644 --- a/langtools/src/share/classes/com/sun/mirror/declaration/InterfaceDeclaration.java +++ b/langtools/src/share/classes/com/sun/mirror/declaration/InterfaceDeclaration.java @@ -40,12 +40,18 @@ import com.sun.mirror.type.InterfaceType; * represents an interface type. * See {@link TypeDeclaration} for more on this distinction. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is included in {@link + * javax.lang.model.element.TypeElement}. + * * @author Joseph D. Darcy * @author Scott Seligman * * @see InterfaceType * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface InterfaceDeclaration extends TypeDeclaration { } diff --git a/langtools/src/share/classes/com/sun/mirror/declaration/MemberDeclaration.java b/langtools/src/share/classes/com/sun/mirror/declaration/MemberDeclaration.java index 8d5feda5524..ec8f1aa6284 100644 --- a/langtools/src/share/classes/com/sun/mirror/declaration/MemberDeclaration.java +++ b/langtools/src/share/classes/com/sun/mirror/declaration/MemberDeclaration.java @@ -31,11 +31,17 @@ package com.sun.mirror.declaration; * type. This includes fields, constructors, methods, and (since they * may be nested) declared types themselves. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is {@link + * javax.lang.model.element.Element}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface MemberDeclaration extends Declaration { /** diff --git a/langtools/src/share/classes/com/sun/mirror/declaration/MethodDeclaration.java b/langtools/src/share/classes/com/sun/mirror/declaration/MethodDeclaration.java index d2abeff5c30..d2fc63b7a31 100644 --- a/langtools/src/share/classes/com/sun/mirror/declaration/MethodDeclaration.java +++ b/langtools/src/share/classes/com/sun/mirror/declaration/MethodDeclaration.java @@ -36,11 +36,17 @@ import com.sun.mirror.type.VoidType; * {@linkplain AnnotationTypeElementDeclaration annotation type element} * is a kind of method. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is included in {@link + * javax.lang.model.element.ExecutableElement}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface MethodDeclaration extends ExecutableDeclaration { /** diff --git a/langtools/src/share/classes/com/sun/mirror/declaration/Modifier.java b/langtools/src/share/classes/com/sun/mirror/declaration/Modifier.java index ccd63b4032b..a00563bcbd8 100644 --- a/langtools/src/share/classes/com/sun/mirror/declaration/Modifier.java +++ b/langtools/src/share/classes/com/sun/mirror/declaration/Modifier.java @@ -35,11 +35,16 @@ package com.sun.mirror.declaration; * then it is customary, though not required, that they appear in the same * order as the constants listed in the detail section below. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this enum is {@link javax.lang.model.element.Modifier}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public enum Modifier { // See JLS2 sections 8.1.1, 8.3.1, 8.4.3, 8.8.3, and 9.1.1. diff --git a/langtools/src/share/classes/com/sun/mirror/declaration/PackageDeclaration.java b/langtools/src/share/classes/com/sun/mirror/declaration/PackageDeclaration.java index 40c09c8611f..88af259e0d2 100644 --- a/langtools/src/share/classes/com/sun/mirror/declaration/PackageDeclaration.java +++ b/langtools/src/share/classes/com/sun/mirror/declaration/PackageDeclaration.java @@ -37,11 +37,17 @@ import java.util.Collection; * provides a simple way to select just the items of interest * when a method returns a collection of declarations. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is {@link + * javax.lang.model.element.PackageElement}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface PackageDeclaration extends Declaration { /** diff --git a/langtools/src/share/classes/com/sun/mirror/declaration/ParameterDeclaration.java b/langtools/src/share/classes/com/sun/mirror/declaration/ParameterDeclaration.java index 28cc7f82b6d..23f9fa82406 100644 --- a/langtools/src/share/classes/com/sun/mirror/declaration/ParameterDeclaration.java +++ b/langtools/src/share/classes/com/sun/mirror/declaration/ParameterDeclaration.java @@ -32,11 +32,17 @@ import com.sun.mirror.type.TypeMirror; /** * Represents a formal parameter of a method or constructor. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is included in {@link + * javax.lang.model.element.VariableElement}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface ParameterDeclaration extends Declaration { /** diff --git a/langtools/src/share/classes/com/sun/mirror/declaration/TypeDeclaration.java b/langtools/src/share/classes/com/sun/mirror/declaration/TypeDeclaration.java index b3d1db54746..5b722db67e6 100644 --- a/langtools/src/share/classes/com/sun/mirror/declaration/TypeDeclaration.java +++ b/langtools/src/share/classes/com/sun/mirror/declaration/TypeDeclaration.java @@ -54,13 +54,19 @@ import com.sun.mirror.type.*; * provides a simple way to select just the items of interest * when a method returns a collection of declarations. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is included in {@link + * javax.lang.model.element.TypeElement}. + * * @author Joseph D. Darcy * @author Scott Seligman * * @see DeclaredType * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface TypeDeclaration extends MemberDeclaration { /** diff --git a/langtools/src/share/classes/com/sun/mirror/declaration/TypeParameterDeclaration.java b/langtools/src/share/classes/com/sun/mirror/declaration/TypeParameterDeclaration.java index 458b39f4312..33f65f90ea2 100644 --- a/langtools/src/share/classes/com/sun/mirror/declaration/TypeParameterDeclaration.java +++ b/langtools/src/share/classes/com/sun/mirror/declaration/TypeParameterDeclaration.java @@ -36,11 +36,17 @@ import com.sun.mirror.type.*; * or constructor declaration. * A type parameter declares a {@link TypeVariable}. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is {@link + * javax.lang.model.element.TypeParameterElement}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface TypeParameterDeclaration extends Declaration { /** diff --git a/langtools/src/share/classes/com/sun/mirror/declaration/package-info.java b/langtools/src/share/classes/com/sun/mirror/declaration/package-info.java new file mode 100644 index 00000000000..362b1e78a6b --- /dev/null +++ b/langtools/src/share/classes/com/sun/mirror/declaration/package-info.java @@ -0,0 +1,40 @@ +/* + * Copyright 2004 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * Interfaces used to model program element declarations. A + * declaration is represented by the appropriate subinterface of + * {@link com.sun.mirror.declaration.Declaration}, and an annotation + * is represented as an {@link + * com.sun.mirror.declaration.AnnotationMirror}. + * + *

The {@code apt} tool and its associated API have been superseded + * by the standardized annotation processing API. The replacement for + * the functionality in this package is {@link + * javax.lang.model.element}. + * + * @since 1.5 + */ +package com.sun.mirror.declaration; diff --git a/langtools/src/share/classes/com/sun/mirror/declaration/package.html b/langtools/src/share/classes/com/sun/mirror/declaration/package.html deleted file mode 100644 index 1920d4dbc7b..00000000000 --- a/langtools/src/share/classes/com/sun/mirror/declaration/package.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - -Interfaces used to model program element declarations. -A declaration is represented by the appropriate subinterface of -{@link com.sun.mirror.declaration.Declaration}, -and an annotation is represented as an -{@link com.sun.mirror.declaration.AnnotationMirror}. - -

Note that the apt tool and its associated APIs may be -changed or superseded in future j2se releases. - -@since 1.5 - - diff --git a/langtools/src/share/classes/com/sun/mirror/type/AnnotationType.java b/langtools/src/share/classes/com/sun/mirror/type/AnnotationType.java index 22db4ca7aca..3d8eca4221c 100644 --- a/langtools/src/share/classes/com/sun/mirror/type/AnnotationType.java +++ b/langtools/src/share/classes/com/sun/mirror/type/AnnotationType.java @@ -32,11 +32,17 @@ import com.sun.mirror.declaration.AnnotationTypeDeclaration; /** * Represents an annotation type. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is included in {@link + * javax.lang.model.type.DeclaredType}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface AnnotationType extends InterfaceType { /** diff --git a/langtools/src/share/classes/com/sun/mirror/type/ArrayType.java b/langtools/src/share/classes/com/sun/mirror/type/ArrayType.java index 4de386ea7b0..56fdfb7d869 100644 --- a/langtools/src/share/classes/com/sun/mirror/type/ArrayType.java +++ b/langtools/src/share/classes/com/sun/mirror/type/ArrayType.java @@ -31,11 +31,17 @@ package com.sun.mirror.type; * A multidimensional array type is represented as an array type * whose component type is also an array type. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is {@link + * javax.lang.model.type.ArrayType}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface ArrayType extends ReferenceType { /** diff --git a/langtools/src/share/classes/com/sun/mirror/type/ClassType.java b/langtools/src/share/classes/com/sun/mirror/type/ClassType.java index 051fd590dda..fbfc86757fd 100644 --- a/langtools/src/share/classes/com/sun/mirror/type/ClassType.java +++ b/langtools/src/share/classes/com/sun/mirror/type/ClassType.java @@ -38,11 +38,17 @@ import com.sun.mirror.declaration.*; * of a class, a ClassType represents a class type. * See {@link TypeDeclaration} for more on this distinction. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is included in {@link + * javax.lang.model.type.DeclaredType}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface ClassType extends DeclaredType { /** diff --git a/langtools/src/share/classes/com/sun/mirror/type/DeclaredType.java b/langtools/src/share/classes/com/sun/mirror/type/DeclaredType.java index d473b61a9b8..59aaf7e194e 100644 --- a/langtools/src/share/classes/com/sun/mirror/type/DeclaredType.java +++ b/langtools/src/share/classes/com/sun/mirror/type/DeclaredType.java @@ -48,11 +48,17 @@ import com.sun.mirror.declaration.TypeDeclaration; * Other method invocations on such an unknown type will not, in general, * return meaningful results. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is included in {@link + * javax.lang.model.type.DeclaredType}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface DeclaredType extends ReferenceType { /** diff --git a/langtools/src/share/classes/com/sun/mirror/type/EnumType.java b/langtools/src/share/classes/com/sun/mirror/type/EnumType.java index 90113a9d53b..758cdddca9f 100644 --- a/langtools/src/share/classes/com/sun/mirror/type/EnumType.java +++ b/langtools/src/share/classes/com/sun/mirror/type/EnumType.java @@ -32,11 +32,17 @@ import com.sun.mirror.declaration.EnumDeclaration; /** * Represents an enum type. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is included in {@link + * javax.lang.model.type.DeclaredType}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface EnumType extends ClassType { /** diff --git a/langtools/src/share/classes/com/sun/mirror/type/InterfaceType.java b/langtools/src/share/classes/com/sun/mirror/type/InterfaceType.java index 8b9068d3f6a..48ec1a23f12 100644 --- a/langtools/src/share/classes/com/sun/mirror/type/InterfaceType.java +++ b/langtools/src/share/classes/com/sun/mirror/type/InterfaceType.java @@ -39,11 +39,17 @@ import com.sun.mirror.declaration.*; * represents an interface type. * See {@link TypeDeclaration} for more on this distinction. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is included in {@link + * javax.lang.model.type.DeclaredType}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface InterfaceType extends DeclaredType { /** diff --git a/langtools/src/share/classes/com/sun/mirror/type/MirroredTypeException.java b/langtools/src/share/classes/com/sun/mirror/type/MirroredTypeException.java index a0048d9e729..93b22bacc9d 100644 --- a/langtools/src/share/classes/com/sun/mirror/type/MirroredTypeException.java +++ b/langtools/src/share/classes/com/sun/mirror/type/MirroredTypeException.java @@ -35,9 +35,16 @@ import com.sun.mirror.declaration.Declaration; * Thrown when an application attempts to access the {@link Class} object * corresponding to a {@link TypeMirror}. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this exception is {@link + * javax.lang.model.type.MirroredTypeException}. + * * @see MirroredTypesException * @see Declaration#getAnnotation(Class) */ +@Deprecated +@SuppressWarnings("deprecation") public class MirroredTypeException extends RuntimeException { private static final long serialVersionUID = 1; diff --git a/langtools/src/share/classes/com/sun/mirror/type/MirroredTypesException.java b/langtools/src/share/classes/com/sun/mirror/type/MirroredTypesException.java index 8d44ec14e96..f4647e52ffc 100644 --- a/langtools/src/share/classes/com/sun/mirror/type/MirroredTypesException.java +++ b/langtools/src/share/classes/com/sun/mirror/type/MirroredTypesException.java @@ -38,9 +38,16 @@ import com.sun.mirror.declaration.Declaration; * Thrown when an application attempts to access a sequence of {@link Class} * objects each corresponding to a {@link TypeMirror}. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this exception is {@link + * javax.lang.model.type.MirroredTypesException}. + * * @see MirroredTypeException * @see Declaration#getAnnotation(Class) */ +@Deprecated +@SuppressWarnings("deprecation") public class MirroredTypesException extends RuntimeException { private static final long serialVersionUID = 1; diff --git a/langtools/src/share/classes/com/sun/mirror/type/PrimitiveType.java b/langtools/src/share/classes/com/sun/mirror/type/PrimitiveType.java index d9ec2f30fab..aee889e409e 100644 --- a/langtools/src/share/classes/com/sun/mirror/type/PrimitiveType.java +++ b/langtools/src/share/classes/com/sun/mirror/type/PrimitiveType.java @@ -31,11 +31,17 @@ package com.sun.mirror.type; * boolean, byte, short, int, * long, char, float, and double. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is {@link + * javax.lang.model.type.PrimitiveType}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface PrimitiveType extends TypeMirror { /** @@ -47,7 +53,13 @@ public interface PrimitiveType extends TypeMirror { /** * An enumeration of the different kinds of primitive types. + * + * @deprecated All components of this API have been superseded by + * the standardized annotation processing API. The replacement + * for the functionality of this enum is {@link + * javax.lang.model.type.TypeKind}. */ + @Deprecated enum Kind { /** The primitive type boolean */ BOOLEAN, /** The primitive type byte */ BYTE, diff --git a/langtools/src/share/classes/com/sun/mirror/type/ReferenceType.java b/langtools/src/share/classes/com/sun/mirror/type/ReferenceType.java index 862eb87caec..c8df04911d2 100644 --- a/langtools/src/share/classes/com/sun/mirror/type/ReferenceType.java +++ b/langtools/src/share/classes/com/sun/mirror/type/ReferenceType.java @@ -30,10 +30,16 @@ package com.sun.mirror.type; * Represents a reference type. * These include class and interface types, array types, and type variables. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is {@link + * javax.lang.model.type.ReferenceType}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface ReferenceType extends TypeMirror { } diff --git a/langtools/src/share/classes/com/sun/mirror/type/TypeMirror.java b/langtools/src/share/classes/com/sun/mirror/type/TypeMirror.java index 6b3033935b8..9816f00e4d6 100644 --- a/langtools/src/share/classes/com/sun/mirror/type/TypeMirror.java +++ b/langtools/src/share/classes/com/sun/mirror/type/TypeMirror.java @@ -43,6 +43,11 @@ import com.sun.mirror.util.TypeVisitor; * There is no guarantee that any particular type will * always be represented by the same object. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is {@link + * javax.lang.model.type.TypeMirror}. + * * @author Joseph D. Darcy * @author Scott Seligman * @@ -50,7 +55,8 @@ import com.sun.mirror.util.TypeVisitor; * @see Types * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface TypeMirror { /** diff --git a/langtools/src/share/classes/com/sun/mirror/type/TypeVariable.java b/langtools/src/share/classes/com/sun/mirror/type/TypeVariable.java index 0c5c097b0f5..8626a2d4332 100644 --- a/langtools/src/share/classes/com/sun/mirror/type/TypeVariable.java +++ b/langtools/src/share/classes/com/sun/mirror/type/TypeVariable.java @@ -35,11 +35,17 @@ import com.sun.mirror.declaration.*; * {@linkplain TypeParameterDeclaration type parameter} of a * type, method, or constructor. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is {@link + * javax.lang.model.type.TypeVariable}. + * * @author Joe Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface TypeVariable extends ReferenceType { /** diff --git a/langtools/src/share/classes/com/sun/mirror/type/VoidType.java b/langtools/src/share/classes/com/sun/mirror/type/VoidType.java index b913e7fdb25..9db96fac7c4 100644 --- a/langtools/src/share/classes/com/sun/mirror/type/VoidType.java +++ b/langtools/src/share/classes/com/sun/mirror/type/VoidType.java @@ -35,9 +35,15 @@ import com.sun.mirror.declaration.MethodDeclaration; * @author Joseph D. Darcy * @author Scott Seligman * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is included in {@link + * javax.lang.model.type.NoType}. + * * @see MethodDeclaration#getReturnType() * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface VoidType extends TypeMirror { } diff --git a/langtools/src/share/classes/com/sun/mirror/type/WildcardType.java b/langtools/src/share/classes/com/sun/mirror/type/WildcardType.java index fc0fa48f767..6cf2141c453 100644 --- a/langtools/src/share/classes/com/sun/mirror/type/WildcardType.java +++ b/langtools/src/share/classes/com/sun/mirror/type/WildcardType.java @@ -41,11 +41,17 @@ import java.util.Collection; * extends clause, its lower bound explicitly set by a * super clause, or neither (but not both). * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is {@link + * javax.lang.model.type.WildcardType}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface WildcardType extends TypeMirror { /** diff --git a/langtools/src/share/classes/com/sun/mirror/type/package-info.java b/langtools/src/share/classes/com/sun/mirror/type/package-info.java new file mode 100644 index 00000000000..d45a71dd0a8 --- /dev/null +++ b/langtools/src/share/classes/com/sun/mirror/type/package-info.java @@ -0,0 +1,37 @@ +/* + * Copyright 2004 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * Interfaces used to model types. A type is represented by the + * appropriate subinterface of {@link com.sun.mirror.type.TypeMirror}. + * + *

The {@code apt} tool and its associated API have been + * superseded by the standardized annotation processing API. The + * replacement for the functionality in this package is {@link + * javax.lang.model.type}. + * + * @since 1.5 + */ +package com.sun.mirror.type; diff --git a/langtools/src/share/classes/com/sun/mirror/type/package.html b/langtools/src/share/classes/com/sun/mirror/type/package.html deleted file mode 100644 index cb83900545d..00000000000 --- a/langtools/src/share/classes/com/sun/mirror/type/package.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - -Interfaces used to model types. -A type is represented by the appropriate subinterface of -{@link com.sun.mirror.type.TypeMirror}. - -

Note that the apt tool and its associated APIs may be -changed or superseded in future j2se releases. - -@since 1.5 - - diff --git a/langtools/src/share/classes/com/sun/mirror/util/DeclarationFilter.java b/langtools/src/share/classes/com/sun/mirror/util/DeclarationFilter.java index 83936dd4e2c..3a64927a3f7 100644 --- a/langtools/src/share/classes/com/sun/mirror/util/DeclarationFilter.java +++ b/langtools/src/share/classes/com/sun/mirror/util/DeclarationFilter.java @@ -69,11 +69,17 @@ import static com.sun.mirror.declaration.Modifier.*; * }; * result = nameFilter.filter(decls); * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this class is {@link + * javax.lang.model.util.ElementFilter}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public class DeclarationFilter { // Predefined filters for convenience. diff --git a/langtools/src/share/classes/com/sun/mirror/util/DeclarationScanner.java b/langtools/src/share/classes/com/sun/mirror/util/DeclarationScanner.java index 6dbb275a538..269a5b58f4d 100644 --- a/langtools/src/share/classes/com/sun/mirror/util/DeclarationScanner.java +++ b/langtools/src/share/classes/com/sun/mirror/util/DeclarationScanner.java @@ -39,11 +39,17 @@ import com.sun.mirror.declaration.*; * are scanned; the postprocessing visitor is called after the * contained declarations are scanned. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this class is {@link + * javax.lang.model.util.ElementScanner6}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") class DeclarationScanner implements DeclarationVisitor { protected DeclarationVisitor pre; protected DeclarationVisitor post; diff --git a/langtools/src/share/classes/com/sun/mirror/util/DeclarationVisitor.java b/langtools/src/share/classes/com/sun/mirror/util/DeclarationVisitor.java index 4b3806efefe..56401d4f23c 100644 --- a/langtools/src/share/classes/com/sun/mirror/util/DeclarationVisitor.java +++ b/langtools/src/share/classes/com/sun/mirror/util/DeclarationVisitor.java @@ -37,11 +37,17 @@ import com.sun.mirror.declaration.*; * visitXxx method applicable to that declaration is * invoked. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is {@link + * javax.lang.model.element.ElementVisitor}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface DeclarationVisitor { /** diff --git a/langtools/src/share/classes/com/sun/mirror/util/DeclarationVisitors.java b/langtools/src/share/classes/com/sun/mirror/util/DeclarationVisitors.java index 9188be76ae1..f8e0171d7b0 100644 --- a/langtools/src/share/classes/com/sun/mirror/util/DeclarationVisitors.java +++ b/langtools/src/share/classes/com/sun/mirror/util/DeclarationVisitors.java @@ -28,10 +28,17 @@ package com.sun.mirror.util; /** * Utilities to create specialized DeclarationVisitor instances. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. There is no direct + * replacement for the functionality of this class in the standardized + * API due to that API's different visitor structure. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ +@Deprecated +@SuppressWarnings("deprecation") public class DeclarationVisitors { private DeclarationVisitors(){} // do not instantiate. diff --git a/langtools/src/share/classes/com/sun/mirror/util/Declarations.java b/langtools/src/share/classes/com/sun/mirror/util/Declarations.java index fe87fa5a9fa..ec8c9eb6a7c 100644 --- a/langtools/src/share/classes/com/sun/mirror/util/Declarations.java +++ b/langtools/src/share/classes/com/sun/mirror/util/Declarations.java @@ -32,11 +32,17 @@ import com.sun.mirror.declaration.*; /** * Utility methods for operating on declarations. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is {@link + * javax.lang.model.util.Elements}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface Declarations { /** diff --git a/langtools/src/share/classes/com/sun/mirror/util/SimpleDeclarationVisitor.java b/langtools/src/share/classes/com/sun/mirror/util/SimpleDeclarationVisitor.java index 7b0ed87e894..6be5d834ae0 100644 --- a/langtools/src/share/classes/com/sun/mirror/util/SimpleDeclarationVisitor.java +++ b/langtools/src/share/classes/com/sun/mirror/util/SimpleDeclarationVisitor.java @@ -37,11 +37,17 @@ import com.sun.mirror.declaration.*; * methods that correspond to the kinds of declarations on which it * will operate. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this class is {@link + * javax.lang.model.util.SimpleElementVisitor6}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public class SimpleDeclarationVisitor implements DeclarationVisitor { /** diff --git a/langtools/src/share/classes/com/sun/mirror/util/SimpleTypeVisitor.java b/langtools/src/share/classes/com/sun/mirror/util/SimpleTypeVisitor.java index eaa37b3dbef..2bea63de137 100644 --- a/langtools/src/share/classes/com/sun/mirror/util/SimpleTypeVisitor.java +++ b/langtools/src/share/classes/com/sun/mirror/util/SimpleTypeVisitor.java @@ -37,11 +37,17 @@ import com.sun.mirror.type.*; * methods that correspond to the kinds of types on which it will * operate. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this class is {@link + * javax.lang.model.util.SimpleTypeVisitor6}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public class SimpleTypeVisitor implements TypeVisitor { /** diff --git a/langtools/src/share/classes/com/sun/mirror/util/SourceOrderDeclScanner.java b/langtools/src/share/classes/com/sun/mirror/util/SourceOrderDeclScanner.java index 3b6e62bec12..62b7209dde4 100644 --- a/langtools/src/share/classes/com/sun/mirror/util/SourceOrderDeclScanner.java +++ b/langtools/src/share/classes/com/sun/mirror/util/SourceOrderDeclScanner.java @@ -42,10 +42,17 @@ import java.util.TreeSet; * are scanned; the postprocessing visitor is called after the * contained declarations are scanned. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this class is {@link + * javax.lang.model.util.SimpleElementVisitor6}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ +@Deprecated +@SuppressWarnings("deprecation") class SourceOrderDeclScanner extends DeclarationScanner { static class SourceOrderComparator implements java.util.Comparator { SourceOrderComparator(){} diff --git a/langtools/src/share/classes/com/sun/mirror/util/SourcePosition.java b/langtools/src/share/classes/com/sun/mirror/util/SourcePosition.java index f300d3c19ab..766cae4f645 100644 --- a/langtools/src/share/classes/com/sun/mirror/util/SourcePosition.java +++ b/langtools/src/share/classes/com/sun/mirror/util/SourcePosition.java @@ -32,11 +32,20 @@ import java.io.File; /** * Represents a position in a source file. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. There is no direct + * replacement for the functionality of this interface since the + * standardized {@link javax.annotation.processing.Messager Messager} + * API implicitly takes a source position argument via any element, + * annotation mirror, or annotation value passed along with the + * message. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface SourcePosition { /** diff --git a/langtools/src/share/classes/com/sun/mirror/util/TypeVisitor.java b/langtools/src/share/classes/com/sun/mirror/util/TypeVisitor.java index 4df15f551d6..4216617d4f3 100644 --- a/langtools/src/share/classes/com/sun/mirror/util/TypeVisitor.java +++ b/langtools/src/share/classes/com/sun/mirror/util/TypeVisitor.java @@ -38,11 +38,17 @@ import com.sun.mirror.type.*; * the most specific visitXxx method applicable to * that type is invoked. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is {@link + * javax.lang.model.element.TypeVisitor}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface TypeVisitor { /** diff --git a/langtools/src/share/classes/com/sun/mirror/util/Types.java b/langtools/src/share/classes/com/sun/mirror/util/Types.java index 8bb2512105f..4324f59b035 100644 --- a/langtools/src/share/classes/com/sun/mirror/util/Types.java +++ b/langtools/src/share/classes/com/sun/mirror/util/Types.java @@ -35,11 +35,17 @@ import com.sun.mirror.type.*; /** * Utility methods for operating on types. * + * @deprecated All components of this API have been superseded by the + * standardized annotation processing API. The replacement for the + * functionality of this interface is {@link + * javax.lang.model.util.Types}. + * * @author Joseph D. Darcy * @author Scott Seligman * @since 1.5 */ - +@Deprecated +@SuppressWarnings("deprecation") public interface Types { /** diff --git a/langtools/src/share/classes/com/sun/mirror/util/package-info.java b/langtools/src/share/classes/com/sun/mirror/util/package-info.java new file mode 100644 index 00000000000..9a74f19a7d1 --- /dev/null +++ b/langtools/src/share/classes/com/sun/mirror/util/package-info.java @@ -0,0 +1,37 @@ +/* + * Copyright 2004 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * Utilities to assist in the processing of {@linkplain + * com.sun.mirror.declaration declarations} and {@linkplain + * com.sun.mirror.type types}. + * + *

The {@code apt} tool and its associated API have been superseded + * by the standardized annotation processing API. The replacement for + * the functionality in this package is {@link javax.lang.model.util}. + * + * @since 1.5 + */ +package com.sun.mirror.util; diff --git a/langtools/src/share/classes/com/sun/mirror/util/package.html b/langtools/src/share/classes/com/sun/mirror/util/package.html deleted file mode 100644 index ef3e71d8dea..00000000000 --- a/langtools/src/share/classes/com/sun/mirror/util/package.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - -Utilities to assist in the processing of {@linkplain -com.sun.mirror.declaration declarations} and {@linkplain -com.sun.mirror.type types}. - -

Note that the apt tool and its associated APIs may be -changed or superseded in future j2se releases. - -@since 1.5 - - diff --git a/langtools/src/share/classes/com/sun/tools/apt/comp/Apt.java b/langtools/src/share/classes/com/sun/tools/apt/comp/Apt.java index 68d5a458a66..fcdf29d461a 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/comp/Apt.java +++ b/langtools/src/share/classes/com/sun/tools/apt/comp/Apt.java @@ -65,6 +65,7 @@ import static com.sun.tools.apt.mirror.declaration.DeclarationMaker.isJavaIdenti * risk. This code and its internal interfaces are subject to change * or deletion without notice. */ +@SuppressWarnings("deprecation") public class Apt extends ListBuffer> { java.util.Set genSourceFileNames = new java.util.LinkedHashSet(); public java.util.Set getSourceFileNames() { diff --git a/langtools/src/share/classes/com/sun/tools/apt/comp/BootstrapAPF.java b/langtools/src/share/classes/com/sun/tools/apt/comp/BootstrapAPF.java index edc71a269f2..2753d734f89 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/comp/BootstrapAPF.java +++ b/langtools/src/share/classes/com/sun/tools/apt/comp/BootstrapAPF.java @@ -29,6 +29,7 @@ import java.util.*; import com.sun.mirror.apt.*; import com.sun.mirror.declaration.AnnotationTypeDeclaration; +@SuppressWarnings("deprecation") public class BootstrapAPF implements AnnotationProcessorFactory { static final Collection supportedOptions = diff --git a/langtools/src/share/classes/com/sun/tools/apt/comp/PrintAP.java b/langtools/src/share/classes/com/sun/tools/apt/comp/PrintAP.java index 59f9e7bdd80..a2715b2ff85 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/comp/PrintAP.java +++ b/langtools/src/share/classes/com/sun/tools/apt/comp/PrintAP.java @@ -36,6 +36,7 @@ import com.sun.mirror.util.*; /** * Class used to implement "-print" option. */ +@SuppressWarnings("deprecation") public class PrintAP implements AnnotationProcessor { diff --git a/langtools/src/share/classes/com/sun/tools/apt/main/JavaCompiler.java b/langtools/src/share/classes/com/sun/tools/apt/main/JavaCompiler.java index 219cd8acb09..cc6aada5508 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/main/JavaCompiler.java +++ b/langtools/src/share/classes/com/sun/tools/apt/main/JavaCompiler.java @@ -50,6 +50,7 @@ import com.sun.tools.javac.parser.DocCommentScanner; * risk. This code and its internal interfaces are subject to change * or deletion without notice. */ +@SuppressWarnings("deprecation") public class JavaCompiler extends com.sun.tools.javac.main.JavaCompiler { /** The context key for the compiler. */ protected static final Context.Key compilerKey = diff --git a/langtools/src/share/classes/com/sun/tools/apt/main/Main.java b/langtools/src/share/classes/com/sun/tools/apt/main/Main.java index 7783652979d..d8e9aac768e 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/main/Main.java +++ b/langtools/src/share/classes/com/sun/tools/apt/main/Main.java @@ -64,6 +64,7 @@ import com.sun.mirror.apt.AnnotationProcessorFactory; * risk. This code and its internal interfaces are subject to change * or deletion without notice. */ +@SuppressWarnings("deprecation") public class Main { /** For testing: enter any options you want to be set implicitly @@ -780,7 +781,6 @@ public class Main { // prefixed to command line arguments. processArgs(forcedOpts); - /* * A run of apt only gets passed the most recently generated * files; the initial run of apt gets passed the files from @@ -792,6 +792,11 @@ public class Main { // assign args the result of parse to capture results of // '@file' expansion origFilenames = processArgs((args=CommandLine.parse(args))); + + if (options.get("suppress-tool-api-removal-message") == null) { + Bark.printLines(out, getLocalizedString("misc.Deprecation")); + } + if (origFilenames == null) { return EXIT_CMDERR; } else if (origFilenames.size() == 0) { diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/AptEnv.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/AptEnv.java index f5e5b1a8ffd..4279a970da4 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/AptEnv.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/AptEnv.java @@ -39,7 +39,7 @@ import com.sun.tools.javac.util.Names; /** * The environment for a run of apt. */ - +@SuppressWarnings("deprecation") public class AptEnv { public Names names; // javac's name table diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/apt/AnnotationProcessorEnvironmentImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/apt/AnnotationProcessorEnvironmentImpl.java index 974d464a330..0e3730332e0 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/apt/AnnotationProcessorEnvironmentImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/apt/AnnotationProcessorEnvironmentImpl.java @@ -47,6 +47,7 @@ import static com.sun.mirror.util.DeclarationVisitors.*; /* * Annotation Processor Environment implementation. */ +@SuppressWarnings("deprecation") public class AnnotationProcessorEnvironmentImpl implements AnnotationProcessorEnvironment { Collection spectypedecls; diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/apt/FilerImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/apt/FilerImpl.java index fb01d6b33d5..983eea0f7ca 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/apt/FilerImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/apt/FilerImpl.java @@ -45,7 +45,7 @@ import static com.sun.mirror.apt.Filer.Location.*; /** * Implementation of Filer. */ - +@SuppressWarnings("deprecation") public class FilerImpl implements Filer { /* * The Filer class must maintain a number of constraints. First, diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/apt/MessagerImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/apt/MessagerImpl.java index 12808476d51..903793f0c5f 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/apt/MessagerImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/apt/MessagerImpl.java @@ -38,7 +38,7 @@ import com.sun.tools.apt.util.Bark; /** * Implementation of Messager. */ - +@SuppressWarnings("deprecation") public class MessagerImpl implements Messager { private final Bark bark; diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/apt/RoundCompleteEventImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/apt/RoundCompleteEventImpl.java index 4a4988af516..7046b1a7c5c 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/apt/RoundCompleteEventImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/apt/RoundCompleteEventImpl.java @@ -29,6 +29,7 @@ import com.sun.mirror.apt.AnnotationProcessorEnvironment; import com.sun.mirror.apt.RoundCompleteEvent; import com.sun.mirror.apt.RoundState; +@SuppressWarnings("deprecation") public class RoundCompleteEventImpl extends RoundCompleteEvent { private static final long serialVersionUID = 7067621446720784300L; diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/apt/RoundStateImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/apt/RoundStateImpl.java index 28edfde00a3..70dbc271ef1 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/apt/RoundStateImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/apt/RoundStateImpl.java @@ -28,6 +28,7 @@ package com.sun.tools.apt.mirror.apt; import com.sun.mirror.apt.RoundState; import java.util.Map; +@SuppressWarnings("deprecation") public class RoundStateImpl implements RoundState { private final boolean finalRound; private final boolean errorRaised; diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationMirrorImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationMirrorImpl.java index acde7c6cdd7..226908a8d61 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationMirrorImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationMirrorImpl.java @@ -42,7 +42,7 @@ import com.sun.tools.javac.util.Pair; /** * Implementation of AnnotationMirror */ - +@SuppressWarnings("deprecation") public class AnnotationMirrorImpl implements AnnotationMirror { protected final AptEnv env; diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationProxyMaker.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationProxyMaker.java index 40eb0d68e12..e1b5ba80918 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationProxyMaker.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationProxyMaker.java @@ -49,7 +49,7 @@ import com.sun.tools.javac.util.Pair; *

The "dynamic proxy return form" of an attribute element value is * the form used by sun.reflect.annotation.AnnotationInvocationHandler. */ - +@SuppressWarnings("deprecation") class AnnotationProxyMaker { private final AptEnv env; diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationTypeDeclarationImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationTypeDeclarationImpl.java index 59a9e6f834f..494522a6bef 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationTypeDeclarationImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationTypeDeclarationImpl.java @@ -37,7 +37,7 @@ import com.sun.tools.javac.code.Symbol.*; /** * Implementation of AnnotationTypeDeclaration */ - +@SuppressWarnings("deprecation") public class AnnotationTypeDeclarationImpl extends InterfaceDeclarationImpl implements AnnotationTypeDeclaration { diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationTypeElementDeclarationImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationTypeElementDeclarationImpl.java index c6086385aa8..d63ddc37006 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationTypeElementDeclarationImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationTypeElementDeclarationImpl.java @@ -35,7 +35,7 @@ import com.sun.tools.javac.code.Symbol.MethodSymbol; /** * Implementation of AnnotationTypeElementDeclaration */ - +@SuppressWarnings("deprecation") public class AnnotationTypeElementDeclarationImpl extends MethodDeclarationImpl implements AnnotationTypeElementDeclaration { diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationValueImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationValueImpl.java index a217393c375..b99bb8a2db6 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationValueImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationValueImpl.java @@ -40,7 +40,7 @@ import com.sun.tools.javac.code.TypeTags; /** * Implementation of AnnotationValue */ - +@SuppressWarnings("deprecation") public class AnnotationValueImpl implements AnnotationValue { protected final AptEnv env; diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/ClassDeclarationImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/ClassDeclarationImpl.java index 600be2906b7..1359d16ea12 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/ClassDeclarationImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/ClassDeclarationImpl.java @@ -42,7 +42,7 @@ import com.sun.tools.javac.code.Symbol.*; /** * Implementation of ClassDeclaration */ - +@SuppressWarnings("deprecation") public class ClassDeclarationImpl extends TypeDeclarationImpl implements ClassDeclaration { diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/Constants.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/Constants.java index ba2afd8b47e..63ed3cfa325 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/Constants.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/Constants.java @@ -39,6 +39,7 @@ import static com.sun.tools.javac.code.TypeTags.*; /** * Utility class for operating on constant expressions. */ +@SuppressWarnings("deprecation") class Constants { /** diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/ConstructorDeclarationImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/ConstructorDeclarationImpl.java index 936dfd8145e..3943100bf0f 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/ConstructorDeclarationImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/ConstructorDeclarationImpl.java @@ -39,7 +39,7 @@ import com.sun.tools.javac.code.Symbol.MethodSymbol; /** * Implementation of ConstructorDeclaration */ - +@SuppressWarnings("deprecation") public class ConstructorDeclarationImpl extends ExecutableDeclarationImpl implements ConstructorDeclaration { diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/DeclarationImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/DeclarationImpl.java index bb2b097aba8..e441424073b 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/DeclarationImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/DeclarationImpl.java @@ -52,7 +52,7 @@ import static com.sun.tools.javac.code.Kinds.*; /** * Implementation of Declaration */ - +@SuppressWarnings("deprecation") public abstract class DeclarationImpl implements Declaration { protected final AptEnv env; diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/DeclarationMaker.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/DeclarationMaker.java index 09eeee29ab2..cd90a964ba9 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/DeclarationMaker.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/DeclarationMaker.java @@ -40,7 +40,7 @@ import com.sun.tools.javac.main.JavaCompiler; /** * Utilities for constructing and caching declarations. */ - +@SuppressWarnings("deprecation") public class DeclarationMaker { private AptEnv env; diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/EnumConstantDeclarationImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/EnumConstantDeclarationImpl.java index 7d4ae315bf3..17191cc8b9f 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/EnumConstantDeclarationImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/EnumConstantDeclarationImpl.java @@ -35,7 +35,7 @@ import com.sun.tools.javac.code.Symbol.VarSymbol; /** * Implementation of EnumConstantDeclaration */ - +@SuppressWarnings("deprecation") public class EnumConstantDeclarationImpl extends FieldDeclarationImpl implements EnumConstantDeclaration { diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/EnumDeclarationImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/EnumDeclarationImpl.java index 2a498d24a77..ed882d43d35 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/EnumDeclarationImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/EnumDeclarationImpl.java @@ -37,7 +37,7 @@ import com.sun.tools.javac.code.Symbol.*; /** * Implementation of EnumDeclaration */ - +@SuppressWarnings("deprecation") public class EnumDeclarationImpl extends ClassDeclarationImpl implements EnumDeclaration { diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/ExecutableDeclarationImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/ExecutableDeclarationImpl.java index b5d758fef51..ae4d92fc80f 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/ExecutableDeclarationImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/ExecutableDeclarationImpl.java @@ -39,7 +39,7 @@ import com.sun.tools.javac.code.Symbol.*; /** * Implementation of ExecutableDeclaration */ - +@SuppressWarnings("deprecation") public abstract class ExecutableDeclarationImpl extends MemberDeclarationImpl implements ExecutableDeclaration { public MethodSymbol sym; diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/FieldDeclarationImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/FieldDeclarationImpl.java index 2ab22fdea4f..14eaefe3024 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/FieldDeclarationImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/FieldDeclarationImpl.java @@ -40,7 +40,7 @@ import com.sun.tools.javac.code.TypeTags; /** * Implementation of FieldDeclaration */ - +@SuppressWarnings("deprecation") class FieldDeclarationImpl extends MemberDeclarationImpl implements FieldDeclaration { diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/InterfaceDeclarationImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/InterfaceDeclarationImpl.java index 866c66d9dc8..ee251c30f35 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/InterfaceDeclarationImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/InterfaceDeclarationImpl.java @@ -35,7 +35,7 @@ import com.sun.tools.javac.code.Symbol.*; /** * Implementation of InterfaceDeclaration */ - +@SuppressWarnings("deprecation") public class InterfaceDeclarationImpl extends TypeDeclarationImpl implements InterfaceDeclaration { diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/MemberDeclarationImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/MemberDeclarationImpl.java index e47d706332e..3da4b4313c7 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/MemberDeclarationImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/MemberDeclarationImpl.java @@ -40,7 +40,7 @@ import com.sun.tools.javac.code.Type; /** * Implementation of MemberDeclaration */ - +@SuppressWarnings("deprecation") public abstract class MemberDeclarationImpl extends DeclarationImpl implements MemberDeclaration { diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/MethodDeclarationImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/MethodDeclarationImpl.java index fff004122b7..29c16b2116e 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/MethodDeclarationImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/MethodDeclarationImpl.java @@ -36,7 +36,7 @@ import com.sun.tools.javac.code.Symbol.MethodSymbol; /** * Implementation of MethodDeclaration */ - +@SuppressWarnings("deprecation") public class MethodDeclarationImpl extends ExecutableDeclarationImpl implements MethodDeclaration { diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/PackageDeclarationImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/PackageDeclarationImpl.java index 2edbeb4314b..1f11b1d5729 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/PackageDeclarationImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/PackageDeclarationImpl.java @@ -39,7 +39,7 @@ import com.sun.tools.javac.code.Symbol.*; /** * Implementation of PackageDeclaration. */ - +@SuppressWarnings("deprecation") public class PackageDeclarationImpl extends DeclarationImpl implements PackageDeclaration { diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/ParameterDeclarationImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/ParameterDeclarationImpl.java index 9016b8073fd..66890da2b63 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/ParameterDeclarationImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/ParameterDeclarationImpl.java @@ -39,7 +39,7 @@ import com.sun.tools.javac.code.Symbol.VarSymbol; /** * Implementation of ParameterDeclaration */ - +@SuppressWarnings("deprecation") public class ParameterDeclarationImpl extends DeclarationImpl implements ParameterDeclaration { diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/TypeDeclarationImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/TypeDeclarationImpl.java index d67d6f21e10..7deeb7cf112 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/TypeDeclarationImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/TypeDeclarationImpl.java @@ -40,7 +40,7 @@ import com.sun.tools.javac.util.Name; /** * Implementation of TypeDeclaration */ - +@SuppressWarnings("deprecation") public class TypeDeclarationImpl extends MemberDeclarationImpl implements TypeDeclaration { diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/TypeParameterDeclarationImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/TypeParameterDeclarationImpl.java index b169f47509f..765a11e7487 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/TypeParameterDeclarationImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/TypeParameterDeclarationImpl.java @@ -40,7 +40,7 @@ import com.sun.tools.javac.code.Symbol.*; /** * Implementation of TypeParameterDeclaration */ - +@SuppressWarnings("deprecation") public class TypeParameterDeclarationImpl extends DeclarationImpl implements TypeParameterDeclaration { diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/type/AnnotationTypeImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/type/AnnotationTypeImpl.java index e39a30dabeb..495bc138b01 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/type/AnnotationTypeImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/type/AnnotationTypeImpl.java @@ -36,7 +36,7 @@ import com.sun.tools.javac.code.Type; /** * Implementation of AnnotationType */ - +@SuppressWarnings("deprecation") public class AnnotationTypeImpl extends InterfaceTypeImpl implements AnnotationType { diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/type/ArrayTypeImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/type/ArrayTypeImpl.java index 8c1458be77f..5d62c01445c 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/type/ArrayTypeImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/type/ArrayTypeImpl.java @@ -35,7 +35,7 @@ import com.sun.tools.javac.code.Type; /** * Implementation of ArrayType */ - +@SuppressWarnings("deprecation") public class ArrayTypeImpl extends TypeMirrorImpl implements ArrayType { protected Type.ArrayType type; diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/type/ClassTypeImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/type/ClassTypeImpl.java index a4b9fd230b3..dd824191499 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/type/ClassTypeImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/type/ClassTypeImpl.java @@ -36,7 +36,7 @@ import com.sun.tools.javac.code.Type; /** * Implementation of ClassType */ - +@SuppressWarnings("deprecation") public class ClassTypeImpl extends DeclaredTypeImpl implements ClassType { ClassTypeImpl(AptEnv env, Type.ClassType type) { diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/type/DeclaredTypeImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/type/DeclaredTypeImpl.java index 81683248c4a..b5a815dc864 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/type/DeclaredTypeImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/type/DeclaredTypeImpl.java @@ -38,7 +38,7 @@ import com.sun.tools.javac.code.Symbol.ClassSymbol; /** * Implementation of DeclaredType */ - +@SuppressWarnings("deprecation") abstract class DeclaredTypeImpl extends TypeMirrorImpl implements DeclaredType { diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/type/EnumTypeImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/type/EnumTypeImpl.java index 883a3ec1ec8..c2d634678e1 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/type/EnumTypeImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/type/EnumTypeImpl.java @@ -36,7 +36,7 @@ import com.sun.tools.javac.code.Type; /** * Implementation of EnumType */ - +@SuppressWarnings("deprecation") public class EnumTypeImpl extends ClassTypeImpl implements EnumType { EnumTypeImpl(AptEnv env, Type.ClassType type) { diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/type/InterfaceTypeImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/type/InterfaceTypeImpl.java index 3e056deeef8..167ea9b50d2 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/type/InterfaceTypeImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/type/InterfaceTypeImpl.java @@ -36,7 +36,7 @@ import com.sun.tools.javac.code.Type; /** * Implementation of InterfaceType */ - +@SuppressWarnings("deprecation") public class InterfaceTypeImpl extends DeclaredTypeImpl implements InterfaceType { diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/type/PrimitiveTypeImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/type/PrimitiveTypeImpl.java index e176d5b487e..bf186620a11 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/type/PrimitiveTypeImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/type/PrimitiveTypeImpl.java @@ -38,7 +38,7 @@ import static com.sun.mirror.type.PrimitiveType.Kind.*; /** * Implementation of PrimitiveType. */ - +@SuppressWarnings("deprecation") class PrimitiveTypeImpl extends TypeMirrorImpl implements PrimitiveType { private final Kind kind; // the kind of primitive diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/type/TypeMaker.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/type/TypeMaker.java index 70d322b5371..d9829784100 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/type/TypeMaker.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/type/TypeMaker.java @@ -41,7 +41,7 @@ import static com.sun.tools.javac.code.TypeTags.*; /** * Utilities for constructing type objects. */ - +@SuppressWarnings("deprecation") public class TypeMaker { private final AptEnv env; diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/type/TypeMirrorImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/type/TypeMirrorImpl.java index 964cd8abdea..2fa704a053c 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/type/TypeMirrorImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/type/TypeMirrorImpl.java @@ -35,7 +35,7 @@ import com.sun.tools.javac.code.*; /** * Implementation of TypeMirror */ - +@SuppressWarnings("deprecation") public abstract class TypeMirrorImpl implements TypeMirror { protected final AptEnv env; diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/type/TypeVariableImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/type/TypeVariableImpl.java index 9e65c82f8e8..43119bd7d94 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/type/TypeVariableImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/type/TypeVariableImpl.java @@ -40,7 +40,7 @@ import com.sun.tools.javac.code.Type; /** * Implementation of TypeVariable */ - +@SuppressWarnings("deprecation") public class TypeVariableImpl extends TypeMirrorImpl implements TypeVariable { protected Type.TypeVar type; diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/type/VoidTypeImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/type/VoidTypeImpl.java index 7f9a7bc2989..41e9ca1dbca 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/type/VoidTypeImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/type/VoidTypeImpl.java @@ -34,7 +34,7 @@ import com.sun.tools.apt.mirror.AptEnv; /** * Implementation of VoidType. */ - +@SuppressWarnings("deprecation") class VoidTypeImpl extends TypeMirrorImpl implements VoidType { VoidTypeImpl(AptEnv env) { diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/type/WildcardTypeImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/type/WildcardTypeImpl.java index 9bda06f994d..6221e8ce7a7 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/type/WildcardTypeImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/type/WildcardTypeImpl.java @@ -41,7 +41,7 @@ import com.sun.tools.javac.code.Symbol.*; /** * Implementation of WildcardType */ - +@SuppressWarnings("deprecation") public class WildcardTypeImpl extends TypeMirrorImpl implements WildcardType { protected Type.WildcardType type; diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/util/DeclarationsImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/util/DeclarationsImpl.java index f6008e0618d..106c7136d70 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/util/DeclarationsImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/util/DeclarationsImpl.java @@ -42,7 +42,7 @@ import static com.sun.tools.javac.code.Kinds.*; /** * Implementation of Declarations utility methods for annotation processors */ - +@SuppressWarnings("deprecation") public class DeclarationsImpl implements Declarations { private final AptEnv env; diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/util/SourcePositionImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/util/SourcePositionImpl.java index d76d0eb3968..7da66d6faa7 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/util/SourcePositionImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/util/SourcePositionImpl.java @@ -36,7 +36,7 @@ import com.sun.tools.javac.util.Position; /** * Implementation of SourcePosition */ - +@SuppressWarnings("deprecation") public class SourcePositionImpl implements SourcePosition { private JavaFileObject sourcefile; diff --git a/langtools/src/share/classes/com/sun/tools/apt/mirror/util/TypesImpl.java b/langtools/src/share/classes/com/sun/tools/apt/mirror/util/TypesImpl.java index 8ada36ded5f..237bd58bf30 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/mirror/util/TypesImpl.java +++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/util/TypesImpl.java @@ -44,7 +44,7 @@ import com.sun.tools.javac.util.ListBuffer; /** * Implementation of Types utility methods for annotation processors */ - +@SuppressWarnings("deprecation") public class TypesImpl implements Types { private final AptEnv env; diff --git a/langtools/src/share/classes/com/sun/tools/apt/resources/apt.properties b/langtools/src/share/classes/com/sun/tools/apt/resources/apt.properties index 80446a08931..97605c32fa2 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/resources/apt.properties +++ b/langtools/src/share/classes/com/sun/tools/apt/resources/apt.properties @@ -111,6 +111,14 @@ apt.err.Messager=\ ## miscellaneous strings ## +apt.misc.Deprecation=\ + \nwarning:\u0020The apt tool and its associated API are planned to be\n\ + removed in the next major JDK release. These features have been\n\ + superseded by javac and the standardized annotation processing API,\n\ + javax.annotation.processing and javax.lang.model. Users are\n\ + recommended to migrate to the annotation processing features of\n\ + javac; see the javac man page for more information.\n + apt.misc.Problem=\ Problem encountered during annotation processing; \nsee stacktrace below for more information. diff --git a/langtools/test/tools/apt/Basics/apt.sh b/langtools/test/tools/apt/Basics/apt.sh index a040241ec33..b34d9e0afbb 100644 --- a/langtools/test/tools/apt/Basics/apt.sh +++ b/langtools/test/tools/apt/Basics/apt.sh @@ -43,7 +43,7 @@ case "${OS}" in esac # Construct path to apt executable -APT="${TESTJAVA}/bin/apt ${TESTTOOLVMOPTS}" +APT="${TESTJAVA}/bin/apt ${TESTTOOLVMOPTS} -XDsuppress-tool-api-removal-message " printf "%s\n" "-classpath ${TESTCLASSES}" > options printf "%s\n" "-factorypath ./nullap.jar" >> options @@ -58,6 +58,7 @@ printf "%s\n" "-nocompile" >> options1 printf "%s\n" "-XListAnnotationTypes" >> options1 printf "%s\n" "-XclassesAsDecls" >> options1 + # Construct path to javac executable JAVAC="${TESTJAVA}/bin/javac ${TESTTOOLVMOPTS} -source 1.5 -sourcepath ${TESTSRC} -classpath ${TESTJAVA}/lib/tools.jar -d . " JAR="${TESTJAVA}/bin/jar " diff --git a/langtools/test/tools/apt/Compile/compile.sh b/langtools/test/tools/apt/Compile/compile.sh index 8e42ea3b180..d93e5d92a31 100644 --- a/langtools/test/tools/apt/Compile/compile.sh +++ b/langtools/test/tools/apt/Compile/compile.sh @@ -67,7 +67,7 @@ case "${OS}" in esac -APT="${TESTJAVA}/bin/apt ${TESTTOOLVMOPTS} " +APT="${TESTJAVA}/bin/apt ${TESTTOOLVMOPTS} -XDsuppress-tool-api-removal-message " JAVA="${TESTJAVA}/bin/java ${TESTVMOPTS} " JAVAC="${TESTJAVA}/bin/javac ${TESTTOOLVMOPTS} " From 642a5040a09d4bdecbd0d600b4518c35864341df Mon Sep 17 00:00:00 2001 From: Dmitry Cherepanov Date: Mon, 27 Jul 2009 15:37:39 +0400 Subject: [PATCH 40/96] 6856929: Frame is not getting resized using Robot in OpenSolaris and Ubuntu Reviewed-by: art, dav --- .../classes/sun/awt/X11/XRobotPeer.java | 6 ++++-- jdk/src/solaris/native/sun/awt/awt_Robot.c | 21 ++++++++----------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/jdk/src/solaris/classes/sun/awt/X11/XRobotPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XRobotPeer.java index 663c0ed8a04..82e226363b9 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XRobotPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XRobotPeer.java @@ -27,6 +27,7 @@ package sun.awt.X11; import java.awt.*; import java.awt.peer.*; import sun.awt.X11GraphicsConfig; +import sun.awt.SunToolkit; class XRobotPeer implements RobotPeer { private X11GraphicsConfig xgc = null; @@ -38,7 +39,8 @@ class XRobotPeer implements RobotPeer { XRobotPeer(GraphicsConfiguration gc) { this.xgc = (X11GraphicsConfig)gc; - setup(); + SunToolkit tk = (SunToolkit)Toolkit.getDefaultToolkit(); + setup(tk.getNumberOfButtons()); } public void dispose() { @@ -81,7 +83,7 @@ class XRobotPeer implements RobotPeer { return pixelArray; } - private static native synchronized void setup(); + private static native synchronized void setup(int numberOfButtons); private static native synchronized void mouseMoveImpl(X11GraphicsConfig xgc, int x, int y); private static native synchronized void mousePressImpl(int buttons); diff --git a/jdk/src/solaris/native/sun/awt/awt_Robot.c b/jdk/src/solaris/native/sun/awt/awt_Robot.c index 18aa1554b98..dbeebfe44fb 100644 --- a/jdk/src/solaris/native/sun/awt/awt_Robot.c +++ b/jdk/src/solaris/native/sun/awt/awt_Robot.c @@ -51,9 +51,8 @@ extern struct X11GraphicsConfigIDs x11GraphicsConfigIDs; -extern int32_t getNumButtons(); - static jint * masks; +static jint num_buttons; static int32_t isXTestAvailable() { int32_t major_opcode, first_event, first_error; @@ -164,34 +163,34 @@ static XImage *getWindowImage(Display * display, Window window, /*********************************************************************************************/ +// this should be called from XRobotPeer constructor JNIEXPORT void JNICALL -Java_sun_awt_X11_XRobotPeer_setup (JNIEnv * env, jclass cls) { +Java_sun_awt_X11_XRobotPeer_setup (JNIEnv * env, jclass cls, jint numberOfButtons) { int32_t xtestAvailable; -// this should be called from XRobotPeer constructor + DTRACE_PRINTLN("RobotPeer: setup()"); + + num_buttons = numberOfButtons; + jclass inputEventClazz = (*env)->FindClass(env, "java/awt/event/InputEvent"); jmethodID getButtonDownMasksID = (*env)->GetStaticMethodID(env, inputEventClazz, "getButtonDownMasks", "()[I"); jintArray obj = (jintArray)(*env)->CallStaticObjectMethod(env, inputEventClazz, getButtonDownMasksID); - jsize len = (*env)->GetArrayLength(env, obj); jint * tmp = (*env)->GetIntArrayElements(env, obj, JNI_FALSE); - masks = (jint *)malloc(sizeof(jint)*len); + masks = (jint *)malloc(sizeof(jint) * num_buttons); if (masks == (jint *) NULL) { JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2), NULL); goto finally; } int i; - for (i = 0; i < len; i++) { + for (i = 0; i < num_buttons; i++) { masks[i] = tmp[i]; } (*env)->ReleaseIntArrayElements(env, obj, tmp, 0); (*env)->DeleteLocalRef(env, obj); - DTRACE_PRINTLN("RobotPeer: setup()"); - AWT_LOCK(); - xtestAvailable = isXTestAvailable(); DTRACE_PRINTLN1("RobotPeer: XTest available = %d", xtestAvailable); if (!xtestAvailable) { @@ -338,8 +337,6 @@ void mouseAction(JNIEnv *env, { AWT_LOCK(); - int32_t num_buttons = getNumButtons(); //from XToolkit.c - DTRACE_PRINTLN1("RobotPeer: mouseAction(%i)", buttonMask); DTRACE_PRINTLN1("RobotPeer: mouseAction, press = %d", isMousePress); From a7e89dff0e237f0055d4b16edb554bfb959f6379 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Mon, 27 Jul 2009 15:19:11 -0700 Subject: [PATCH 41/96] 6854244: change source/target used to compile JDK to 7 Reviewed-by: ohair --- make/README.pre-components | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make/README.pre-components b/make/README.pre-components index 8d2eab571cb..cb79e68df27 100644 --- a/make/README.pre-components +++ b/make/README.pre-components @@ -18,7 +18,7 @@ The make/makefile rules are: ALT_LANGTOOLS_DIST The dist area from a langtools build to use, if provided ALT_OUTPUTDIR Parent dir of build and dist directories, if provided VARIANT If DBG, debug build, if OPT, optimized build - TARGET_CLASS_VERSION The classfile version number (currently 5) + TARGET_CLASS_VERSION The classfile version number (currently 7) ANT_HOME Home of ant to use, if provided QUIET If defined, be quiet VERBOSE If defined, be verbose From 103e820d941781b4beeb00d84b4edb2a368e4e8e Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Mon, 27 Jul 2009 15:19:26 -0700 Subject: [PATCH 42/96] 6854244: change source/target used to compile JDK to 7 Reviewed-by: ohair --- corba/make/Makefile | 2 +- corba/make/common/shared/Defs-java.gmk | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/corba/make/Makefile b/corba/make/Makefile index 1cd81c90ab0..8241b33baf9 100644 --- a/corba/make/Makefile +++ b/corba/make/Makefile @@ -110,7 +110,7 @@ BOOTSTRAP_TARGET_LEVEL = 5 ifdef TARGET_CLASS_VERSION TARGET_LEVEL = $(TARGET_CLASS_VERSION) else - TARGET_LEVEL = 6 + TARGET_LEVEL = 7 endif ifndef TARGET_JAVA diff --git a/corba/make/common/shared/Defs-java.gmk b/corba/make/common/shared/Defs-java.gmk index f80f0ffa4e1..a9c65959ebd 100644 --- a/corba/make/common/shared/Defs-java.gmk +++ b/corba/make/common/shared/Defs-java.gmk @@ -107,12 +107,12 @@ endif NO_PROPRIETARY_API_WARNINGS = -XDignore.symbol.file=true JAVACFLAGS += $(NO_PROPRIETARY_API_WARNINGS) -# Add the source level (currently all source is 1.5, should this be 1.6?) -LANGUAGE_VERSION = -source 1.5 +# Add the source level +LANGUAGE_VERSION = -source 7 JAVACFLAGS += $(LANGUAGE_VERSION) -# Add the class version we want (currently this is 5, should it be 6 or even 7?) -TARGET_CLASS_VERSION = 5 +# Add the class version we want +TARGET_CLASS_VERSION = 7 CLASS_VERSION = -target $(TARGET_CLASS_VERSION) JAVACFLAGS += $(CLASS_VERSION) JAVACFLAGS += -encoding ascii From 8ae07c63e4f3aac4f943e00518baa05d3f4992a7 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Mon, 27 Jul 2009 15:19:33 -0700 Subject: [PATCH 43/96] 6854244: change source/target used to compile JDK to 7 Reviewed-by: ohair --- jaxp/make/build.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jaxp/make/build.properties b/jaxp/make/build.properties index ed598102aa9..a7d8d0670fe 100644 --- a/jaxp/make/build.properties +++ b/jaxp/make/build.properties @@ -30,8 +30,8 @@ # one of the standard user build.properties files (see build.xml) # options for the tasks used to compile the tools -javac.source = 5 -javac.target = 5 +javac.source = 7 +javac.target = 7 javac.debug = true javac.no.jdk.warnings = -XDignore.symbol.file=true # set the following to -version to verify the versions of javac being used From 33e236c76603e48d57e874a6feba0dc41ba2796c Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Mon, 27 Jul 2009 15:19:44 -0700 Subject: [PATCH 44/96] 6854244: change source/target used to compile JDK to 7 Reviewed-by: ohair --- jaxws/make/build.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jaxws/make/build.properties b/jaxws/make/build.properties index ed598102aa9..a7d8d0670fe 100644 --- a/jaxws/make/build.properties +++ b/jaxws/make/build.properties @@ -30,8 +30,8 @@ # one of the standard user build.properties files (see build.xml) # options for the tasks used to compile the tools -javac.source = 5 -javac.target = 5 +javac.source = 7 +javac.target = 7 javac.debug = true javac.no.jdk.warnings = -XDignore.symbol.file=true # set the following to -version to verify the versions of javac being used From b84cd5a9cdbf18a6d24d339c3351c36831b7db09 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Mon, 27 Jul 2009 15:20:03 -0700 Subject: [PATCH 45/96] 6854244: change source/target used to compile JDK to 7 Reviewed-by: ohair --- langtools/make/build.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/langtools/make/build.properties b/langtools/make/build.properties index 53dd569ebd6..0782dda6cdd 100644 --- a/langtools/make/build.properties +++ b/langtools/make/build.properties @@ -60,8 +60,8 @@ full.version = ${release}-${build.number} bootstrap.full.version = ${bootstrap.release}-${build.number} # options for the tasks used to compile the tools -javac.source = 5 -javac.target = 5 +javac.source = 7 +javac.target = 7 javac.debug = true javac.debuglevel = source,lines javac.no.jdk.warnings = -XDignore.symbol.file=true From 2a737b4aa9b8c55ea422f5a26a04185c936c5b5f Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Mon, 27 Jul 2009 19:52:42 -0700 Subject: [PATCH 46/96] 6865399: some javac files are missing Sun internal API comment Reviewed-by: darcy --- .../com/sun/tools/javac/api/DiagnosticFormatter.java | 5 +++++ .../classes/com/sun/tools/javac/api/Formattable.java | 5 +++++ .../share/classes/com/sun/tools/javac/api/Messages.java | 5 +++++ .../share/classes/com/sun/tools/javac/code/BoundKind.java | 8 +++++++- .../share/classes/com/sun/tools/javac/code/Printer.java | 5 +++++ .../classes/com/sun/tools/javac/file/BaseFileObject.java | 6 ++++++ .../classes/com/sun/tools/javac/file/CacheFSInfo.java | 7 ++++++- .../share/classes/com/sun/tools/javac/file/FSInfo.java | 5 +++++ .../com/sun/tools/javac/file/JavacFileManager.java | 5 +++++ .../com/sun/tools/javac/file/RegularFileObject.java | 5 +++++ .../classes/com/sun/tools/javac/file/RelativePath.java | 5 +++++ .../classes/com/sun/tools/javac/file/SymbolArchive.java | 6 ++++++ .../classes/com/sun/tools/javac/file/ZipArchive.java | 6 ++++++ .../classes/com/sun/tools/javac/file/ZipFileIndex.java | 5 +++++ .../com/sun/tools/javac/file/ZipFileIndexArchive.java | 6 ++++++ .../classes/com/sun/tools/javac/parser/ParserFactory.java | 5 +++++ .../sun/tools/javac/util/AbstractDiagnosticFormatter.java | 4 ++++ .../sun/tools/javac/util/BasicDiagnosticFormatter.java | 5 +++++ .../tools/javac/util/ForwardingDiagnosticFormatter.java | 5 +++++ .../com/sun/tools/javac/util/RawDiagnosticFormatter.java | 5 +++++ .../com/sun/tools/javac/util/RichDiagnosticFormatter.java | 5 +++++ .../share/classes/com/sun/tools/javac/util/Warner.java | 8 ++++---- 22 files changed, 115 insertions(+), 6 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/javac/api/DiagnosticFormatter.java b/langtools/src/share/classes/com/sun/tools/javac/api/DiagnosticFormatter.java index 576a1687f89..aaa25d81c42 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/api/DiagnosticFormatter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/api/DiagnosticFormatter.java @@ -32,6 +32,11 @@ import com.sun.tools.javac.api.DiagnosticFormatter.*; /** * Provides simple functionalities for javac diagnostic formatting. * @param type of diagnostic handled by this formatter + * + *

This is NOT part of any API supported by Sun Microsystems. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. */ public interface DiagnosticFormatter> { diff --git a/langtools/src/share/classes/com/sun/tools/javac/api/Formattable.java b/langtools/src/share/classes/com/sun/tools/javac/api/Formattable.java index e2a381f9f29..c942a63f945 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/api/Formattable.java +++ b/langtools/src/share/classes/com/sun/tools/javac/api/Formattable.java @@ -31,6 +31,11 @@ import java.util.Locale; * This interface must be implemented by any javac class that has non-trivial * formatting needs (e.g. where toString() does not apply because of localization). * + *

This is NOT part of any API supported by Sun Microsystems. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. + * * @author Maurizio Cimadamore */ public interface Formattable { diff --git a/langtools/src/share/classes/com/sun/tools/javac/api/Messages.java b/langtools/src/share/classes/com/sun/tools/javac/api/Messages.java index ad76d6ce794..290d316ab38 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/api/Messages.java +++ b/langtools/src/share/classes/com/sun/tools/javac/api/Messages.java @@ -32,6 +32,11 @@ import java.util.MissingResourceException; * This interface defines the minimum requirements in order to provide support * for localized formatted strings. * + *

This is NOT part of any API supported by Sun Microsystems. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. + * * @author Maurizio Cimadamore */ public interface Messages { diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/BoundKind.java b/langtools/src/share/classes/com/sun/tools/javac/code/BoundKind.java index e190f5d645b..89932ff5202 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/BoundKind.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/BoundKind.java @@ -25,7 +25,13 @@ package com.sun.tools.javac.code; - +/** + * + *

This is NOT part of any API supported by Sun Microsystems. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. + */ public enum BoundKind { EXTENDS("? extends "), SUPER("? super "), diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java b/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java index 2447ac585dc..baa490954b3 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java @@ -40,6 +40,11 @@ import static com.sun.tools.javac.code.Flags.*; /** * A combined type/symbol visitor for generating non-trivial localized string * representation of types and symbols. + * + *

This is NOT part of any API supported by Sun Microsystems. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. */ public abstract class Printer implements Type.Visitor, Symbol.Visitor { diff --git a/langtools/src/share/classes/com/sun/tools/javac/file/BaseFileObject.java b/langtools/src/share/classes/com/sun/tools/javac/file/BaseFileObject.java index e66ae933efe..ce2736e5556 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/file/BaseFileObject.java +++ b/langtools/src/share/classes/com/sun/tools/javac/file/BaseFileObject.java @@ -36,6 +36,12 @@ import javax.tools.JavaFileObject; import static javax.tools.JavaFileObject.Kind.*; +/** + *

This is NOT part of any API supported by Sun Microsystems. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. +*/ public abstract class BaseFileObject implements JavaFileObject { protected BaseFileObject(JavacFileManager fileManager) { this.fileManager = fileManager; diff --git a/langtools/src/share/classes/com/sun/tools/javac/file/CacheFSInfo.java b/langtools/src/share/classes/com/sun/tools/javac/file/CacheFSInfo.java index 9cd55db589a..cdd091471b9 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/file/CacheFSInfo.java +++ b/langtools/src/share/classes/com/sun/tools/javac/file/CacheFSInfo.java @@ -34,7 +34,12 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** - * Caching implementation of FSInfo + * Caching implementation of FSInfo. + * + *

This is NOT part of any API supported by Sun Microsystems. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. */ public class CacheFSInfo extends FSInfo { diff --git a/langtools/src/share/classes/com/sun/tools/javac/file/FSInfo.java b/langtools/src/share/classes/com/sun/tools/javac/file/FSInfo.java index 840757a5c0d..cfe0dae5066 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/file/FSInfo.java +++ b/langtools/src/share/classes/com/sun/tools/javac/file/FSInfo.java @@ -16,6 +16,11 @@ import com.sun.tools.javac.util.Context; /** * Get meta-info about files. Default direct (non-caching) implementation. * @see CacheFSInfo + * + *

This is NOT part of any API supported by Sun Microsystems. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. */ public class FSInfo { diff --git a/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java b/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java index d8ccc0211fd..3ea1978b3ef 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java +++ b/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java @@ -82,6 +82,11 @@ import static com.sun.tools.javac.main.OptionName.*; /** * This class provides access to the source, class and other files * used by the compiler and related tools. + * + *

This is NOT part of any API supported by Sun Microsystems. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. */ public class JavacFileManager implements StandardJavaFileManager { diff --git a/langtools/src/share/classes/com/sun/tools/javac/file/RegularFileObject.java b/langtools/src/share/classes/com/sun/tools/javac/file/RegularFileObject.java index c604134cab1..6b55187091f 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/file/RegularFileObject.java +++ b/langtools/src/share/classes/com/sun/tools/javac/file/RegularFileObject.java @@ -42,6 +42,11 @@ import javax.tools.JavaFileObject; /** * A subclass of JavaFileObject representing regular files. + * + *

This is NOT part of any API supported by Sun Microsystems. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. */ class RegularFileObject extends BaseFileObject { diff --git a/langtools/src/share/classes/com/sun/tools/javac/file/RelativePath.java b/langtools/src/share/classes/com/sun/tools/javac/file/RelativePath.java index 92cc8862193..d661f447423 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/file/RelativePath.java +++ b/langtools/src/share/classes/com/sun/tools/javac/file/RelativePath.java @@ -34,6 +34,11 @@ import javax.tools.JavaFileObject; * Used to represent a platform-neutral path within a platform-specific * container, such as a directory or zip file. * Internally, the file separator is always '/'. + * + *

This is NOT part of any API supported by Sun Microsystems. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. */ public abstract class RelativePath implements Comparable { /** diff --git a/langtools/src/share/classes/com/sun/tools/javac/file/SymbolArchive.java b/langtools/src/share/classes/com/sun/tools/javac/file/SymbolArchive.java index 89c9a236706..70688db8402 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/file/SymbolArchive.java +++ b/langtools/src/share/classes/com/sun/tools/javac/file/SymbolArchive.java @@ -35,6 +35,12 @@ import com.sun.tools.javac.file.RelativePath.RelativeDirectory; import com.sun.tools.javac.file.RelativePath.RelativeFile; import com.sun.tools.javac.util.List; +/** + *

This is NOT part of any API supported by Sun Microsystems. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. +*/ public class SymbolArchive extends ZipArchive { final File origFile; diff --git a/langtools/src/share/classes/com/sun/tools/javac/file/ZipArchive.java b/langtools/src/share/classes/com/sun/tools/javac/file/ZipArchive.java index 9af25f7788b..63f0dd158ef 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/file/ZipArchive.java +++ b/langtools/src/share/classes/com/sun/tools/javac/file/ZipArchive.java @@ -48,6 +48,12 @@ import com.sun.tools.javac.file.RelativePath.RelativeDirectory; import com.sun.tools.javac.file.RelativePath.RelativeFile; import com.sun.tools.javac.util.List; +/** + *

This is NOT part of any API supported by Sun Microsystems. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. + */ public class ZipArchive implements Archive { public ZipArchive(JavacFileManager fm, ZipFile zdir) throws IOException { diff --git a/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java b/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java index 8a7f6508c4f..f39359992a1 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java +++ b/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java @@ -67,6 +67,11 @@ import com.sun.tools.javac.file.RelativePath.RelativeFile; * If nonBatchMode option is specified (-XDnonBatchMode) the compiler will use timestamp * checking to reindex the zip files if it is needed. In batch mode the timestamps are not checked * and the compiler uses the cached indexes. + * + *

This is NOT part of any API supported by Sun Microsystems. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. */ public class ZipFileIndex { private static final String MIN_CHAR = String.valueOf(Character.MIN_VALUE); diff --git a/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndexArchive.java b/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndexArchive.java index 4ed00d119e4..458910e8928 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndexArchive.java +++ b/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndexArchive.java @@ -44,6 +44,12 @@ import com.sun.tools.javac.file.RelativePath.RelativeDirectory; import com.sun.tools.javac.file.RelativePath.RelativeFile; import com.sun.tools.javac.util.List; +/** + *

This is NOT part of any API supported by Sun Microsystems. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. + */ public class ZipFileIndexArchive implements Archive { private final ZipFileIndex zfIndex; diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/ParserFactory.java b/langtools/src/share/classes/com/sun/tools/javac/parser/ParserFactory.java index 861f3e5d3ca..70588366e46 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/parser/ParserFactory.java +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/ParserFactory.java @@ -34,6 +34,11 @@ import com.sun.tools.javac.util.Options; /** * A factory for creating parsers. + * + *

This is NOT part of any API supported by Sun Microsystems. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. */ public class ParserFactory { diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java b/langtools/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java index d8578ec711d..db7b273e277 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java @@ -57,6 +57,10 @@ import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticType.*; *

  • Provides the formatting logic for rendering the arguments of a JCDiagnostic object. *
      * + *

      This is NOT part of any API supported by Sun Microsystems. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. */ public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter { diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java b/langtools/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java index 77063af34a2..a4442dbff53 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java @@ -57,6 +57,11 @@ import static com.sun.tools.javac.util.LayoutCharacters.*; *

    • %m: the text or the diagnostic, including any appropriate arguments *
    • %_: space delimiter, useful for formatting purposes *
    + * + *

    This is NOT part of any API supported by Sun Microsystems. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. */ public class BasicDiagnosticFormatter extends AbstractDiagnosticFormatter { diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/ForwardingDiagnosticFormatter.java b/langtools/src/share/classes/com/sun/tools/javac/util/ForwardingDiagnosticFormatter.java index aca7fd105e0..f989e38365e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/ForwardingDiagnosticFormatter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/ForwardingDiagnosticFormatter.java @@ -37,6 +37,11 @@ import com.sun.tools.javac.api.DiagnosticFormatter.PositionKind; /** * A delegated diagnostic formatter delegates all formatting * actions to an underlying formatter (aka the delegated formatter). + * + *

    This is NOT part of any API supported by Sun Microsystems. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. */ public class ForwardingDiagnosticFormatter, F extends DiagnosticFormatter> implements DiagnosticFormatter { diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java b/langtools/src/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java index 13674e2e7d2..f9e5126ea21 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java @@ -39,6 +39,11 @@ import static com.sun.tools.javac.api.DiagnosticFormatter.PositionKind.*; * The raw formatter will format a diagnostic according to one of two format patterns, depending on whether * or not the source name and position are set. This formatter provides a standardized, localize-independent * implementation of a diagnostic formatter; as such, this formatter is best suited for testing purposes. + * + *

    This is NOT part of any API supported by Sun Microsystems. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. */ public final class RawDiagnosticFormatter extends AbstractDiagnosticFormatter { diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java b/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java index 60e323f7bda..0996c42f715 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java @@ -58,6 +58,11 @@ import static com.sun.tools.javac.util.RichDiagnosticFormatter.RichConfiguration * formatted and (iii) type-variable disambiguation - when the diagnostic refers * to two different type-variables with the same name, their representation is * disambiguated by appending an index to the type variable name. + * + *

    This is NOT part of any API supported by Sun Microsystems. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. */ public class RichDiagnosticFormatter extends ForwardingDiagnosticFormatter { diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/Warner.java b/langtools/src/share/classes/com/sun/tools/javac/util/Warner.java index 4d739417382..ea9054c3ff0 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/Warner.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/Warner.java @@ -31,10 +31,10 @@ import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; * An interface to support optional warnings, needed for support of * unchecked conversions and unchecked casts. * - *

    Nothing described in this source file is part of any supported - * API. If you write code that depends on this, you do so at your own - * risk. This code and its internal interfaces are subject to change - * or deletion without notice. + *

    This is NOT part of any API supported by Sun Microsystems. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. */ public class Warner { public static final Warner noWarnings = new Warner(); From c1073a5d61ee8d81c7ed1b39f9572e2eb3bd3e63 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Tue, 28 Jul 2009 13:10:14 +0400 Subject: [PATCH 47/96] 6864297: Right-to-left oriented JScrollPane is aligned to the wrong direction while resizing the container Reviewed-by: peterz --- .../swing/plaf/basic/BasicScrollPaneUI.java | 19 +-- .../javax/swing/JScrollPane/Test6526631.java | 102 +++++++++++ jdk/test/javax/swing/SwingTest.java | 160 ++++++++++++++++++ 3 files changed, 269 insertions(+), 12 deletions(-) create mode 100644 jdk/test/javax/swing/JScrollPane/Test6526631.java create mode 100644 jdk/test/javax/swing/SwingTest.java diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicScrollPaneUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicScrollPaneUI.java index af5eaa5df9f..ec33129c346 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicScrollPaneUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicScrollPaneUI.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2009 Sun Microsystems, Inc. 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 @@ -37,17 +37,12 @@ import java.beans.PropertyChangeListener; import java.beans.PropertyChangeEvent; import java.awt.Component; -import java.awt.Container; -import java.awt.LayoutManager; import java.awt.Rectangle; import java.awt.Dimension; import java.awt.Point; import java.awt.Insets; import java.awt.Graphics; import java.awt.event.*; -import java.io.Serializable; -import java.awt.Toolkit; -import java.awt.ComponentOrientation; /** * A default L&F implementation of ScrollPaneUI. @@ -63,6 +58,7 @@ public class BasicScrollPaneUI protected ChangeListener viewportChangeListener; protected PropertyChangeListener spPropertyChangeListener; private MouseWheelListener mouseScrollListener; + private int oldExtent = Integer.MIN_VALUE; /** * PropertyChangeListener installed on the vertical scrollbar. @@ -327,9 +323,13 @@ public class BasicScrollPaneUI * leave it until someone claims. */ value = Math.max(0, Math.min(max - extent, max - extent - viewPosition.x)); + if (oldExtent > extent) { + value -= oldExtent - extent; + } } } } + oldExtent = extent; hsb.setValues(value, extent, 0, max); } @@ -1020,7 +1020,7 @@ public class BasicScrollPaneUI if (viewport != null) { if (e.getSource() == viewport) { - viewportStateChanged(e); + syncScrollPaneWithViewport(); } else { JScrollBar hsb = scrollpane.getHorizontalScrollBar(); @@ -1077,11 +1077,6 @@ public class BasicScrollPaneUI viewport.setViewPosition(p); } - private void viewportStateChanged(ChangeEvent e) { - syncScrollPaneWithViewport(); - } - - // // PropertyChangeListener: This is installed on both the JScrollPane // and the horizontal/vertical scrollbars. diff --git a/jdk/test/javax/swing/JScrollPane/Test6526631.java b/jdk/test/javax/swing/JScrollPane/Test6526631.java new file mode 100644 index 00000000000..ec324623ee5 --- /dev/null +++ b/jdk/test/javax/swing/JScrollPane/Test6526631.java @@ -0,0 +1,102 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6526631 + * @summary Resizes right-oriented scroll pane + * @author Sergey Malenkov + * @library .. + * @build SwingTest + * @run main Test6526631 + */ + +import java.awt.Dimension; +import javax.swing.JFrame; +import javax.swing.JScrollBar; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import javax.swing.JViewport; + +import static java.awt.ComponentOrientation.RIGHT_TO_LEFT; + +public class Test6526631 { + + private static final int COLS = 90; + private static final int ROWS = 50; + private static final int OFFSET = 10; + + public static void main(String[] args) { + SwingTest.start(Test6526631.class); + } + + private final JScrollPane pane; + private final JFrame frame; + + public Test6526631(JFrame frame) { + this.pane = new JScrollPane(new JTextArea(ROWS, COLS)); + this.pane.setComponentOrientation(RIGHT_TO_LEFT); + this.frame = frame; + this.frame.add(this.pane); + } + + private void update(int offset) { + Dimension size = this.frame.getSize(); + size.width += offset; + this.frame.setSize(size); + } + + public void validateFirst() { + validateThird(); + update(OFFSET); + } + + public void validateSecond() { + validateThird(); + update(-OFFSET); + } + + public void validateThird() { + JViewport viewport = this.pane.getViewport(); + JScrollBar scroller = this.pane.getHorizontalScrollBar(); + if (!scroller.getComponentOrientation().equals(RIGHT_TO_LEFT)) { + throw new IllegalStateException("unexpected component orientation"); + } + int value = scroller.getValue(); + if (value != 0) { + throw new IllegalStateException("unexpected scroll value"); + } + int extent = viewport.getExtentSize().width; + if (extent != scroller.getVisibleAmount()) { + throw new IllegalStateException("unexpected visible amount"); + } + int size = viewport.getViewSize().width; + if (size != scroller.getMaximum()) { + throw new IllegalStateException("unexpected maximum"); + } + int pos = size - extent - value; + if (pos != viewport.getViewPosition().x) { + throw new IllegalStateException("unexpected position"); + } + } +} diff --git a/jdk/test/javax/swing/SwingTest.java b/jdk/test/javax/swing/SwingTest.java new file mode 100644 index 00000000000..7f486122e8c --- /dev/null +++ b/jdk/test/javax/swing/SwingTest.java @@ -0,0 +1,160 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +import java.io.PrintWriter; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Comparator; +import java.util.Iterator; +import java.util.Set; +import java.util.TreeSet; +import javax.swing.JFrame; + +import static javax.swing.SwingUtilities.invokeLater; + +/** + * SwingTestHelper is a utility class for writing regression tests + * that require interacting with the UI. + * + * @author Sergey A. Malenkov + */ +final class SwingTest implements Runnable { + + private static final int WIDTH = 640; + private static final int HEIGHT = 480; + + public static void start(Class type) { + new SwingTest(type).start(); + } + + private final PrintWriter writer = new PrintWriter(System.out, true); + + private Class type; + private JFrame frame; + private Iterator methods; + private Object object; + private Method method; + private Throwable error; + + private SwingTest(Class type) { + this.type = type; + } + + public void run() { + synchronized (this.writer) { + if (this.error != null) { + this.frame.dispose(); + this.frame = null; + } + else if (this.object == null) { + invoke(); + Set methods = new TreeSet(new Comparator() { + public int compare(Method first, Method second) { + return first.getName().compareTo(second.getName()); + } + }); + for (Method method : this.type.getMethods()) { + if (method.getDeclaringClass().equals(this.type)) { + if (method.getReturnType().equals(void.class)) { + if (0 == method.getParameterTypes().length) { + methods.add(method); + } + } + } + } + this.methods = methods.iterator(); + } + else if (this.method != null) { + invoke(); + } + else if (this.methods.hasNext()) { + this.method = this.methods.next(); + } + else { + this.frame.dispose(); + this.frame = null; + this.type = null; + } + this.writer.notifyAll(); + } + } + + private void start() { + synchronized (this.writer) { + while (this.type != null) { + if ((this.method != null) && Modifier.isStatic(this.method.getModifiers())) { + invoke(); + } + else { + invokeLater(this); + try { + this.writer.wait(); + } + catch (InterruptedException exception) { + exception.printStackTrace(this.writer); + } + } + if ((this.frame == null) && (this.error != null)) { + throw new Error("unexpected error", this.error); + } + } + } + } + + private void invoke() { + try { + if (this.method != null) { + this.writer.println(this.method); + this.method.invoke(this.object); + this.method = null; + } + else { + this.writer.println(this.type); + this.frame = new JFrame(this.type.getSimpleName()); + this.frame.setSize(WIDTH, HEIGHT); + this.frame.setLocationRelativeTo(null); + this.object = this.type.getConstructor(JFrame.class).newInstance(this.frame); + this.frame.setVisible(true); + } + } + catch (NoSuchMethodException exception) { + this.error = exception; + } + catch (SecurityException exception) { + this.error = exception; + } + catch (IllegalAccessException exception) { + this.error = exception; + } + catch (IllegalArgumentException exception) { + this.error = exception; + } + catch (InstantiationException exception) { + this.error = exception; + } + catch (InvocationTargetException exception) { + this.error = exception.getTargetException(); + } + } +} From 6909a95df2749bf301866ce4bd62e4230d63ddf7 Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 30 Jul 2009 10:58:20 -0700 Subject: [PATCH 48/96] Added tag jdk7-b67 for changeset f86e6d4a49b4 --- .hgtags-top-repo | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 6681557af03..7dc9b1b0dc4 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -41,3 +41,4 @@ c7ed15ab92ce36a09d264a5e34025884b2d7607f jdk7-b62 269c1ec4435dfb7b452ae6e3bdde005d55c5c830 jdk7-b64 e01380cd1de4ce048b87d059d238e5ab5e341947 jdk7-b65 6bad5e3fe50337d95b1416d744780d65bc570da6 jdk7-b66 +c4523c6f82048f420bf0d57c4cd47976753b7d2c jdk7-b67 From 0971a646028213ab6c1fe44cc545dae1f58f80c1 Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 30 Jul 2009 10:58:21 -0700 Subject: [PATCH 49/96] Added tag jdk7-b67 for changeset 805a72a26925 --- corba/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/corba/.hgtags b/corba/.hgtags index 55f6338adba..3e1753626fb 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -41,3 +41,4 @@ d20e45cd539f20405ff843652069cfd7550c5ab3 jdk7-b63 047dd27fddb607f8135296b3754131f6e13cb8c7 jdk7-b64 97fd9b42f5c2d342b90d18f0a2b57e4117e39415 jdk7-b65 a821e059a961bcb02830280d51f6dd030425c066 jdk7-b66 +a12ea7c7b497b4ba7830550095ef633bd6f43971 jdk7-b67 From d1a146f00347361ef605df6f9c76003872cd0b19 Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 30 Jul 2009 10:58:25 -0700 Subject: [PATCH 50/96] Added tag jdk7-b67 for changeset c8b1b0aecdfe --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index e805fe0c0aa..ad4c8f2596c 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -41,3 +41,4 @@ a88386380bdaaa5ab4ffbedf22c57bac5dbec034 jdk7-b62 ba36394eb84b949b31212bdb32a518a8f92bab5b jdk7-b64 ba313800759b678979434d6da8ed3bf49eb8bea4 jdk7-b65 57c71ad0341b8b64ed20f81151eb7f06324f8894 jdk7-b66 +18f526145aea355a9320b724373386fc2170f183 jdk7-b67 From f0f100555b6cd600e5c230dd0cfcb7d2ecb95922 Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 30 Jul 2009 10:58:30 -0700 Subject: [PATCH 51/96] Added tag jdk7-b67 for changeset 8943b2e74175 --- jaxp/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxp/.hgtags b/jaxp/.hgtags index 9b724960f39..f196582041b 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -41,3 +41,4 @@ ae449e9c04c1fe651bd30f0f4d4cc24ba794e0c4 jdk7-b63 a10eec7a1edf536f39b5828d8623054dbc62c2b7 jdk7-b64 008c662e0ee9a91aebb75e46b97de979083d5c1c jdk7-b65 22f9d5d5b5fe0f47048f41e6c6e54fee5edad0ec jdk7-b66 +a033af8d824a408d3ac602205ecdefc128749e1e jdk7-b67 From a2e3e2663f29f23ddb13605d50656148c89b76ea Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 30 Jul 2009 10:58:31 -0700 Subject: [PATCH 52/96] Added tag jdk7-b67 for changeset d4ab6018e6f6 --- jaxws/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxws/.hgtags b/jaxws/.hgtags index a5dc8fecee0..36dc0d6feff 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -41,3 +41,4 @@ b8a6e883c0a6708f6d818815040525d472262495 jdk7-b63 aaa25dfd3de68c6f1a1d3ef8c45fd99f76bca6dd jdk7-b64 aa22a1be5866a6608ba17a7a443945559409ae0f jdk7-b65 fa8712c099edd5c9a6b3ed9729353738004d388f jdk7-b66 +faa13cd4d6cdcfb155da5ed23b0da6e0ed0f9ea8 jdk7-b67 From f3564aefecd781916417df55c8dc8638a5494d41 Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 30 Jul 2009 10:58:48 -0700 Subject: [PATCH 53/96] Added tag jdk7-b67 for changeset 02ba23f205f3 --- langtools/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/langtools/.hgtags b/langtools/.hgtags index 23d21f876dc..2d35b7fcf82 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -41,3 +41,4 @@ dbdeb4a7581b2a8699644b91cae6793cb01953f7 jdk7-b53 d8f23a81d46f47a4186f1044dd9e44841bbeab84 jdk7-b64 7e0056ded28c802609d2bd79bfcda551d72a3fec jdk7-b65 634f519d6f9a602b16bba1c7cd4a17242a8f6889 jdk7-b66 +14b1a8ede95493fc53c37ff2626f1f98ce94d108 jdk7-b67 From 7bf64229838b7225332570262561d36be6618c37 Mon Sep 17 00:00:00 2001 From: Bradford Wetmore Date: Mon, 3 Aug 2009 18:06:51 -0700 Subject: [PATCH 54/96] 6647452: Remove obfuscation, framework and provider self-verification checking Reviewed-by: valeriep, vinnie --- jdk/make/com/sun/crypto/provider/Makefile | 120 ++++--------- jdk/make/javax/crypto/Defs-jce.gmk | 19 +-- jdk/make/javax/crypto/Makefile | 157 ++++++------------ jdk/make/sun/security/mscapi/Makefile | 32 ++-- jdk/make/sun/security/pkcs11/Makefile | 32 ++-- .../com/sun/crypto/provider/AESCipher.java | 6 +- .../sun/crypto/provider/AESKeyGenerator.java | 11 +- .../sun/crypto/provider/AESWrapCipher.java | 6 +- .../sun/crypto/provider/ARCFOURCipher.java | 3 +- .../sun/crypto/provider/BlowfishCipher.java | 6 +- .../crypto/provider/BlowfishKeyGenerator.java | 11 +- .../com/sun/crypto/provider/DESCipher.java | 6 +- .../sun/crypto/provider/DESKeyFactory.java | 12 +- .../sun/crypto/provider/DESKeyGenerator.java | 11 +- .../com/sun/crypto/provider/DESedeCipher.java | 6 +- .../sun/crypto/provider/DESedeKeyFactory.java | 11 +- .../crypto/provider/DESedeKeyGenerator.java | 11 +- .../sun/crypto/provider/DESedeWrapCipher.java | 6 +- .../sun/crypto/provider/DHKeyAgreement.java | 11 +- .../com/sun/crypto/provider/DHKeyFactory.java | 11 +- .../com/sun/crypto/provider/HmacCore.java | 5 +- .../com/sun/crypto/provider/HmacMD5.java | 10 +- .../crypto/provider/HmacMD5KeyGenerator.java | 11 +- .../crypto/provider/HmacPKCS12PBESHA1.java | 7 +- .../com/sun/crypto/provider/HmacSHA1.java | 10 +- .../crypto/provider/HmacSHA1KeyGenerator.java | 11 +- .../com/sun/crypto/provider/JarVerifier.java | 72 -------- .../sun/crypto/provider/KeyGeneratorCore.java | 7 +- .../sun/crypto/provider/PBEKeyFactory.java | 11 +- .../provider/PBEWithMD5AndDESCipher.java | 9 +- .../PBEWithMD5AndTripleDESCipher.java | 11 +- .../provider/PBKDF2HmacSHA1Factory.java | 11 +- .../crypto/provider/PKCS12PBECipherCore.java | 4 +- .../com/sun/crypto/provider/RC2Cipher.java | 3 +- .../com/sun/crypto/provider/RSACipher.java | 3 +- .../com/sun/crypto/provider/SslMacCore.java | 8 +- .../com/sun/crypto/provider/SunJCE.java | 23 +-- .../provider/TlsKeyMaterialGenerator.java | 3 +- .../provider/TlsMasterSecretGenerator.java | 3 +- .../sun/crypto/provider/TlsPrfGenerator.java | 3 +- .../TlsRsaPremasterSecretGenerator.java | 3 +- .../classes/javax/crypto/JarVerifier.java | 15 +- .../classes/javax/crypto/JceSecurity.java | 8 +- .../sun/security/pkcs11/JarVerifier.java | 72 -------- .../sun/security/pkcs11/SunPKCS11.java | 26 +-- .../sun/security/mscapi/JarVerifier.java | 73 -------- .../sun/security/mscapi/RSACipher.java | 3 +- .../sun/security/mscapi/SunMSCAPI.java | 20 +-- 48 files changed, 172 insertions(+), 761 deletions(-) delete mode 100644 jdk/src/share/classes/com/sun/crypto/provider/JarVerifier.java delete mode 100644 jdk/src/share/classes/sun/security/pkcs11/JarVerifier.java delete mode 100644 jdk/src/windows/classes/sun/security/mscapi/JarVerifier.java diff --git a/jdk/make/com/sun/crypto/provider/Makefile b/jdk/make/com/sun/crypto/provider/Makefile index 5dccb9f81b3..8cf809dc469 100644 --- a/jdk/make/com/sun/crypto/provider/Makefile +++ b/jdk/make/com/sun/crypto/provider/Makefile @@ -1,5 +1,5 @@ # -# Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2007-2009 Sun Microsystems, Inc. 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 @@ -45,54 +45,49 @@ # For OpenJDK, the jar files built here are installed directly into the # OpenJDK. # -# For JDK, the binaries use pre-built/pre-signed/pre-obfuscated binary -# files stored in the closed workspace that are not shipped in the -# OpenJDK workspaces. We still build the JDK files here to verify the -# files compile, and in preparation for possible signing and -# obfuscation. Developers working on JCE in JDK must sign the JCE files -# before testing: obfuscation is optional during development. The JCE -# signing key is kept separate from the JDK workspace to prevent its -# disclosure. The obfuscation tool has not been licensed for general -# usage. -# +# For JDK, the binaries use pre-built/pre-signed binary files stored in +# the closed workspace that are not shipped in the OpenJDK workspaces. +# We still build the JDK files here to verify the files compile, and in +# preparation for possible signing. Developers working on JCE in JDK +# must sign the JCE files before testing. The JCE signing key is kept +# separate from the JDK workspace to prevent its disclosure. +# # SPECIAL NOTE TO JCE/JDK developers: The source files must eventually -# be built, obfuscated, signed, and then the resulting jar files MUST BE -# CHECKED INTO THE CLOSED PART OF THE WORKSPACE*. This separate step -# *MUST NOT BE FORGOTTEN*, otherwise a bug fixed in the source code will -# not be reflected in the shipped binaries. The "release" target should be +# be built and signed, and the resulting jar files MUST BE CHECKED INTO +# THE CLOSED PART OF THE WORKSPACE*. This separate step *MUST NOT BE +# FORGOTTEN*, otherwise a bug fixed in the source code will not be +# reflected in the shipped binaries. The "release" target should be # used to generate the required files. # # There are a number of targets to help both JDK/OpenJDK developers. # # Main Targets (JDK/OPENJDK): # -# all/clobber/clean The usual. -# If OpenJDK, installs sunjce_provider.jar. -# If JDK, installs prebuilt -# sunjce_provider.jar. +# all/clobber/clean The usual. +# If OpenJDK, installs sunjce_provider.jar. +# If JDK, installs prebuilt +# sunjce_provider.jar. # -# jar Builds/installs sunjce_provider.jar -# If OpenJDK, does not sign. -# If JDK, tries to sign. +# jar Builds/installs sunjce_provider.jar +# If OpenJDK, does not sign. +# If JDK, tries to sign. # # Other lesser-used Targets (JDK/OPENJDK): # -# build-jar Builds sunjce_provider.jar -# (does not sign/install) +# build-jar Builds sunjce_provider.jar +# (does not sign/install) # -# install-jar Alias for "jar" above. +# install-jar Alias for "jar" above. # # Other targets (JDK only): # -# sign Alias for sign-jar -# sign-jar Builds/signs sunjce_provider.jar (no install) +# sign Alias for sign-jar +# sign-jar Builds/signs sunjce_provider.jar (no install) # -# obfus Builds/obfuscates/signs sunjce_provider.jar +# release Builds all targets in preparation +# for workspace integration. # -# release Builds all targets in preparation -# for workspace integration. -# -# install-prebuilt Installs the pre-built jar files +# install-prebuilt Installs the pre-built jar files # # This makefile was written to support parallel target execution. # @@ -103,7 +98,7 @@ PRODUCT = sun # # The following is for when we need to do postprocessing -# (signing/obfuscation) against a read-only build. If the OUTPUTDIR +# (signing) against a read-only build. If the OUTPUTDIR # isn't writable, the build currently crashes out. # ifndef OPENJDK @@ -158,8 +153,8 @@ endif # OPENJDK # # We use a variety of subdirectories in the $(TEMPDIR) depending on what # part of the build we're doing. Both OPENJDK/JDK builds are initially -# done in the unsigned area. When files are signed or obfuscated in JDK, -# they will be placed in the appropriate areas. +# done in the unsigned area. When files are signed in JDK, they will be +# placed in the appropriate areas. # UNSIGNED_DIR = $(TEMPDIR)/unsigned @@ -223,62 +218,15 @@ $(SIGNED_DIR)/sunjce_provider.jar: endif $(call sign-file, $(UNSIGNED_DIR)/sunjce_provider.jar) -# ===================================================== -# Obfuscate/sign/install the JDK build. Not needed for OpenJDK. -# - -OBFUS_DIR = $(JCE_BUILD_DIR)/obfus/sunjce - -CLOSED_DIR = $(BUILDDIR)/closed/com/sun/crypto/provider - -obfus: $(OBFUS_DIR)/sunjce_provider.jar - $(release-warning) - -ifndef ALT_JCE_BUILD_DIR -$(OBFUS_DIR)/sunjce_provider.jar: build-jar $(JCE_MANIFEST_FILE) \ - $(OBFUS_DIR)/sunjce.dox -else -$(OBFUS_DIR)/sunjce_provider.jar: $(JCE_MANIFEST_FILE) $(OBFUS_DIR)/sunjce.dox - @if [ ! -d $(CLASSDESTDIR) ] ; then \ - $(ECHO) "Couldn't find $(CLASSDESTDIR)"; \ - exit 1; \ - fi -endif - @$(ECHO) ">>>Obfuscating SunJCE Provider..." - $(presign) - $(preobfus) - $(prep-target) - $(CD) $(OBFUS_DIR); \ - $(OBFUSCATOR) -fv sunjce.dox - @$(CD) $(OBFUS_DIR); $(java-vm-cleanup) - $(BOOT_JAR_CMD) cmf $(JCE_MANIFEST_FILE) $@ \ - -C $(OBFUS_DIR)/build com \ - $(BOOT_JAR_JFLAGS) - $(sign-target) - @$(java-vm-cleanup) - -$(OBFUS_DIR)/sunjce.dox: $(CLOSED_DIR)/obfus/sunjce.dox - @$(ECHO) ">>>Creating sunjce.dox" - $(prep-target) - $(SED) "s:@@TEMPDIR@@:$(ABS_TEMPDIR):" $< > $@ - -# -# The current obfuscator has a limitation in that it currently only -# supports up to v49 class file format. Force v49 classfiles in our -# builds for now. -# -SOURCE_LANGUAGE_VERSION = 5 -TARGET_CLASS_VERSION = 5 - # ===================================================== -# Create the Release Engineering files. Obfuscated builds, etc. +# Create the Release Engineering files. Signed builds, etc. # -release: $(OBFUS_DIR)/sunjce_provider.jar +release: $(SIGNED_DIR)/sunjce_provider.jar $(RM) $(JCE_BUILD_DIR)/release/sunjce_provider.jar $(MKDIR) -p $(JCE_BUILD_DIR)/release - $(CP) $(OBFUS_DIR)/sunjce_provider.jar $(JCE_BUILD_DIR)/release + $(CP) $(SIGNED_DIR)/sunjce_provider.jar $(JCE_BUILD_DIR)/release $(release-warning) endif # OPENJDK @@ -320,5 +268,5 @@ clobber clean:: .PHONY: build-jar jar install-jar ifndef OPENJDK -.PHONY: sign sign-jar obfus release install-prebuilt +.PHONY: sign sign-jar release install-prebuilt endif diff --git a/jdk/make/javax/crypto/Defs-jce.gmk b/jdk/make/javax/crypto/Defs-jce.gmk index 46fe1118dca..0b75bceb984 100644 --- a/jdk/make/javax/crypto/Defs-jce.gmk +++ b/jdk/make/javax/crypto/Defs-jce.gmk @@ -1,5 +1,5 @@ # -# Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2007-2009 Sun Microsystems, Inc. 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 @@ -61,7 +61,7 @@ SIGNING_PASSPHRASE = $(SIGNING_KEY_DIR)/passphrase.txt SIGNING_ALIAS = jce_rsa # -# Defines for signing/obfuscating the various jar files. +# Defines for signing the various jar files. # define presign @@ -100,19 +100,4 @@ define sign-file $(sign-target) endef -# -# Location for the Obfuscation product. JDK currently has -# the requirement that we obfuscate our JCE jars. -# -OBFUSCATOR = /security/tools/bin/obfus -OBFUS_DIR = $(TEMPDIR)/obfus - -define preobfus - @if [ ! -f $(OBFUSCATOR) ]; then \ - $(ECHO) "\n$(OBFUSCATOR): Obfuscator *NOT* available..." \ - $(README-MAKEFILE_WARNING); \ - exit 2; \ - fi -endef - endif # !OPENJDK diff --git a/jdk/make/javax/crypto/Makefile b/jdk/make/javax/crypto/Makefile index 815a530ce27..fe07ed5edf7 100644 --- a/jdk/make/javax/crypto/Makefile +++ b/jdk/make/javax/crypto/Makefile @@ -1,5 +1,5 @@ # -# Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2007-2009 Sun Microsystems, Inc. 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 @@ -44,64 +44,65 @@ # For OpenJDK, the jar files built here are installed directly into the # OpenJDK. # -# For JDK, the binaries use pre-built/pre-signed/pre-obfuscated binary -# files stored in the closed workspace that are not shipped in the -# OpenJDK workspaces. We still build the JDK files here to verify the -# files compile, and in preparation for possible signing and -# obfuscation. Developers working on JCE in JDK must sign the JCE files -# before testing: obfuscation is optional during development. The JCE -# signing key is kept separate from the JDK workspace to prevent its -# disclosure. The obfuscation tool has not been licensed for general -# usage. +# For JDK, the binaries use pre-built/pre-signed binary files stored in +# the closed workspace that are not shipped in the OpenJDK workspaces. +# We still build the JDK files here to verify the files compile, and in +# preparation for possible signing. Developers working on JCE in JDK +# must sign the JCE files before testing. The JCE signing key is kept +# separate from the JDK workspace to prevent its disclosure. # # SPECIAL NOTE TO JCE/JDK developers: The source files must eventually -# be built, obfuscated, signed, and the resulting jar files *MUST BE -# CHECKED INTO THE CLOSED PART OF THE WORKSPACE*. This separate step -# *MUST NOT BE FORGOTTEN*, otherwise a bug fixed in the source code will -# not be reflected in the shipped binaries. The "release" target should -# be used to generate the required files. +# be built and signed, and the resulting jar files *MUST BE CHECKED INTO +# THE CLOSED PART OF THE WORKSPACE*. This separate step *MUST NOT BE +# FORGOTTEN*, otherwise a bug fixed in the source code will not be +# reflected in the shipped binaries. The "release" target should be +# used to generate the required files. # # There are a number of targets to help both JDK/OpenJDK developers. # # Main Targets (JDK/OPENJDK): # -# all/clobber/clean The usual. -# If OpenJDK, installs -# jce.jar/limited policy files. -# If JDK, installs prebuilt -# jce.jar/limited policy files. +# all/clobber/clean The usual. +# If OpenJDK: builds/installs the +# jce.jar/limited policy files. +# If JDK: builds but does not install. +# During full tops-down builds, +# prebuilt/presigned jce.jar & +# limited policy files are copied +# in by make/java/redist/Makefile. +# If you are working in this directory +# and want to install the prebuilts, +# use the "install-prebuilt" target. # -# jar Builds/installs jce.jar -# If OpenJDK, does not sign -# If JDK, tries to sign +# jar Builds/installs jce.jar +# If OpenJDK, does not sign +# If JDK, tries to sign # # Other lesser-used Targets (JDK/OPENJDK): # -# build-jar Builds jce.jar (does not sign/install) +# build-jar Builds jce.jar (does not sign/install) # -# build-policy Builds policy files (does not sign/install) +# build-policy Builds policy files (does not sign/install) # -# install-jar Alias for "jar" above +# install-jar Alias for "jar" above # -# install-limited Builds/installs limited policy files -# If OpenJDK, does not sign -# If JDK, tries to sign -# install-unlimited Builds/nstalls unlimited policy files -# If OpenJDK, does not sign -# If JDK, tries to sign +# install-limited Builds/installs limited policy files +# If OpenJDK, does not sign +# If JDK, tries to sign +# install-unlimited Builds/nstalls unlimited policy files +# If OpenJDK, does not sign +# If JDK, tries to sign # # Other targets (JDK only): # -# sign Alias for sign-jar and sign-policy -# sign-jar Builds/signs jce.jar file (no install) -# sign-policy Builds/signs policy files (no install) +# sign Alias for sign-jar and sign-policy +# sign-jar Builds/signs jce.jar file (no install) +# sign-policy Builds/signs policy files (no install) # -# obfus Builds/obfuscates/signs jce.jar +# release Builds all targets in preparation +# for workspace integration. # -# release Builds all targets in preparation -# for workspace integration. -# -# install-prebuilt Installs the pre-built jar files +# install-prebuilt Installs the pre-built jar files # # This makefile was written to support parallel target execution. # @@ -112,7 +113,7 @@ PRODUCT = sun # # The following is for when we need to do postprocessing -# (signing/obfuscation) against a read-only build. If the OUTPUTDIR +# (signing) against a read-only build. If the OUTPUTDIR # isn't writable, the build currently crashes out. # ifndef OPENJDK @@ -169,8 +170,8 @@ endif # OPENJDK # # We use a variety of subdirectories in the $(TEMPDIR) depending on what # part of the build we're doing. Both OPENJDK/JDK builds are initially -# done in the unsigned area. When files are signed or obfuscated in JDK, -# they will be placed in the appropriate areas. +# done in the unsigned area. When files are signed in JDK, they will be +# placed in the appropriate areas. # UNSIGNED_DIR = $(TEMPDIR)/unsigned @@ -178,7 +179,7 @@ include Defs-jce.gmk # ===================================================== -# Build the unsigned jce.jar file. Signing/obfuscation comes later. +# Build the unsigned jce.jar file. Signing comes later. # JAR_DESTFILE = $(LIBDIR)/jce.jar @@ -363,69 +364,13 @@ $(SIGNED_POLICY_BUILDDIR)/limited/local_policy.jar: \ # ===================================================== -# Obfuscate/sign/install the JDK build. Not needed for OpenJDK. -# - -OBFUS_DIR = $(JCE_BUILD_DIR)/obfus/jce - -CLOSED_DIR = $(BUILDDIR)/closed/javax/crypto - -obfus: $(OBFUS_DIR)/jce.jar - $(release-warning) - -ifndef ALT_JCE_BUILD_DIR -$(OBFUS_DIR)/jce.jar: build-jar $(JCE_MANIFEST_FILE) $(OBFUS_DIR)/framework.dox -else -# -# We have to remove the build dependency, otherwise, we'll try to rebuild it -# which we can't do on a read-only filesystem. -# -$(OBFUS_DIR)/jce.jar: $(JCE_MANIFEST_FILE) $(OBFUS_DIR)/framework.dox - @if [ ! -d $(CLASSDESTDIR) ] ; then \ - $(ECHO) "Couldn't find $(CLASSDESTDIR)"; \ - exit 1; \ - fi -endif - @$(ECHO) ">>>Obfuscating JCE framework..." - $(presign) - $(preobfus) - $(prep-target) - $(CD) $(OBFUS_DIR); \ - $(OBFUSCATOR) -fv framework.dox - @$(CD) $(OBFUS_DIR); $(java-vm-cleanup) - @# - @# The sun.security.internal classes are currently not obfuscated - @# due to an obfus problem. Manually copy them to the build directory - @# so that they are included in the jce.jar file. - @# - $(CP) -r $(CLASSDESTDIR)/sun $(OBFUS_DIR)/build - $(BOOT_JAR_CMD) cmf $(JCE_MANIFEST_FILE) $@ \ - -C $(OBFUS_DIR)/build javax \ - -C $(OBFUS_DIR)/build sun \ - $(BOOT_JAR_JFLAGS) - $(sign-target) - @$(java-vm-cleanup) - -$(OBFUS_DIR)/framework.dox: $(CLOSED_DIR)/obfus/framework.dox - @$(ECHO) ">>>Creating framework.dox" - $(prep-target) - $(SED) "s:@@TEMPDIR@@:$(ABS_TEMPDIR):" $< > $@ - -# -# The current obfuscator has a limitation in that it currently only -# supports up to v49 class file format. Force v49 classfiles in our -# builds for now. -# -SOURCE_LANGUAGE_VERSION = 5 -TARGET_CLASS_VERSION = 5 - - -# ===================================================== -# Create the Release Engineering files. Obfuscated builds, +# Create the Release Engineering files. Signed builds, # unlimited policy file distribution, etc. # -release: $(OBFUS_DIR)/jce.jar sign-policy $(CLOSED_DIR)/doc/COPYRIGHT.html \ +CLOSED_DIR = $(BUILDDIR)/closed/javax/crypto + +release: $(SIGNED_DIR)/jce.jar sign-policy $(CLOSED_DIR)/doc/COPYRIGHT.html \ $(CLOSED_DIR)/doc/README.txt $(RM) -r \ $(JCE_BUILD_DIR)/release/UnlimitedJCEPolicy \ @@ -434,7 +379,7 @@ release: $(OBFUS_DIR)/jce.jar sign-policy $(CLOSED_DIR)/doc/COPYRIGHT.html \ $(JCE_BUILD_DIR)/release/local_policy.jar \ $(JCE_BUILD_DIR)/release/UnlimitedJCEPolicy.zip $(MKDIR) -p $(JCE_BUILD_DIR)/release/UnlimitedJCEPolicy - $(CP) $(OBFUS_DIR)/jce.jar $(JCE_BUILD_DIR)/release + $(CP) $(SIGNED_DIR)/jce.jar $(JCE_BUILD_DIR)/release $(CP) \ $(SIGNED_POLICY_BUILDDIR)/limited/US_export_policy.jar \ $(SIGNED_POLICY_BUILDDIR)/limited/local_policy.jar \ @@ -530,5 +475,5 @@ clobber clean:: .PHONY: build-jar jar build-policy unlimited limited install-jar \ install-limited install-unlimited ifndef OPENJDK -.PHONY: sign sign-jar sign-policy obfus release install-prebuilt +.PHONY: sign sign-jar sign-policy release install-prebuilt endif diff --git a/jdk/make/sun/security/mscapi/Makefile b/jdk/make/sun/security/mscapi/Makefile index 08d6609e166..c16d130504f 100644 --- a/jdk/make/sun/security/mscapi/Makefile +++ b/jdk/make/sun/security/mscapi/Makefile @@ -1,5 +1,5 @@ # -# Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2005-2009 Sun Microsystems, Inc. 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 @@ -59,31 +59,31 @@ # # Main Targets (JDK/OPENJDK): # -# all/clobber/clean The usual, plus the native libraries. -# If OpenJDK, installs sunmscapi.jar. -# If JDK, installs prebuilt -# sunmscapi.jar. +# all/clobber/clean The usual, plus the native libraries. +# If OpenJDK, installs sunmscapi.jar. +# If JDK, installs prebuilt +# sunmscapi.jar. # -# jar Builds/installs sunmscapi.jar -# If OpenJDK, does not sign. -# If JDK, tries to sign. +# jar Builds/installs sunmscapi.jar +# If OpenJDK, does not sign. +# If JDK, tries to sign. # # Other lesser-used Targets (JDK/OPENJDK): # -# build-jar Builds sunmscapi.jar -# (does not sign/install) +# build-jar Builds sunmscapi.jar +# (does not sign/install) # -# install-jar Alias for "jar" above. +# install-jar Alias for "jar" above. # # Other targets (JDK only): # -# sign Alias for sign-jar -# sign-jar Builds/signs sunmscapi.jar (no install) +# sign Alias for sign-jar +# sign-jar Builds/signs sunmscapi.jar (no install) # -# release Builds all targets in preparation -# for workspace integration. +# release Builds all targets in preparation +# for workspace integration. # -# install-prebuilt Installs the pre-built jar files +# install-prebuilt Installs the pre-built jar files # # This makefile was written to support parallel target execution. # diff --git a/jdk/make/sun/security/pkcs11/Makefile b/jdk/make/sun/security/pkcs11/Makefile index f20910b7ed2..9a4a4089be4 100644 --- a/jdk/make/sun/security/pkcs11/Makefile +++ b/jdk/make/sun/security/pkcs11/Makefile @@ -1,5 +1,5 @@ # -# Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2003-2009 Sun Microsystems, Inc. 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 @@ -59,31 +59,31 @@ # # Main Targets (JDK/OPENJDK): # -# all/clobber/clean The usual, plus the native libraries. -# If OpenJDK, installs sunpkcs11.jar. -# If JDK, installs prebuilt -# sunpkcs11.jar. +# all/clobber/clean The usual, plus the native libraries. +# If OpenJDK, installs sunpkcs11.jar. +# If JDK, installs prebuilt +# sunpkcs11.jar. # -# jar Builds/installs sunpkcs11.jar -# If OpenJDK, does not sign. -# If JDK, tries to sign. +# jar Builds/installs sunpkcs11.jar +# If OpenJDK, does not sign. +# If JDK, tries to sign. # # Other lesser-used Targets (JDK/OPENJDK): # -# build-jar Builds sunpkcs11.jar -# (does not sign/install) +# build-jar Builds sunpkcs11.jar +# (does not sign/install) # -# install-jar Alias for "jar" above. +# install-jar Alias for "jar" above. # # Other targets (JDK only): # -# sign Alias for sign-jar -# sign-jar Builds/signs sunpkcs11.jar (no install) +# sign Alias for sign-jar +# sign-jar Builds/signs sunpkcs11.jar (no install) # -# release Builds all targets in preparation -# for workspace integration. +# release Builds all targets in preparation +# for workspace integration. # -# install-prebuilt Installs the pre-built jar files +# install-prebuilt Installs the pre-built jar files # # This makefile was written to support parallel target execution. # diff --git a/jdk/src/share/classes/com/sun/crypto/provider/AESCipher.java b/jdk/src/share/classes/com/sun/crypto/provider/AESCipher.java index 1809f6d82ae..1d58e21edd0 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/AESCipher.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/AESCipher.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2009 Sun Microsystems, Inc. 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 @@ -56,12 +56,8 @@ public final class AESCipher extends CipherSpi { /** * Creates an instance of AES cipher with default ECB mode and * PKCS5Padding. - * - * @exception SecurityException if this constructor fails to verify - * its own integrity */ public AESCipher() { - SunJCE.ensureIntegrity(getClass()); core = new CipherCore(new AESCrypt(), AESConstants.AES_BLOCK_SIZE); } diff --git a/jdk/src/share/classes/com/sun/crypto/provider/AESKeyGenerator.java b/jdk/src/share/classes/com/sun/crypto/provider/AESKeyGenerator.java index d6a715d8e55..83cf3223d75 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/AESKeyGenerator.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/AESKeyGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2009 Sun Microsystems, Inc. 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 @@ -48,16 +48,9 @@ public final class AESKeyGenerator extends KeyGeneratorSpi { private int keySize = 16; // default keysize (in number of bytes) /** - * Verify the SunJCE provider in the constructor. - * - * @exception SecurityException if fails to verify - * its own integrity + * Empty constructor. */ public AESKeyGenerator() { - if (!SunJCE.verifySelfIntegrity(this.getClass())) { - throw new SecurityException("The SunJCE provider may have " + - "been tampered."); - } } /** diff --git a/jdk/src/share/classes/com/sun/crypto/provider/AESWrapCipher.java b/jdk/src/share/classes/com/sun/crypto/provider/AESWrapCipher.java index 5bdcb135442..501e2b69936 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/AESWrapCipher.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/AESWrapCipher.java @@ -1,5 +1,5 @@ /* - * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2004-2009 Sun Microsystems, Inc. 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 @@ -65,12 +65,8 @@ public final class AESWrapCipher extends CipherSpi { /** * Creates an instance of AES KeyWrap cipher with default * mode, i.e. "ECB" and padding scheme, i.e. "NoPadding". - * - * @exception SecurityException if this constructor fails to verify - * its own integrity */ public AESWrapCipher() { - SunJCE.ensureIntegrity(getClass()); cipher = new AESCrypt(); } diff --git a/jdk/src/share/classes/com/sun/crypto/provider/ARCFOURCipher.java b/jdk/src/share/classes/com/sun/crypto/provider/ARCFOURCipher.java index 5876a45dbb3..62affa324b6 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/ARCFOURCipher.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/ARCFOURCipher.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2009 Sun Microsystems, Inc. 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 @@ -62,7 +62,6 @@ public final class ARCFOURCipher extends CipherSpi { // called by the JCE framework public ARCFOURCipher() { - SunJCE.ensureIntegrity(getClass()); S = new int[256]; } diff --git a/jdk/src/share/classes/com/sun/crypto/provider/BlowfishCipher.java b/jdk/src/share/classes/com/sun/crypto/provider/BlowfishCipher.java index 2b5f0fb7300..14d049f8037 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/BlowfishCipher.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/BlowfishCipher.java @@ -1,5 +1,5 @@ /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2009 Sun Microsystems, Inc. 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 @@ -60,12 +60,8 @@ public final class BlowfishCipher extends CipherSpi { /** * Creates an instance of Blowfish cipher with default ECB mode and * PKCS5Padding. - * - * @exception SecurityException if this constructor fails to verify - * its own integrity */ public BlowfishCipher() { - SunJCE.ensureIntegrity(getClass()); core = new CipherCore(new BlowfishCrypt(), BlowfishConstants.BLOWFISH_BLOCK_SIZE); } diff --git a/jdk/src/share/classes/com/sun/crypto/provider/BlowfishKeyGenerator.java b/jdk/src/share/classes/com/sun/crypto/provider/BlowfishKeyGenerator.java index 2d8fb85c420..96a2c7186e3 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/BlowfishKeyGenerator.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/BlowfishKeyGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2009 Sun Microsystems, Inc. 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 @@ -46,16 +46,9 @@ public final class BlowfishKeyGenerator extends KeyGeneratorSpi { private int keysize = 16; // default keysize (in number of bytes) /** - * Verify the SunJCE provider in the constructor. - * - * @exception SecurityException if fails to verify - * its own integrity + * Empty constructor */ public BlowfishKeyGenerator() { - if (!SunJCE.verifySelfIntegrity(this.getClass())) { - throw new SecurityException("The SunJCE provider may have " + - "been tampered."); - } } /** diff --git a/jdk/src/share/classes/com/sun/crypto/provider/DESCipher.java b/jdk/src/share/classes/com/sun/crypto/provider/DESCipher.java index 07ddf318ff2..30f36f3b982 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/DESCipher.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/DESCipher.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2009 Sun Microsystems, Inc. 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 @@ -56,12 +56,8 @@ public final class DESCipher extends CipherSpi { /** * Creates an instance of DES cipher with default ECB mode and * PKCS5Padding. - * - * @exception SecurityException if this constructor fails to verify - * its own integrity */ public DESCipher() { - SunJCE.ensureIntegrity(getClass()); core = new CipherCore(new DESCrypt(), DESConstants.DES_BLOCK_SIZE); } diff --git a/jdk/src/share/classes/com/sun/crypto/provider/DESKeyFactory.java b/jdk/src/share/classes/com/sun/crypto/provider/DESKeyFactory.java index 3ffa89d996c..968d6f78f43 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/DESKeyFactory.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/DESKeyFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2009 Sun Microsystems, Inc. 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 @@ -42,17 +42,11 @@ import java.security.spec.InvalidKeySpecException; public final class DESKeyFactory extends SecretKeyFactorySpi { /** - * Verify the SunJCE provider in the constructor. - * - * @exception SecurityException if fails to verify - * its own integrity + * Empty constructor */ public DESKeyFactory() { - if (!SunJCE.verifySelfIntegrity(this.getClass())) { - throw new SecurityException("The SunJCE provider may have " + - "been tampered."); - } } + /** * Generates a SecretKey object from the provided key * specification (key material). diff --git a/jdk/src/share/classes/com/sun/crypto/provider/DESKeyGenerator.java b/jdk/src/share/classes/com/sun/crypto/provider/DESKeyGenerator.java index 2a7ac8e0771..cd028d4ac73 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/DESKeyGenerator.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/DESKeyGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2009 Sun Microsystems, Inc. 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 @@ -46,16 +46,9 @@ public final class DESKeyGenerator extends KeyGeneratorSpi { private SecureRandom random = null; /** - * Verify the SunJCE provider in the constructor. - * - * @exception SecurityException if fails to verify - * its own integrity + * Empty constructor */ public DESKeyGenerator() { - if (!SunJCE.verifySelfIntegrity(this.getClass())) { - throw new SecurityException("The SunJCE provider may have " + - "been tampered."); - } } /** diff --git a/jdk/src/share/classes/com/sun/crypto/provider/DESedeCipher.java b/jdk/src/share/classes/com/sun/crypto/provider/DESedeCipher.java index 1514f44eddb..394a784215a 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/DESedeCipher.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/DESedeCipher.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2009 Sun Microsystems, Inc. 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 @@ -53,12 +53,8 @@ public final class DESedeCipher extends CipherSpi { /** * Creates an instance of DESede cipher with default ECB mode and * PKCS5Padding. - * - * @exception SecurityException if this constructor fails to verify - * its own integrity */ public DESedeCipher() { - SunJCE.ensureIntegrity(getClass()); core = new CipherCore(new DESedeCrypt(), DESConstants.DES_BLOCK_SIZE); } diff --git a/jdk/src/share/classes/com/sun/crypto/provider/DESedeKeyFactory.java b/jdk/src/share/classes/com/sun/crypto/provider/DESedeKeyFactory.java index 831ca8cd7ad..fcd619b7af6 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/DESedeKeyFactory.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/DESedeKeyFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2009 Sun Microsystems, Inc. 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 @@ -42,16 +42,9 @@ import java.security.spec.InvalidKeySpecException; public final class DESedeKeyFactory extends SecretKeyFactorySpi { /** - * Verify the SunJCE provider in the constructor. - * - * @exception SecurityException if fails to verify - * its own integrity + * Empty constructor */ public DESedeKeyFactory() { - if (!SunJCE.verifySelfIntegrity(this.getClass())) { - throw new SecurityException("The SunJCE provider may have been " + - "tampered."); - } } /** diff --git a/jdk/src/share/classes/com/sun/crypto/provider/DESedeKeyGenerator.java b/jdk/src/share/classes/com/sun/crypto/provider/DESedeKeyGenerator.java index 439c8facc91..333375e3edb 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/DESedeKeyGenerator.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/DESedeKeyGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2009 Sun Microsystems, Inc. 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 @@ -47,16 +47,9 @@ public final class DESedeKeyGenerator extends KeyGeneratorSpi { private int keysize = 168; /** - * Verify the SunJCE provider in the constructor. - * - * @exception SecurityException if fails to verify - * its own integrity + * Empty constructor */ public DESedeKeyGenerator() { - if (!SunJCE.verifySelfIntegrity(this.getClass())) { - throw new SecurityException("The SunJCE provider may have been " + - "tampered."); - } } /** diff --git a/jdk/src/share/classes/com/sun/crypto/provider/DESedeWrapCipher.java b/jdk/src/share/classes/com/sun/crypto/provider/DESedeWrapCipher.java index 48cbb1edbc3..c3a36d1e9ce 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/DESedeWrapCipher.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/DESedeWrapCipher.java @@ -1,5 +1,5 @@ /* - * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2004-2009 Sun Microsystems, Inc. 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 @@ -74,12 +74,8 @@ public final class DESedeWrapCipher extends CipherSpi { /** * Creates an instance of CMS DESede KeyWrap cipher with default * mode, i.e. "CBC" and padding scheme, i.e. "NoPadding". - * - * @exception SecurityException if this constructor fails to verify - * its own integrity. */ public DESedeWrapCipher() { - SunJCE.ensureIntegrity(getClass()); cipher = new CipherBlockChaining(new DESedeCrypt()); } diff --git a/jdk/src/share/classes/com/sun/crypto/provider/DHKeyAgreement.java b/jdk/src/share/classes/com/sun/crypto/provider/DHKeyAgreement.java index 30bec726117..e2a3cf08daf 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/DHKeyAgreement.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/DHKeyAgreement.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2009 Sun Microsystems, Inc. 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 @@ -58,16 +58,9 @@ extends KeyAgreementSpi { private BigInteger y = BigInteger.ZERO; /** - * Verify the SunJCE provider in the constructor. - * - * @exception SecurityException if fails to verify - * its own integrity + * Empty constructor */ public DHKeyAgreement() { - if (!SunJCE.verifySelfIntegrity(this.getClass())) { - throw new SecurityException("The SunJCE provider may have been " + - "tampered."); - } } /** diff --git a/jdk/src/share/classes/com/sun/crypto/provider/DHKeyFactory.java b/jdk/src/share/classes/com/sun/crypto/provider/DHKeyFactory.java index e7c5f53b4d4..01a449c6a2f 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/DHKeyFactory.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/DHKeyFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2009 Sun Microsystems, Inc. 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 @@ -49,16 +49,9 @@ import javax.crypto.spec.DHParameterSpec; public final class DHKeyFactory extends KeyFactorySpi { /** - * Verify the SunJCE provider in the constructor. - * - * @exception SecurityException if fails to verify - * its own integrity + * Empty constructor */ public DHKeyFactory() { - if (!SunJCE.verifySelfIntegrity(this.getClass())) { - throw new SecurityException("The SunJCE provider may have " + - "been tampered."); - } } /** diff --git a/jdk/src/share/classes/com/sun/crypto/provider/HmacCore.java b/jdk/src/share/classes/com/sun/crypto/provider/HmacCore.java index 9950d112ff1..87d9e04bc0e 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/HmacCore.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/HmacCore.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2009 Sun Microsystems, Inc. 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 @@ -241,7 +241,6 @@ final class HmacCore implements Cloneable { public static final class HmacSHA256 extends MacSpi implements Cloneable { private final HmacCore core; public HmacSHA256() throws NoSuchAlgorithmException { - SunJCE.ensureIntegrity(getClass()); core = new HmacCore("SHA-256", 64); } private HmacSHA256(HmacSHA256 base) throws CloneNotSupportedException { @@ -278,7 +277,6 @@ final class HmacCore implements Cloneable { public static final class HmacSHA384 extends MacSpi implements Cloneable { private final HmacCore core; public HmacSHA384() throws NoSuchAlgorithmException { - SunJCE.ensureIntegrity(getClass()); core = new HmacCore("SHA-384", 128); } private HmacSHA384(HmacSHA384 base) throws CloneNotSupportedException { @@ -315,7 +313,6 @@ final class HmacCore implements Cloneable { public static final class HmacSHA512 extends MacSpi implements Cloneable { private final HmacCore core; public HmacSHA512() throws NoSuchAlgorithmException { - SunJCE.ensureIntegrity(getClass()); core = new HmacCore("SHA-512", 128); } private HmacSHA512(HmacSHA512 base) throws CloneNotSupportedException { diff --git a/jdk/src/share/classes/com/sun/crypto/provider/HmacMD5.java b/jdk/src/share/classes/com/sun/crypto/provider/HmacMD5.java index 26e76389d4f..ce3793c917a 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/HmacMD5.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/HmacMD5.java @@ -1,5 +1,5 @@ /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2009 Sun Microsystems, Inc. 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 @@ -44,16 +44,8 @@ public final class HmacMD5 extends MacSpi implements Cloneable { /** * Standard constructor, creates a new HmacMD5 instance. - * Verify the SunJCE provider in the constructor. - * - * @exception SecurityException if fails to verify - * its own integrity */ public HmacMD5() throws NoSuchAlgorithmException { - if (!SunJCE.verifySelfIntegrity(this.getClass())) { - throw new SecurityException("The SunJCE provider may have " + - "been tampered."); - } hmac = new HmacCore(MessageDigest.getInstance("MD5"), MD5_BLOCK_LENGTH); } diff --git a/jdk/src/share/classes/com/sun/crypto/provider/HmacMD5KeyGenerator.java b/jdk/src/share/classes/com/sun/crypto/provider/HmacMD5KeyGenerator.java index c1b65264571..1f73f32c7e9 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/HmacMD5KeyGenerator.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/HmacMD5KeyGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2009 Sun Microsystems, Inc. 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 @@ -46,16 +46,9 @@ public final class HmacMD5KeyGenerator extends KeyGeneratorSpi { private int keysize = 64; // default keysize (in number of bytes) /** - * Verify the SunJCE provider in the constructor. - * - * @exception SecurityException if fails to verify - * its own integrity + * Empty constructor */ public HmacMD5KeyGenerator() { - if (!SunJCE.verifySelfIntegrity(this.getClass())) { - throw new SecurityException("The SunJCE provider may have " + - "been tampered."); - } } /** diff --git a/jdk/src/share/classes/com/sun/crypto/provider/HmacPKCS12PBESHA1.java b/jdk/src/share/classes/com/sun/crypto/provider/HmacPKCS12PBESHA1.java index 150477c5ea1..4508c242e96 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/HmacPKCS12PBESHA1.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/HmacPKCS12PBESHA1.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2009 Sun Microsystems, Inc. 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 @@ -48,13 +48,8 @@ public final class HmacPKCS12PBESHA1 extends MacSpi implements Cloneable { /** * Standard constructor, creates a new HmacSHA1 instance. - * Verify the SunJCE provider in the constructor. - * - * @exception SecurityException if fails to verify - * its own integrity */ public HmacPKCS12PBESHA1() throws NoSuchAlgorithmException { - SunJCE.ensureIntegrity(this.getClass()); this.hmac = new HmacCore(MessageDigest.getInstance("SHA1"), SHA1_BLOCK_LENGTH); } diff --git a/jdk/src/share/classes/com/sun/crypto/provider/HmacSHA1.java b/jdk/src/share/classes/com/sun/crypto/provider/HmacSHA1.java index 1421e855b9b..0b4bea2c7f7 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/HmacSHA1.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/HmacSHA1.java @@ -1,5 +1,5 @@ /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2009 Sun Microsystems, Inc. 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 @@ -44,16 +44,8 @@ public final class HmacSHA1 extends MacSpi implements Cloneable { /** * Standard constructor, creates a new HmacSHA1 instance. - * Verify the SunJCE provider in the constructor. - * - * @exception SecurityException if fails to verify - * its own integrity */ public HmacSHA1() throws NoSuchAlgorithmException { - if (!SunJCE.verifySelfIntegrity(this.getClass())) { - throw new SecurityException("The SunJCE provider may have " + - "been tampered."); - } this.hmac = new HmacCore(MessageDigest.getInstance("SHA1"), SHA1_BLOCK_LENGTH); } diff --git a/jdk/src/share/classes/com/sun/crypto/provider/HmacSHA1KeyGenerator.java b/jdk/src/share/classes/com/sun/crypto/provider/HmacSHA1KeyGenerator.java index 561e4f1593c..2bf214280ce 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/HmacSHA1KeyGenerator.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/HmacSHA1KeyGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2009 Sun Microsystems, Inc. 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 @@ -46,16 +46,9 @@ public final class HmacSHA1KeyGenerator extends KeyGeneratorSpi { private int keysize = 64; // default keysize (in number of bytes) /** - * Verify the SunJCE provider in the constructor. - * - * @exception SecurityException if fails to verify - * its own integrity + * Empty constructor */ public HmacSHA1KeyGenerator() { - if (!SunJCE.verifySelfIntegrity(this.getClass())) { - throw new SecurityException("The SunJCE provider may have " + - "been tampered."); - } } /** diff --git a/jdk/src/share/classes/com/sun/crypto/provider/JarVerifier.java b/jdk/src/share/classes/com/sun/crypto/provider/JarVerifier.java deleted file mode 100644 index ea5f856955a..00000000000 --- a/jdk/src/share/classes/com/sun/crypto/provider/JarVerifier.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2007 Sun Microsystems, Inc. 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. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package com.sun.crypto.provider; - -// NOTE: this class is duplicated amongst SunJCE, SunPKCS11, and SunMSCAPI. -// All files should be kept in sync. - -import java.io.*; -import java.util.*; -import java.util.jar.*; -import java.net.URL; -import java.net.JarURLConnection; -import java.net.MalformedURLException; - -import java.security.*; -import java.security.cert.*; -import java.security.cert.Certificate; - -/** - * This class verifies JAR files (and any supporting JAR files), and - * determines whether they may be used in this implementation. - * - * The JCE in OpenJDK has an open cryptographic interface, meaning it - * does not restrict which providers can be used. Compliance with - * United States export controls and with local law governing the - * import/export of products incorporating the JCE in the OpenJDK is - * the responsibility of the licensee. - * - * @since 1.7 - */ -final class JarVerifier { - - private static final boolean debug = false; - - /** - * Verify the JAR file is signed by an entity which has a certificate - * issued by a trusted CA. - * - * Note: this is a temporary method and will change soon to use the - * exception chaining mechanism, which can provide more details - * as to why the verification failed. - * - * @param c the class to be verified. - * @return true if verification is successful. - */ - static boolean verify(final Class c) { - return true; - } -} diff --git a/jdk/src/share/classes/com/sun/crypto/provider/KeyGeneratorCore.java b/jdk/src/share/classes/com/sun/crypto/provider/KeyGeneratorCore.java index 242db61d83f..6864dad5f7b 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/KeyGeneratorCore.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/KeyGeneratorCore.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2009 Sun Microsystems, Inc. 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 @@ -109,7 +109,6 @@ final class KeyGeneratorCore { public static final class HmacSHA256KG extends KeyGeneratorSpi { private final KeyGeneratorCore core; public HmacSHA256KG() { - SunJCE.ensureIntegrity(getClass()); core = new KeyGeneratorCore("HmacSHA256", 256); } protected void engineInit(SecureRandom random) { @@ -131,7 +130,6 @@ final class KeyGeneratorCore { public static final class HmacSHA384KG extends KeyGeneratorSpi { private final KeyGeneratorCore core; public HmacSHA384KG() { - SunJCE.ensureIntegrity(getClass()); core = new KeyGeneratorCore("HmacSHA384", 384); } protected void engineInit(SecureRandom random) { @@ -153,7 +151,6 @@ final class KeyGeneratorCore { public static final class HmacSHA512KG extends KeyGeneratorSpi { private final KeyGeneratorCore core; public HmacSHA512KG() { - SunJCE.ensureIntegrity(getClass()); core = new KeyGeneratorCore("HmacSHA512", 512); } protected void engineInit(SecureRandom random) { @@ -175,7 +172,6 @@ final class KeyGeneratorCore { public static final class RC2KeyGenerator extends KeyGeneratorSpi { private final KeyGeneratorCore core; public RC2KeyGenerator() { - SunJCE.ensureIntegrity(getClass()); core = new KeyGeneratorCore("RC2", 128); } protected void engineInit(SecureRandom random) { @@ -201,7 +197,6 @@ final class KeyGeneratorCore { public static final class ARCFOURKeyGenerator extends KeyGeneratorSpi { private final KeyGeneratorCore core; public ARCFOURKeyGenerator() { - SunJCE.ensureIntegrity(getClass()); core = new KeyGeneratorCore("ARCFOUR", 128); } protected void engineInit(SecureRandom random) { diff --git a/jdk/src/share/classes/com/sun/crypto/provider/PBEKeyFactory.java b/jdk/src/share/classes/com/sun/crypto/provider/PBEKeyFactory.java index 23478f8fc0e..f86dad561bf 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/PBEKeyFactory.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/PBEKeyFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2009 Sun Microsystems, Inc. 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 @@ -49,16 +49,9 @@ abstract class PBEKeyFactory extends SecretKeyFactorySpi { private static HashSet validTypes; /** - * Verify the SunJCE provider in the constructor. - * - * @exception SecurityException if fails to verify - * its own integrity + * Simple constructor */ private PBEKeyFactory(String keytype) { - if (!SunJCE.verifySelfIntegrity(this.getClass())) { - throw new SecurityException("The SunJCE provider may have " + - "been tampered."); - } type = keytype; } diff --git a/jdk/src/share/classes/com/sun/crypto/provider/PBEWithMD5AndDESCipher.java b/jdk/src/share/classes/com/sun/crypto/provider/PBEWithMD5AndDESCipher.java index 1bf6d6f89e2..8eec23d3998 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/PBEWithMD5AndDESCipher.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/PBEWithMD5AndDESCipher.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2009 Sun Microsystems, Inc. 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 @@ -55,16 +55,9 @@ public final class PBEWithMD5AndDESCipher extends CipherSpi { * unavailable * @exception NoSuchPaddingException if the required padding mechanism * (PKCS5Padding) is unavailable - * - * @exception SecurityException if this constructor fails to verify - * its own integrity */ public PBEWithMD5AndDESCipher() throws NoSuchAlgorithmException, NoSuchPaddingException { - if (!SunJCE.verifySelfIntegrity(this.getClass())) { - throw new SecurityException("The SunJCE provider may have " + - "been tampered."); - } core = new PBECipherCore("DES"); } diff --git a/jdk/src/share/classes/com/sun/crypto/provider/PBEWithMD5AndTripleDESCipher.java b/jdk/src/share/classes/com/sun/crypto/provider/PBEWithMD5AndTripleDESCipher.java index 7af04b6d810..c121bd12bfc 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/PBEWithMD5AndTripleDESCipher.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/PBEWithMD5AndTripleDESCipher.java @@ -1,5 +1,5 @@ /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2009 Sun Microsystems, Inc. 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 @@ -61,23 +61,14 @@ public final class PBEWithMD5AndTripleDESCipher extends CipherSpi { * Creates an instance of this cipher, and initializes its mode (CBC) and * padding (PKCS5). * - * Verify the SunJCE provider in the constructor. - * * @exception NoSuchAlgorithmException if the required cipher mode (CBC) is * unavailable * @exception NoSuchPaddingException if the required padding mechanism * (PKCS5Padding) is unavailable - * @exception SecurityException if fails to verify - * its own integrity */ public PBEWithMD5AndTripleDESCipher() throws NoSuchAlgorithmException, NoSuchPaddingException { - if (!SunJCE.verifySelfIntegrity(this.getClass())) { - throw new SecurityException("The SunJCE provider may have " + - "been tampered."); - } - // set the encapsulated cipher to do triple DES core = new PBECipherCore("DESede"); } diff --git a/jdk/src/share/classes/com/sun/crypto/provider/PBKDF2HmacSHA1Factory.java b/jdk/src/share/classes/com/sun/crypto/provider/PBKDF2HmacSHA1Factory.java index 9ba53036a5e..205e38cf729 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/PBKDF2HmacSHA1Factory.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/PBKDF2HmacSHA1Factory.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2009 Sun Microsystems, Inc. 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 @@ -45,16 +45,9 @@ import javax.crypto.spec.SecretKeySpec; public final class PBKDF2HmacSHA1Factory extends SecretKeyFactorySpi { /** - * Verify the SunJCE provider in the constructor. - * - * @exception SecurityException if fails to verify - * its own integrity + * Empty constructor */ public PBKDF2HmacSHA1Factory() { - if (!SunJCE.verifySelfIntegrity(this.getClass())) { - throw new SecurityException("The SunJCE provider may have " + - "been tampered."); - } } /** diff --git a/jdk/src/share/classes/com/sun/crypto/provider/PKCS12PBECipherCore.java b/jdk/src/share/classes/com/sun/crypto/provider/PKCS12PBECipherCore.java index 277a7b30045..ba7e7fec4f2 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/PKCS12PBECipherCore.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/PKCS12PBECipherCore.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2009 Sun Microsystems, Inc. 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 @@ -370,7 +370,6 @@ final class PKCS12PBECipherCore { public static final class PBEWithSHA1AndDESede extends CipherSpi { private final PKCS12PBECipherCore core; public PBEWithSHA1AndDESede() throws NoSuchAlgorithmException { - SunJCE.ensureIntegrity(this.getClass()); core = new PKCS12PBECipherCore("DESede", 24); } protected byte[] engineDoFinal(byte[] in, int inOff, int inLen) @@ -446,7 +445,6 @@ final class PKCS12PBECipherCore { public static final class PBEWithSHA1AndRC2_40 extends CipherSpi { private final PKCS12PBECipherCore core; public PBEWithSHA1AndRC2_40() throws NoSuchAlgorithmException { - SunJCE.ensureIntegrity(this.getClass()); core = new PKCS12PBECipherCore("RC2", 5); } protected byte[] engineDoFinal(byte[] in, int inOff, int inLen) diff --git a/jdk/src/share/classes/com/sun/crypto/provider/RC2Cipher.java b/jdk/src/share/classes/com/sun/crypto/provider/RC2Cipher.java index c96d07f726a..d119a0688cd 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/RC2Cipher.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/RC2Cipher.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2009 Sun Microsystems, Inc. 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 @@ -45,7 +45,6 @@ public final class RC2Cipher extends CipherSpi { private final RC2Crypt embeddedCipher; public RC2Cipher() { - SunJCE.ensureIntegrity(getClass()); embeddedCipher = new RC2Crypt(); core = new CipherCore(embeddedCipher, 8); } diff --git a/jdk/src/share/classes/com/sun/crypto/provider/RSACipher.java b/jdk/src/share/classes/com/sun/crypto/provider/RSACipher.java index e5c6c019e0f..9f5179e3325 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/RSACipher.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/RSACipher.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2009 Sun Microsystems, Inc. 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 @@ -111,7 +111,6 @@ public final class RSACipher extends CipherSpi { private String oaepHashAlgorithm = "SHA-1"; public RSACipher() { - SunJCE.ensureIntegrity(getClass()); paddingType = PAD_PKCS1; } diff --git a/jdk/src/share/classes/com/sun/crypto/provider/SslMacCore.java b/jdk/src/share/classes/com/sun/crypto/provider/SslMacCore.java index 7756e73ce77..8046a22ed71 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/SslMacCore.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/SslMacCore.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2009 Sun Microsystems, Inc. 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 @@ -226,9 +226,6 @@ final class SslMacCore { static final byte[] md5Pad1 = genPad((byte)0x36, 48); static final byte[] md5Pad2 = genPad((byte)0x5c, 48); - static { - SunJCE.ensureIntegrity(SslMacMD5.class); - } } // nested static class for the SslMacMD5 implementation @@ -262,9 +259,6 @@ final class SslMacCore { static final byte[] shaPad1 = genPad((byte)0x36, 40); static final byte[] shaPad2 = genPad((byte)0x5c, 40); - static { - SunJCE.ensureIntegrity(SslMacSHA1.class); - } } } diff --git a/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java b/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java index 13691b0167b..af46b030a6f 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2009 Sun Microsystems, Inc. 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 @@ -93,10 +93,6 @@ public final class SunJCE extends Provider { static final SecureRandom RANDOM = new SecureRandom(); - // After the SunJCE passed self-integrity checking, - // verifiedSelfIntegrity will be set to true. - private static boolean verifiedSelfIntegrity = false; - public SunJCE() { /* We are the "SunJCE" provider */ super("SunJCE", 1.7d, info); @@ -441,21 +437,4 @@ public final class SunJCE extends Provider { } }); } - - // set to true once self verification is complete - private static volatile boolean integrityVerified; - - static void ensureIntegrity(Class c) { - if (verifySelfIntegrity(c) == false) { - throw new SecurityException("The SunJCE provider may have " + - "been tampered."); - } - } - - static final boolean verifySelfIntegrity(Class c) { - if (verifiedSelfIntegrity) { - return true; - } - return (integrityVerified = JarVerifier.verify(c)); - } } diff --git a/jdk/src/share/classes/com/sun/crypto/provider/TlsKeyMaterialGenerator.java b/jdk/src/share/classes/com/sun/crypto/provider/TlsKeyMaterialGenerator.java index 260fdd8a946..8f27f74c6ee 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/TlsKeyMaterialGenerator.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/TlsKeyMaterialGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2009 Sun Microsystems, Inc. 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 @@ -52,7 +52,6 @@ public final class TlsKeyMaterialGenerator extends KeyGeneratorSpi { private int protocolVersion; public TlsKeyMaterialGenerator() { - SunJCE.ensureIntegrity(getClass()); } protected void engineInit(SecureRandom random) { diff --git a/jdk/src/share/classes/com/sun/crypto/provider/TlsMasterSecretGenerator.java b/jdk/src/share/classes/com/sun/crypto/provider/TlsMasterSecretGenerator.java index ad47dda2d32..d56c3b9afc6 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/TlsMasterSecretGenerator.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/TlsMasterSecretGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2009 Sun Microsystems, Inc. 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 @@ -51,7 +51,6 @@ public final class TlsMasterSecretGenerator extends KeyGeneratorSpi { private int protocolVersion; public TlsMasterSecretGenerator() { - SunJCE.ensureIntegrity(getClass()); } protected void engineInit(SecureRandom random) { diff --git a/jdk/src/share/classes/com/sun/crypto/provider/TlsPrfGenerator.java b/jdk/src/share/classes/com/sun/crypto/provider/TlsPrfGenerator.java index 5306a720fc5..f2c885f5a30 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/TlsPrfGenerator.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/TlsPrfGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2009 Sun Microsystems, Inc. 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 @@ -109,7 +109,6 @@ public final class TlsPrfGenerator extends KeyGeneratorSpi { private TlsPrfParameterSpec spec; public TlsPrfGenerator() { - SunJCE.ensureIntegrity(getClass()); } protected void engineInit(SecureRandom random) { diff --git a/jdk/src/share/classes/com/sun/crypto/provider/TlsRsaPremasterSecretGenerator.java b/jdk/src/share/classes/com/sun/crypto/provider/TlsRsaPremasterSecretGenerator.java index 6986dec21ce..742d3e1bdfd 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/TlsRsaPremasterSecretGenerator.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/TlsRsaPremasterSecretGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2009 Sun Microsystems, Inc. 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 @@ -48,7 +48,6 @@ public final class TlsRsaPremasterSecretGenerator extends KeyGeneratorSpi { private SecureRandom random; public TlsRsaPremasterSecretGenerator() { - SunJCE.ensureIntegrity(getClass()); } protected void engineInit(SecureRandom random) { diff --git a/jdk/src/share/classes/javax/crypto/JarVerifier.java b/jdk/src/share/classes/javax/crypto/JarVerifier.java index 376761012dc..03f80839f90 100644 --- a/jdk/src/share/classes/javax/crypto/JarVerifier.java +++ b/jdk/src/share/classes/javax/crypto/JarVerifier.java @@ -1,5 +1,5 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007-2009 Sun Microsystems, Inc. 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 @@ -28,9 +28,7 @@ package javax.crypto; import java.io.*; import java.net.*; import java.security.*; -import java.util.*; import java.util.jar.*; -import javax.crypto.CryptoPolicyParser.ParsingException; /** * This class verifies JAR files (and any supporting JAR files), and @@ -134,17 +132,6 @@ final class JarVerifier { } } - /** - * Verify that the provided JarEntry was indeed signed by the - * framework signing certificate. - * - * @param je the URL of the jar entry to be checked. - * @throws Exception if the jar entry was not signed by - * the proper certificate - */ - static void verifyFrameworkSigned(URL je) throws Exception { - } - /** * Verify that the provided certs include the * framework signing certificate. diff --git a/jdk/src/share/classes/javax/crypto/JceSecurity.java b/jdk/src/share/classes/javax/crypto/JceSecurity.java index 11b124ac00a..b204f384337 100644 --- a/jdk/src/share/classes/javax/crypto/JceSecurity.java +++ b/jdk/src/share/classes/javax/crypto/JceSecurity.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2009 Sun Microsystems, Inc. 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 @@ -25,7 +25,6 @@ package javax.crypto; -import java.lang.ref.*; import java.util.*; import java.util.jar.*; import java.io.*; @@ -256,11 +255,6 @@ final class JceSecurity { ("Cannot locate policy or framework files!"); } - // Enforce the signer restraint, i.e. signer of JCE framework - // jar should also be the signer of the two jurisdiction policy - // jar files. - JarVerifier.verifyFrameworkSigned(jceCipherURL); - // Read jurisdiction policies. CryptoPermissions defaultExport = new CryptoPermissions(); CryptoPermissions exemptExport = new CryptoPermissions(); diff --git a/jdk/src/share/classes/sun/security/pkcs11/JarVerifier.java b/jdk/src/share/classes/sun/security/pkcs11/JarVerifier.java deleted file mode 100644 index 092c5725dba..00000000000 --- a/jdk/src/share/classes/sun/security/pkcs11/JarVerifier.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2007 Sun Microsystems, Inc. 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. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package sun.security.pkcs11; - -// NOTE: this class is duplicated amongst SunJCE, SunPKCS11, and SunMSCAPI. -// All files should be kept in sync. - -import java.io.*; -import java.util.*; -import java.util.jar.*; -import java.net.URL; -import java.net.JarURLConnection; -import java.net.MalformedURLException; - -import java.security.*; -import java.security.cert.*; -import java.security.cert.Certificate; - -/** - * This class verifies JAR files (and any supporting JAR files), and - * determines whether they may be used in this implementation. - * - * The JCE in OpenJDK has an open cryptographic interface, meaning it - * does not restrict which providers can be used. Compliance with - * United States export controls and with local law governing the - * import/export of products incorporating the JCE in the OpenJDK is - * the responsibility of the licensee. - * - * @since 1.7 - */ -final class JarVerifier { - - private static final boolean debug = false; - - /** - * Verify the JAR file is signed by an entity which has a certificate - * issued by a trusted CA. - * - * Note: this is a temporary method and will change soon to use the - * exception chaining mechanism, which can provide more details - * as to why the verification failed. - * - * @param c the class to be verified. - * @return true if verification is successful. - */ - static boolean verify(final Class c) { - return true; - } -} diff --git a/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java b/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java index 6d0e045f2ee..674092e1617 100644 --- a/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java +++ b/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2009 Sun Microsystems, Inc. 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 @@ -390,24 +390,6 @@ public final class SunPKCS11 extends AuthProvider { return sb.toString(); } - // set to true once self verification is complete - private static volatile boolean integrityVerified; - - static void verifySelfIntegrity(Class c) { - if (integrityVerified) { - return; - } - doVerifySelfIntegrity(c); - } - - private static synchronized void doVerifySelfIntegrity(Class c) { - integrityVerified = JarVerifier.verify(c); - if (integrityVerified == false) { - throw new ProviderException - ("The SunPKCS11 provider may have been tampered with."); - } - } - public boolean equals(Object obj) { return this == obj; } @@ -923,7 +905,6 @@ public final class SunPKCS11 extends AuthProvider { if (type == MD) { return new P11Digest(token, algorithm, mechanism); } else if (type == CIP) { - verifySelfIntegrity(getClass()); if (algorithm.startsWith("RSA")) { return new P11RSACipher(token, algorithm, mechanism); } else { @@ -932,12 +913,10 @@ public final class SunPKCS11 extends AuthProvider { } else if (type == SIG) { return new P11Signature(token, algorithm, mechanism); } else if (type == MAC) { - verifySelfIntegrity(getClass()); return new P11Mac(token, algorithm, mechanism); } else if (type == KPG) { return new P11KeyPairGenerator(token, algorithm, mechanism); } else if (type == KA) { - verifySelfIntegrity(getClass()); if (algorithm.equals("ECDH")) { return new P11ECDHKeyAgreement(token, algorithm, mechanism); } else { @@ -946,11 +925,8 @@ public final class SunPKCS11 extends AuthProvider { } else if (type == KF) { return token.getKeyFactory(algorithm); } else if (type == SKF) { - verifySelfIntegrity(getClass()); return new P11SecretKeyFactory(token, algorithm); } else if (type == KG) { - verifySelfIntegrity(getClass()); - // reference equality if (algorithm == "SunTlsRsaPremasterSecret") { return new P11TlsRsaPremasterSecretGenerator( diff --git a/jdk/src/windows/classes/sun/security/mscapi/JarVerifier.java b/jdk/src/windows/classes/sun/security/mscapi/JarVerifier.java deleted file mode 100644 index 1fcd6c997ae..00000000000 --- a/jdk/src/windows/classes/sun/security/mscapi/JarVerifier.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2007 Sun Microsystems, Inc. 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. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - - -package sun.security.mscapi; - -// NOTE: this class is duplicated amongst SunJCE, SunPKCS11, and SunMSCAPI. -// All files should be kept in sync. - -import java.io.*; -import java.util.*; -import java.util.jar.*; -import java.net.URL; -import java.net.JarURLConnection; -import java.net.MalformedURLException; - -import java.security.*; -import java.security.cert.*; -import java.security.cert.Certificate; - -/** - * This class verifies JAR files (and any supporting JAR files), and - * determines whether they may be used in this implementation. - * - * The JCE in OpenJDK has an open cryptographic interface, meaning it - * does not restrict which providers can be used. Compliance with - * United States export controls and with local law governing the - * import/export of products incorporating the JCE in the OpenJDK is - * the responsibility of the licensee. - * - * @since 1.7 - */ -final class JarVerifier { - - private static final boolean debug = false; - - /** - * Verify the JAR file is signed by an entity which has a certificate - * issued by a trusted CA. - * - * Note: this is a temporary method and will change soon to use the - * exception chaining mechanism, which can provide more details - * as to why the verification failed. - * - * @param c the class to be verified. - * @return true if verification is successful. - */ - static boolean verify(final Class c) { - return true; - } -} diff --git a/jdk/src/windows/classes/sun/security/mscapi/RSACipher.java b/jdk/src/windows/classes/sun/security/mscapi/RSACipher.java index 06a82c5cdde..9a4a01c7cd6 100644 --- a/jdk/src/windows/classes/sun/security/mscapi/RSACipher.java +++ b/jdk/src/windows/classes/sun/security/mscapi/RSACipher.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2009 Sun Microsystems, Inc. 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 @@ -93,7 +93,6 @@ public final class RSACipher extends CipherSpi { private sun.security.mscapi.Key privateKey; public RSACipher() { - SunMSCAPI.verifySelfIntegrity(getClass()); paddingType = PAD_PKCS1; } diff --git a/jdk/src/windows/classes/sun/security/mscapi/SunMSCAPI.java b/jdk/src/windows/classes/sun/security/mscapi/SunMSCAPI.java index 4dcf217117d..009406c60c9 100644 --- a/jdk/src/windows/classes/sun/security/mscapi/SunMSCAPI.java +++ b/jdk/src/windows/classes/sun/security/mscapi/SunMSCAPI.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2009 Sun Microsystems, Inc. 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 @@ -117,22 +117,4 @@ public final class SunMSCAPI extends Provider { AccessController.doPrivileged(new PutAllAction(this, map)); } } - - // set to true once self verification is complete - private static volatile boolean integrityVerified; - - static void verifySelfIntegrity(Class c) { - if (integrityVerified) { - return; - } - doVerifySelfIntegrity(c); - } - - private static synchronized void doVerifySelfIntegrity(Class c) { - integrityVerified = JarVerifier.verify(c); - if (integrityVerified == false) { - throw new ProviderException - ("The SunMSCAPI provider may have been tampered with."); - } - } } From 9130e7d347313d51ad329eaa99d9a22549375f29 Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 6 Aug 2009 10:25:00 -0700 Subject: [PATCH 55/96] Added tag jdk7-b68 for changeset a3946f62adaa --- .hgtags-top-repo | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 7dc9b1b0dc4..887ebba35be 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -42,3 +42,4 @@ c7ed15ab92ce36a09d264a5e34025884b2d7607f jdk7-b62 e01380cd1de4ce048b87d059d238e5ab5e341947 jdk7-b65 6bad5e3fe50337d95b1416d744780d65bc570da6 jdk7-b66 c4523c6f82048f420bf0d57c4cd47976753b7d2c jdk7-b67 +e1b972ff53cd58f825791f8ed9b2deffd16e768c jdk7-b68 From d66b689a4b09422eaf74d61d89be950c2e193ac2 Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 6 Aug 2009 10:25:01 -0700 Subject: [PATCH 56/96] Added tag jdk7-b68 for changeset 0589e2ed45b3 --- corba/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/corba/.hgtags b/corba/.hgtags index 3e1753626fb..28557923b83 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -42,3 +42,4 @@ d20e45cd539f20405ff843652069cfd7550c5ab3 jdk7-b63 97fd9b42f5c2d342b90d18f0a2b57e4117e39415 jdk7-b65 a821e059a961bcb02830280d51f6dd030425c066 jdk7-b66 a12ea7c7b497b4ba7830550095ef633bd6f43971 jdk7-b67 +5182bcc9c60cac429d1f7988676cec7320752be3 jdk7-b68 From 8fae4c547c8ebb42718b9c31a2ff9cab0273fe1b Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 6 Aug 2009 10:25:05 -0700 Subject: [PATCH 57/96] Added tag jdk7-b68 for changeset 4ae7310eb37d --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index ad4c8f2596c..a7ee64a37aa 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -42,3 +42,4 @@ ba36394eb84b949b31212bdb32a518a8f92bab5b jdk7-b64 ba313800759b678979434d6da8ed3bf49eb8bea4 jdk7-b65 57c71ad0341b8b64ed20f81151eb7f06324f8894 jdk7-b66 18f526145aea355a9320b724373386fc2170f183 jdk7-b67 +d07e68298d4e17ebf93d8299e43fcc3ded26472a jdk7-b68 From 314304f9ba59ec1a3a5a16b635bc2d7cfef46230 Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 6 Aug 2009 10:25:10 -0700 Subject: [PATCH 58/96] Added tag jdk7-b68 for changeset 8cfea160b2e5 --- jaxp/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxp/.hgtags b/jaxp/.hgtags index f196582041b..4391dbd2d7d 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -42,3 +42,4 @@ a10eec7a1edf536f39b5828d8623054dbc62c2b7 jdk7-b64 008c662e0ee9a91aebb75e46b97de979083d5c1c jdk7-b65 22f9d5d5b5fe0f47048f41e6c6e54fee5edad0ec jdk7-b66 a033af8d824a408d3ac602205ecdefc128749e1e jdk7-b67 +83b2a9331383f9db7a49350d4cb13b7635f6b861 jdk7-b68 From a79bbfdcfef794597024b86dac830ab7a0041a9f Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 6 Aug 2009 10:25:11 -0700 Subject: [PATCH 59/96] Added tag jdk7-b68 for changeset 7df0da9e6d70 --- jaxws/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxws/.hgtags b/jaxws/.hgtags index 36dc0d6feff..900795887f8 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -42,3 +42,4 @@ aaa25dfd3de68c6f1a1d3ef8c45fd99f76bca6dd jdk7-b64 aa22a1be5866a6608ba17a7a443945559409ae0f jdk7-b65 fa8712c099edd5c9a6b3ed9729353738004d388f jdk7-b66 faa13cd4d6cdcfb155da5ed23b0da6e0ed0f9ea8 jdk7-b67 +845fa487f0f72a9f232ead8315c0087a477a5a31 jdk7-b68 From 6ceaf265fd953f005fef09a62aef4ed76c318c1b Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 6 Aug 2009 10:25:18 -0700 Subject: [PATCH 60/96] Added tag jdk7-b68 for changeset a02edc83f1b4 --- jdk/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/.hgtags b/jdk/.hgtags index 73634a197c7..1d2a3d286ba 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -42,3 +42,4 @@ a50217eb3ee10b9f9547e0708e5c9625405083ef jdk7-b64 382a27aa78d3236fa123c60577797a887fe93e09 jdk7-b65 bd31b30a5b21f20e42965b1633f18a5c7946d398 jdk7-b66 a952aafd5181af953b0ef3010dbd2fcc28460e8a jdk7-b67 +b23d905cb5d3b382295240d28ab0bfb266b4503c jdk7-b68 From ef226d3a7e7cb867684166fecfbc5f429ab7af8c Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 6 Aug 2009 10:25:29 -0700 Subject: [PATCH 61/96] Added tag jdk7-b68 for changeset 2974ea6ad890 --- langtools/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/langtools/.hgtags b/langtools/.hgtags index 2d35b7fcf82..e35171f3f7d 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -42,3 +42,4 @@ d8f23a81d46f47a4186f1044dd9e44841bbeab84 jdk7-b64 7e0056ded28c802609d2bd79bfcda551d72a3fec jdk7-b65 634f519d6f9a602b16bba1c7cd4a17242a8f6889 jdk7-b66 14b1a8ede95493fc53c37ff2626f1f98ce94d108 jdk7-b67 +95c1212b07e33b1b8c689b1d279d82ffd5a56e43 jdk7-b68 From 792cd2a88a9eb88aae1f4b682cbe439513bbd6e2 Mon Sep 17 00:00:00 2001 From: Tim Bell Date: Thu, 6 Aug 2009 17:16:31 -0700 Subject: [PATCH 62/96] 6865853: Additional code changes needed to build deploy using WXP SP2 and Visual Studio 2008 Reviewed-by: ohair --- jdk/src/windows/native/sun/jkernel/kernel.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jdk/src/windows/native/sun/jkernel/kernel.cpp b/jdk/src/windows/native/sun/jkernel/kernel.cpp index 354b47cf2b5..e67bb3a0595 100644 --- a/jdk/src/windows/native/sun/jkernel/kernel.cpp +++ b/jdk/src/windows/native/sun/jkernel/kernel.cpp @@ -116,11 +116,11 @@ char* getStringPlatformChars(JNIEnv* env, jstring jstr) { char *result = NULL; size_t len; const jchar* utf16 = env->GetStringChars(jstr, NULL); - len = wcstombs(NULL, utf16, env->GetStringLength(jstr) * 4) + 1; + len = wcstombs(NULL, (const wchar_t*)utf16, env->GetStringLength(jstr) * 4) + 1; if (len == -1) return NULL; result = (char*) malloc(len); - if (wcstombs(result, utf16, len) == -1) + if (wcstombs(result, (const wchar_t*)utf16, len) == -1) return NULL; env->ReleaseStringChars(jstr, utf16); return result; @@ -640,7 +640,7 @@ JNIEXPORT void JNICALL Java_sun_jkernel_DownloadManager_startBackgroundDownloadW } -void getParent(const TCHAR *path, TCHAR *dest) { +void getParent(TCHAR *path, TCHAR *dest) { char* lastSlash = max(strrchr(path, '\\'), strrchr(path, '/')); if (lastSlash == NULL) { *dest = NULL; From fc188b8b292d7f987191f68aba8267a92d892f99 Mon Sep 17 00:00:00 2001 From: Bradford Wetmore Date: Thu, 6 Aug 2009 17:56:59 -0700 Subject: [PATCH 63/96] 6867657: Many JSN tests do not run under cygwin Reviewed-by: ohair --- jdk/test/java/net/Authenticator/B4933582.sh | 10 ++-- .../ADatagramSocket.sh | 4 ++ jdk/test/java/net/Socket/OldSocketImpl.sh | 4 ++ jdk/test/java/net/URL/B5086147.sh | 4 ++ jdk/test/java/net/URL/runconstructor.sh | 4 ++ jdk/test/java/net/URLClassLoader/B5077773.sh | 4 ++ .../net/URLClassLoader/sealing/checksealed.sh | 12 +++-- .../java/net/URLConnection/6212146/test.sh | 4 ++ .../ClassLoaderDeadlock.sh | 6 ++- .../Security/ClassLoaderDeadlock/Deadlock.sh | 6 ++- .../java/security/Security/signedfirst/Dyn.sh | 6 ++- .../security/Security/signedfirst/Static.sh | 8 ++- .../crypto/SecretKeyFactory/FailOverTest.sh | 9 +++- .../javax/security/auth/Subject/doAs/Test.sh | 5 ++ .../lib/security/java.policy/Ext_AllPolicy.sh | 6 +++ jdk/test/sun/net/www/MarkResetTest.sh | 4 ++ .../ChunkedInputStream/ChunkedCharEncoding.sh | 4 ++ .../sun/net/www/http/HttpClient/RetryPost.sh | 4 ++ jdk/test/sun/net/www/protocol/jar/B5105410.sh | 4 ++ .../sun/net/www/protocol/jar/jarbug/run.sh | 49 +++++++++++++++---- .../pkcs11/Provider/ConfigQuotedString.sh | 14 ++++++ .../sun/security/pkcs11/Provider/Login.sh | 14 ++++++ .../PolicyFile/getinstance/getinstance.sh | 4 ++ .../ssl/SSLSocketImpl/NotifyHandshakeTest.sh | 23 ++++++--- .../https/HttpsURLConnection/PostThruProxy.sh | 7 ++- .../PostThruProxyWithAuth.sh | 8 ++- .../security/tools/jarsigner/AlgOptions.sh | 7 +++ .../security/tools/jarsigner/PercentSign.sh | 7 +++ .../sun/security/tools/jarsigner/oldsig.sh | 7 +++ .../security/tools/keytool/AltProviderPath.sh | 31 ++++++++++-- .../tools/keytool/CloneKeyAskPassword.sh | 4 ++ .../sun/security/tools/keytool/NoExtNPE.sh | 3 ++ .../sun/security/tools/keytool/SecretKeyKS.sh | 6 +++ .../security/tools/keytool/StandardAlgName.sh | 6 +++ jdk/test/sun/security/tools/keytool/i18n.sh | 6 +++ .../sun/security/tools/keytool/printssl.sh | 3 ++ .../sun/security/tools/keytool/resource.sh | 5 ++ .../sun/security/tools/keytool/standard.sh | 6 ++- 38 files changed, 280 insertions(+), 38 deletions(-) diff --git a/jdk/test/java/net/Authenticator/B4933582.sh b/jdk/test/java/net/Authenticator/B4933582.sh index b103592f42d..0826063a805 100644 --- a/jdk/test/java/net/Authenticator/B4933582.sh +++ b/jdk/test/java/net/Authenticator/B4933582.sh @@ -30,6 +30,10 @@ case "$OS" in PS=":" FS="/" ;; + CYGWIN* ) + PS=";" + FS="/" + ;; Windows* ) PS=";" FS="\\" @@ -39,7 +43,7 @@ case "$OS" in exit 1; ;; esac -${TESTJAVA}${FS}bin${FS}javac -d . -classpath ${TESTSRC}${FS}..${FS}..${FS}..${FS}sun${FS}net${FS}www${FS}httptest ${TESTSRC}${FS}B4933582.java +${TESTJAVA}${FS}bin${FS}javac -d . -classpath "${TESTSRC}${FS}..${FS}..${FS}..${FS}sun${FS}net${FS}www${FS}httptest" ${TESTSRC}${FS}B4933582.java rm -f cache.ser auth.save -${TESTJAVA}${FS}bin${FS}java -classpath ${TESTSRC}${FS}..${FS}..${FS}..${FS}sun${FS}net${FS}www${FS}httptest${PS}. B4933582 first -${TESTJAVA}${FS}bin${FS}java -classpath ${TESTSRC}${FS}..${FS}..${FS}..${FS}sun${FS}net${FS}www${FS}httptest${PS}. B4933582 second +${TESTJAVA}${FS}bin${FS}java -classpath "${TESTSRC}${FS}..${FS}..${FS}..${FS}sun${FS}net${FS}www${FS}httptest${PS}." B4933582 first +${TESTJAVA}${FS}bin${FS}java -classpath "${TESTSRC}${FS}..${FS}..${FS}..${FS}sun${FS}net${FS}www${FS}httptest${PS}." B4933582 second diff --git a/jdk/test/java/net/DatagramSocket/SetDatagramSocketImplFactory/ADatagramSocket.sh b/jdk/test/java/net/DatagramSocket/SetDatagramSocketImplFactory/ADatagramSocket.sh index ba8b7cb5184..18f7c0ea94c 100644 --- a/jdk/test/java/net/DatagramSocket/SetDatagramSocketImplFactory/ADatagramSocket.sh +++ b/jdk/test/java/net/DatagramSocket/SetDatagramSocketImplFactory/ADatagramSocket.sh @@ -35,6 +35,10 @@ case "$OS" in PATHSEP=":" FILESEP="/" ;; + CYGWIN* ) + PATHSEP=";" + FILESEP="/" + ;; Windows* ) PATHSEP=";" FILESEP="\\" diff --git a/jdk/test/java/net/Socket/OldSocketImpl.sh b/jdk/test/java/net/Socket/OldSocketImpl.sh index 85845464f2b..50692f8e045 100644 --- a/jdk/test/java/net/Socket/OldSocketImpl.sh +++ b/jdk/test/java/net/Socket/OldSocketImpl.sh @@ -32,6 +32,10 @@ case "$OS" in PS=":" FS="/" ;; + CYGWIN* ) + PS=";" + FS="/" + ;; Windows* ) PS=";" FS="\\" diff --git a/jdk/test/java/net/URL/B5086147.sh b/jdk/test/java/net/URL/B5086147.sh index 53034443a80..aaa9eadf31c 100644 --- a/jdk/test/java/net/URL/B5086147.sh +++ b/jdk/test/java/net/URL/B5086147.sh @@ -29,6 +29,10 @@ case "$OS" in SunOS | Linux ) exit 0 ;; + CYGWIN* ) + PS=";" + FS="/" + ;; Windows* ) PS=";" FS="\\" diff --git a/jdk/test/java/net/URL/runconstructor.sh b/jdk/test/java/net/URL/runconstructor.sh index 93a80de4b3c..30ae96a3c10 100644 --- a/jdk/test/java/net/URL/runconstructor.sh +++ b/jdk/test/java/net/URL/runconstructor.sh @@ -31,6 +31,10 @@ case "$OS" in PS=":" FS="/" ;; + CYGWIN* ) + PS=";" + FS="/" + ;; Windows* ) PS=";" FS="\\" diff --git a/jdk/test/java/net/URLClassLoader/B5077773.sh b/jdk/test/java/net/URLClassLoader/B5077773.sh index 6dcba9c39a9..43bff5ad4a1 100644 --- a/jdk/test/java/net/URLClassLoader/B5077773.sh +++ b/jdk/test/java/net/URLClassLoader/B5077773.sh @@ -42,6 +42,10 @@ case "$OS" in PS=":" FS="/" ;; + CYGWIN* ) + PS=";" + FS="/" + ;; Windows* ) PS=";" FS="\\" diff --git a/jdk/test/java/net/URLClassLoader/sealing/checksealed.sh b/jdk/test/java/net/URLClassLoader/sealing/checksealed.sh index e46ac2915ce..191ff6f4750 100644 --- a/jdk/test/java/net/URLClassLoader/sealing/checksealed.sh +++ b/jdk/test/java/net/URLClassLoader/sealing/checksealed.sh @@ -35,6 +35,10 @@ case "$OS" in PS=":" FS="/" ;; + CYGWIN* ) + PS=";" + FS="/" + ;; Windows* ) PS=";" FS="\\" @@ -49,10 +53,10 @@ esac if [ x"$TESTJAVA" = x ]; then TESTJAVA=$1; fi if [ x"$TESTSRC" = x ]; then TESTSRC=.; fi -CLASSPATH=.${PS}${TESTSRC}${FS}a${PS}${TESTSRC}${FS}b.jar +CLASSPATH=".${PS}${TESTSRC}${FS}a${PS}${TESTSRC}${FS}b.jar" -${TESTJAVA}${FS}bin${FS}javac -classpath ${CLASSPATH} -d . ${TESTSRC}${FS}CheckSealed.java -${TESTJAVA}${FS}bin${FS}java -cp ${CLASSPATH} CheckSealed 1 +${TESTJAVA}${FS}bin${FS}javac -classpath "${CLASSPATH}" -d . ${TESTSRC}${FS}CheckSealed.java +${TESTJAVA}${FS}bin${FS}java -cp "${CLASSPATH}" CheckSealed 1 if [ $? != 0 ]; then exit 1; fi -${TESTJAVA}${FS}bin${FS}java -cp ${CLASSPATH} CheckSealed 2 +${TESTJAVA}${FS}bin${FS}java -cp "${CLASSPATH}" CheckSealed 2 if [ $? != 0 ]; then exit 1; fi diff --git a/jdk/test/java/net/URLConnection/6212146/test.sh b/jdk/test/java/net/URLConnection/6212146/test.sh index 29b187ab307..cdf970db41e 100644 --- a/jdk/test/java/net/URLConnection/6212146/test.sh +++ b/jdk/test/java/net/URLConnection/6212146/test.sh @@ -41,6 +41,10 @@ case "$OS" in PS=":" FS="/" ;; + CYGWIN* ) + PS=";" + FS="/" + ;; Windows* ) PS=";" FS="\\" diff --git a/jdk/test/java/security/Security/ClassLoaderDeadlock/ClassLoaderDeadlock.sh b/jdk/test/java/security/Security/ClassLoaderDeadlock/ClassLoaderDeadlock.sh index 02ab6fcfd50..a1c1d80d696 100644 --- a/jdk/test/java/security/Security/ClassLoaderDeadlock/ClassLoaderDeadlock.sh +++ b/jdk/test/java/security/Security/ClassLoaderDeadlock/ClassLoaderDeadlock.sh @@ -54,6 +54,10 @@ case "$OS" in PATHSEP=":" FILESEP="/" ;; + CYGWIN* ) + PATHSEP=";" + FILESEP="/" + ;; Windows* ) PATHSEP=";" FILESEP="\\" @@ -81,7 +85,7 @@ ${TESTJAVA}${FILESEP}bin${FILESEP}javac \ # run the test ${TESTJAVA}${FILESEP}bin${FILESEP}java \ - -classpath ${TESTCLASSES}${PATHSEP}${TESTSRC}${FILESEP}Deadlock.jar \ + -classpath "${TESTCLASSES}${PATHSEP}${TESTSRC}${FILESEP}Deadlock.jar" \ ClassLoaderDeadlock exit $? diff --git a/jdk/test/java/security/Security/ClassLoaderDeadlock/Deadlock.sh b/jdk/test/java/security/Security/ClassLoaderDeadlock/Deadlock.sh index 4ed9b785e5f..e631389f023 100644 --- a/jdk/test/java/security/Security/ClassLoaderDeadlock/Deadlock.sh +++ b/jdk/test/java/security/Security/ClassLoaderDeadlock/Deadlock.sh @@ -42,6 +42,10 @@ case "$OS" in PATHSEP=":" FILESEP="/" ;; + CYGWIN* ) + PATHSEP=";" + FILESEP="/" + ;; Windows* ) PATHSEP=";" FILESEP="\\" @@ -54,5 +58,5 @@ esac JAVA="${TESTJAVA}${FILESEP}bin${FILESEP}java" -${JAVA} -cp ${TESTCLASSES}${PATHSEP}${TESTSRC}${FILESEP}Deadlock.jar Deadlock +${JAVA} -cp "${TESTCLASSES}${PATHSEP}${TESTSRC}${FILESEP}Deadlock.jar" Deadlock diff --git a/jdk/test/java/security/Security/signedfirst/Dyn.sh b/jdk/test/java/security/Security/signedfirst/Dyn.sh index b64a6b6621b..b897d5900a9 100644 --- a/jdk/test/java/security/Security/signedfirst/Dyn.sh +++ b/jdk/test/java/security/Security/signedfirst/Dyn.sh @@ -54,6 +54,10 @@ case "$OS" in PATHSEP=":" FILESEP="/" ;; + CYGWIN* ) + PATHSEP=";" + FILESEP="/" + ;; Windows* ) PATHSEP=";" FILESEP="\\" @@ -76,7 +80,7 @@ ${TESTJAVA}${FILESEP}bin${FILESEP}javac \ # run the test ${TESTJAVA}${FILESEP}bin${FILESEP}java \ - -classpath ${TESTCLASSES}${PATHSEP}${TESTSRC}${FILESEP}exp.jar \ + -classpath "${TESTCLASSES}${PATHSEP}${TESTSRC}${FILESEP}exp.jar" \ DynSignedProvFirst exit $? diff --git a/jdk/test/java/security/Security/signedfirst/Static.sh b/jdk/test/java/security/Security/signedfirst/Static.sh index cec9df72279..519766f9d60 100644 --- a/jdk/test/java/security/Security/signedfirst/Static.sh +++ b/jdk/test/java/security/Security/signedfirst/Static.sh @@ -54,6 +54,10 @@ case "$OS" in PATHSEP=":" FILESEP="/" ;; + CYGWIN* ) + PATHSEP=";" + FILESEP="/" + ;; Windows* ) PATHSEP=";" FILESEP="\\" @@ -70,14 +74,14 @@ rm StaticSignedProvFirst.class # compile the test program ${TESTJAVA}${FILESEP}bin${FILESEP}javac \ - -classpath ${TESTCLASSES}${PATHSEP}${TESTSRC}${FILESEP}exp.jar \ + -classpath "${TESTCLASSES}${PATHSEP}${TESTSRC}${FILESEP}exp.jar" \ -d ${TESTCLASSES}${FILESEP} \ ${TESTSRC}${FILESEP}StaticSignedProvFirst.java # run the test cd ${TESTSRC}${FILESEP} ${TESTJAVA}${FILESEP}bin${FILESEP}java \ - -classpath ${TESTCLASSES}${PATHSEP}${TESTSRC}${FILESEP}exp.jar \ + -classpath "${TESTCLASSES}${PATHSEP}${TESTSRC}${FILESEP}exp.jar" \ -Djava.security.properties=file:${TESTSRC}${FILESEP}Static.props \ StaticSignedProvFirst diff --git a/jdk/test/javax/crypto/SecretKeyFactory/FailOverTest.sh b/jdk/test/javax/crypto/SecretKeyFactory/FailOverTest.sh index b433dedb221..6eef3944d9f 100644 --- a/jdk/test/javax/crypto/SecretKeyFactory/FailOverTest.sh +++ b/jdk/test/javax/crypto/SecretKeyFactory/FailOverTest.sh @@ -56,6 +56,11 @@ case "$OS" in PS=":" FS="/" ;; + CYGWIN* ) + NULL=/dev/null + PS=";" + FS="/" + ;; Windows* ) NULL=NUL PS=";" @@ -69,7 +74,7 @@ esac ${TESTJAVA}${FS}bin${FS}javac \ -d . \ - -classpath ${TESTSRC}${FS}P1.jar${PS}${TESTSRC}${FS}P2.jar \ + -classpath "${TESTSRC}${FS}P1.jar${PS}${TESTSRC}${FS}P2.jar" \ ${TESTSRC}${FS}FailOverTest.java if [ $? -ne 0 ]; then @@ -77,7 +82,7 @@ if [ $? -ne 0 ]; then fi ${TESTJAVA}${FS}bin${FS}java \ - -classpath ${TESTSRC}${FS}P1.jar${PS}${TESTSRC}${FS}P2.jar${PS}. \ + -classpath "${TESTSRC}${FS}P1.jar${PS}${TESTSRC}${FS}P2.jar${PS}." \ FailOverTest result=$? diff --git a/jdk/test/javax/security/auth/Subject/doAs/Test.sh b/jdk/test/javax/security/auth/Subject/doAs/Test.sh index 9844c994968..61c4d7cd6cf 100644 --- a/jdk/test/javax/security/auth/Subject/doAs/Test.sh +++ b/jdk/test/javax/security/auth/Subject/doAs/Test.sh @@ -43,6 +43,11 @@ case "$OS" in FS="/" RM="/bin/rm -f" ;; + CYGWIN* ) + PS=";" + FS="/" + RM="rm" + ;; Windows* ) PS=";" FS="\\" diff --git a/jdk/test/lib/security/java.policy/Ext_AllPolicy.sh b/jdk/test/lib/security/java.policy/Ext_AllPolicy.sh index 357a586b443..288dedf15fa 100644 --- a/jdk/test/lib/security/java.policy/Ext_AllPolicy.sh +++ b/jdk/test/lib/security/java.policy/Ext_AllPolicy.sh @@ -56,6 +56,12 @@ case "$OS" in FS="/" TMP=/tmp ;; + CYGWIN* ) + NULL=/dev/null + PS=";" + FS="/" + TMP=/tmp + ;; Windows_95 | Windows_98 | Windows_NT ) NULL=NUL PS=";" diff --git a/jdk/test/sun/net/www/MarkResetTest.sh b/jdk/test/sun/net/www/MarkResetTest.sh index 61e73344b0a..bf0b0ceb3c1 100644 --- a/jdk/test/sun/net/www/MarkResetTest.sh +++ b/jdk/test/sun/net/www/MarkResetTest.sh @@ -32,6 +32,10 @@ case "$OS" in PS=":" FS="/" ;; + CYGWIN* ) + PS=";" + FS="/" + ;; Windows* ) PS=";" FS="\\" diff --git a/jdk/test/sun/net/www/http/ChunkedInputStream/ChunkedCharEncoding.sh b/jdk/test/sun/net/www/http/ChunkedInputStream/ChunkedCharEncoding.sh index 615d1e5a293..06d10520ebb 100644 --- a/jdk/test/sun/net/www/http/ChunkedInputStream/ChunkedCharEncoding.sh +++ b/jdk/test/sun/net/www/http/ChunkedInputStream/ChunkedCharEncoding.sh @@ -32,6 +32,10 @@ case "$OS" in PS=":" FS="/" ;; + CYGWIN* ) + PS=";" + FS="/" + ;; Windows* ) PS=";" FS="\\" diff --git a/jdk/test/sun/net/www/http/HttpClient/RetryPost.sh b/jdk/test/sun/net/www/http/HttpClient/RetryPost.sh index b72b168c208..677a13cc69a 100644 --- a/jdk/test/sun/net/www/http/HttpClient/RetryPost.sh +++ b/jdk/test/sun/net/www/http/HttpClient/RetryPost.sh @@ -32,6 +32,10 @@ case "$OS" in PS=":" FS="/" ;; + CYGWIN* ) + PS=";" + FS="/" + ;; Windows* ) PS=";" FS="\\" diff --git a/jdk/test/sun/net/www/protocol/jar/B5105410.sh b/jdk/test/sun/net/www/protocol/jar/B5105410.sh index 3250ecba807..7b1d33ea4fb 100644 --- a/jdk/test/sun/net/www/protocol/jar/B5105410.sh +++ b/jdk/test/sun/net/www/protocol/jar/B5105410.sh @@ -39,6 +39,10 @@ case "$OS" in PS=":" FS="/" ;; + CYGWIN* ) + PS=";" + FS="/" + ;; Windows* ) PS=";" FS="\\" diff --git a/jdk/test/sun/net/www/protocol/jar/jarbug/run.sh b/jdk/test/sun/net/www/protocol/jar/jarbug/run.sh index 7db91d98862..351614dde3d 100644 --- a/jdk/test/sun/net/www/protocol/jar/jarbug/run.sh +++ b/jdk/test/sun/net/www/protocol/jar/jarbug/run.sh @@ -28,23 +28,54 @@ # @summary various resource and classloading bugs related to jar files #set -x DEST=`pwd` + +OS=`uname -s` +case "$OS" in + SunOS ) + PS=":" + FS="/" + ;; + Linux ) + PS=":" + FS="/" + ;; + Windows* ) + PS=";" + FS="\\" + ;; + CYGWIN* ) + PS=";" + FS="/" + # + # javac does not like /cygdrive produced by `pwd`. + # + DEST=`cygpath -d ${DEST}` + ;; + * ) + echo "Unrecognized system!" + exit 1; + ;; +esac + # # build jar1 # -mkdir ${DEST}/jar1 -cd ${TESTSRC}/etc/jar1 -cp -r . ${DEST}/jar1 -${TESTJAVA}/bin/javac -d ${DEST}/jar1 ${TESTSRC}/src/jar1/LoadResourceBundle.java -${TESTJAVA}/bin/javac -d ${DEST}/jar1 ${TESTSRC}/src/jar1/GetResource.java -cd ${DEST}/jar1 -${TESTJAVA}/bin/jar cfM jar1.jar jar1 res1.txt +mkdir -p ${DEST}${FS}jar1 +cd ${TESTSRC}${FS}etc${FS}jar1 +cp -r . ${DEST}${FS}jar1 +${TESTJAVA}${FS}bin${FS}javac -d ${DEST}${FS}jar1 \ + ${TESTSRC}${FS}src${FS}jar1${FS}LoadResourceBundle.java +${TESTJAVA}${FS}bin${FS}javac -d ${DEST}${FS}jar1 \ + ${TESTSRC}${FS}src${FS}jar1${FS}GetResource.java +cd ${DEST}${FS}jar1 +${TESTJAVA}${FS}bin${FS}jar cfM jar1.jar jar1 res1.txt mv jar1.jar .. # # build the test sources and run them # -${TESTJAVA}/bin/javac -d ${DEST} ${TESTSRC}/src/test/*.java +${TESTJAVA}${FS}bin${FS}javac -d ${DEST} ${TESTSRC}${FS}src${FS}test${FS}*.java cd ${DEST} -${TESTJAVA}/bin/java RunAllTests +${TESTJAVA}${FS}bin${FS}java RunAllTests result=$? if [ "$result" -ne "0" ]; then exit 1 diff --git a/jdk/test/sun/security/pkcs11/Provider/ConfigQuotedString.sh b/jdk/test/sun/security/pkcs11/Provider/ConfigQuotedString.sh index 4711e7e3cd3..8974fe62d45 100644 --- a/jdk/test/sun/security/pkcs11/Provider/ConfigQuotedString.sh +++ b/jdk/test/sun/security/pkcs11/Provider/ConfigQuotedString.sh @@ -68,6 +68,20 @@ case "$OS" in CP="cp" CHMOD="chmod" ;; + CYGWIN* ) + FS="/" + PS=";" + CP="cp" + CHMOD="chmod" + # + # javac does not like /cygdrive produced by `pwd` + # + TESTSRC=`cygpath -d ${TESTSRC}` + ;; + * ) + echo "Unrecognized system!" + exit 1; + ;; esac # compile test diff --git a/jdk/test/sun/security/pkcs11/Provider/Login.sh b/jdk/test/sun/security/pkcs11/Provider/Login.sh index a41720b63de..6b285adb82d 100644 --- a/jdk/test/sun/security/pkcs11/Provider/Login.sh +++ b/jdk/test/sun/security/pkcs11/Provider/Login.sh @@ -69,6 +69,20 @@ case "$OS" in CP="cp" CHMOD="chmod" ;; + CYGWIN* ) + FS="/" + PS=";" + CP="cp" + CHMOD="chmod" + # + # javac does not like /cygdrive produced by `pwd` + # + TESTSRC=`cygpath -d ${TESTSRC}` + ;; + * ) + echo "Unrecognized system!" + exit 1; + ;; esac # first make cert/key DBs writable diff --git a/jdk/test/sun/security/provider/PolicyFile/getinstance/getinstance.sh b/jdk/test/sun/security/provider/PolicyFile/getinstance/getinstance.sh index cb4325b464b..9cb9d04de95 100644 --- a/jdk/test/sun/security/provider/PolicyFile/getinstance/getinstance.sh +++ b/jdk/test/sun/security/provider/PolicyFile/getinstance/getinstance.sh @@ -55,6 +55,10 @@ case "$OS" in PS=":" FS="/" ;; + CYGWIN* ) + PS=";" + FS="/" + ;; Windows* ) PS=";" FS="\\" diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/NotifyHandshakeTest.sh b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/NotifyHandshakeTest.sh index 9ebf5ee3f64..1f49a952fb3 100644 --- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/NotifyHandshakeTest.sh +++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/NotifyHandshakeTest.sh @@ -43,10 +43,17 @@ fi OS=`uname -s` case "$OS" in SunOS | Linux ) + FILESEP="/" PATHSEP=":" ;; + CYGWIN* ) + FILESEP="/" + PATHSEP=";" + ;; + Windows* ) + FILESEP="\\" PATHSEP=";" ;; esac @@ -56,11 +63,13 @@ set -ex # # Compile the tests, package into their respective jars # -${TESTJAVA}/bin/javac -d . \ - ${TESTSRC}/NotifyHandshakeTest.java \ - ${TESTSRC}/NotifyHandshakeTestHeyYou.java -${TESTJAVA}/bin/jar -cvf com.jar com/NotifyHandshakeTest*.class -${TESTJAVA}/bin/jar -cvf edu.jar edu/NotifyHandshakeTestHeyYou.class +${TESTJAVA}${FILESEP}bin${FILESEP}javac -d . \ + ${TESTSRC}${FILESEP}NotifyHandshakeTest.java \ + ${TESTSRC}${FILESEP}NotifyHandshakeTestHeyYou.java +${TESTJAVA}${FILESEP}bin${FILESEP}jar -cvf com.jar \ + com${FILESEP}NotifyHandshakeTest*.class +${TESTJAVA}${FILESEP}bin${FILESEP}jar -cvf edu.jar \ + edu${FILESEP}NotifyHandshakeTestHeyYou.class # # Don't want the original class files to be used, because @@ -73,11 +82,11 @@ rm -rf com edu # This is the only thing we really care about as far as # test status goes. # -${TESTJAVA}/bin/java \ +${TESTJAVA}${FILESEP}bin${FILESEP}java \ -Dtest.src=${TESTSRC} \ -classpath "com.jar${PATHSEP}edu.jar" \ -Djava.security.manager \ - -Djava.security.policy=${TESTSRC}/NotifyHandshakeTest.policy \ + -Djava.security.policy=${TESTSRC}${FILESEP}NotifyHandshakeTest.policy \ com.NotifyHandshakeTest retval=$? diff --git a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.sh b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.sh index 3e66175cf66..de5f0318e8b 100644 --- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.sh +++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.sh @@ -36,6 +36,10 @@ case "$OS" in PS=":" FS="/" ;; + CYGWIN* ) + PS=";" + FS="/" + ;; Windows* ) PS=";" FS="\\" @@ -46,6 +50,7 @@ case "$OS" in ;; esac -${TESTJAVA}${FS}bin${FS}javac -d . ${TESTSRC}${FS}OriginServer.java ${TESTSRC}${FS}ProxyTunnelServer.java ${TESTSRC}${FS}PostThruProxy.java +${TESTJAVA}${FS}bin${FS}javac -d . ${TESTSRC}${FS}OriginServer.java \ + ${TESTSRC}${FS}ProxyTunnelServer.java ${TESTSRC}${FS}PostThruProxy.java ${TESTJAVA}${FS}bin${FS}java PostThruProxy ${HOSTNAME} ${TESTSRC} exit diff --git a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.sh b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.sh index 2a40eb790ce..e9e20336222 100644 --- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.sh +++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.sh @@ -36,6 +36,10 @@ case "$OS" in PS=":" FS="/" ;; + CYGWIN* ) + PS=";" + FS="/" + ;; Windows* ) PS=";" FS="\\" @@ -46,6 +50,8 @@ case "$OS" in ;; esac -${TESTJAVA}${FS}bin${FS}javac -d . ${TESTSRC}${FS}OriginServer.java ${TESTSRC}${FS}ProxyTunnelServer.java ${TESTSRC}${FS}PostThruProxyWithAuth.java +${TESTJAVA}${FS}bin${FS}javac -d . ${TESTSRC}${FS}OriginServer.java \ + ${TESTSRC}${FS}ProxyTunnelServer.java \ + ${TESTSRC}${FS}PostThruProxyWithAuth.java ${TESTJAVA}${FS}bin${FS}java PostThruProxyWithAuth ${HOSTNAME} ${TESTSRC} exit diff --git a/jdk/test/sun/security/tools/jarsigner/AlgOptions.sh b/jdk/test/sun/security/tools/jarsigner/AlgOptions.sh index 5501116b9c9..3dda55f30c2 100644 --- a/jdk/test/sun/security/tools/jarsigner/AlgOptions.sh +++ b/jdk/test/sun/security/tools/jarsigner/AlgOptions.sh @@ -53,6 +53,13 @@ case "$OS" in CP="${FS}bin${FS}cp -f" TMP=/tmp ;; + CYGWIN* ) + NULL=/dev/null + PS=";" + FS="/" + CP="cp -f" + TMP=/tmp + ;; Windows_* ) NULL=NUL PS=";" diff --git a/jdk/test/sun/security/tools/jarsigner/PercentSign.sh b/jdk/test/sun/security/tools/jarsigner/PercentSign.sh index a07011f0a2a..3a9f315d015 100644 --- a/jdk/test/sun/security/tools/jarsigner/PercentSign.sh +++ b/jdk/test/sun/security/tools/jarsigner/PercentSign.sh @@ -53,6 +53,13 @@ case "$OS" in CP="${FS}bin${FS}cp -f" TMP=/tmp ;; + CYGWIN* ) + NULL=/dev/null + PS=";" + FS="/" + CP="cp -f" + TMP=/tmp + ;; Windows_* ) NULL=NUL PS=";" diff --git a/jdk/test/sun/security/tools/jarsigner/oldsig.sh b/jdk/test/sun/security/tools/jarsigner/oldsig.sh index 14668810446..d7420dc4f3e 100644 --- a/jdk/test/sun/security/tools/jarsigner/oldsig.sh +++ b/jdk/test/sun/security/tools/jarsigner/oldsig.sh @@ -49,6 +49,13 @@ case "$OS" in CP="${FS}bin${FS}cp -f" TMP=/tmp ;; + CYGWIN* ) + NULL=/dev/null + PS=";" + FS="/" + CP="cp -f" + TMP=/tmp + ;; Windows_* ) NULL=NUL PS=";" diff --git a/jdk/test/sun/security/tools/keytool/AltProviderPath.sh b/jdk/test/sun/security/tools/keytool/AltProviderPath.sh index 7deb733c095..8f253a76c9b 100644 --- a/jdk/test/sun/security/tools/keytool/AltProviderPath.sh +++ b/jdk/test/sun/security/tools/keytool/AltProviderPath.sh @@ -52,6 +52,12 @@ case "$OS" in FS="/" TMP=/tmp ;; + CYGWIN* ) + NULL=/dev/null + PS=";" + FS="/" + TMP=/tmp + ;; Windows_* ) NULL=NUL PS=";" @@ -66,14 +72,21 @@ esac # the test code #genkey -${TESTJAVA}${FS}bin${FS}keytool -genkey -v -alias dummyTestCA -keyalg "RSA" -keysize 1024 -sigalg "ShA1WithRSA" -dname "cn=Dummy Test CA, ou=JSN, o=JavaSoft, c=US" -validity 3650 -keypass storepass -keystore keystoreCA.dks -storepass storepass -storetype "dks" -provider "org.test.dummy.DummyProvider" -providerPath ${TESTCLASSES} +${TESTJAVA}${FS}bin${FS}keytool -genkey -v -alias dummyTestCA \ + -keyalg "RSA" -keysize 1024 -sigalg "ShA1WithRSA" \ + -dname "cn=Dummy Test CA, ou=JSN, o=JavaSoft, c=US" -validity 3650 \ + -keypass storepass -keystore keystoreCA.dks -storepass storepass \ + -storetype "dks" -provider "org.test.dummy.DummyProvider" \ + -providerPath ${TESTCLASSES} if [ $? -ne 0 ]; then exit 1 fi #Change keystore password -${TESTJAVA}${FS}bin${FS}keytool -storepasswd -new storepass2 -keystore keystoreCA.dks -storetype "dks" -storepass storepass -provider "org.test.dummy.DummyProvider" -providerPath ${TESTCLASSES} +${TESTJAVA}${FS}bin${FS}keytool -storepasswd -new storepass2 \ + -keystore keystoreCA.dks -storetype "dks" -storepass storepass \ + -provider "org.test.dummy.DummyProvider" -providerPath ${TESTCLASSES} if [ $? -ne 0 ]; then exit 1 @@ -81,21 +94,29 @@ fi #Change keystore key password -${TESTJAVA}${FS}bin${FS}keytool -keypasswd -alias "dummyTestCA" -keypass storepass -new keypass -keystore keystoreCA.dks -storetype "dks" -storepass storepass2 -provider "org.test.dummy.DummyProvider" -providerPath ${TESTCLASSES} +${TESTJAVA}${FS}bin${FS}keytool -keypasswd -alias "dummyTestCA" \ + -keypass storepass -new keypass -keystore keystoreCA.dks \ + -storetype "dks" -storepass storepass2 \ + -provider "org.test.dummy.DummyProvider" -providerPath ${TESTCLASSES} if [ $? -ne 0 ]; then exit 1 fi #Export certificate -${TESTJAVA}${FS}bin${FS}keytool -v -export -rfc -alias "dummyTestCA" -file "dummyTestCA.der" -keystore keystoreCA.dks -storetype "dks" -storepass storepass2 -provider "org.test.dummy.DummyProvider" -providerPath ${TESTCLASSES} +${TESTJAVA}${FS}bin${FS}keytool -v -export -rfc -alias "dummyTestCA" \ + -file "dummyTestCA.der" -keystore keystoreCA.dks -storetype "dks" \ + -storepass storepass2 -provider "org.test.dummy.DummyProvider" \ + -providerPath ${TESTCLASSES} if [ $? -ne 0 ]; then exit 1 fi #list keystore -${TESTJAVA}${FS}bin${FS}keytool -v -list -keystore keystoreCA.dks -storetype "dks" -storepass storepass2 -provider "org.test.dummy.DummyProvider" -providerPath ${TESTCLASSES} +${TESTJAVA}${FS}bin${FS}keytool -v -list -keystore keystoreCA.dks \ + -storetype "dks" -storepass storepass2 \ + -provider "org.test.dummy.DummyProvider" -providerPath ${TESTCLASSES} if [ $? -ne 0 ]; then exit 1 diff --git a/jdk/test/sun/security/tools/keytool/CloneKeyAskPassword.sh b/jdk/test/sun/security/tools/keytool/CloneKeyAskPassword.sh index c5bbca9786c..4934fc7b6ce 100644 --- a/jdk/test/sun/security/tools/keytool/CloneKeyAskPassword.sh +++ b/jdk/test/sun/security/tools/keytool/CloneKeyAskPassword.sh @@ -55,6 +55,10 @@ case "$OS" in PATHSEP=":" FILESEP="/" ;; + CYGWIN* ) + PATHSEP=";" + FILESEP="/" + ;; Windows* ) PATHSEP=";" FILESEP="\\" diff --git a/jdk/test/sun/security/tools/keytool/NoExtNPE.sh b/jdk/test/sun/security/tools/keytool/NoExtNPE.sh index 3e929b5354f..80cc3c85aea 100644 --- a/jdk/test/sun/security/tools/keytool/NoExtNPE.sh +++ b/jdk/test/sun/security/tools/keytool/NoExtNPE.sh @@ -48,6 +48,9 @@ case "$OS" in Linux ) FILESEP="/" ;; + CYGWIN* ) + FILESEP="/" + ;; Windows* ) FILESEP="\\" ;; diff --git a/jdk/test/sun/security/tools/keytool/SecretKeyKS.sh b/jdk/test/sun/security/tools/keytool/SecretKeyKS.sh index 96a1885db9f..787e37e04a5 100644 --- a/jdk/test/sun/security/tools/keytool/SecretKeyKS.sh +++ b/jdk/test/sun/security/tools/keytool/SecretKeyKS.sh @@ -51,6 +51,12 @@ case "$OS" in FS="/" TMP=/tmp ;; + CYGWIN* ) + NULL=/dev/null + PS=";" + FS="/" + TMP=/tmp + ;; Windows_* ) NULL=NUL PS=";" diff --git a/jdk/test/sun/security/tools/keytool/StandardAlgName.sh b/jdk/test/sun/security/tools/keytool/StandardAlgName.sh index 77e9a98ef93..82e9e208e10 100644 --- a/jdk/test/sun/security/tools/keytool/StandardAlgName.sh +++ b/jdk/test/sun/security/tools/keytool/StandardAlgName.sh @@ -52,6 +52,12 @@ case "$OS" in FS="/" TMP=/tmp ;; + CYGWIN* ) + NULL=/dev/null + PS=";" + FS="/" + TMP=/tmp + ;; Windows_* ) NULL=NUL PS=";" diff --git a/jdk/test/sun/security/tools/keytool/i18n.sh b/jdk/test/sun/security/tools/keytool/i18n.sh index 2d37ae97664..33abf76f62e 100644 --- a/jdk/test/sun/security/tools/keytool/i18n.sh +++ b/jdk/test/sun/security/tools/keytool/i18n.sh @@ -52,6 +52,12 @@ case "$OS" in FS="/" TMP=/tmp ;; + CYGWIN* ) + NULL=/dev/null + PS=";" + FS="/" + TMP=/tmp + ;; Windows* ) NULL=NUL PS=";" diff --git a/jdk/test/sun/security/tools/keytool/printssl.sh b/jdk/test/sun/security/tools/keytool/printssl.sh index 9fc19cd9b20..73bd21cb83b 100644 --- a/jdk/test/sun/security/tools/keytool/printssl.sh +++ b/jdk/test/sun/security/tools/keytool/printssl.sh @@ -40,6 +40,9 @@ case "$OS" in SunOS | Linux ) FS="/" ;; + CYGWIN* ) + FS="/" + ;; Windows_* ) FS="\\" ;; diff --git a/jdk/test/sun/security/tools/keytool/resource.sh b/jdk/test/sun/security/tools/keytool/resource.sh index ab8e9520555..1fc515217ae 100644 --- a/jdk/test/sun/security/tools/keytool/resource.sh +++ b/jdk/test/sun/security/tools/keytool/resource.sh @@ -48,6 +48,11 @@ case "$OS" in FS="/" TMP=/tmp ;; + CYGWIN* ) + NULL=/dev/null + FS="/" + TMP=/tmp + ;; Windows_* ) NULL=NUL FS="\\" diff --git a/jdk/test/sun/security/tools/keytool/standard.sh b/jdk/test/sun/security/tools/keytool/standard.sh index f3e052ed510..4328c681454 100644 --- a/jdk/test/sun/security/tools/keytool/standard.sh +++ b/jdk/test/sun/security/tools/keytool/standard.sh @@ -44,11 +44,15 @@ fi # set platform-dependent variables OS=`uname -s` case "$OS" in + SunOS | Linux | CYGWIN* ) + FS="/" + ;; Windows_* ) FS="\\" ;; * ) - FS="/" + echo "Unrecognized system!" + exit 1; ;; esac From d8b50037deb6faedcaa86d9982ee96fa0427675b Mon Sep 17 00:00:00 2001 From: John R Rose Date: Thu, 6 Aug 2009 18:30:33 -0700 Subject: [PATCH 64/96] 6838598: Legal notice repair: jdk/src/share/classes/sun/dyn/FilterGeneric.java Reviewed-by: xdono --- jdk/src/share/classes/sun/dyn/FilterGeneric.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/share/classes/sun/dyn/FilterGeneric.java b/jdk/src/share/classes/sun/dyn/FilterGeneric.java index a99eb26c9ee..a746ad21b95 100644 --- a/jdk/src/share/classes/sun/dyn/FilterGeneric.java +++ b/jdk/src/share/classes/sun/dyn/FilterGeneric.java @@ -16,7 +16,7 @@ * * 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 Sf, tifth Floor, Boston, MA 02110-1301 USA. + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or From 75379fe244cd0b17776116f0ef7ea4496508cfa4 Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Fri, 7 Aug 2009 10:50:26 +0100 Subject: [PATCH 65/96] 6826780: URLClassPath should use HashMap instead of HashMap Replace URL with a String representation. Reviewed-by: michaelm, jccollet --- jdk/make/sun/net/FILES_java.gmk | 1 + .../share/classes/sun/misc/URLClassPath.java | 28 ++++--- .../share/classes/sun/net/util/URLUtil.java | 80 +++++++++++++++++++ 3 files changed, 97 insertions(+), 12 deletions(-) create mode 100644 jdk/src/share/classes/sun/net/util/URLUtil.java diff --git a/jdk/make/sun/net/FILES_java.gmk b/jdk/make/sun/net/FILES_java.gmk index 3d729947667..5082c3d370f 100644 --- a/jdk/make/sun/net/FILES_java.gmk +++ b/jdk/make/sun/net/FILES_java.gmk @@ -41,6 +41,7 @@ FILES_java = \ sun/net/NetProperties.java \ sun/net/NetHooks.java \ sun/net/util/IPAddressUtil.java \ + sun/net/util/URLUtil.java \ sun/net/dns/ResolverConfiguration.java \ sun/net/dns/ResolverConfigurationImpl.java \ sun/net/ftp/FtpClient.java \ diff --git a/jdk/src/share/classes/sun/misc/URLClassPath.java b/jdk/src/share/classes/sun/misc/URLClassPath.java index d9b1035ba6d..5c60e2fe81d 100644 --- a/jdk/src/share/classes/sun/misc/URLClassPath.java +++ b/jdk/src/share/classes/sun/misc/URLClassPath.java @@ -51,6 +51,7 @@ import java.security.PrivilegedAction; import java.security.PrivilegedExceptionAction; import java.security.cert.Certificate; import sun.misc.FileURLMapper; +import sun.net.util.URLUtil; /** * This class is used to maintain a search path of URLs for loading classes @@ -80,7 +81,7 @@ public class URLClassPath { ArrayList loaders = new ArrayList(); /* Map of each URL opened to its corresponding Loader */ - HashMap lmap = new HashMap(); + HashMap lmap = new HashMap(); /* The jar protocol handler to use when creating new URLs */ private URLStreamHandler jarHandler; @@ -317,7 +318,8 @@ public class URLClassPath { // Skip this URL if it already has a Loader. (Loader // may be null in the case where URL has not been opened // but is referenced by a JAR index.) - if (lmap.containsKey(url)) { + String urlNoFragString = URLUtil.urlNoFragString(url); + if (lmap.containsKey(urlNoFragString)) { continue; } // Otherwise, create a new Loader for the URL. @@ -336,7 +338,7 @@ public class URLClassPath { } // Finally, add the Loader to the search path. loaders.add(loader); - lmap.put(url, loader); + lmap.put(urlNoFragString, loader); } return loaders.get(index); } @@ -576,7 +578,7 @@ public class URLClassPath { private JarIndex index; private MetaIndex metaIndex; private URLStreamHandler handler; - private HashMap lmap; + private HashMap lmap; private boolean closed = false; /* @@ -584,7 +586,7 @@ public class URLClassPath { * a JAR file. */ JarLoader(URL url, URLStreamHandler jarHandler, - HashMap loaderMap) + HashMap loaderMap) throws IOException { super(new URL("jar", "", -1, url + "!/", jarHandler)); @@ -663,8 +665,9 @@ public class URLClassPath { try { URL jarURL = new URL(csu, jarfiles[i]); // If a non-null loader already exists, leave it alone. - if (!lmap.containsKey(jarURL)) { - lmap.put(jarURL, null); + String urlNoFragString = URLUtil.urlNoFragString(jarURL); + if (!lmap.containsKey(urlNoFragString)) { + lmap.put(urlNoFragString, null); } } catch (MalformedURLException e) { continue; @@ -806,7 +809,7 @@ public class URLClassPath { if (index == null) return null; - HashSet visited = new HashSet(); + HashSet visited = new HashSet(); return getResource(name, check, visited); } @@ -818,7 +821,7 @@ public class URLClassPath { * non-existent resource */ Resource getResource(final String name, boolean check, - Set visited) { + Set visited) { Resource res; Object[] jarFiles; @@ -843,7 +846,8 @@ public class URLClassPath { try{ url = new URL(csu, jarName); - if ((newLoader = (JarLoader)lmap.get(url)) == null) { + String urlNoFragString = URLUtil.urlNoFragString(url); + if ((newLoader = (JarLoader)lmap.get(urlNoFragString)) == null) { /* no loader has been set up for this jar file * before */ @@ -867,7 +871,7 @@ public class URLClassPath { } /* put it in the global hashtable */ - lmap.put(url, newLoader); + lmap.put(urlNoFragString, newLoader); } } catch (java.security.PrivilegedActionException pae) { continue; @@ -879,7 +883,7 @@ public class URLClassPath { /* Note that the addition of the url to the list of visited * jars incorporates a check for presence in the hashmap */ - boolean visitedURL = !visited.add(url); + boolean visitedURL = !visited.add(URLUtil.urlNoFragString(url)); if (!visitedURL) { try { newLoader.ensureOpen(); diff --git a/jdk/src/share/classes/sun/net/util/URLUtil.java b/jdk/src/share/classes/sun/net/util/URLUtil.java new file mode 100644 index 00000000000..047df3ebe9a --- /dev/null +++ b/jdk/src/share/classes/sun/net/util/URLUtil.java @@ -0,0 +1,80 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.net.util; + +import java.net.URL; + +/** + * URL Utility class. + */ +public class URLUtil { + /** + * Returns a string form of the url suitable for use as a key in HashMap/Sets. + * + * The string form should be behave in the same manner as the URL when + * compared for equality in a HashMap/Set, except that no nameservice + * lookup is done on the hostname (only string comparison), and the fragment + * is not considered. + * + * @see java.net.URLStreamHandler.sameFile(java.net.URL) + */ + public static String urlNoFragString(URL url) { + StringBuilder strForm = new StringBuilder(); + + String protocol = url.getProtocol(); + if (protocol != null) { + /* protocol is compared case-insensitive, so convert to lowercase */ + protocol = protocol.toLowerCase(); + strForm.append(protocol); + strForm.append("://"); + } + + String host = url.getHost(); + if (host != null) { + /* host is compared case-insensitive, so convert to lowercase */ + host = host.toLowerCase(); + strForm.append(host); + + int port = url.getPort(); + if (port == -1) { + /* if no port is specificed then use the protocols + * default, if there is one */ + port = url.getDefaultPort(); + } + if (port != -1) { + strForm.append(":").append(port); + } + } + + String file = url.getFile(); + if (file != null) { + strForm.append(file); + } + + return strForm.toString(); + } +} + From aca1227406040fd2663b684acc00692d62b342e9 Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Fri, 7 Aug 2009 10:51:25 +0100 Subject: [PATCH 66/96] 6826801: JarFileFactory should not use HashMap Replace URL with a String representation. Reviewed-by: michaelm, jccollet --- .../net/www/protocol/jar/JarFileFactory.java | 26 ++++++++++--------- .../net/www/protocol/jar/JarFileFactory.java | 26 ++++++++++--------- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/jdk/src/solaris/classes/sun/net/www/protocol/jar/JarFileFactory.java b/jdk/src/solaris/classes/sun/net/www/protocol/jar/JarFileFactory.java index c51f15eaec9..0d1b3099836 100644 --- a/jdk/src/solaris/classes/sun/net/www/protocol/jar/JarFileFactory.java +++ b/jdk/src/solaris/classes/sun/net/www/protocol/jar/JarFileFactory.java @@ -25,12 +25,14 @@ package sun.net.www.protocol.jar; -import java.io.*; -import java.net.*; -import java.util.*; -import java.util.jar.*; -import java.util.zip.ZipFile; +import java.io.IOException; +import java.io.FileNotFoundException; +import java.net.URL; +import java.net.URLConnection; +import java.util.HashMap; +import java.util.jar.JarFile; import java.security.Permission; +import sun.net.util.URLUtil; /* A factory for cached JAR file. This class is used to both retrieve * and cache Jar files. @@ -41,13 +43,13 @@ import java.security.Permission; class JarFileFactory implements URLJarFile.URLJarFileCloseController { /* the url to file cache */ - private static HashMap fileCache = new HashMap(); + private static HashMap fileCache = new HashMap(); /* the file to url cache */ - private static HashMap urlCache = new HashMap(); + private static HashMap urlCache = new HashMap(); URLConnection getConnection(JarFile jarFile) throws IOException { - URL u = (URL)urlCache.get(jarFile); + URL u = urlCache.get(jarFile); if (u != null) return u.openConnection(); @@ -72,7 +74,7 @@ class JarFileFactory implements URLJarFile.URLJarFileCloseController { synchronized (this) { result = getCachedJarFile(url); if (result == null) { - fileCache.put(url, local_result); + fileCache.put(URLUtil.urlNoFragString(url), local_result); urlCache.put(local_result, url); result = local_result; } else { @@ -97,15 +99,15 @@ class JarFileFactory implements URLJarFile.URLJarFileCloseController { * remove the JarFile from the cache */ public void close(JarFile jarFile) { - URL urlRemoved = (URL) urlCache.remove(jarFile); + URL urlRemoved = urlCache.remove(jarFile); if( urlRemoved != null) { - fileCache.remove(urlRemoved); + fileCache.remove(URLUtil.urlNoFragString(urlRemoved)); } } private JarFile getCachedJarFile(URL url) { - JarFile result = (JarFile)fileCache.get(url); + JarFile result = fileCache.get(URLUtil.urlNoFragString(url)); /* if the JAR file is cached, the permission will always be there */ if (result != null) { diff --git a/jdk/src/windows/classes/sun/net/www/protocol/jar/JarFileFactory.java b/jdk/src/windows/classes/sun/net/www/protocol/jar/JarFileFactory.java index 3192c52d030..9df86326e40 100644 --- a/jdk/src/windows/classes/sun/net/www/protocol/jar/JarFileFactory.java +++ b/jdk/src/windows/classes/sun/net/www/protocol/jar/JarFileFactory.java @@ -25,12 +25,14 @@ package sun.net.www.protocol.jar; -import java.io.*; -import java.net.*; -import java.util.*; -import java.util.jar.*; -import java.util.zip.ZipFile; +import java.io.IOException; +import java.io.FileNotFoundException; +import java.net.URL; +import java.net.URLConnection; +import java.util.HashMap; +import java.util.jar.JarFile; import java.security.Permission; +import sun.net.util.URLUtil; /* A factory for cached JAR file. This class is used to both retrieve * and cache Jar files. @@ -41,13 +43,13 @@ import java.security.Permission; class JarFileFactory implements URLJarFile.URLJarFileCloseController { /* the url to file cache */ - private static HashMap fileCache = new HashMap(); + private static HashMap fileCache = new HashMap(); /* the file to url cache */ - private static HashMap urlCache = new HashMap(); + private static HashMap urlCache = new HashMap(); URLConnection getConnection(JarFile jarFile) throws IOException { - URL u = (URL)urlCache.get(jarFile); + URL u = urlCache.get(jarFile); if (u != null) return u.openConnection(); @@ -82,7 +84,7 @@ class JarFileFactory implements URLJarFile.URLJarFileCloseController { synchronized (this) { result = getCachedJarFile(url); if (result == null) { - fileCache.put(url, local_result); + fileCache.put(URLUtil.urlNoFragString(url), local_result); urlCache.put(local_result, url); result = local_result; } else { @@ -107,14 +109,14 @@ class JarFileFactory implements URLJarFile.URLJarFileCloseController { * remove the JarFile from the cache */ public void close(JarFile jarFile) { - URL urlRemoved = (URL) urlCache.remove(jarFile); + URL urlRemoved = urlCache.remove(jarFile); if( urlRemoved != null) { - fileCache.remove(urlRemoved); + fileCache.remove(URLUtil.urlNoFragString(urlRemoved)); } } private JarFile getCachedJarFile(URL url) { - JarFile result = (JarFile)fileCache.get(url); + JarFile result = fileCache.get(URLUtil.urlNoFragString(url)); /* if the JAR file is cached, the permission will always be there */ if (result != null) { From 9a5d0532c5334b2448bff1946250972594c82a9d Mon Sep 17 00:00:00 2001 From: Andrew John Hughes Date: Fri, 7 Aug 2009 18:15:03 +0100 Subject: [PATCH 67/96] 6869697: Missing entry in makefiles for java/lang/ReflectiveOperationException.java Add new dependency explicitly so all compilers pick it up Reviewed-by: darcy, ohair --- jdk/make/java/java/FILES_java.gmk | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/make/java/java/FILES_java.gmk b/jdk/make/java/java/FILES_java.gmk index f9dd26383ce..e8a2223f67a 100644 --- a/jdk/make/java/java/FILES_java.gmk +++ b/jdk/make/java/java/FILES_java.gmk @@ -77,6 +77,7 @@ JAVA_JAVA_java = \ java/lang/Compiler.java \ java/lang/Throwable.java \ java/lang/Exception.java \ + java/lang/ReflectiveOperationException.java \ java/lang/IllegalAccessException.java \ java/lang/InstantiationException.java \ java/lang/ClassNotFoundException.java \ From 02d508cbf217eb2029384a21757d030cf7ebe8f1 Mon Sep 17 00:00:00 2001 From: Abhijit Saha Date: Fri, 7 Aug 2009 11:32:04 -0700 Subject: [PATCH 68/96] 6803688: Integrate latest JAX-WS (2.1.6) in to JDK 6u14 Reviewed-by: darcy, ramap --- jdk/THIRD_PARTY_README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/THIRD_PARTY_README b/jdk/THIRD_PARTY_README index 690890548f2..43058486295 100644 --- a/jdk/THIRD_PARTY_README +++ b/jdk/THIRD_PARTY_README @@ -32,7 +32,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. --- end of LICENSE file --- %% This notice is provided with respect to ASM, which may be included with this software: -Copyright (c) 2000-2005 INRIA, France Telecom +Copyright (c) 2000-2007 INRIA, France Telecom All rights reserved. Redistribution and use in source and binary forms, with or without From cb2742d7b21cfe83b391b9dd8a98f326cd12ecf0 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Tue, 11 Aug 2009 12:15:24 +0800 Subject: [PATCH 69/96] 6866479: libzip.so caused JVM to crash when running jarsigner Reviewed-by: mullan --- .../classes/sun/security/tools/JarSigner.java | 10 +++ .../sun/security/tools/jarsigner/samename.sh | 61 +++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 jdk/test/sun/security/tools/jarsigner/samename.sh diff --git a/jdk/src/share/classes/sun/security/tools/JarSigner.java b/jdk/src/share/classes/sun/security/tools/JarSigner.java index 76a9c403145..fd0797a854d 100644 --- a/jdk/src/share/classes/sun/security/tools/JarSigner.java +++ b/jdk/src/share/classes/sun/security/tools/JarSigner.java @@ -412,6 +412,16 @@ public class JarSigner { } storetype = KeyStoreUtil.niceStoreTypeName(storetype); + try { + if (signedjar != null && new File(signedjar).getCanonicalPath().equals( + new File(jarfile).getCanonicalPath())) { + signedjar = null; + } + } catch (IOException ioe) { + // File system error? + // Just ignore it. + } + if (P11KEYSTORE.equalsIgnoreCase(storetype) || KeyStoreUtil.isWindowsKeyStore(storetype)) { token = true; diff --git a/jdk/test/sun/security/tools/jarsigner/samename.sh b/jdk/test/sun/security/tools/jarsigner/samename.sh new file mode 100644 index 00000000000..7949088a7b9 --- /dev/null +++ b/jdk/test/sun/security/tools/jarsigner/samename.sh @@ -0,0 +1,61 @@ +# +# Copyright 2009 Sun Microsystems, Inc. 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. +# +# 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +# CA 95054 USA or visit www.sun.com if you need additional information or +# have any questions. +# + +# @test +# @bug 6866479 +# @summary libzip.so caused JVM to crash when running jarsigner +# + +if [ "${TESTJAVA}" = "" ] ; then + JAVAC_CMD=`which javac` + TESTJAVA=`dirname $JAVAC_CMD`/.. +fi + +# set platform-dependent variables +OS=`uname -s` +case "$OS" in + Windows_* | CYGWIN* ) + SIGNEDJAR=EM.jar + FS="\\" + ;; + * ) + SIGNEDJAR=em.jar + FS="/" + ;; +esac + +KS=samename.jks +JFILE=em.jar + +KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit -keystore $KS" +JAR=$TESTJAVA${FS}bin${FS}jar +JARSIGNER=$TESTJAVA${FS}bin${FS}jarsigner + +rm $KS $JFILE $SIGNEDJAR +echo A > A +$JAR cvf $JFILE A + +$KT -alias a -dname CN=a -keyalg rsa -genkey -validity 300 + +$JARSIGNER -keystore $KS -storepass changeit -signedjar $SIGNEDJAR $JFILE a + From 50689ce53631940317bc75381f2aedce1b344029 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Tue, 11 Aug 2009 12:17:13 +0800 Subject: [PATCH 70/96] 6710360: export Kerberos session key to applications Reviewed-by: valeriep --- .../sun/security/jgss/ExtendedGSSContext.java | 90 +++++++++++++++++++ .../jgss/InquireSecContextPermission.java | 54 +++++++++++ .../com/sun/security/jgss/InquireType.java | 38 ++++++++ .../sun/security/jgss/GSSContextImpl.java | 19 +++- .../sun/security/jgss/krb5/Krb5Context.java | 52 +++++++++++ .../sun/security/jgss/spi/GSSContextSpi.java | 16 +++- .../security/jgss/spnego/SpNegoContext.java | 22 ++++- .../jgss/wrapper/NativeGSSContext.java | 9 +- .../sun/security/tools/PolicyTool.java | 19 ++-- .../InquireSecContextPermissionCheck.java | 50 +++++++++++ jdk/test/sun/security/krb5/auto/Context.java | 16 +++- 11 files changed, 368 insertions(+), 17 deletions(-) create mode 100644 jdk/src/share/classes/com/sun/security/jgss/ExtendedGSSContext.java create mode 100644 jdk/src/share/classes/com/sun/security/jgss/InquireSecContextPermission.java create mode 100644 jdk/src/share/classes/com/sun/security/jgss/InquireType.java create mode 100644 jdk/test/com/sun/security/jgss/InquireSecContextPermissionCheck.java diff --git a/jdk/src/share/classes/com/sun/security/jgss/ExtendedGSSContext.java b/jdk/src/share/classes/com/sun/security/jgss/ExtendedGSSContext.java new file mode 100644 index 00000000000..ed1ab747136 --- /dev/null +++ b/jdk/src/share/classes/com/sun/security/jgss/ExtendedGSSContext.java @@ -0,0 +1,90 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.security.jgss; + +import org.ietf.jgss.*; + +/** + * The extended GSSContext interface for supporting additional + * functionalities not defined by {@code org.ietf.jgss.GSSContext}, + * such as querying context-specific attributes. + */ +public interface ExtendedGSSContext extends GSSContext { + /** + * Return the mechanism-specific attribute associated with {@code type}. + *

    + * For each supported attribute type, the type for the output are + * defined below. + *

      + *
    1. {@code KRB5_GET_SESSION_KEY}: + * the returned object is an instance of {@link java.security.Key}, + * which has the following properties: + *
        + *
      • Algorithm: enctype as a string, where + * enctype is defined in RFC 3961, section 8. + *
      • Format: "RAW" + *
      • Encoded form: the raw key bytes, not in any ASN.1 encoding + *
      + *
    + * + * If there is a security manager, an {@link InquireSecContextPermission} + * with the name {@code type.mech} must be granted. Otherwise, this could + * result in a {@link SecurityException}.

    + * + * Example: + *

    +     *      GSSContext ctxt = m.createContext(...)
    +     *      // Establishing the context
    +     *      if (ctxt instanceof ExtendedGSSContext) {
    +     *          ExtendedGSSContext ex = (ExtendedGSSContext)ctxt;
    +     *          try {
    +     *              Key key = (key)ex.inquireSecContext(
    +     *                      InquireType.KRB5_GET_SESSION_KEY);
    +     *              // read key info
    +     *          } catch (GSSException gsse) {
    +     *              // deal with exception
    +     *          }
    +     *      }
    +     * 
    + * @param type the type of the attribute requested + * @return the attribute, see the method documentation for details. + * @throws GSSException containing the following + * major error codes: + * {@link GSSException#BAD_MECH GSSException.BAD_MECH} if the mechanism + * does not support this method, + * {@link GSSException#UNAVAILABLE GSSException.UNAVAILABLE} if the + * type specified is not supported, + * {@link GSSException#NO_CONTEXT GSSException.NO_CONTEXT} if the + * security context is invalid, + * {@link GSSException#FAILURE GSSException.FAILURE} for other + * unspecified failures. + * @throws SecurityException if a security manager exists and a proper + * {@link InquireSecContextPermission} is not granted. + * @see InquireSecContextPermission + */ + public Object inquireSecContext(InquireType type) + throws GSSException; +} diff --git a/jdk/src/share/classes/com/sun/security/jgss/InquireSecContextPermission.java b/jdk/src/share/classes/com/sun/security/jgss/InquireSecContextPermission.java new file mode 100644 index 00000000000..2acb9ab9e97 --- /dev/null +++ b/jdk/src/share/classes/com/sun/security/jgss/InquireSecContextPermission.java @@ -0,0 +1,54 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.security.jgss; + +import java.security.BasicPermission; + +/** + * This class is used to protect various attributes of an established + * GSS security context that can be accessed using the + * {@link com.sun.security.jgss.ExtendedGSSContext#inquireSecContext} + * method. + * + *

    The target name is the {@link InquireType} allowed. + */ +public final class InquireSecContextPermission extends BasicPermission { + + /** + * Constructs a new {@code InquireSecContextPermission} object with + * the specified name. The name is the symbolic name of the + * {@link InquireType} allowed. + * + * @param name the {@link InquireType} allowed by this + * permission. "*" means all {@link InquireType}s are allowed. + * + * @throws NullPointerException if name is null. + * @throws IllegalArgumentException if name is empty. + */ + public InquireSecContextPermission(String name) { + super(name); + } +} diff --git a/jdk/src/share/classes/com/sun/security/jgss/InquireType.java b/jdk/src/share/classes/com/sun/security/jgss/InquireType.java new file mode 100644 index 00000000000..2b1d8172e72 --- /dev/null +++ b/jdk/src/share/classes/com/sun/security/jgss/InquireType.java @@ -0,0 +1,38 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.security.jgss; + +/** + * Attribute types that can be specified as an argument of + * {@link com.sun.security.jgss.ExtendedGSSContext#inquireSecContext} + */ +public enum InquireType { + /** + * Attribute type for retrieving the session key of an + * established security context. + */ + KRB5_GET_SESSION_KEY +} diff --git a/jdk/src/share/classes/sun/security/jgss/GSSContextImpl.java b/jdk/src/share/classes/sun/security/jgss/GSSContextImpl.java index 046f6478277..de703ef4ded 100644 --- a/jdk/src/share/classes/sun/security/jgss/GSSContextImpl.java +++ b/jdk/src/share/classes/sun/security/jgss/GSSContextImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2009 Sun Microsystems, Inc. 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 @@ -27,14 +27,13 @@ package sun.security.jgss; import org.ietf.jgss.*; import sun.security.jgss.spi.*; -import sun.security.jgss.*; import sun.security.util.ObjectIdentifier; import java.io.InputStream; import java.io.OutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; - +import com.sun.security.jgss.*; /** * This class represents the JGSS security context and its associated @@ -88,7 +87,7 @@ import java.io.IOException; * per-message operations are returned in an instance of the MessageProp * class, which is used as an argument in these calls. */ -class GSSContextImpl implements GSSContext { +class GSSContextImpl implements ExtendedGSSContext { private GSSManagerImpl gssManager = null; @@ -630,4 +629,16 @@ class GSSContextImpl implements GSSContext { srcName = null; targName = null; } + + @Override + public Object inquireSecContext(InquireType type) throws GSSException { + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkPermission(new InquireSecContextPermission(type.toString())); + } + if (mechCtxt == null) { + throw new GSSException(GSSException.NO_CONTEXT); + } + return mechCtxt.inquireSecContext(type); + } } diff --git a/jdk/src/share/classes/sun/security/jgss/krb5/Krb5Context.java b/jdk/src/share/classes/sun/security/jgss/krb5/Krb5Context.java index f2ef7d59875..48d62c76c26 100644 --- a/jdk/src/share/classes/sun/security/jgss/krb5/Krb5Context.java +++ b/jdk/src/share/classes/sun/security/jgss/krb5/Krb5Context.java @@ -25,6 +25,7 @@ package sun.security.jgss.krb5; +import com.sun.security.jgss.InquireType; import org.ietf.jgss.*; import sun.misc.HexDumpEncoder; import sun.security.jgss.GSSUtil; @@ -38,6 +39,7 @@ import java.io.IOException; import java.security.Provider; import java.security.AccessController; import java.security.AccessControlContext; +import java.security.Key; import java.security.PrivilegedExceptionAction; import java.security.PrivilegedActionException; import javax.crypto.Cipher; @@ -1283,4 +1285,54 @@ class Krb5Context implements GSSContextSpi { // Currently used by InitialToken only return caller; } + + /** + * The session key returned by inquireSecContext(KRB5_INQ_SSPI_SESSION_KEY) + */ + static class KerberosSessionKey implements Key { + private EncryptionKey key; + + KerberosSessionKey(EncryptionKey key) { + this.key = key; + } + + @Override + public String getAlgorithm() { + return Integer.toString(key.getEType()); + } + + @Override + public String getFormat() { + return "RAW"; + } + + @Override + public byte[] getEncoded() { + return key.getBytes().clone(); + } + + @Override + public String toString() { + return "Kerberos session key: etype: " + key.getEType() + "\n" + + new sun.misc.HexDumpEncoder().encodeBuffer(key.getBytes()); + } + } + + /** + * Return the mechanism-specific attribute associated with {@code type}. + * Only KRB5_GET_SESSION_KEY is supported now. + */ + public Object inquireSecContext(InquireType type) + throws GSSException { + if (type == InquireType.KRB5_GET_SESSION_KEY) { + if (key == null) { + throw new GSSException(GSSException.NO_CONTEXT, -1, + "Session key not established."); + } else { + return new KerberosSessionKey(key); + } + } + throw new GSSException(GSSException.UNAVAILABLE, -1, + "Inquire type not supported."); + } } diff --git a/jdk/src/share/classes/sun/security/jgss/spi/GSSContextSpi.java b/jdk/src/share/classes/sun/security/jgss/spi/GSSContextSpi.java index b4ce37a4c0e..5bf359a1f8c 100644 --- a/jdk/src/share/classes/sun/security/jgss/spi/GSSContextSpi.java +++ b/jdk/src/share/classes/sun/security/jgss/spi/GSSContextSpi.java @@ -1,5 +1,5 @@ /* - * Portions Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved. + * Portions Copyright 2000-2009 Sun Microsystems, Inc. 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 @@ -46,6 +46,7 @@ import org.ietf.jgss.*; import java.io.InputStream; import java.io.OutputStream; import java.security.Provider; +import com.sun.security.jgss.*; /** * This interface is implemented by a mechanism specific instance of a GSS @@ -265,7 +266,6 @@ public interface GSSContextSpi { * @param msgPro on input it contains the requested qop and * confidentiality state, on output, the applied values * @exception GSSException may be thrown - * @see MessageInfo * @see unwrap */ public void wrap(InputStream is, OutputStream os, MessageProp msgProp) @@ -315,7 +315,6 @@ public interface GSSContextSpi { * @param msgProp will contain the applied qop and confidentiality * of the input token and any informatory status values * @exception GSSException may be thrown - * @see MessageInfo * @see wrap */ public void unwrap(InputStream is, OutputStream os, @@ -403,4 +402,15 @@ public interface GSSContextSpi { * @exception GSSException may be thrown */ public void dispose() throws GSSException; + + /** + * Return the mechanism-specific attribute associated with (@code type}. + * + * @param type the type of the attribute requested + * @return the attribute + * @throws GSSException see {@link ExtendedGSSContext#inquireSecContext} + * for details + */ + public Object inquireSecContext(InquireType type) + throws GSSException; } diff --git a/jdk/src/share/classes/sun/security/jgss/spnego/SpNegoContext.java b/jdk/src/share/classes/sun/security/jgss/spnego/SpNegoContext.java index a84e8a26001..a436092f1bb 100644 --- a/jdk/src/share/classes/sun/security/jgss/spnego/SpNegoContext.java +++ b/jdk/src/share/classes/sun/security/jgss/spnego/SpNegoContext.java @@ -25,10 +25,10 @@ package sun.security.jgss.spnego; +import com.sun.security.jgss.ExtendedGSSContext; +import com.sun.security.jgss.InquireType; import java.io.*; import java.security.Provider; -import java.util.List; -import java.util.ArrayList; import org.ietf.jgss.*; import sun.security.jgss.*; import sun.security.jgss.spi.*; @@ -1185,4 +1185,22 @@ public class SpNegoContext implements GSSContextSpi { return ("Unknown state " + state); } } + + /** + * Retrieve attribute of the context for {@code type}. + */ + public Object inquireSecContext(InquireType type) + throws GSSException { + if (mechContext == null) { + throw new GSSException(GSSException.NO_CONTEXT, -1, + "Underlying mech not established."); + } + if (mechContext instanceof ExtendedGSSContext) { + return ((ExtendedGSSContext)mechContext).inquireSecContext(type); + } else { + throw new GSSException(GSSException.BAD_MECH, -1, + "inquireSecContext not supported by underlying mech."); + } + } + } diff --git a/jdk/src/share/classes/sun/security/jgss/wrapper/NativeGSSContext.java b/jdk/src/share/classes/sun/security/jgss/wrapper/NativeGSSContext.java index 63f37e47614..5b2a670b054 100644 --- a/jdk/src/share/classes/sun/security/jgss/wrapper/NativeGSSContext.java +++ b/jdk/src/share/classes/sun/security/jgss/wrapper/NativeGSSContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2009 Sun Microsystems, Inc. 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 @@ -36,6 +36,7 @@ import sun.security.util.ObjectIdentifier; import sun.security.jgss.spnego.NegTokenInit; import sun.security.jgss.spnego.NegTokenTarg; import javax.security.auth.kerberos.DelegationPermission; +import com.sun.security.jgss.InquireType; import java.io.*; @@ -615,4 +616,10 @@ class NativeGSSContext implements GSSContextSpi { protected void finalize() throws Throwable { dispose(); } + + public Object inquireSecContext(InquireType type) + throws GSSException { + throw new GSSException(GSSException.UNAVAILABLE, -1, + "Inquire type not supported."); + } } diff --git a/jdk/src/share/classes/sun/security/tools/PolicyTool.java b/jdk/src/share/classes/sun/security/tools/PolicyTool.java index c2c6218bd35..afc3a9b8988 100644 --- a/jdk/src/share/classes/sun/security/tools/PolicyTool.java +++ b/jdk/src/share/classes/sun/security/tools/PolicyTool.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2009 Sun Microsystems, Inc. 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 @@ -35,21 +35,16 @@ import java.net.MalformedURLException; import java.lang.reflect.*; import java.text.Collator; import java.text.MessageFormat; -import sun.misc.BASE64Decoder; -import sun.security.provider.PolicyParser.PermissionEntry; import sun.security.util.PropertyExpander; import sun.security.util.PropertyExpander.ExpandException; import java.awt.*; import java.awt.event.*; import java.security.cert.Certificate; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; import java.security.cert.CertificateException; import java.security.*; import sun.security.provider.*; import sun.security.util.PolicyUtil; import javax.security.auth.x500.X500Principal; -import java.util.HashSet; /** * PolicyTool may be used by users and administrators to configure the @@ -1459,6 +1454,7 @@ class ToolDialog extends Dialog { PERM_ARRAY.add(new AWTPerm()); PERM_ARRAY.add(new DelegationPerm()); PERM_ARRAY.add(new FilePerm()); + PERM_ARRAY.add(new InqSecContextPerm()); PERM_ARRAY.add(new LogPerm()); PERM_ARRAY.add(new MgmtPerm()); PERM_ARRAY.add(new MBeanPerm()); @@ -3961,6 +3957,17 @@ class FilePerm extends Perm { } } +class InqSecContextPerm extends Perm { + public InqSecContextPerm() { + super("InquireSecContextPermission", + "com.sun.security.jgss.InquireSecContextPermission", + new String[] { + "KRB5_GET_SESSION_KEY" + }, + null); + } +} + class LogPerm extends Perm { public LogPerm() { super("LoggingPermission", diff --git a/jdk/test/com/sun/security/jgss/InquireSecContextPermissionCheck.java b/jdk/test/com/sun/security/jgss/InquireSecContextPermissionCheck.java new file mode 100644 index 00000000000..5a940ae91eb --- /dev/null +++ b/jdk/test/com/sun/security/jgss/InquireSecContextPermissionCheck.java @@ -0,0 +1,50 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6710360 + * @summary export Kerberos session key to applications + */ + +import com.sun.security.jgss.InquireSecContextPermission; + +public class InquireSecContextPermissionCheck { + + public static void main(String[] args) throws Exception { + + InquireSecContextPermission p0, p1; + p0 = new InquireSecContextPermission( + "KRB5_GET_SESSION_KEY"); + p1 = new InquireSecContextPermission("*"); + + if (!p1.implies(p0) || !p1.implies(p1) || !p0.implies(p0)) { + throw new Exception("Check failed"); + } + + if (p0.implies(p1)) { + throw new Exception("This is bad"); + } + } +} + diff --git a/jdk/test/sun/security/krb5/auto/Context.java b/jdk/test/sun/security/krb5/auto/Context.java index 2439aa24037..b8ce532be19 100644 --- a/jdk/test/sun/security/krb5/auto/Context.java +++ b/jdk/test/sun/security/krb5/auto/Context.java @@ -1,5 +1,5 @@ /* - * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2008-2009 Sun Microsystems, Inc. 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 @@ -22,6 +22,7 @@ */ import com.sun.security.auth.module.Krb5LoginModule; +import java.security.Key; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.util.Arrays; @@ -38,6 +39,8 @@ import org.ietf.jgss.GSSManager; import org.ietf.jgss.GSSName; import org.ietf.jgss.MessageProp; import org.ietf.jgss.Oid; +import com.sun.security.jgss.ExtendedGSSContext; +import com.sun.security.jgss.InquireType; /** * Context of a JGSS subject, encapsulating Subject and GSSContext. @@ -276,6 +279,17 @@ public class Context { } } } + if (x != null && x instanceof ExtendedGSSContext) { + if (x.isEstablished()) { + ExtendedGSSContext ex = (ExtendedGSSContext)x; + Key k = (Key)ex.inquireSecContext( + InquireType.KRB5_GET_SESSION_KEY); + if (k == null) { + throw new Exception("Session key cannot be null"); + } + System.out.println("Session key is: " + k); + } + } } /** From be3a1f1294df8c38d5c26c8377e897d8eb1325bb Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Tue, 11 Aug 2009 12:20:32 +0800 Subject: [PATCH 71/96] 6821190: more InquireType values for ExtendedGSSContext Reviewed-by: valeriep --- .../security/jgss/AuthorizationDataEntry.java | 68 +++++++++++++++++++ .../sun/security/jgss/ExtendedGSSContext.java | 12 ++++ .../com/sun/security/jgss/InquireType.java | 20 +++++- .../jgss/krb5/InitSecContextToken.java | 24 ++++++- .../sun/security/jgss/krb5/Krb5Context.java | 43 +++++++++--- .../sun/security/krb5/Credentials.java | 22 +++++- .../classes/sun/security/krb5/KrbApReq.java | 7 +- .../krb5/internal/AuthorizationData.java | 8 +++ .../sun/security/tools/PolicyTool.java | 5 +- jdk/test/sun/security/krb5/auto/Context.java | 18 +++++ 10 files changed, 210 insertions(+), 17 deletions(-) create mode 100644 jdk/src/share/classes/com/sun/security/jgss/AuthorizationDataEntry.java diff --git a/jdk/src/share/classes/com/sun/security/jgss/AuthorizationDataEntry.java b/jdk/src/share/classes/com/sun/security/jgss/AuthorizationDataEntry.java new file mode 100644 index 00000000000..0386792a7c2 --- /dev/null +++ b/jdk/src/share/classes/com/sun/security/jgss/AuthorizationDataEntry.java @@ -0,0 +1,68 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.security.jgss; + +/** + * Kerberos 5 AuthorizationData entry. + */ +final public class AuthorizationDataEntry { + + private final int type; + private final byte[] data; + + /** + * Create an AuthorizationDataEntry object. + * @param type the ad-type + * @param data the ad-data, a copy of the data will be saved + * inside the object. + */ + public AuthorizationDataEntry(int type, byte[] data) { + this.type = type; + this.data = data.clone(); + } + + /** + * Get the ad-type field. + * @return ad-type + */ + public int getType() { + return type; + } + + /** + * Get a copy of the ad-data field. + * @return ad-data + */ + public byte[] getData() { + return data.clone(); + } + + public String toString() { + return "AuthorizationDataEntry: type="+type+", data=" + + data.length + " bytes:\n" + + new sun.misc.HexDumpEncoder().encode(data); + } +} diff --git a/jdk/src/share/classes/com/sun/security/jgss/ExtendedGSSContext.java b/jdk/src/share/classes/com/sun/security/jgss/ExtendedGSSContext.java index ed1ab747136..dc7a3556d7d 100644 --- a/jdk/src/share/classes/com/sun/security/jgss/ExtendedGSSContext.java +++ b/jdk/src/share/classes/com/sun/security/jgss/ExtendedGSSContext.java @@ -39,6 +39,11 @@ public interface ExtendedGSSContext extends GSSContext { * For each supported attribute type, the type for the output are * defined below. *

      + *
    1. {@code KRB5_GET_TKT_FLAGS}: + * the returned object is a boolean array for the service ticket flags, + * which is long enough to contain all true bits. This means if + * the user wants to get the n'th bit but the length of the + * returned array is less than n, it is regarded as false. *
    2. {@code KRB5_GET_SESSION_KEY}: * the returned object is an instance of {@link java.security.Key}, * which has the following properties: @@ -48,6 +53,13 @@ public interface ExtendedGSSContext extends GSSContext { *
    3. Format: "RAW" *
    4. Encoded form: the raw key bytes, not in any ASN.1 encoding * + *
    5. {@code KRB5_GET_AUTHZ_DATA}: + * the returned object is an array of + * {@link com.sun.security.jgss.AuthorizationDataEntry}, or null if the + * optional field is missing in the service ticket. + *
    6. {@code KRB5_GET_AUTHTIME}: + * the returned object is a String object in the standard KerberosTime + * format defined in RFC 4120 5.2.3 *
    * * If there is a security manager, an {@link InquireSecContextPermission} diff --git a/jdk/src/share/classes/com/sun/security/jgss/InquireType.java b/jdk/src/share/classes/com/sun/security/jgss/InquireType.java index 2b1d8172e72..b9ea04098b5 100644 --- a/jdk/src/share/classes/com/sun/security/jgss/InquireType.java +++ b/jdk/src/share/classes/com/sun/security/jgss/InquireType.java @@ -32,7 +32,23 @@ package com.sun.security.jgss; public enum InquireType { /** * Attribute type for retrieving the session key of an - * established security context. + * established Kerberos 5 security context. */ - KRB5_GET_SESSION_KEY + KRB5_GET_SESSION_KEY, + /** + * Attribute type for retrieving the service ticket flags of an + * established Kerberos 5 security context. + */ + KRB5_GET_TKT_FLAGS, + /** + * Attribute type for retrieving the authorization data in the + * service ticket of an established Kerberos 5 security context. + * Only supported on the acceptor side. + */ + KRB5_GET_AUTHZ_DATA, + /** + * Attribute type for retrieving the authtime in the service ticket + * of an established Kerberos 5 security context. + */ + KRB5_GET_AUTHTIME } diff --git a/jdk/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java b/jdk/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java index 6706e8e4a4c..5f88068ccec 100644 --- a/jdk/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java +++ b/jdk/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2009 Sun Microsystems, Inc. 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 @@ -25,12 +25,14 @@ package sun.security.jgss.krb5; +import com.sun.security.jgss.AuthorizationDataEntry; import org.ietf.jgss.*; import java.io.InputStream; -import java.io.OutputStream; import java.io.IOException; import sun.security.krb5.*; import java.net.InetAddress; +import sun.security.krb5.internal.AuthorizationData; +import sun.security.krb5.internal.KerberosTime; class InitSecContextToken extends InitialToken { @@ -59,6 +61,9 @@ class InitSecContextToken extends InitialToken { Checksum checksum = gssChecksum.getChecksum(); + context.setTktFlags(serviceTicket.getFlags()); + context.setAuthTime( + new KerberosTime(serviceTicket.getAuthTime()).toString()); apReq = new KrbApReq(serviceTicket, mutualRequired, useSubkey, @@ -143,6 +148,21 @@ class InitSecContextToken extends InitialToken { // Use the same sequence number as the peer // (Behaviour exhibited by the Windows SSPI server) context.resetMySequenceNumber(peerSeqNumber); + context.setAuthTime( + new KerberosTime(apReq.getCreds().getAuthTime()).toString()); + context.setTktFlags(apReq.getCreds().getFlags()); + AuthorizationData ad = apReq.getCreds().getAuthzData(); + if (ad == null) { + context.setAuthzData(null); + } else { + AuthorizationDataEntry[] authzData = + new AuthorizationDataEntry[ad.count()]; + for (int i=0; i>> KrbApReq: authenticate succeed."); } diff --git a/jdk/src/share/classes/sun/security/krb5/internal/AuthorizationData.java b/jdk/src/share/classes/sun/security/krb5/internal/AuthorizationData.java index 269edec71a1..13c89dec7d8 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/AuthorizationData.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/AuthorizationData.java @@ -174,4 +174,12 @@ public class AuthorizationData implements Cloneable { } return retVal; } + + public int count() { + return entry.length; + } + + public AuthorizationDataEntry item(int i) { + return (AuthorizationDataEntry)entry[i].clone(); + } } diff --git a/jdk/src/share/classes/sun/security/tools/PolicyTool.java b/jdk/src/share/classes/sun/security/tools/PolicyTool.java index afc3a9b8988..ce54ba61ca9 100644 --- a/jdk/src/share/classes/sun/security/tools/PolicyTool.java +++ b/jdk/src/share/classes/sun/security/tools/PolicyTool.java @@ -3962,7 +3962,10 @@ class InqSecContextPerm extends Perm { super("InquireSecContextPermission", "com.sun.security.jgss.InquireSecContextPermission", new String[] { - "KRB5_GET_SESSION_KEY" + "KRB5_GET_SESSION_KEY", + "KRB5_GET_TKT_FLAGS", + "KRB5_GET_AUTHZ_DATA", + "KRB5_GET_AUTHTIME" }, null); } diff --git a/jdk/test/sun/security/krb5/auto/Context.java b/jdk/test/sun/security/krb5/auto/Context.java index b8ce532be19..140623f8310 100644 --- a/jdk/test/sun/security/krb5/auto/Context.java +++ b/jdk/test/sun/security/krb5/auto/Context.java @@ -41,6 +41,7 @@ import org.ietf.jgss.MessageProp; import org.ietf.jgss.Oid; import com.sun.security.jgss.ExtendedGSSContext; import com.sun.security.jgss.InquireType; +import com.sun.security.jgss.AuthorizationDataEntry; /** * Context of a JGSS subject, encapsulating Subject and GSSContext. @@ -288,6 +289,23 @@ public class Context { throw new Exception("Session key cannot be null"); } System.out.println("Session key is: " + k); + boolean[] flags = (boolean[])ex.inquireSecContext( + InquireType.KRB5_GET_TKT_FLAGS); + if (flags == null) { + throw new Exception("Ticket flags cannot be null"); + } + System.out.println("Ticket flags is: " + Arrays.toString(flags)); + String authTime = (String)ex.inquireSecContext( + InquireType.KRB5_GET_AUTHTIME); + if (authTime == null) { + throw new Exception("Auth time cannot be null"); + } + System.out.println("AuthTime is: " + authTime); + if (!x.isInitiator()) { + AuthorizationDataEntry[] ad = (AuthorizationDataEntry[])ex.inquireSecContext( + InquireType.KRB5_GET_AUTHZ_DATA); + System.out.println("AuthzData is: " + Arrays.toString(ad)); + } } } } From aa514761f5d1ad1d0346ea6530c58abe4914a31d Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Tue, 11 Aug 2009 15:36:52 +0800 Subject: [PATCH 72/96] 6868867: Test: sun/security/tools/keytool/standard.sh fails under windows/cygwin Reviewed-by: wetmore --- .../classes/sun/security/tools/KeyTool.java | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/jdk/src/share/classes/sun/security/tools/KeyTool.java b/jdk/src/share/classes/sun/security/tools/KeyTool.java index 892e86447e9..8f9e86ee063 100644 --- a/jdk/src/share/classes/sun/security/tools/KeyTool.java +++ b/jdk/src/share/classes/sun/security/tools/KeyTool.java @@ -880,41 +880,41 @@ public final class KeyTool { // might not work properly, since -gencert is slow // and there's no data in the pipe at the beginning. ByteArrayOutputStream bout = new ByteArrayOutputStream(); - byte[] b = new byte[4096]; - while (true) { - int len = inStream.read(b); - if (len < 0) break; - bout.write(b, 0, len); - } - inStream = new ByteArrayInputStream(bout.toByteArray()); try { - String importAlias = (alias!=null)?alias:keyAlias; - if (keyStore.entryInstanceOf(importAlias, KeyStore.PrivateKeyEntry.class)) { - kssave = installReply(importAlias, inStream); - if (kssave) { - System.err.println(rb.getString - ("Certificate reply was installed in keystore")); - } else { - System.err.println(rb.getString - ("Certificate reply was not installed in keystore")); - } - } else if (!keyStore.containsAlias(importAlias) || - keyStore.entryInstanceOf(importAlias, - KeyStore.TrustedCertificateEntry.class)) { - kssave = addTrustedCert(importAlias, inStream); - if (kssave) { - System.err.println(rb.getString - ("Certificate was added to keystore")); - } else { - System.err.println(rb.getString - ("Certificate was not added to keystore")); - } + byte[] b = new byte[4096]; + while (true) { + int len = inStream.read(b); + if (len < 0) break; + bout.write(b, 0, len); } } finally { if (inStream != System.in) { inStream.close(); } } + inStream = new ByteArrayInputStream(bout.toByteArray()); + String importAlias = (alias!=null)?alias:keyAlias; + if (keyStore.entryInstanceOf(importAlias, KeyStore.PrivateKeyEntry.class)) { + kssave = installReply(importAlias, inStream); + if (kssave) { + System.err.println(rb.getString + ("Certificate reply was installed in keystore")); + } else { + System.err.println(rb.getString + ("Certificate reply was not installed in keystore")); + } + } else if (!keyStore.containsAlias(importAlias) || + keyStore.entryInstanceOf(importAlias, + KeyStore.TrustedCertificateEntry.class)) { + kssave = addTrustedCert(importAlias, inStream); + if (kssave) { + System.err.println(rb.getString + ("Certificate was added to keystore")); + } else { + System.err.println(rb.getString + ("Certificate was not added to keystore")); + } + } } else if (command == IMPORTKEYSTORE) { doImportKeyStore(); kssave = true; From 3db64bc897b13ee0225f79c700626a0c0be987af Mon Sep 17 00:00:00 2001 From: Xue-Lei Andrew Fan Date: Tue, 11 Aug 2009 18:27:01 +0800 Subject: [PATCH 73/96] 6585239: Regression: 2 DNS tests fail with JDK 5.0u13 b01 and pass with 5.0u12fcs Reviewed-by: vinnie --- jdk/src/share/classes/com/sun/jndi/dns/DnsContext.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/jdk/src/share/classes/com/sun/jndi/dns/DnsContext.java b/jdk/src/share/classes/com/sun/jndi/dns/DnsContext.java index 3b30bb96a6e..4375af2db55 100644 --- a/jdk/src/share/classes/com/sun/jndi/dns/DnsContext.java +++ b/jdk/src/share/classes/com/sun/jndi/dns/DnsContext.java @@ -972,14 +972,11 @@ class NameClassPairEnumeration implements NamingEnumeration { } /* - * ctx will be closed when no longer needed by the enumeration. + * ctx will be set to null when no longer needed by the enumeration. */ - public void close () { + public void close() { nodes = null; - if (ctx != null) { - ctx.close(); - ctx = null; - } + ctx = null; } public boolean hasMore() { From 90b1aee14250684e2bf4941dbb515613b6da2f90 Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Tue, 11 Aug 2009 12:37:02 +0100 Subject: [PATCH 74/96] 4516760: (so) Intermittent SocketException: Transport endpoint is not connected (lnx) Reviewed-by: sherman --- jdk/src/solaris/native/sun/nio/ch/Net.c | 2 +- .../nio/channels/SocketChannel/Shutdown.java | 69 +++++++++++++++---- 2 files changed, 55 insertions(+), 16 deletions(-) diff --git a/jdk/src/solaris/native/sun/nio/ch/Net.c b/jdk/src/solaris/native/sun/nio/ch/Net.c index 14ef8d14305..79031de6b59 100644 --- a/jdk/src/solaris/native/sun/nio/ch/Net.c +++ b/jdk/src/solaris/native/sun/nio/ch/Net.c @@ -541,7 +541,7 @@ Java_sun_nio_ch_Net_shutdown(JNIEnv *env, jclass cl, jobject fdo, jint jhow) { int how = (jhow == sun_nio_ch_Net_SHUT_RD) ? SHUT_RD : (jhow == sun_nio_ch_Net_SHUT_WR) ? SHUT_WR : SHUT_RDWR; - if (shutdown(fdval(env, fdo), how) < 0) + if ((shutdown(fdval(env, fdo), how) < 0) && (errno != ENOTCONN)) handleSocketError(env, errno); } diff --git a/jdk/test/java/nio/channels/SocketChannel/Shutdown.java b/jdk/test/java/nio/channels/SocketChannel/Shutdown.java index 16bd7a011ad..c2e579304f0 100644 --- a/jdk/test/java/nio/channels/SocketChannel/Shutdown.java +++ b/jdk/test/java/nio/channels/SocketChannel/Shutdown.java @@ -1,5 +1,5 @@ /* - * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2009 Sun Microsystems, Inc. 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 @@ -22,26 +22,65 @@ */ /* @test - * @bug 4618960 - * @summary Test isInputShutdown - * @library .. + * @bug 4618960 4516760 + * @summary Test shutdownXXX and isInputShutdown */ +import java.io.IOException; import java.net.*; -import java.nio.*; +import java.nio.ByteBuffer; import java.nio.channels.*; public class Shutdown { - public static void main(String args[]) throws Exception { - InetSocketAddress sa = new InetSocketAddress( - InetAddress.getByName(TestUtil.HOST), 23); - SocketChannel sc = SocketChannel.open(sa); - boolean before = sc.socket().isInputShutdown(); - sc.socket().shutdownInput(); - boolean after = sc.socket().isInputShutdown(); - sc.close(); - if (before || !after) - throw new Exception("Test failed"); + /** + * Accept a connection, and close it immediately causing a hard reset. + */ + static void acceptAndReset(ServerSocketChannel ssc) throws IOException { + SocketChannel peer = ssc.accept(); + try { + peer.setOption(StandardSocketOption.SO_LINGER, 0); + peer.configureBlocking(false); + peer.write(ByteBuffer.wrap(new byte[128*1024])); + } finally { + peer.close(); + } + } + + public static void main(String[] args) throws Exception { + ServerSocketChannel ssc = ServerSocketChannel.open() + .bind(new InetSocketAddress(0)); + try { + InetAddress lh = InetAddress.getLocalHost(); + int port = ((InetSocketAddress)(ssc.getLocalAddress())).getPort(); + SocketAddress remote = new InetSocketAddress(lh, port); + + // Test SocketChannel shutdownXXX + SocketChannel sc; + sc = SocketChannel.open(remote); + try { + acceptAndReset(ssc); + sc.shutdownInput(); + sc.shutdownOutput(); + } finally { + sc.close(); + } + + // Test Socket adapter shutdownXXX and isShutdownInput + sc = SocketChannel.open(remote); + try { + acceptAndReset(ssc); + boolean before = sc.socket().isInputShutdown(); + sc.socket().shutdownInput(); + boolean after = sc.socket().isInputShutdown(); + if (before || !after) + throw new RuntimeException("Before and after test failed"); + sc.socket().shutdownOutput(); + } finally { + sc.close(); + } + } finally { + ssc.close(); + } } } From c583b690e31a11739b3fcbab219762f7296e8f93 Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Tue, 11 Aug 2009 12:38:43 +0100 Subject: [PATCH 75/96] 6867781: (file) Examples in javadoc use newFileAttributeView instead of getFileAttributeView Reviewed-by: sherman --- .../classes/java/nio/file/attribute/AclFileAttributeView.java | 2 +- .../classes/java/nio/file/attribute/PosixFileAttributeView.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jdk/src/share/classes/java/nio/file/attribute/AclFileAttributeView.java b/jdk/src/share/classes/java/nio/file/attribute/AclFileAttributeView.java index 4127a78e942..13583381cbb 100644 --- a/jdk/src/share/classes/java/nio/file/attribute/AclFileAttributeView.java +++ b/jdk/src/share/classes/java/nio/file/attribute/AclFileAttributeView.java @@ -75,7 +75,7 @@ import java.io.IOException; * .lookupPrincipalByName("joe"); * * // get view - * AclFileAttributeView view = file.newFileAttributeView(AclFileAttributeView.class); + * AclFileAttributeView view = file.getFileAttributeView(AclFileAttributeView.class); * * // create ACE to give "joe" read access * AclEntry entry = AclEntry.newBuilder() diff --git a/jdk/src/share/classes/java/nio/file/attribute/PosixFileAttributeView.java b/jdk/src/share/classes/java/nio/file/attribute/PosixFileAttributeView.java index aeec36a941a..2dfb2c92eac 100644 --- a/jdk/src/share/classes/java/nio/file/attribute/PosixFileAttributeView.java +++ b/jdk/src/share/classes/java/nio/file/attribute/PosixFileAttributeView.java @@ -61,7 +61,7 @@ import java.io.IOException; * Suppose we need to print out the owner and access permissions of a file: *
      *     FileRef file = ...
    - *     PosixFileAttributes attrs = file.newFileAttributeView(PosixFileAttributeView.class)
    + *     PosixFileAttributes attrs = file.getFileAttributeView(PosixFileAttributeView.class)
      *         .readAttributes();
      *     System.out.format("%s %s%n",
      *         attrs.owner().getName(),
    
    From a3af9140c99c387a7c94ddf479ea1f3466f90664 Mon Sep 17 00:00:00 2001
    From: Alan Bateman 
    Date: Tue, 11 Aug 2009 12:49:16 +0100
    Subject: [PATCH 76/96] 6865748: (file) SimpleFileVisitor methods ignore null
     arguments
    
    Reviewed-by: sherman
    ---
     .../java/nio/file/SimpleFileVisitor.java      | 16 +++++++++++
     jdk/test/java/nio/file/Files/Misc.java        | 27 ++++++++++++++++++-
     2 files changed, 42 insertions(+), 1 deletion(-)
    
    diff --git a/jdk/src/share/classes/java/nio/file/SimpleFileVisitor.java b/jdk/src/share/classes/java/nio/file/SimpleFileVisitor.java
    index 36852392327..761773513ed 100644
    --- a/jdk/src/share/classes/java/nio/file/SimpleFileVisitor.java
    +++ b/jdk/src/share/classes/java/nio/file/SimpleFileVisitor.java
    @@ -47,6 +47,14 @@ public class SimpleFileVisitor implements FileVisitor {
         protected SimpleFileVisitor() {
         }
     
    +    /**
    +     * Throws NullPointerException if obj is null.
    +     */
    +    private static void checkNotNull(Object obj) {
    +        if (obj == null)
    +            throw new NullPointerException();
    +    }
    +
         /**
          * Invoked for a directory before entries in the directory are visited.
          *
    @@ -55,6 +63,7 @@ public class SimpleFileVisitor implements FileVisitor {
          */
         @Override
         public FileVisitResult preVisitDirectory(T dir) {
    +        checkNotNull(dir);
             return FileVisitResult.CONTINUE;
         }
     
    @@ -70,6 +79,8 @@ public class SimpleFileVisitor implements FileVisitor {
          */
         @Override
         public FileVisitResult preVisitDirectoryFailed(T dir, IOException exc) {
    +        checkNotNull(dir);
    +        checkNotNull(exc);
             throw new IOError(exc);
         }
     
    @@ -81,6 +92,8 @@ public class SimpleFileVisitor implements FileVisitor {
          */
         @Override
         public FileVisitResult visitFile(T file, BasicFileAttributes attrs) {
    +        checkNotNull(file);
    +        checkNotNull(attrs);
             return FileVisitResult.CONTINUE;
         }
     
    @@ -96,6 +109,8 @@ public class SimpleFileVisitor implements FileVisitor {
          */
         @Override
         public FileVisitResult visitFileFailed(T file, IOException exc) {
    +        checkNotNull(file);
    +        checkNotNull(exc);
             throw new IOError(exc);
         }
     
    @@ -114,6 +129,7 @@ public class SimpleFileVisitor implements FileVisitor {
          */
         @Override
         public FileVisitResult postVisitDirectory(T dir, IOException exc) {
    +        checkNotNull(dir);
             if (exc != null)
                 throw new IOError(exc);
             return FileVisitResult.CONTINUE;
    diff --git a/jdk/test/java/nio/file/Files/Misc.java b/jdk/test/java/nio/file/Files/Misc.java
    index cd7e17a4bb8..a262274c436 100644
    --- a/jdk/test/java/nio/file/Files/Misc.java
    +++ b/jdk/test/java/nio/file/Files/Misc.java
    @@ -22,13 +22,14 @@
      */
     
     /* @test
    - * @bug 4313887 6838333
    + * @bug 4313887 6838333 6865748
      * @summary Unit test for java.nio.file.Files for miscellenous cases not
      *   covered by other tests
      * @library ..
      */
     
     import java.nio.file.*;
    +import java.nio.file.attribute.Attributes;
     import java.io.IOException;
     import java.util.*;
     
    @@ -113,5 +114,29 @@ public class Misc {
                 npeExpected();
             } catch (NullPointerException e) {
             }
    +
    +        SimpleFileVisitor visitor = new SimpleFileVisitor() { };
    +        boolean ranTheGauntlet = false;
    +        try { visitor.preVisitDirectory(null);
    +        } catch (NullPointerException x0) {
    +        try { visitor.preVisitDirectoryFailed(null, new IOException());
    +        } catch (NullPointerException x1) {
    +        try { visitor.preVisitDirectoryFailed(dir, null);
    +        } catch (NullPointerException x2) {
    +        try { visitor.visitFile(null, Attributes.readBasicFileAttributes(Paths.get(".")));
    +        } catch (NullPointerException x3) {
    +        try {  visitor.visitFile(dir, null);
    +        } catch (NullPointerException x4) {
    +        try { visitor.visitFileFailed(null, new IOException());
    +        } catch (NullPointerException x5) {
    +        try { visitor.visitFileFailed(dir, null);
    +        } catch (NullPointerException x6) {
    +        try { visitor.postVisitDirectory(null, new IOException());
    +        } catch (NullPointerException x7) {
    +            // if we get here then all visit* methods threw NPE as expected
    +            ranTheGauntlet = true;
    +        }}}}}}}}
    +        if (!ranTheGauntlet)
    +            throw new RuntimeException("A visit method did not throw NPE");
         }
     }
    
    From 59d983ade01766714e16106623884ec7129c47cd Mon Sep 17 00:00:00 2001
    From: Vinnie Ryan 
    Date: Tue, 11 Aug 2009 16:52:26 +0100
    Subject: [PATCH 77/96] 6840752: Provide out-of-the-box support for ECC
     algorithms
    
    Reviewed-by: alanb, mullan, wetmore
    ---
     jdk/make/sun/security/Makefile                |    4 +-
     jdk/make/sun/security/ec/FILES_c.gmk          |   54 +
     jdk/make/sun/security/ec/Makefile             |  319 ++
     jdk/make/sun/security/ec/mapfile-vers         |   37 +
     jdk/make/sun/security/other/Makefile          |    3 +-
     .../sun/security/ec/ECDHKeyAgreement.java     |  189 +
     .../sun/security/ec/ECDSASignature.java       |  447 ++
     .../sun/security/ec/ECKeyPairGenerator.java   |  191 +
     .../share/classes/sun/security/ec/SunEC.java  |   65 +
     .../classes/sun/security/ec/SunECEntries.java |  109 +
     jdk/src/share/lib/security/java.security      |   13 +-
     .../share/lib/security/java.security-solaris  |   13 +-
     .../share/lib/security/java.security-windows  |   15 +-
     .../share/native/sun/security/ec/ECC_JNI.cpp  |  418 ++
     jdk/src/share/native/sun/security/ec/ec.c     | 1099 ++++
     jdk/src/share/native/sun/security/ec/ec.h     |   72 +
     jdk/src/share/native/sun/security/ec/ec2.h    |  146 +
     .../share/native/sun/security/ec/ec2_163.c    |  281 +
     .../share/native/sun/security/ec/ec2_193.c    |  298 +
     .../share/native/sun/security/ec/ec2_233.c    |  321 ++
     .../share/native/sun/security/ec/ec2_aff.c    |  368 ++
     .../share/native/sun/security/ec/ec2_mont.c   |  296 +
     jdk/src/share/native/sun/security/ec/ec_naf.c |  123 +
     .../share/native/sun/security/ec/ecc_impl.h   |  278 +
     .../share/native/sun/security/ec/ecdecode.c   |  632 +++
     .../share/native/sun/security/ec/ecl-curve.h  |  710 +++
     .../share/native/sun/security/ec/ecl-exp.h    |  216 +
     .../share/native/sun/security/ec/ecl-priv.h   |  304 +
     jdk/src/share/native/sun/security/ec/ecl.c    |  475 ++
     jdk/src/share/native/sun/security/ec/ecl.h    |  111 +
     .../share/native/sun/security/ec/ecl_curve.c  |  216 +
     jdk/src/share/native/sun/security/ec/ecl_gf.c | 1062 ++++
     .../share/native/sun/security/ec/ecl_mult.c   |  378 ++
     jdk/src/share/native/sun/security/ec/ecp.h    |  160 +
     .../share/native/sun/security/ec/ecp_192.c    |  538 ++
     .../share/native/sun/security/ec/ecp_224.c    |  394 ++
     .../share/native/sun/security/ec/ecp_256.c    |  451 ++
     .../share/native/sun/security/ec/ecp_384.c    |  315 ++
     .../share/native/sun/security/ec/ecp_521.c    |  192 +
     .../share/native/sun/security/ec/ecp_aff.c    |  379 ++
     .../share/native/sun/security/ec/ecp_jac.c    |  575 ++
     jdk/src/share/native/sun/security/ec/ecp_jm.c |  353 ++
     .../share/native/sun/security/ec/ecp_mont.c   |  223 +
     jdk/src/share/native/sun/security/ec/logtab.h |   82 +
     .../native/sun/security/ec/mp_gf2m-priv.h     |  122 +
     .../share/native/sun/security/ec/mp_gf2m.c    |  624 +++
     .../share/native/sun/security/ec/mp_gf2m.h    |   83 +
     .../share/native/sun/security/ec/mpi-config.h |  130 +
     .../share/native/sun/security/ec/mpi-priv.h   |  340 ++
     jdk/src/share/native/sun/security/ec/mpi.c    | 4886 +++++++++++++++++
     jdk/src/share/native/sun/security/ec/mpi.h    |  409 ++
     .../share/native/sun/security/ec/mplogic.c    |  242 +
     .../share/native/sun/security/ec/mplogic.h    |  105 +
     .../share/native/sun/security/ec/mpmontg.c    |  199 +
     .../share/native/sun/security/ec/mpprime.h    |   89 +
     jdk/src/share/native/sun/security/ec/oid.c    |  473 ++
     .../share/native/sun/security/ec/secitem.c    |  199 +
     .../share/native/sun/security/ec/secoidt.h    |  103 +
     jdk/test/sun/security/ec/TestEC.java          |   66 +
     jdk/test/sun/security/ec/p12passwords.txt     |   18 +
     .../ec/pkcs12/secp256r1server-secp384r1ca.p12 |  Bin 0 -> 1273 bytes
     .../ec/pkcs12/sect193r1server-rsa1024ca.p12   |  Bin 0 -> 1252 bytes
     62 files changed, 20990 insertions(+), 23 deletions(-)
     create mode 100644 jdk/make/sun/security/ec/FILES_c.gmk
     create mode 100644 jdk/make/sun/security/ec/Makefile
     create mode 100644 jdk/make/sun/security/ec/mapfile-vers
     create mode 100644 jdk/src/share/classes/sun/security/ec/ECDHKeyAgreement.java
     create mode 100644 jdk/src/share/classes/sun/security/ec/ECDSASignature.java
     create mode 100644 jdk/src/share/classes/sun/security/ec/ECKeyPairGenerator.java
     create mode 100644 jdk/src/share/classes/sun/security/ec/SunEC.java
     create mode 100644 jdk/src/share/classes/sun/security/ec/SunECEntries.java
     create mode 100644 jdk/src/share/native/sun/security/ec/ECC_JNI.cpp
     create mode 100644 jdk/src/share/native/sun/security/ec/ec.c
     create mode 100644 jdk/src/share/native/sun/security/ec/ec.h
     create mode 100644 jdk/src/share/native/sun/security/ec/ec2.h
     create mode 100644 jdk/src/share/native/sun/security/ec/ec2_163.c
     create mode 100644 jdk/src/share/native/sun/security/ec/ec2_193.c
     create mode 100644 jdk/src/share/native/sun/security/ec/ec2_233.c
     create mode 100644 jdk/src/share/native/sun/security/ec/ec2_aff.c
     create mode 100644 jdk/src/share/native/sun/security/ec/ec2_mont.c
     create mode 100644 jdk/src/share/native/sun/security/ec/ec_naf.c
     create mode 100644 jdk/src/share/native/sun/security/ec/ecc_impl.h
     create mode 100644 jdk/src/share/native/sun/security/ec/ecdecode.c
     create mode 100644 jdk/src/share/native/sun/security/ec/ecl-curve.h
     create mode 100644 jdk/src/share/native/sun/security/ec/ecl-exp.h
     create mode 100644 jdk/src/share/native/sun/security/ec/ecl-priv.h
     create mode 100644 jdk/src/share/native/sun/security/ec/ecl.c
     create mode 100644 jdk/src/share/native/sun/security/ec/ecl.h
     create mode 100644 jdk/src/share/native/sun/security/ec/ecl_curve.c
     create mode 100644 jdk/src/share/native/sun/security/ec/ecl_gf.c
     create mode 100644 jdk/src/share/native/sun/security/ec/ecl_mult.c
     create mode 100644 jdk/src/share/native/sun/security/ec/ecp.h
     create mode 100644 jdk/src/share/native/sun/security/ec/ecp_192.c
     create mode 100644 jdk/src/share/native/sun/security/ec/ecp_224.c
     create mode 100644 jdk/src/share/native/sun/security/ec/ecp_256.c
     create mode 100644 jdk/src/share/native/sun/security/ec/ecp_384.c
     create mode 100644 jdk/src/share/native/sun/security/ec/ecp_521.c
     create mode 100644 jdk/src/share/native/sun/security/ec/ecp_aff.c
     create mode 100644 jdk/src/share/native/sun/security/ec/ecp_jac.c
     create mode 100644 jdk/src/share/native/sun/security/ec/ecp_jm.c
     create mode 100644 jdk/src/share/native/sun/security/ec/ecp_mont.c
     create mode 100644 jdk/src/share/native/sun/security/ec/logtab.h
     create mode 100644 jdk/src/share/native/sun/security/ec/mp_gf2m-priv.h
     create mode 100644 jdk/src/share/native/sun/security/ec/mp_gf2m.c
     create mode 100644 jdk/src/share/native/sun/security/ec/mp_gf2m.h
     create mode 100644 jdk/src/share/native/sun/security/ec/mpi-config.h
     create mode 100644 jdk/src/share/native/sun/security/ec/mpi-priv.h
     create mode 100644 jdk/src/share/native/sun/security/ec/mpi.c
     create mode 100644 jdk/src/share/native/sun/security/ec/mpi.h
     create mode 100644 jdk/src/share/native/sun/security/ec/mplogic.c
     create mode 100644 jdk/src/share/native/sun/security/ec/mplogic.h
     create mode 100644 jdk/src/share/native/sun/security/ec/mpmontg.c
     create mode 100644 jdk/src/share/native/sun/security/ec/mpprime.h
     create mode 100644 jdk/src/share/native/sun/security/ec/oid.c
     create mode 100644 jdk/src/share/native/sun/security/ec/secitem.c
     create mode 100644 jdk/src/share/native/sun/security/ec/secoidt.h
     create mode 100644 jdk/test/sun/security/ec/TestEC.java
     create mode 100644 jdk/test/sun/security/ec/p12passwords.txt
     create mode 100644 jdk/test/sun/security/ec/pkcs12/secp256r1server-secp384r1ca.p12
     create mode 100644 jdk/test/sun/security/ec/pkcs12/sect193r1server-rsa1024ca.p12
    
    diff --git a/jdk/make/sun/security/Makefile b/jdk/make/sun/security/Makefile
    index 13394fc2100..2b7cc6b2ab3 100644
    --- a/jdk/make/sun/security/Makefile
    +++ b/jdk/make/sun/security/Makefile
    @@ -1,5 +1,5 @@
     #
    -# Copyright 1996-2007 Sun Microsystems, Inc.  All Rights Reserved.
    +# Copyright 1996-2009 Sun Microsystems, Inc.  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
    @@ -60,7 +60,7 @@ ifeq ($(PLATFORM), windows)
       endif
     endif
     
    -SUBDIRS = other action util tools jgss krb5 smartcardio $(PKCS11) \
    +SUBDIRS = ec other action util tools jgss krb5 smartcardio $(PKCS11) \
               $(JGSS_WRAPPER) $(MSCAPI)
     
     all build clean clobber::
    diff --git a/jdk/make/sun/security/ec/FILES_c.gmk b/jdk/make/sun/security/ec/FILES_c.gmk
    new file mode 100644
    index 00000000000..8a1bd099b38
    --- /dev/null
    +++ b/jdk/make/sun/security/ec/FILES_c.gmk
    @@ -0,0 +1,54 @@
    +#
    +# Copyright 2009 Sun Microsystems, Inc.  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.  Sun designates this
    +# particular file as subject to the "Classpath" exception as provided
    +# by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    +# CA 95054 USA or visit www.sun.com if you need additional information or
    +# have any questions.
    +#
    +
    +FILES_c = \
    +	ec.c \
    +	ec2_163.c \
    +	ec2_193.c \
    +	ec2_233.c \
    +	ec2_aff.c \
    +	ec2_mont.c \
    +	ecdecode.c \
    +	ecl.c \
    +	ecl_curve.c \
    +	ecl_gf.c \
    +	ecl_mult.c \
    +	ec_naf.c \
    +	ecp_192.c \
    +	ecp_224.c \
    +	ecp_256.c \
    +	ecp_384.c \
    +	ecp_521.c \
    +	ecp_aff.c \
    +	ecp_jac.c \
    +	ecp_jm.c \
    +	ecp_mont.c \
    +	mp_gf2m.c \
    +	mpi.c \
    +	mplogic.c \
    +	mpmontg.c \
    +	oid.c \
    +	secitem.c
    +
    diff --git a/jdk/make/sun/security/ec/Makefile b/jdk/make/sun/security/ec/Makefile
    new file mode 100644
    index 00000000000..297a2deab08
    --- /dev/null
    +++ b/jdk/make/sun/security/ec/Makefile
    @@ -0,0 +1,319 @@
    +#
    +# Copyright 2009 Sun Microsystems, Inc.  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.  Sun designates this
    +# particular file as subject to the "Classpath" exception as provided
    +# by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    +# CA 95054 USA or visit www.sun.com if you need additional information or
    +# have any questions.
    +#
    +
    +#
    +# Makefile for building sunec.jar and sunecc native library.
    +#
    +# This file was derived from make/com/sun/crypto/provider/Makefile.
    +#
    +
    +#
    +# (The terms "OpenJDK" and "JDK" below refer to OpenJDK and Sun JDK builds
    +# respectively.)
    +#
    +# JCE builds are very different between OpenJDK and JDK.  The OpenJDK JCE
    +# jar files do not require signing, but those for JDK do.  If an unsigned
    +# jar file is installed into JDK, things will break when the crypto
    +# routines are called.
    +#
    +# This Makefile does the "real" build of the JCE files.  For OpenJDK,
    +# the jar files built here are installed directly into the OpenJDK.
    +#
    +# For JDK, the binaries use pre-built/pre-signed binary files stored in
    +# the closed workspace that are not shipped in the OpenJDK workspaces.
    +# We still build the JDK files here to verify the files compile, and in
    +# preparation for possible signing.  Developers working on JCE in JDK
    +# must sign the JCE files before testing.  The JCE signing key is kept
    +# separate from the JDK workspace to prevent its disclosure.
    +#
    +# SPECIAL NOTE TO JCE/JDK developers:  The source files must eventually
    +# be built, signed, and then the resulting jar files MUST BE CHECKED
    +# INTO THE CLOSED PART OF THE WORKSPACE*.  This separate step *MUST NOT
    +# BE FORGOTTEN*, otherwise a bug fixed in the source code will not be
    +# reflected in the shipped binaries.  The "release" target should be
    +# used to generate the required files.
    +#
    +# There are a number of targets to help both JDK/OpenJDK developers.
    +#
    +# Main Targets (JDK/OPENJDK):
    +#
    +#     all/clobber/clean		The usual, plus the native libraries.
    +#				    If OpenJDK, installs sunec.jar.
    +#				    If JDK, installs prebuilt
    +#				    sunec.jar.
    +#
    +#     jar			Builds/installs sunec.jar
    +#				    If OpenJDK, does not sign.
    +#				    If JDK, tries to sign.
    +#
    +# Other lesser-used Targets (JDK/OPENJDK):
    +#
    +#     build-jar			Builds sunec.jar
    +#				    (does not sign/install)
    +#
    +#     install-jar		Alias for "jar" above.
    +#
    +# Other targets (JDK only):
    +#
    +#     sign			Alias for sign-jar
    +#	  sign-jar		Builds/signs sunec.jar (no install)
    +#
    +#     release			Builds all targets in preparation
    +#				for workspace integration.
    +#
    +#     install-prebuilt		Installs the pre-built jar files
    +#
    +# This makefile was written to support parallel target execution.
    +#
    +
    +BUILDDIR = ../../..
    +PACKAGE = sun.security.ec
    +PRODUCT = sun
    +
    +#
    +# The following is for when we need to do postprocessing
    +# (signing) against a read-only build.  If the OUTPUTDIR
    +# isn't writable, the build currently crashes out.
    +#
    +ifndef OPENJDK
    +  ifdef ALT_JCE_BUILD_DIR
    +    # =====================================================
    +    # Where to place the output, in case we're building from a read-only
    +    # build area.  (e.g. a release engineering build.)
    +    JCE_BUILD_DIR=${ALT_JCE_BUILD_DIR}
    +    IGNORE_WRITABLE_OUTPUTDIR_TEST=true
    +  else
    +    JCE_BUILD_DIR=${TEMPDIR}
    +  endif
    +endif
    +
    +include $(BUILDDIR)/common/Defs.gmk
    +
    +#
    +# Location for the newly built classfiles.
    +#
    +CLASSDESTDIR = $(TEMPDIR)/classes
    +
    +#
    +# Java files
    +#
    +AUTO_FILES_JAVA_DIRS = $(PKGDIR)
    +
    +include $(BUILDDIR)/common/Classes.gmk
    +
    +#
    +# Some licensees do not get the native ECC sources, but we still need to
    +# be able to build "all" for them.  Check here to see if the sources are
    +# available.  If not, then skip them.
    +#
    +
    +NATIVE_ECC_AVAILABLE := $(shell \
    +    if [ -d $(SHARE_SRC)/native/$(PKGDIR) ] ; then \
    +	$(ECHO) true; \
    +    else \
    +	$(ECHO) false; \
    +    fi)
    +
    +ifeq ($(NATIVE_ECC_AVAILABLE), true)
    +
    +  LIBRARY = sunecc
    +
    +  #
    +  # Java files that define native methods
    +  #
    +  FILES_export = \
    +      $(PKGDIR)/ECDHKeyAgreement.java \
    +      $(PKGDIR)/ECDSASignature.java \
    +      $(PKGDIR)/ECKeyPairGenerator.java
    +
    +  JAVAHFLAGS += -classpath $(CLASSDESTDIR)
    +
    +  #
    +  # C and C++ files
    +  #
    +  include FILES_c.gmk
    +
    +  FILES_cpp = ECC_JNI.cpp
    +
    +  CPLUSPLUSLIBRARY=true
    +
    +  FILES_m = mapfile-vers
    +
    +  #
    +  # Find native code
    +  #
    +  vpath %.cpp $(SHARE_SRC)/native/$(PKGDIR)
    +
    +  vpath %.c $(SHARE_SRC)/native/$(PKGDIR)
    +
    +  #
    +  # Find include files
    +  #
    +  OTHER_INCLUDES += -I$(SHARE_SRC)/native/$(PKGDIR)
    +
    +  #
    +  # Compiler flags
    +  #
    +  OTHER_CFLAGS += -DMP_API_COMPATIBLE -DNSS_ECC_MORE_THAN_SUITE_B
    +
    +  #
    +  # Libraries to link
    +  #
    +  ifeq ($(PLATFORM), windows)
    +    OTHER_LDLIBS += $(JVMLIB)
    +  else
    +    OTHER_LDLIBS = -ldl $(JVMLIB) $(LIBCXX)
    +  endif
    +
    +  include $(BUILDDIR)/common/Mapfile-vers.gmk
    +
    +  include $(BUILDDIR)/common/Library.gmk
    +
    +endif # NATIVE_ECC_AVAILABLE
    +
    +#
    +# We use a variety of subdirectories in the $(TEMPDIR) depending on what
    +# part of the build we're doing.  Both OPENJDK/JDK builds are initially
    +# done in the unsigned area.  When files are signed in JDK,
    +# they will be placed in the appropriate area.
    +#
    +UNSIGNED_DIR = $(TEMPDIR)/unsigned
    +
    +include $(BUILDDIR)/javax/crypto/Defs-jce.gmk
    +
    +#
    +# Rules
    +#
    +
    +ifdef OPENJDK
    +all: build-jar install-jar
    +else
    +all: build-jar install-prebuilt
    +	$(build-warning)
    +endif
    +
    +
    +# =====================================================
    +# Build the unsigned sunec.jar file.
    +#
    +
    +JAR_DESTFILE = $(EXTDIR)/sunec.jar
    +
    +#
    +# Since the -C option to jar is used below, each directory entry must be
    +# preceded with the appropriate directory to "cd" into.
    +#
    +JAR_DIRS = $(patsubst %, -C $(CLASSDESTDIR) %, $(AUTO_FILES_JAVA_DIRS))
    +
    +build-jar: $(UNSIGNED_DIR)/sunec.jar
    +
    +#
    +# Build sunec.jar.
    +#
    +$(UNSIGNED_DIR)/sunec.jar: build
    +	$(prep-target)
    +	$(BOOT_JAR_CMD) cf $@ $(JAR_DIRS) \
    +	    $(BOOT_JAR_JFLAGS)
    +	@$(java-vm-cleanup)
    +
    +
    +ifndef OPENJDK
    +# =====================================================
    +# Sign the provider jar file.  Not needed for OpenJDK.
    +#
    +
    +SIGNED_DIR = $(JCE_BUILD_DIR)/signed
    +
    +sign: sign-jar
    +
    +sign-jar: $(SIGNED_DIR)/sunec.jar
    +
    +ifndef ALT_JCE_BUILD_DIR
    +$(SIGNED_DIR)/sunec.jar: $(UNSIGNED_DIR)/sunec.jar
    +else
    +#
    +# We have to remove the build dependency, otherwise, we'll try to rebuild it
    +# which we can't do on a read-only filesystem.
    +#
    +$(SIGNED_DIR)/sunec.jar:
    +	@if [ ! -r $(UNSIGNED_DIR)/sunec.jar ] ; then \
    +	    $(ECHO) "Couldn't find $(UNSIGNED_DIR)/sunec.jar"; \
    +	    exit 1; \
    +	fi
    +endif
    +	$(call sign-file, $(UNSIGNED_DIR)/sunec.jar)
    +
    +
    +# =====================================================
    +# Create the Release Engineering files.  Signed builds, etc.
    +#
    +
    +release: $(SIGNED_DIR)/sunec.jar
    +	$(RM) $(JCE_BUILD_DIR)/release/sunec.jar
    +	$(MKDIR) -p $(JCE_BUILD_DIR)/release
    +	$(CP) $(SIGNED_DIR)/sunec.jar $(JCE_BUILD_DIR)/release
    +	$(release-warning)
    +
    +endif # OPENJDK
    +
    +
    +# =====================================================
    +# Install routines.
    +#
    +
    +#
    +# Install sunec.jar, depending on which type is requested.
    +#
    +install-jar jar: $(JAR_DESTFILE)
    +ifndef OPENJDK
    +	$(release-warning)
    +endif
    +
    +ifdef OPENJDK
    +$(JAR_DESTFILE): $(UNSIGNED_DIR)/sunec.jar
    +else
    +$(JAR_DESTFILE): $(SIGNED_DIR)/sunec.jar
    +endif
    +	$(install-file)
    +
    +ifndef OPENJDK
    +install-prebuilt:
    +	@$(ECHO) "\n>>>Installing prebuilt SunEC provider..."
    +	$(RM) $(JAR_DESTFILE)
    +	$(CP) $(PREBUILT_DIR)/ec/sunec.jar $(JAR_DESTFILE)
    +endif
    +
    +
    +# =====================================================
    +# Support routines.
    +#
    +
    +clobber clean::
    +	$(RM) -r $(JAR_DESTFILE) $(TEMPDIR) $(JCE_BUILD_DIR)
    +
    +.PHONY: build-jar jar install-jar
    +ifndef OPENJDK
    +.PHONY: sign sign-jar release install-prebuilt
    +endif
    diff --git a/jdk/make/sun/security/ec/mapfile-vers b/jdk/make/sun/security/ec/mapfile-vers
    new file mode 100644
    index 00000000000..2bda0206608
    --- /dev/null
    +++ b/jdk/make/sun/security/ec/mapfile-vers
    @@ -0,0 +1,37 @@
    +#
    +# Copyright 2009 Sun Microsystems, Inc.  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.  Sun designates this
    +# particular file as subject to the "Classpath" exception as provided
    +# by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    +# CA 95054 USA or visit www.sun.com if you need additional information or
    +# have any questions.
    +#
    +
    +# Define public interface.
    +
    +SUNWprivate_1.1 {
    +        global:
    +                Java_sun_security_ec_ECKeyPairGenerator_generateECKeyPair;
    +                Java_sun_security_ec_ECKeyPairGenerator_getEncodedBytes;
    +		Java_sun_security_ec_ECDSASignature_signDigest;
    +		Java_sun_security_ec_ECDSASignature_verifySignedDigest;
    +		Java_sun_security_ec_ECDHKeyAgreement_deriveKey;
    +        local:
    +                *;
    +};
    diff --git a/jdk/make/sun/security/other/Makefile b/jdk/make/sun/security/other/Makefile
    index 8fea7ce903f..3f120fa473f 100644
    --- a/jdk/make/sun/security/other/Makefile
    +++ b/jdk/make/sun/security/other/Makefile
    @@ -1,5 +1,5 @@
     #
    -# Copyright 1996-2007 Sun Microsystems, Inc.  All Rights Reserved.
    +# Copyright 1996-2009 Sun Microsystems, Inc.  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
    @@ -33,7 +33,6 @@ include $(BUILDDIR)/common/Defs.gmk
     #
     AUTO_FILES_JAVA_DIRS = \
         sun/security/acl \
    -    sun/security/ec \
         sun/security/jca \
         sun/security/pkcs \
         sun/security/pkcs12 \
    diff --git a/jdk/src/share/classes/sun/security/ec/ECDHKeyAgreement.java b/jdk/src/share/classes/sun/security/ec/ECDHKeyAgreement.java
    new file mode 100644
    index 00000000000..8a61a7b1193
    --- /dev/null
    +++ b/jdk/src/share/classes/sun/security/ec/ECDHKeyAgreement.java
    @@ -0,0 +1,189 @@
    +/*
    + * Copyright 2009 Sun Microsystems, Inc.  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.  Sun designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    + * CA 95054 USA or visit www.sun.com if you need additional information or
    + * have any questions.
    + */
    +
    +package sun.security.ec;
    +
    +import java.security.*;
    +import java.security.interfaces.*;
    +import java.security.spec.*;
    +
    +import javax.crypto.*;
    +import javax.crypto.spec.*;
    +
    +/**
    + * KeyAgreement implementation for ECDH.
    + *
    + * @since   1.7
    + */
    +public final class ECDHKeyAgreement extends KeyAgreementSpi {
    +
    +    // flag indicating whether the native ECC implementation is present
    +    private static boolean implementationPresent = true;
    +    static {
    +        try {
    +            AccessController.doPrivileged(new PrivilegedAction() {
    +                public Void run() {
    +                    System.loadLibrary("sunecc");
    +                    return null;
    +                }
    +            });
    +        } catch (UnsatisfiedLinkError e) {
    +            implementationPresent = false;
    +        }
    +    }
    +
    +    // private key, if initialized
    +    private ECPrivateKey privateKey;
    +
    +    // encoded public point, non-null between doPhase() & generateSecret() only
    +    private byte[] publicValue;
    +
    +    // length of the secret to be derived
    +    private int secretLen;
    +
    +    /**
    +     * Constructs a new ECDHKeyAgreement.
    +     *
    +     * @exception ProviderException if the native ECC library is unavailable.
    +     */
    +    public ECDHKeyAgreement() {
    +        if (!implementationPresent) {
    +            throw new ProviderException("ECDH implementation is not available");
    +        }
    +    }
    +
    +    // see JCE spec
    +    protected void engineInit(Key key, SecureRandom random)
    +            throws InvalidKeyException {
    +        if (!(key instanceof PrivateKey)) {
    +            throw new InvalidKeyException
    +                        ("Key must be instance of PrivateKey");
    +        }
    +        privateKey = (ECPrivateKey) ECKeyFactory.toECKey(key);
    +        publicValue = null;
    +    }
    +
    +    // see JCE spec
    +    protected void engineInit(Key key, AlgorithmParameterSpec params,
    +            SecureRandom random) throws InvalidKeyException,
    +            InvalidAlgorithmParameterException {
    +        if (params != null) {
    +            throw new InvalidAlgorithmParameterException
    +                        ("Parameters not supported");
    +        }
    +        engineInit(key, random);
    +    }
    +
    +    // see JCE spec
    +    protected Key engineDoPhase(Key key, boolean lastPhase)
    +            throws InvalidKeyException, IllegalStateException {
    +        if (privateKey == null) {
    +            throw new IllegalStateException("Not initialized");
    +        }
    +        if (publicValue != null) {
    +            throw new IllegalStateException("Phase already executed");
    +        }
    +        if (!lastPhase) {
    +            throw new IllegalStateException
    +                ("Only two party agreement supported, lastPhase must be true");
    +        }
    +        if (!(key instanceof ECPublicKey)) {
    +            throw new InvalidKeyException
    +                ("Key must be a PublicKey with algorithm EC");
    +        }
    +
    +        ECPublicKey ecKey = (ECPublicKey)key;
    +        ECParameterSpec params = ecKey.getParams();
    +
    +        if (ecKey instanceof ECPublicKeyImpl) {
    +            publicValue = ((ECPublicKeyImpl)ecKey).getEncodedPublicValue();
    +        } else { // instanceof ECPublicKey
    +            publicValue =
    +                ECParameters.encodePoint(ecKey.getW(), params.getCurve());
    +        }
    +        int keyLenBits = params.getCurve().getField().getFieldSize();
    +        secretLen = (keyLenBits + 7) >> 3;
    +
    +        return null;
    +    }
    +
    +    // see JCE spec
    +    protected byte[] engineGenerateSecret() throws IllegalStateException {
    +        if ((privateKey == null) || (publicValue == null)) {
    +            throw new IllegalStateException("Not initialized correctly");
    +        }
    +
    +        byte[] s = privateKey.getS().toByteArray();
    +        byte[] encodedParams =
    +            ECParameters.encodeParameters(privateKey.getParams()); // DER OID
    +
    +        try {
    +
    +            return deriveKey(s, publicValue, encodedParams);
    +
    +        } catch (GeneralSecurityException e) {
    +            throw new ProviderException("Could not derive key", e);
    +        }
    +
    +    }
    +
    +    // see JCE spec
    +    protected int engineGenerateSecret(byte[] sharedSecret, int
    +            offset) throws IllegalStateException, ShortBufferException {
    +        if (offset + secretLen > sharedSecret.length) {
    +            throw new ShortBufferException("Need " + secretLen
    +                + " bytes, only " + (sharedSecret.length - offset) + " available");
    +        }
    +        byte[] secret = engineGenerateSecret();
    +        System.arraycopy(secret, 0, sharedSecret, offset, secret.length);
    +        return secret.length;
    +    }
    +
    +    // see JCE spec
    +    protected SecretKey engineGenerateSecret(String algorithm)
    +            throws IllegalStateException, NoSuchAlgorithmException,
    +            InvalidKeyException {
    +        if (algorithm == null) {
    +            throw new NoSuchAlgorithmException("Algorithm must not be null");
    +        }
    +        if (!(algorithm.equals("TlsPremasterSecret"))) {
    +            throw new NoSuchAlgorithmException
    +                ("Only supported for algorithm TlsPremasterSecret");
    +        }
    +        return new SecretKeySpec(engineGenerateSecret(), "TlsPremasterSecret");
    +    }
    +
    +    /**
    +     * Generates a secret key using the public and private keys.
    +     *
    +     * @param s the private key's S value.
    +     * @param w the public key's W point (in uncompressed form).
    +     * @param encodedParams the curve's DER encoded object identifier.
    +     *
    +     * @return byte[] the secret key.
    +     */
    +    private static native byte[] deriveKey(byte[] s, byte[] w,
    +        byte[] encodedParams) throws GeneralSecurityException;
    +}
    diff --git a/jdk/src/share/classes/sun/security/ec/ECDSASignature.java b/jdk/src/share/classes/sun/security/ec/ECDSASignature.java
    new file mode 100644
    index 00000000000..b2bf8936c15
    --- /dev/null
    +++ b/jdk/src/share/classes/sun/security/ec/ECDSASignature.java
    @@ -0,0 +1,447 @@
    +/*
    + * Copyright 2009 Sun Microsystems, Inc.  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.  Sun designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    + * CA 95054 USA or visit www.sun.com if you need additional information or
    + * have any questions.
    + */
    +
    +package sun.security.ec;
    +
    +import java.io.IOException;
    +import java.nio.ByteBuffer;
    +import java.math.BigInteger;
    +import java.util.Arrays;
    +
    +import java.security.*;
    +import java.security.interfaces.*;
    +import java.security.spec.*;
    +
    +import sun.security.jca.JCAUtil;
    +import sun.security.util.*;
    +import sun.security.x509.AlgorithmId;
    +
    +/**
    + * ECDSA signature implementation. This class currently supports the
    + * following algorithm names:
    + *
    + *   . "NONEwithECDSA"
    + *   . "SHA1withECDSA"
    + *   . "SHA256withECDSA"
    + *   . "SHA384withECDSA"
    + *   . "SHA512withECDSA"
    + *
    + * @since   1.7
    + */
    +abstract class ECDSASignature extends SignatureSpi {
    +
    +    // flag indicating whether the native ECC implementation is present
    +    private static boolean implementationPresent = true;
    +    static {
    +        try {
    +            AccessController.doPrivileged(new PrivilegedAction() {
    +                public Void run() {
    +                    System.loadLibrary("sunecc");
    +                    return null;
    +                }
    +            });
    +        } catch (UnsatisfiedLinkError e) {
    +            implementationPresent = false;
    +        }
    +    }
    +
    +    // message digest implementation we use
    +    private final MessageDigest messageDigest;
    +
    +    // supplied entropy
    +    private SecureRandom random;
    +
    +    // flag indicating whether the digest has been reset
    +    private boolean needsReset;
    +
    +    // private key, if initialized for signing
    +    private ECPrivateKey privateKey;
    +
    +    // public key, if initialized for verifying
    +    private ECPublicKey publicKey;
    +
    +    /**
    +     * Constructs a new ECDSASignature. Used by Raw subclass.
    +     *
    +     * @exception ProviderException if the native ECC library is unavailable.
    +     */
    +    ECDSASignature() {
    +        if (!implementationPresent) {
    +            throw new
    +                ProviderException("ECDSA implementation is not available");
    +        }
    +        messageDigest = null;
    +    }
    +
    +    /**
    +     * Constructs a new ECDSASignature. Used by subclasses.
    +     *
    +     * @exception ProviderException if the native ECC library is unavailable.
    +     */
    +    ECDSASignature(String digestName) {
    +        if (!implementationPresent) {
    +            throw new
    +                ProviderException("ECDSA implementation is not available");
    +        }
    +
    +        try {
    +            messageDigest = MessageDigest.getInstance(digestName);
    +        } catch (NoSuchAlgorithmException e) {
    +            throw new ProviderException(e);
    +        }
    +        needsReset = false;
    +    }
    +
    +    // Nested class for NONEwithECDSA signatures
    +    public static final class Raw extends ECDSASignature {
    +
    +        // the longest supported digest is 512 bits (SHA-512)
    +        private static final int RAW_ECDSA_MAX = 64;
    +
    +        private final byte[] precomputedDigest;
    +        private int offset = 0;
    +
    +        public Raw() {
    +            precomputedDigest = new byte[RAW_ECDSA_MAX];
    +        }
    +
    +        // Stores the precomputed message digest value.
    +        @Override
    +        protected void engineUpdate(byte b) throws SignatureException {
    +            if (offset >= precomputedDigest.length) {
    +                offset = RAW_ECDSA_MAX + 1;
    +                return;
    +            }
    +            precomputedDigest[offset++] = b;
    +        }
    +
    +        // Stores the precomputed message digest value.
    +        @Override
    +        protected void engineUpdate(byte[] b, int off, int len)
    +                throws SignatureException {
    +            if (offset >= precomputedDigest.length) {
    +                offset = RAW_ECDSA_MAX + 1;
    +                return;
    +            }
    +            System.arraycopy(b, off, precomputedDigest, offset, len);
    +            offset += len;
    +        }
    +
    +        // Stores the precomputed message digest value.
    +        @Override
    +        protected void engineUpdate(ByteBuffer byteBuffer) {
    +            int len = byteBuffer.remaining();
    +            if (len <= 0) {
    +                return;
    +            }
    +            if (offset + len >= precomputedDigest.length) {
    +                offset = RAW_ECDSA_MAX + 1;
    +                return;
    +            }
    +            byteBuffer.get(precomputedDigest, offset, len);
    +            offset += len;
    +        }
    +
    +        @Override
    +        protected void resetDigest(){
    +            offset = 0;
    +        }
    +
    +        // Returns the precomputed message digest value.
    +        @Override
    +        protected byte[] getDigestValue() throws SignatureException {
    +            if (offset > RAW_ECDSA_MAX) {
    +                throw new SignatureException("Message digest is too long");
    +
    +            }
    +            byte[] result = new byte[offset];
    +            System.arraycopy(precomputedDigest, 0, result, 0, offset);
    +            offset = 0;
    +
    +            return result;
    +        }
    +    }
    +
    +    // Nested class for SHA1withECDSA signatures
    +    public static final class SHA1 extends ECDSASignature {
    +        public SHA1() {
    +            super("SHA1");
    +        }
    +    }
    +
    +    // Nested class for SHA256withECDSA signatures
    +    public static final class SHA256 extends ECDSASignature {
    +        public SHA256() {
    +            super("SHA-256");
    +        }
    +    }
    +
    +    // Nested class for SHA384withECDSA signatures
    +    public static final class SHA384 extends ECDSASignature {
    +        public SHA384() {
    +            super("SHA-384");
    +        }
    +    }
    +
    +    // Nested class for SHA512withECDSA signatures
    +    public static final class SHA512 extends ECDSASignature {
    +        public SHA512() {
    +            super("SHA-512");
    +        }
    +    }
    +
    +    // initialize for verification. See JCA doc
    +    @Override
    +    protected void engineInitVerify(PublicKey publicKey)
    +            throws InvalidKeyException {
    +        this.publicKey = (ECPublicKey) ECKeyFactory.toECKey(publicKey);
    +
    +        // Should check that the supplied key is appropriate for signature
    +        // algorithm (e.g. P-256 for SHA256withECDSA)
    +        this.privateKey = null;
    +        resetDigest();
    +    }
    +
    +    // initialize for signing. See JCA doc
    +    @Override
    +    protected void engineInitSign(PrivateKey privateKey)
    +            throws InvalidKeyException {
    +        engineInitSign(privateKey, null);
    +    }
    +
    +    // initialize for signing. See JCA doc
    +    @Override
    +    protected void engineInitSign(PrivateKey privateKey, SecureRandom random)
    +            throws InvalidKeyException {
    +        this.privateKey = (ECPrivateKey) ECKeyFactory.toECKey(privateKey);
    +
    +        // Should check that the supplied key is appropriate for signature
    +        // algorithm (e.g. P-256 for SHA256withECDSA)
    +        this.publicKey = null;
    +        this.random = random;
    +        resetDigest();
    +    }
    +
    +    /**
    +     * Resets the message digest if needed.
    +     */
    +    protected void resetDigest() {
    +        if (needsReset) {
    +            if (messageDigest != null) {
    +                messageDigest.reset();
    +            }
    +            needsReset = false;
    +        }
    +    }
    +
    +    /**
    +     * Returns the message digest value.
    +     */
    +    protected byte[] getDigestValue() throws SignatureException {
    +        needsReset = false;
    +        return messageDigest.digest();
    +    }
    +
    +    // update the signature with the plaintext data. See JCA doc
    +    @Override
    +    protected void engineUpdate(byte b) throws SignatureException {
    +        messageDigest.update(b);
    +        needsReset = true;
    +    }
    +
    +    // update the signature with the plaintext data. See JCA doc
    +    @Override
    +    protected void engineUpdate(byte[] b, int off, int len)
    +            throws SignatureException {
    +        messageDigest.update(b, off, len);
    +        needsReset = true;
    +    }
    +
    +    // update the signature with the plaintext data. See JCA doc
    +    @Override
    +    protected void engineUpdate(ByteBuffer byteBuffer) {
    +        int len = byteBuffer.remaining();
    +        if (len <= 0) {
    +            return;
    +        }
    +
    +        messageDigest.update(byteBuffer);
    +        needsReset = true;
    +    }
    +
    +    // sign the data and return the signature. See JCA doc
    +    @Override
    +    protected byte[] engineSign() throws SignatureException {
    +        byte[] s = privateKey.getS().toByteArray();
    +        ECParameterSpec params = privateKey.getParams();
    +        byte[] encodedParams = ECParameters.encodeParameters(params); // DER OID
    +        int keySize = params.getCurve().getField().getFieldSize();
    +
    +        // seed is twice the key size (in bytes)
    +        byte[] seed = new byte[((keySize + 7) >> 3) * 2];
    +        if (random == null) {
    +            random = JCAUtil.getSecureRandom();
    +        }
    +        random.nextBytes(seed);
    +
    +        try {
    +
    +            return encodeSignature(
    +                signDigest(getDigestValue(), s, encodedParams, seed));
    +
    +        } catch (GeneralSecurityException e) {
    +            throw new SignatureException("Could not sign data", e);
    +        }
    +    }
    +
    +    // verify the data and return the result. See JCA doc
    +    @Override
    +    protected boolean engineVerify(byte[] signature) throws SignatureException {
    +
    +        byte[] w;
    +        ECParameterSpec params = publicKey.getParams();
    +        byte[] encodedParams = ECParameters.encodeParameters(params); // DER OID
    +
    +        if (publicKey instanceof ECPublicKeyImpl) {
    +            w = ((ECPublicKeyImpl)publicKey).getEncodedPublicValue();
    +        } else { // instanceof ECPublicKey
    +            w = ECParameters.encodePoint(publicKey.getW(), params.getCurve());
    +        }
    +
    +        try {
    +
    +            return verifySignedDigest(
    +                decodeSignature(signature), getDigestValue(), w, encodedParams);
    +
    +        } catch (GeneralSecurityException e) {
    +            throw new SignatureException("Could not verify signature", e);
    +        }
    +    }
    +
    +    // set parameter, not supported. See JCA doc
    +    @Override
    +    protected void engineSetParameter(String param, Object value)
    +            throws InvalidParameterException {
    +        throw new UnsupportedOperationException("setParameter() not supported");
    +    }
    +
    +    // get parameter, not supported. See JCA doc
    +    @Override
    +    protected Object engineGetParameter(String param)
    +            throws InvalidParameterException {
    +        throw new UnsupportedOperationException("getParameter() not supported");
    +    }
    +
    +    // Convert the concatenation of R and S into their DER encoding
    +    private byte[] encodeSignature(byte[] signature) throws SignatureException {
    +        try {
    +
    +            int n = signature.length >> 1;
    +            byte[] bytes = new byte[n];
    +            System.arraycopy(signature, 0, bytes, 0, n);
    +            BigInteger r = new BigInteger(1, bytes);
    +            System.arraycopy(signature, n, bytes, 0, n);
    +            BigInteger s = new BigInteger(1, bytes);
    +
    +            DerOutputStream out = new DerOutputStream(signature.length + 10);
    +            out.putInteger(r);
    +            out.putInteger(s);
    +            DerValue result =
    +                new DerValue(DerValue.tag_Sequence, out.toByteArray());
    +
    +            return result.toByteArray();
    +
    +        } catch (Exception e) {
    +            throw new SignatureException("Could not encode signature", e);
    +        }
    +    }
    +
    +    // Convert the DER encoding of R and S into a concatenation of R and S
    +    private byte[] decodeSignature(byte[] signature) throws SignatureException {
    +
    +        try {
    +            DerInputStream in = new DerInputStream(signature);
    +            DerValue[] values = in.getSequence(2);
    +            BigInteger r = values[0].getPositiveBigInteger();
    +            BigInteger s = values[1].getPositiveBigInteger();
    +            // trim leading zeroes
    +            byte[] rBytes = trimZeroes(r.toByteArray());
    +            byte[] sBytes = trimZeroes(s.toByteArray());
    +            int k = Math.max(rBytes.length, sBytes.length);
    +            // r and s each occupy half the array
    +            byte[] result = new byte[k << 1];
    +            System.arraycopy(rBytes, 0, result, k - rBytes.length,
    +                rBytes.length);
    +            System.arraycopy(sBytes, 0, result, result.length - sBytes.length,
    +                sBytes.length);
    +            return result;
    +
    +        } catch (Exception e) {
    +            throw new SignatureException("Could not decode signature", e);
    +        }
    +    }
    +
    +    // trim leading (most significant) zeroes from the result
    +    private static byte[] trimZeroes(byte[] b) {
    +        int i = 0;
    +        while ((i < b.length - 1) && (b[i] == 0)) {
    +            i++;
    +        }
    +        if (i == 0) {
    +            return b;
    +        }
    +        byte[] t = new byte[b.length - i];
    +        System.arraycopy(b, i, t, 0, t.length);
    +        return t;
    +    }
    +
    +    /**
    +     * Signs the digest using the private key.
    +     *
    +     * @param digest the digest to be signed.
    +     * @param s the private key's S value.
    +     * @param encodedParams the curve's DER encoded object identifier.
    +     * @param seed the random seed.
    +     *
    +     * @return byte[] the signature.
    +     */
    +    private static native byte[] signDigest(byte[] digest, byte[] s,
    +        byte[] encodedParams, byte[] seed) throws GeneralSecurityException;
    +
    +    /**
    +     * Verifies the signed digest using the public key.
    +     *
    +     * @param signedDigest the signature to be verified. It is encoded
    +     *        as a concatenation of the key's R and S values.
    +     * @param digest the digest to be used.
    +     * @param w the public key's W point (in uncompressed form).
    +     * @param encodedParams the curve's DER encoded object identifier.
    +     *
    +     * @return boolean true if the signature is successfully verified.
    +     */
    +    private static native boolean verifySignedDigest(byte[] signature,
    +        byte[] digest, byte[] w, byte[] encodedParams)
    +            throws GeneralSecurityException;
    +}
    diff --git a/jdk/src/share/classes/sun/security/ec/ECKeyPairGenerator.java b/jdk/src/share/classes/sun/security/ec/ECKeyPairGenerator.java
    new file mode 100644
    index 00000000000..af98de60b8b
    --- /dev/null
    +++ b/jdk/src/share/classes/sun/security/ec/ECKeyPairGenerator.java
    @@ -0,0 +1,191 @@
    +/*
    + * Copyright 2009 Sun Microsystems, Inc.  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.  Sun designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    + * CA 95054 USA or visit www.sun.com if you need additional information or
    + * have any questions.
    + */
    +
    +package sun.security.ec;
    +
    +import java.math.BigInteger;
    +import java.security.*;
    +import java.security.spec.AlgorithmParameterSpec;
    +import java.security.spec.ECGenParameterSpec;
    +import java.security.spec.ECParameterSpec;
    +import java.security.spec.ECPoint;
    +
    +import sun.security.ec.NamedCurve;
    +import sun.security.ec.ECParameters;
    +import sun.security.ec.ECPrivateKeyImpl;
    +import sun.security.ec.ECPublicKeyImpl;
    +import sun.security.jca.JCAUtil;
    +
    +/**
    + * EC keypair generator.
    + * Standard algorithm, minimum key length is 112 bits, maximum is 571 bits.
    + *
    + * @since 1.7
    + */
    +public final class ECKeyPairGenerator extends KeyPairGeneratorSpi {
    +
    +    // flag indicating whether the native ECC implementation is present
    +    private static boolean implementationPresent = true;
    +    static {
    +        try {
    +            AccessController.doPrivileged(new PrivilegedAction() {
    +                public Void run() {
    +                    System.loadLibrary("sunecc");
    +                    return null;
    +                }
    +            });
    +        } catch (UnsatisfiedLinkError e) {
    +            implementationPresent = false;
    +        }
    +    }
    +    private static final int KEY_SIZE_MIN = 112; // min bits (see ecc_impl.h)
    +    private static final int KEY_SIZE_MAX = 571; // max bits (see ecc_impl.h)
    +    private static final int KEY_SIZE_DEFAULT = 256;
    +
    +    // used to seed the keypair generator
    +    private SecureRandom random;
    +
    +    // size of the key to generate, KEY_SIZE_MIN <= keySize <= KEY_SIZE_MAX
    +    private int keySize;
    +
    +    // parameters specified via init, if any
    +    private AlgorithmParameterSpec params = null;
    +
    +    /**
    +     * Constructs a new ECKeyPairGenerator.
    +     *
    +     * @exception ProviderException if the native ECC library is unavailable.
    +     */
    +    public ECKeyPairGenerator() {
    +        if (!implementationPresent) {
    +            throw new ProviderException("EC implementation is not available");
    +        }
    +        // initialize to default in case the app does not call initialize()
    +        initialize(KEY_SIZE_DEFAULT, null);
    +    }
    +
    +    // initialize the generator. See JCA doc
    +    @Override
    +    public void initialize(int keySize, SecureRandom random) {
    +
    +        checkKeySize(keySize);
    +        this.params = NamedCurve.getECParameterSpec(keySize);
    +        if (params == null) {
    +            throw new InvalidParameterException(
    +                "No EC parameters available for key size " + keySize + " bits");
    +        }
    +        this.random = random;
    +    }
    +
    +    // second initialize method. See JCA doc
    +    @Override
    +    public void initialize(AlgorithmParameterSpec params, SecureRandom random)
    +            throws InvalidAlgorithmParameterException {
    +
    +        if (params instanceof ECParameterSpec) {
    +            this.params = ECParameters.getNamedCurve((ECParameterSpec)params);
    +            if (this.params == null) {
    +                throw new InvalidAlgorithmParameterException(
    +                    "Unsupported curve: " + params);
    +            }
    +        } else if (params instanceof ECGenParameterSpec) {
    +            String name = ((ECGenParameterSpec)params).getName();
    +            this.params = NamedCurve.getECParameterSpec(name);
    +            if (this.params == null) {
    +                throw new InvalidAlgorithmParameterException(
    +                    "Unknown curve name: " + name);
    +            }
    +        } else {
    +            throw new InvalidAlgorithmParameterException(
    +                "ECParameterSpec or ECGenParameterSpec required for EC");
    +        }
    +        this.keySize =
    +            ((ECParameterSpec)this.params).getCurve().getField().getFieldSize();
    +        this.random = random;
    +    }
    +
    +    // generate the keypair. See JCA doc
    +    @Override
    +    public KeyPair generateKeyPair() {
    +
    +        byte[] encodedParams =
    +            ECParameters.encodeParameters((ECParameterSpec)params);
    +
    +        // seed is twice the key size (in bytes)
    +        byte[] seed = new byte[2 * ((keySize + 7) >> 3)];
    +        if (random == null) {
    +            random = JCAUtil.getSecureRandom();
    +        }
    +        random.nextBytes(seed);
    +
    +        long[] handles = generateECKeyPair(keySize, encodedParams, seed);
    +
    +        // The 'params' object supplied above is equivalent to the native one
    +        // so there is no need to fetch it.
    +
    +        // handles[0] points to the native private key
    +        BigInteger s = new BigInteger(1, getEncodedBytes(handles[0]));
    +
    +        try {
    +            PrivateKey privateKey =
    +                new ECPrivateKeyImpl(s, (ECParameterSpec)params);
    +
    +            // handles[1] points to the native public key
    +            ECPoint w = ECParameters.decodePoint(getEncodedBytes(handles[1]),
    +                ((ECParameterSpec)params).getCurve());
    +            PublicKey publicKey =
    +                new ECPublicKeyImpl(w, (ECParameterSpec)params);
    +
    +            return new KeyPair(publicKey, privateKey);
    +
    +        } catch (Exception e) {
    +            throw new ProviderException(e);
    +        }
    +    }
    +
    +    private void checkKeySize(int keySize) throws InvalidParameterException {
    +        if (keySize < KEY_SIZE_MIN) {
    +            throw new InvalidParameterException
    +                ("Key size must be at least " + KEY_SIZE_MIN + " bits");
    +        }
    +        if (keySize > KEY_SIZE_MAX) {
    +            throw new InvalidParameterException
    +                ("Key size must be at most " + KEY_SIZE_MAX + " bits");
    +        }
    +        this.keySize = keySize;
    +    }
    +
    +    /*
    +     * Generates the keypair and returns a 2-element array of handles.
    +     * The first handle points to the private key, the second to the public key.
    +     */
    +    private static native long[] generateECKeyPair(int keySize,
    +        byte[] encodedParams, byte[] seed);
    +
    +    /*
    +     * Extracts the encoded key data using the supplied handle.
    +     */
    +    private static native byte[] getEncodedBytes(long handle);
    +}
    diff --git a/jdk/src/share/classes/sun/security/ec/SunEC.java b/jdk/src/share/classes/sun/security/ec/SunEC.java
    new file mode 100644
    index 00000000000..49223ca37b2
    --- /dev/null
    +++ b/jdk/src/share/classes/sun/security/ec/SunEC.java
    @@ -0,0 +1,65 @@
    +/*
    + * Copyright 2009 Sun Microsystems, Inc.  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.  Sun designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    + * CA 95054 USA or visit www.sun.com if you need additional information or
    + * have any questions.
    + */
    +
    +package sun.security.ec;
    +
    +import java.util.*;
    +import java.security.*;
    +import sun.security.action.PutAllAction;
    +
    +/**
    + * Provider class for the Elliptic Curve provider.
    + * Supports EC keypair and parameter generation, ECDSA signing and
    + * ECDH key agreement.
    + *
    + * IMPLEMENTATION NOTE:
    + * The Java classes in this provider access a native ECC implementation
    + * via JNI to a C++ wrapper class which in turn calls C functions.
    + * The Java classes are packaged into the signed sunec.jar in the JRE
    + * extensions directory and the C++ and C functions are packaged into
    + * libsunecc.so or sunecc.dll in the JRE native libraries directory.
    + *
    + * @since   1.7
    + */
    +public final class SunEC extends Provider {
    +
    +    private static final long serialVersionUID = -2279741672933606418L;
    +
    +    public SunEC() {
    +        super("SunEC", 1.7d, "Sun Elliptic Curve provider (EC, ECDSA, ECDH)");
    +
    +        // if there is no security manager installed, put directly into
    +        // the provider. Otherwise, create a temporary map and use a
    +        // doPrivileged() call at the end to transfer the contents
    +        if (System.getSecurityManager() == null) {
    +            SunECEntries.putEntries(this);
    +        } else {
    +            Map map = new HashMap();
    +            SunECEntries.putEntries(map);
    +            AccessController.doPrivileged(new PutAllAction(this, map));
    +        }
    +    }
    +
    +}
    diff --git a/jdk/src/share/classes/sun/security/ec/SunECEntries.java b/jdk/src/share/classes/sun/security/ec/SunECEntries.java
    new file mode 100644
    index 00000000000..759d3007e85
    --- /dev/null
    +++ b/jdk/src/share/classes/sun/security/ec/SunECEntries.java
    @@ -0,0 +1,109 @@
    +/*
    + * Copyright 2009 Sun Microsystems, Inc.  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.  Sun designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    + * CA 95054 USA or visit www.sun.com if you need additional information or
    + * have any questions.
    + */
    +
    +package sun.security.ec;
    +
    +import java.util.Map;
    +
    +/**
    + * Defines the entries of the SunEC provider.
    + *
    + * @since 1.7
    + */
    +final class SunECEntries {
    +
    +    private SunECEntries() {
    +        // empty
    +    }
    +
    +    static void putEntries(Map map) {
    +
    +        /*
    +         * Signature engines
    +         */
    +        map.put("Signature.NONEwithECDSA",
    +            "sun.security.ec.ECDSASignature$Raw");
    +        map.put("Signature.SHA1withECDSA",
    +            "sun.security.ec.ECDSASignature$SHA1");
    +        map.put("Signature.SHA256withECDSA",
    +            "sun.security.ec.ECDSASignature$SHA256");
    +        map.put("Signature.SHA384withECDSA",
    +            "sun.security.ec.ECDSASignature$SHA384");
    +        map.put("Signature.SHA512withECDSA",
    +            "sun.security.ec.ECDSASignature$SHA512");
    +
    +        String ecKeyClasses = "java.security.interfaces.ECPublicKey" +
    +                "|java.security.interfaces.ECPrivateKey";
    +        map.put("Signature.NONEwithECDSA SupportedKeyClasses", ecKeyClasses);
    +        map.put("Signature.SHA1withECDSA SupportedKeyClasses", ecKeyClasses);
    +        map.put("Signature.SHA256withECDSA SupportedKeyClasses", ecKeyClasses);
    +        map.put("Signature.SHA384withECDSA SupportedKeyClasses", ecKeyClasses);
    +        map.put("Signature.SHA512withECDSA SupportedKeyClasses", ecKeyClasses);
    +
    +        /*
    +         *  Key Pair Generator engine
    +         */
    +        map.put("KeyPairGenerator.EC", "sun.security.ec.ECKeyPairGenerator");
    +        map.put("Alg.Alias.KeyPairGenerator.EllipticCurve", "EC");
    +
    +        /*
    +         *  Key Factory engine
    +         */
    +        map.put("KeyFactory.EC", "sun.security.ec.ECKeyFactory");
    +        map.put("Alg.Alias.KeyFactory.EllipticCurve", "EC");
    +
    +        /*
    +         * Algorithm Parameter engine
    +         */
    +        map.put("AlgorithmParameters.EC", "sun.security.ec.ECParameters");
    +        map.put("Alg.Alias.AlgorithmParameters.EllipticCurve", "EC");
    +
    +        /*
    +         * Key Agreement engine
    +         */
    +        map.put("KeyAgreement.ECDH", "sun.security.ec.ECDHKeyAgreement");
    +        map.put("KeyAgreement.ECDH SupportedKeyClasses", ecKeyClasses);
    +
    +        /*
    +         * Key sizes
    +         */
    +        map.put("Signature.SHA1withECDSA KeySize", "256");
    +        map.put("KeyPairGenerator.EC KeySize", "256");
    +        map.put("AlgorithmParameterGenerator.ECDSA KeySize", "256");
    +
    +        /*
    +         * Implementation type: software or hardware
    +         */
    +        map.put("Signature.NONEwithECDSA ImplementedIn", "Software");
    +        map.put("Signature.SHA1withECDSA ImplementedIn", "Software");
    +        map.put("Signature.SHA256withECDSA ImplementedIn", "Software");
    +        map.put("Signature.SHA384withECDSA ImplementedIn", "Software");
    +        map.put("Signature.SHA512withECDSA ImplementedIn", "Software");
    +        map.put("KeyPairGenerator.EC ImplementedIn", "Software");
    +        map.put("KeyFactory.EC ImplementedIn", "Software");
    +        map.put("KeyAgreement.ECDH ImplementedIn", "Software");
    +        map.put("AlgorithmParameters.EC ImplementedIn", "Software");
    +    }
    +}
    diff --git a/jdk/src/share/lib/security/java.security b/jdk/src/share/lib/security/java.security
    index c2a07506c15..b975f25e1e5 100644
    --- a/jdk/src/share/lib/security/java.security
    +++ b/jdk/src/share/lib/security/java.security
    @@ -45,12 +45,13 @@
     #
     security.provider.1=sun.security.provider.Sun
     security.provider.2=sun.security.rsa.SunRsaSign
    -security.provider.3=com.sun.net.ssl.internal.ssl.Provider
    -security.provider.4=com.sun.crypto.provider.SunJCE
    -security.provider.5=sun.security.jgss.SunProvider
    -security.provider.6=com.sun.security.sasl.Provider
    -security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI
    -security.provider.8=sun.security.smartcardio.SunPCSC
    +security.provider.3=sun.security.ec.SunEC
    +security.provider.4=com.sun.net.ssl.internal.ssl.Provider
    +security.provider.5=com.sun.crypto.provider.SunJCE
    +security.provider.6=sun.security.jgss.SunProvider
    +security.provider.7=com.sun.security.sasl.Provider
    +security.provider.8=org.jcp.xml.dsig.internal.dom.XMLDSigRI
    +security.provider.9=sun.security.smartcardio.SunPCSC
     
     #
     # Select the source of seed data for SecureRandom. By default an
    diff --git a/jdk/src/share/lib/security/java.security-solaris b/jdk/src/share/lib/security/java.security-solaris
    index 05dfcb17728..1e447b7c24d 100644
    --- a/jdk/src/share/lib/security/java.security-solaris
    +++ b/jdk/src/share/lib/security/java.security-solaris
    @@ -46,12 +46,13 @@
     security.provider.1=sun.security.pkcs11.SunPKCS11 ${java.home}/lib/security/sunpkcs11-solaris.cfg
     security.provider.2=sun.security.provider.Sun
     security.provider.3=sun.security.rsa.SunRsaSign
    -security.provider.4=com.sun.net.ssl.internal.ssl.Provider
    -security.provider.5=com.sun.crypto.provider.SunJCE
    -security.provider.6=sun.security.jgss.SunProvider
    -security.provider.7=com.sun.security.sasl.Provider
    -security.provider.8=org.jcp.xml.dsig.internal.dom.XMLDSigRI
    -security.provider.9=sun.security.smartcardio.SunPCSC
    +security.provider.4=sun.security.ec.SunEC
    +security.provider.5=com.sun.net.ssl.internal.ssl.Provider
    +security.provider.6=com.sun.crypto.provider.SunJCE
    +security.provider.7=sun.security.jgss.SunProvider
    +security.provider.8=com.sun.security.sasl.Provider
    +security.provider.9=org.jcp.xml.dsig.internal.dom.XMLDSigRI
    +security.provider.10=sun.security.smartcardio.SunPCSC
     
     #
     # Select the source of seed data for SecureRandom. By default an
    diff --git a/jdk/src/share/lib/security/java.security-windows b/jdk/src/share/lib/security/java.security-windows
    index 062b85b63c3..c94c76b7ffb 100644
    --- a/jdk/src/share/lib/security/java.security-windows
    +++ b/jdk/src/share/lib/security/java.security-windows
    @@ -45,13 +45,14 @@
     #
     security.provider.1=sun.security.provider.Sun
     security.provider.2=sun.security.rsa.SunRsaSign
    -security.provider.3=com.sun.net.ssl.internal.ssl.Provider
    -security.provider.4=com.sun.crypto.provider.SunJCE
    -security.provider.5=sun.security.jgss.SunProvider
    -security.provider.6=com.sun.security.sasl.Provider
    -security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI
    -security.provider.8=sun.security.smartcardio.SunPCSC
    -security.provider.9=sun.security.mscapi.SunMSCAPI
    +security.provider.3=sun.security.ec.SunEC
    +security.provider.4=com.sun.net.ssl.internal.ssl.Provider
    +security.provider.5=com.sun.crypto.provider.SunJCE
    +security.provider.6=sun.security.jgss.SunProvider
    +security.provider.7=com.sun.security.sasl.Provider
    +security.provider.8=org.jcp.xml.dsig.internal.dom.XMLDSigRI
    +security.provider.9=sun.security.smartcardio.SunPCSC
    +security.provider.10=sun.security.mscapi.SunMSCAPI
     
     #
     # Select the source of seed data for SecureRandom. By default an
    diff --git a/jdk/src/share/native/sun/security/ec/ECC_JNI.cpp b/jdk/src/share/native/sun/security/ec/ECC_JNI.cpp
    new file mode 100644
    index 00000000000..fb227e82cac
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/ECC_JNI.cpp
    @@ -0,0 +1,418 @@
    +/*
    + * Copyright 2009 Sun Microsystems, Inc.  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.  Sun designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    + * CA 95054 USA or visit www.sun.com if you need additional information or
    + * have any questions.
    + */
    +
    +#include 
    +#include "ecc_impl.h"
    +
    +#define ILLEGAL_STATE_EXCEPTION "java/lang/IllegalStateException"
    +#define INVALID_ALGORITHM_PARAMETER_EXCEPTION \
    +        "java/security/InvalidAlgorithmParameterException"
    +#define INVALID_PARAMETER_EXCEPTION \
    +        "java/security/InvalidParameterException"
    +#define KEY_EXCEPTION   "java/security/KeyException"
    +
    +extern "C" {
    +
    +/*
    + * Throws an arbitrary Java exception.
    + */
    +void ThrowException(JNIEnv *env, char *exceptionName)
    +{
    +    jclass exceptionClazz = env->FindClass(exceptionName);
    +    env->ThrowNew(exceptionClazz, NULL);
    +}
    +
    +/*
    + * Deep free of the ECParams struct
    + */
    +void FreeECParams(ECParams *ecparams, jboolean freeStruct)
    +{
    +    // Use B_FALSE to free the SECItem->data element, but not the SECItem itself
    +    // Use B_TRUE to free both
    +
    +    SECITEM_FreeItem(&ecparams->fieldID.u.prime, B_FALSE);
    +    SECITEM_FreeItem(&ecparams->curve.a, B_FALSE);
    +    SECITEM_FreeItem(&ecparams->curve.b, B_FALSE);
    +    SECITEM_FreeItem(&ecparams->curve.seed, B_FALSE);
    +    SECITEM_FreeItem(&ecparams->base, B_FALSE);
    +    SECITEM_FreeItem(&ecparams->order, B_FALSE);
    +    SECITEM_FreeItem(&ecparams->DEREncoding, B_FALSE);
    +    SECITEM_FreeItem(&ecparams->curveOID, B_FALSE);
    +    if (freeStruct)
    +        free(ecparams);
    +}
    +
    +/*
    + * Class:     sun_security_ec_ECKeyPairGenerator
    + * Method:    generateECKeyPair
    + * Signature: (I[B[B)[J
    + */
    +JNIEXPORT jlongArray
    +JNICALL Java_sun_security_ec_ECKeyPairGenerator_generateECKeyPair
    +  (JNIEnv *env, jclass clazz, jint keySize, jbyteArray encodedParams, jbyteArray seed)
    +{
    +    ECPrivateKey *privKey;      /* contains both public and private values */
    +    ECParams *ecparams = NULL;
    +    SECKEYECParams params_item;
    +    jint jSeedLength;
    +    jbyte* pSeedBuffer = NULL;
    +    jlongArray result = NULL;
    +    jlong* resultElements = NULL;
    +
    +    // Initialize the ECParams struct
    +    params_item.len = env->GetArrayLength(encodedParams);
    +    params_item.data =
    +        (unsigned char *) env->GetByteArrayElements(encodedParams, 0);
    +
    +    // Fill a new ECParams using the supplied OID
    +    if (EC_DecodeParams(¶ms_item, &ecparams, 0) != SECSuccess) {
    +        /* bad curve OID */
    +        ThrowException(env, INVALID_ALGORITHM_PARAMETER_EXCEPTION);
    +        goto cleanup;
    +    }
    +
    +    // Copy seed from Java to native buffer
    +    jSeedLength = env->GetArrayLength(seed);
    +    pSeedBuffer = new jbyte[jSeedLength];
    +    env->GetByteArrayRegion(seed, 0, jSeedLength, pSeedBuffer);
    +
    +    // Generate the new keypair (using the supplied seed)
    +    if (EC_NewKey(ecparams, &privKey, (unsigned char *) pSeedBuffer,
    +        jSeedLength, 0) != SECSuccess) {
    +        ThrowException(env, KEY_EXCEPTION);
    +        goto cleanup;
    +    }
    +
    +    jboolean isCopy;
    +    result = env->NewLongArray(2);
    +    resultElements = env->GetLongArrayElements(result, &isCopy);
    +
    +    resultElements[0] = (jlong) &(privKey->privateValue); // private big integer
    +    resultElements[1] = (jlong) &(privKey->publicValue); // encoded ec point
    +
    +    // If the array is a copy then we must write back our changes
    +    if (isCopy == JNI_TRUE) {
    +        env->ReleaseLongArrayElements(result, resultElements, 0);
    +    }
    +
    +cleanup:
    +    {
    +        if (params_item.data)
    +            env->ReleaseByteArrayElements(encodedParams,
    +                (jbyte *) params_item.data, JNI_ABORT);
    +
    +        if (ecparams)
    +            FreeECParams(ecparams, true);
    +
    +        if (privKey) {
    +            FreeECParams(&privKey->ecParams, false);
    +            SECITEM_FreeItem(&privKey->version, B_FALSE);
    +            // Don't free privKey->privateValue and privKey->publicValue
    +        }
    +
    +        if (pSeedBuffer)
    +            delete [] pSeedBuffer;
    +    }
    +
    +    return result;
    +}
    +
    +/*
    + * Class:     sun_security_ec_ECKeyPairGenerator
    + * Method:    getEncodedBytes
    + * Signature: (J)[B
    + */
    +JNIEXPORT jbyteArray
    +JNICALL Java_sun_security_ec_ECKeyPairGenerator_getEncodedBytes
    +  (JNIEnv *env, jclass clazz, jlong hSECItem)
    +{
    +    SECItem *s = (SECItem *)hSECItem;
    +    jbyteArray jEncodedBytes = env->NewByteArray(s->len);
    +
    +    // Copy bytes from a native SECItem buffer to Java byte array
    +    env->SetByteArrayRegion(jEncodedBytes, 0, s->len, (jbyte *)s->data);
    +
    +    // Use B_FALSE to free only the SECItem->data
    +    SECITEM_FreeItem(s, B_FALSE);
    +
    +    return jEncodedBytes;
    +}
    +
    +/*
    + * Class:     sun_security_ec_ECDSASignature
    + * Method:    signDigest
    + * Signature: ([B[B[B[B)[B
    + */
    +JNIEXPORT jbyteArray
    +JNICALL Java_sun_security_ec_ECDSASignature_signDigest
    +  (JNIEnv *env, jclass clazz, jbyteArray digest, jbyteArray privateKey, jbyteArray encodedParams, jbyteArray seed)
    +{
    +    jbyte* pDigestBuffer = NULL;
    +    jint jDigestLength = env->GetArrayLength(digest);
    +    jbyteArray jSignedDigest = NULL;
    +
    +    SECItem signature_item;
    +    jbyte* pSignedDigestBuffer = NULL;
    +    jbyteArray temp;
    +
    +    jint jSeedLength = env->GetArrayLength(seed);
    +    jbyte* pSeedBuffer = NULL;
    +
    +    // Copy digest from Java to native buffer
    +    pDigestBuffer = new jbyte[jDigestLength];
    +    env->GetByteArrayRegion(digest, 0, jDigestLength, pDigestBuffer);
    +    SECItem digest_item;
    +    digest_item.data = (unsigned char *) pDigestBuffer;
    +    digest_item.len = jDigestLength;
    +
    +    ECPrivateKey privKey;
    +
    +    // Initialize the ECParams struct
    +    ECParams *ecparams = NULL;
    +    SECKEYECParams params_item;
    +    params_item.len = env->GetArrayLength(encodedParams);
    +    params_item.data =
    +        (unsigned char *) env->GetByteArrayElements(encodedParams, 0);
    +
    +    // Fill a new ECParams using the supplied OID
    +    if (EC_DecodeParams(¶ms_item, &ecparams, 0) != SECSuccess) {
    +        /* bad curve OID */
    +        ThrowException(env, INVALID_ALGORITHM_PARAMETER_EXCEPTION);
    +        goto cleanup;
    +    }
    +
    +    // Extract private key data
    +    privKey.ecParams = *ecparams; // struct assignment
    +    privKey.privateValue.len = env->GetArrayLength(privateKey);
    +    privKey.privateValue.data =
    +        (unsigned char *) env->GetByteArrayElements(privateKey, 0);
    +
    +    // Prepare a buffer for the signature (twice the key length)
    +    pSignedDigestBuffer = new jbyte[ecparams->order.len * 2];
    +    signature_item.data = (unsigned char *) pSignedDigestBuffer;
    +    signature_item.len = ecparams->order.len * 2;
    +
    +    // Copy seed from Java to native buffer
    +    pSeedBuffer = new jbyte[jSeedLength];
    +    env->GetByteArrayRegion(seed, 0, jSeedLength, pSeedBuffer);
    +
    +    // Sign the digest (using the supplied seed)
    +    if (ECDSA_SignDigest(&privKey, &signature_item, &digest_item,
    +        (unsigned char *) pSeedBuffer, jSeedLength, 0) != SECSuccess) {
    +        ThrowException(env, KEY_EXCEPTION);
    +        goto cleanup;
    +    }
    +
    +    // Create new byte array
    +    temp = env->NewByteArray(signature_item.len);
    +
    +    // Copy data from native buffer
    +    env->SetByteArrayRegion(temp, 0, signature_item.len, pSignedDigestBuffer);
    +    jSignedDigest = temp;
    +
    +cleanup:
    +    {
    +        if (params_item.data)
    +            env->ReleaseByteArrayElements(encodedParams,
    +                (jbyte *) params_item.data, JNI_ABORT);
    +
    +        if (pDigestBuffer)
    +            delete [] pDigestBuffer;
    +
    +        if (pSignedDigestBuffer)
    +            delete [] pSignedDigestBuffer;
    +
    +        if (pSeedBuffer)
    +            delete [] pSeedBuffer;
    +
    +        if (ecparams)
    +            FreeECParams(ecparams, true);
    +    }
    +
    +    return jSignedDigest;
    +}
    +
    +/*
    + * Class:     sun_security_ec_ECDSASignature
    + * Method:    verifySignedDigest
    + * Signature: ([B[B[B[B)Z
    + */
    +JNIEXPORT jboolean
    +JNICALL Java_sun_security_ec_ECDSASignature_verifySignedDigest
    +  (JNIEnv *env, jclass clazz, jbyteArray signedDigest, jbyteArray digest, jbyteArray publicKey, jbyteArray encodedParams)
    +{
    +    jboolean isValid = false;
    +
    +    // Copy signedDigest from Java to native buffer
    +    jbyte* pSignedDigestBuffer = NULL;
    +    jint jSignedDigestLength = env->GetArrayLength(signedDigest);
    +    pSignedDigestBuffer = new jbyte[jSignedDigestLength];
    +    env->GetByteArrayRegion(signedDigest, 0, jSignedDigestLength,
    +        pSignedDigestBuffer);
    +    SECItem signature_item;
    +    signature_item.data = (unsigned char *) pSignedDigestBuffer;
    +    signature_item.len = jSignedDigestLength;
    +
    +    // Copy digest from Java to native buffer
    +    jbyte* pDigestBuffer = NULL;
    +    jint jDigestLength = env->GetArrayLength(digest);
    +    pDigestBuffer = new jbyte[jDigestLength];
    +    env->GetByteArrayRegion(digest, 0, jDigestLength, pDigestBuffer);
    +    SECItem digest_item;
    +    digest_item.data = (unsigned char *) pDigestBuffer;
    +    digest_item.len = jDigestLength;
    +
    +    // Extract public key data
    +    ECPublicKey pubKey;
    +    pubKey.publicValue.data = NULL;
    +    ECParams *ecparams = NULL;
    +    SECKEYECParams params_item;
    +
    +    // Initialize the ECParams struct
    +    params_item.len = env->GetArrayLength(encodedParams);
    +    params_item.data =
    +        (unsigned char *) env->GetByteArrayElements(encodedParams, 0);
    +
    +    // Fill a new ECParams using the supplied OID
    +    if (EC_DecodeParams(¶ms_item, &ecparams, 0) != SECSuccess) {
    +        /* bad curve OID */
    +        ThrowException(env, INVALID_ALGORITHM_PARAMETER_EXCEPTION);
    +        goto cleanup;
    +    }
    +    pubKey.ecParams = *ecparams; // struct assignment
    +    pubKey.publicValue.len = env->GetArrayLength(publicKey);
    +    pubKey.publicValue.data =
    +        (unsigned char *) env->GetByteArrayElements(publicKey, 0);
    +
    +    if (ECDSA_VerifyDigest(&pubKey, &signature_item, &digest_item, 0)
    +            != SECSuccess) {
    +        goto cleanup;
    +    }
    +
    +    isValid = true;
    +
    +cleanup:
    +    {
    +        if (params_item.data)
    +            env->ReleaseByteArrayElements(encodedParams,
    +                (jbyte *) params_item.data, JNI_ABORT);
    +
    +        if (pubKey.publicValue.data)
    +            env->ReleaseByteArrayElements(publicKey,
    +                (jbyte *) pubKey.publicValue.data, JNI_ABORT);
    +
    +        if (ecparams)
    +            FreeECParams(ecparams, true);
    +
    +        if (pSignedDigestBuffer)
    +            delete [] pSignedDigestBuffer;
    +
    +        if (pDigestBuffer)
    +            delete [] pDigestBuffer;
    +    }
    +
    +    return isValid;
    +}
    +
    +/*
    + * Class:     sun_security_ec_ECDHKeyAgreement
    + * Method:    deriveKey
    + * Signature: ([B[B[B)[B
    + */
    +JNIEXPORT jbyteArray
    +JNICALL Java_sun_security_ec_ECDHKeyAgreement_deriveKey
    +  (JNIEnv *env, jclass clazz, jbyteArray privateKey, jbyteArray publicKey, jbyteArray encodedParams)
    +{
    +    jbyteArray jSecret = NULL;
    +
    +    // Extract private key value
    +    SECItem privateValue_item;
    +    privateValue_item.len = env->GetArrayLength(privateKey);
    +    privateValue_item.data =
    +            (unsigned char *) env->GetByteArrayElements(privateKey, 0);
    +
    +    // Extract public key value
    +    SECItem publicValue_item;
    +    publicValue_item.len = env->GetArrayLength(publicKey);
    +    publicValue_item.data =
    +        (unsigned char *) env->GetByteArrayElements(publicKey, 0);
    +
    +    // Initialize the ECParams struct
    +    ECParams *ecparams = NULL;
    +    SECKEYECParams params_item;
    +    params_item.len = env->GetArrayLength(encodedParams);
    +    params_item.data =
    +        (unsigned char *) env->GetByteArrayElements(encodedParams, 0);
    +
    +    // Fill a new ECParams using the supplied OID
    +    if (EC_DecodeParams(¶ms_item, &ecparams, 0) != SECSuccess) {
    +        /* bad curve OID */
    +        ThrowException(env, INVALID_ALGORITHM_PARAMETER_EXCEPTION);
    +        goto cleanup;
    +    }
    +
    +    // Prepare a buffer for the secret
    +    SECItem secret_item;
    +    secret_item.data = NULL;
    +    secret_item.len = ecparams->order.len * 2;
    +
    +    if (ECDH_Derive(&publicValue_item, ecparams, &privateValue_item, B_FALSE,
    +        &secret_item, 0) != SECSuccess) {
    +        ThrowException(env, ILLEGAL_STATE_EXCEPTION);
    +        goto cleanup;
    +    }
    +
    +    // Create new byte array
    +    jSecret = env->NewByteArray(secret_item.len);
    +
    +    // Copy bytes from the SECItem buffer to a Java byte array
    +    env->SetByteArrayRegion(jSecret, 0, secret_item.len,
    +        (jbyte *)secret_item.data);
    +
    +    // Free the SECItem data buffer
    +    SECITEM_FreeItem(&secret_item, B_FALSE);
    +
    +cleanup:
    +    {
    +        if (privateValue_item.data)
    +            env->ReleaseByteArrayElements(privateKey,
    +                (jbyte *) privateValue_item.data, JNI_ABORT);
    +
    +        if (publicValue_item.data)
    +            env->ReleaseByteArrayElements(publicKey,
    +                (jbyte *) publicValue_item.data, JNI_ABORT);
    +
    +        if (params_item.data)
    +            env->ReleaseByteArrayElements(encodedParams,
    +                (jbyte *) params_item.data, JNI_ABORT);
    +
    +        if (ecparams)
    +            FreeECParams(ecparams, true);
    +    }
    +
    +    return jSecret;
    +}
    +
    +} /* extern "C" */
    diff --git a/jdk/src/share/native/sun/security/ec/ec.c b/jdk/src/share/native/sun/security/ec/ec.c
    new file mode 100644
    index 00000000000..d77f110af64
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/ec.c
    @@ -0,0 +1,1099 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the Elliptic Curve Cryptography library.
    + *
    + * The Initial Developer of the Original Code is
    + * Sun Microsystems, Inc.
    + * Portions created by the Initial Developer are Copyright (C) 2003
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Dr Vipul Gupta  and
    + *   Douglas Stebila , Sun Microsystems Laboratories
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +#include "mplogic.h"
    +#include "ec.h"
    +#include "ecl.h"
    +
    +#include 
    +#ifndef _KERNEL
    +#include 
    +#include 
    +
    +#ifndef _WIN32
    +#include 
    +#endif /* _WIN32 */
    +
    +#endif
    +#include "ecl-exp.h"
    +#include "mpi.h"
    +#include "ecc_impl.h"
    +
    +#ifdef _KERNEL
    +#define PORT_ZFree(p, l)                bzero((p), (l)); kmem_free((p), (l))
    +#else
    +#ifndef _WIN32
    +#define PORT_ZFree(p, l)                bzero((p), (l)); free((p))
    +#else
    +#define PORT_ZFree(p, l)                memset((p), 0, (l)); free((p))
    +#endif /* _WIN32 */
    +#endif
    +
    +/*
    + * Returns true if pointP is the point at infinity, false otherwise
    + */
    +PRBool
    +ec_point_at_infinity(SECItem *pointP)
    +{
    +    unsigned int i;
    +
    +    for (i = 1; i < pointP->len; i++) {
    +        if (pointP->data[i] != 0x00) return PR_FALSE;
    +    }
    +
    +    return PR_TRUE;
    +}
    +
    +/*
    + * Computes scalar point multiplication pointQ = k1 * G + k2 * pointP for
    + * the curve whose parameters are encoded in params with base point G.
    + */
    +SECStatus
    +ec_points_mul(const ECParams *params, const mp_int *k1, const mp_int *k2,
    +             const SECItem *pointP, SECItem *pointQ, int kmflag)
    +{
    +    mp_int Px, Py, Qx, Qy;
    +    mp_int Gx, Gy, order, irreducible, a, b;
    +#if 0 /* currently don't support non-named curves */
    +    unsigned int irr_arr[5];
    +#endif
    +    ECGroup *group = NULL;
    +    SECStatus rv = SECFailure;
    +    mp_err err = MP_OKAY;
    +    int len;
    +
    +#if EC_DEBUG
    +    int i;
    +    char mpstr[256];
    +
    +    printf("ec_points_mul: params [len=%d]:", params->DEREncoding.len);
    +    for (i = 0; i < params->DEREncoding.len; i++)
    +            printf("%02x:", params->DEREncoding.data[i]);
    +    printf("\n");
    +
    +        if (k1 != NULL) {
    +                mp_tohex(k1, mpstr);
    +                printf("ec_points_mul: scalar k1: %s\n", mpstr);
    +                mp_todecimal(k1, mpstr);
    +                printf("ec_points_mul: scalar k1: %s (dec)\n", mpstr);
    +        }
    +
    +        if (k2 != NULL) {
    +                mp_tohex(k2, mpstr);
    +                printf("ec_points_mul: scalar k2: %s\n", mpstr);
    +                mp_todecimal(k2, mpstr);
    +                printf("ec_points_mul: scalar k2: %s (dec)\n", mpstr);
    +        }
    +
    +        if (pointP != NULL) {
    +                printf("ec_points_mul: pointP [len=%d]:", pointP->len);
    +                for (i = 0; i < pointP->len; i++)
    +                        printf("%02x:", pointP->data[i]);
    +                printf("\n");
    +        }
    +#endif
    +
    +        /* NOTE: We only support uncompressed points for now */
    +        len = (params->fieldID.size + 7) >> 3;
    +        if (pointP != NULL) {
    +                if ((pointP->data[0] != EC_POINT_FORM_UNCOMPRESSED) ||
    +                        (pointP->len != (2 * len + 1))) {
    +                        return SECFailure;
    +                };
    +        }
    +
    +        MP_DIGITS(&Px) = 0;
    +        MP_DIGITS(&Py) = 0;
    +        MP_DIGITS(&Qx) = 0;
    +        MP_DIGITS(&Qy) = 0;
    +        MP_DIGITS(&Gx) = 0;
    +        MP_DIGITS(&Gy) = 0;
    +        MP_DIGITS(&order) = 0;
    +        MP_DIGITS(&irreducible) = 0;
    +        MP_DIGITS(&a) = 0;
    +        MP_DIGITS(&b) = 0;
    +        CHECK_MPI_OK( mp_init(&Px, kmflag) );
    +        CHECK_MPI_OK( mp_init(&Py, kmflag) );
    +        CHECK_MPI_OK( mp_init(&Qx, kmflag) );
    +        CHECK_MPI_OK( mp_init(&Qy, kmflag) );
    +        CHECK_MPI_OK( mp_init(&Gx, kmflag) );
    +        CHECK_MPI_OK( mp_init(&Gy, kmflag) );
    +        CHECK_MPI_OK( mp_init(&order, kmflag) );
    +        CHECK_MPI_OK( mp_init(&irreducible, kmflag) );
    +        CHECK_MPI_OK( mp_init(&a, kmflag) );
    +        CHECK_MPI_OK( mp_init(&b, kmflag) );
    +
    +        if ((k2 != NULL) && (pointP != NULL)) {
    +                /* Initialize Px and Py */
    +                CHECK_MPI_OK( mp_read_unsigned_octets(&Px, pointP->data + 1, (mp_size) len) );
    +                CHECK_MPI_OK( mp_read_unsigned_octets(&Py, pointP->data + 1 + len, (mp_size) len) );
    +        }
    +
    +        /* construct from named params, if possible */
    +        if (params->name != ECCurve_noName) {
    +                group = ECGroup_fromName(params->name, kmflag);
    +        }
    +
    +#if 0 /* currently don't support non-named curves */
    +        if (group == NULL) {
    +                /* Set up mp_ints containing the curve coefficients */
    +                CHECK_MPI_OK( mp_read_unsigned_octets(&Gx, params->base.data + 1,
    +                                                                                  (mp_size) len) );
    +                CHECK_MPI_OK( mp_read_unsigned_octets(&Gy, params->base.data + 1 + len,
    +                                                                                  (mp_size) len) );
    +                SECITEM_TO_MPINT( params->order, &order );
    +                SECITEM_TO_MPINT( params->curve.a, &a );
    +                SECITEM_TO_MPINT( params->curve.b, &b );
    +                if (params->fieldID.type == ec_field_GFp) {
    +                        SECITEM_TO_MPINT( params->fieldID.u.prime, &irreducible );
    +                        group = ECGroup_consGFp(&irreducible, &a, &b, &Gx, &Gy, &order, params->cofactor);
    +                } else {
    +                        SECITEM_TO_MPINT( params->fieldID.u.poly, &irreducible );
    +                        irr_arr[0] = params->fieldID.size;
    +                        irr_arr[1] = params->fieldID.k1;
    +                        irr_arr[2] = params->fieldID.k2;
    +                        irr_arr[3] = params->fieldID.k3;
    +                        irr_arr[4] = 0;
    +                        group = ECGroup_consGF2m(&irreducible, irr_arr, &a, &b, &Gx, &Gy, &order, params->cofactor);
    +                }
    +        }
    +#endif
    +        if (group == NULL)
    +                goto cleanup;
    +
    +        if ((k2 != NULL) && (pointP != NULL)) {
    +                CHECK_MPI_OK( ECPoints_mul(group, k1, k2, &Px, &Py, &Qx, &Qy) );
    +        } else {
    +                CHECK_MPI_OK( ECPoints_mul(group, k1, NULL, NULL, NULL, &Qx, &Qy) );
    +    }
    +
    +    /* Construct the SECItem representation of point Q */
    +    pointQ->data[0] = EC_POINT_FORM_UNCOMPRESSED;
    +    CHECK_MPI_OK( mp_to_fixlen_octets(&Qx, pointQ->data + 1,
    +                                      (mp_size) len) );
    +    CHECK_MPI_OK( mp_to_fixlen_octets(&Qy, pointQ->data + 1 + len,
    +                                      (mp_size) len) );
    +
    +    rv = SECSuccess;
    +
    +#if EC_DEBUG
    +    printf("ec_points_mul: pointQ [len=%d]:", pointQ->len);
    +    for (i = 0; i < pointQ->len; i++)
    +            printf("%02x:", pointQ->data[i]);
    +    printf("\n");
    +#endif
    +
    +cleanup:
    +    ECGroup_free(group);
    +    mp_clear(&Px);
    +    mp_clear(&Py);
    +    mp_clear(&Qx);
    +    mp_clear(&Qy);
    +    mp_clear(&Gx);
    +    mp_clear(&Gy);
    +    mp_clear(&order);
    +    mp_clear(&irreducible);
    +    mp_clear(&a);
    +    mp_clear(&b);
    +    if (err) {
    +        MP_TO_SEC_ERROR(err);
    +        rv = SECFailure;
    +    }
    +
    +    return rv;
    +}
    +
    +/* Generates a new EC key pair. The private key is a supplied
    + * value and the public key is the result of performing a scalar
    + * point multiplication of that value with the curve's base point.
    + */
    +SECStatus
    +ec_NewKey(ECParams *ecParams, ECPrivateKey **privKey,
    +    const unsigned char *privKeyBytes, int privKeyLen, int kmflag)
    +{
    +    SECStatus rv = SECFailure;
    +    PRArenaPool *arena;
    +    ECPrivateKey *key;
    +    mp_int k;
    +    mp_err err = MP_OKAY;
    +    int len;
    +
    +#if EC_DEBUG
    +    printf("ec_NewKey called\n");
    +#endif
    +
    +#ifndef _WIN32
    +int printf();
    +#endif /* _WIN32 */
    +
    +    if (!ecParams || !privKey || !privKeyBytes || (privKeyLen < 0)) {
    +        PORT_SetError(SEC_ERROR_INVALID_ARGS);
    +        return SECFailure;
    +    }
    +
    +    /* Initialize an arena for the EC key. */
    +    if (!(arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE)))
    +        return SECFailure;
    +
    +    key = (ECPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(ECPrivateKey),
    +        kmflag);
    +    if (!key) {
    +        PORT_FreeArena(arena, PR_TRUE);
    +        return SECFailure;
    +    }
    +
    +    /* Set the version number (SEC 1 section C.4 says it should be 1) */
    +    SECITEM_AllocItem(arena, &key->version, 1, kmflag);
    +    key->version.data[0] = 1;
    +
    +    /* Copy all of the fields from the ECParams argument to the
    +     * ECParams structure within the private key.
    +     */
    +    key->ecParams.arena = arena;
    +    key->ecParams.type = ecParams->type;
    +    key->ecParams.fieldID.size = ecParams->fieldID.size;
    +    key->ecParams.fieldID.type = ecParams->fieldID.type;
    +    if (ecParams->fieldID.type == ec_field_GFp) {
    +        CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.fieldID.u.prime,
    +            &ecParams->fieldID.u.prime, kmflag));
    +    } else {
    +        CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.fieldID.u.poly,
    +            &ecParams->fieldID.u.poly, kmflag));
    +    }
    +    key->ecParams.fieldID.k1 = ecParams->fieldID.k1;
    +    key->ecParams.fieldID.k2 = ecParams->fieldID.k2;
    +    key->ecParams.fieldID.k3 = ecParams->fieldID.k3;
    +    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curve.a,
    +        &ecParams->curve.a, kmflag));
    +    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curve.b,
    +        &ecParams->curve.b, kmflag));
    +    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curve.seed,
    +        &ecParams->curve.seed, kmflag));
    +    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.base,
    +        &ecParams->base, kmflag));
    +    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.order,
    +        &ecParams->order, kmflag));
    +    key->ecParams.cofactor = ecParams->cofactor;
    +    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.DEREncoding,
    +        &ecParams->DEREncoding, kmflag));
    +    key->ecParams.name = ecParams->name;
    +    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curveOID,
    +        &ecParams->curveOID, kmflag));
    +
    +    len = (ecParams->fieldID.size + 7) >> 3;
    +    SECITEM_AllocItem(arena, &key->publicValue, 2*len + 1, kmflag);
    +    len = ecParams->order.len;
    +    SECITEM_AllocItem(arena, &key->privateValue, len, kmflag);
    +
    +    /* Copy private key */
    +    if (privKeyLen >= len) {
    +        memcpy(key->privateValue.data, privKeyBytes, len);
    +    } else {
    +        memset(key->privateValue.data, 0, (len - privKeyLen));
    +        memcpy(key->privateValue.data + (len - privKeyLen), privKeyBytes, privKeyLen);
    +    }
    +
    +    /* Compute corresponding public key */
    +    MP_DIGITS(&k) = 0;
    +    CHECK_MPI_OK( mp_init(&k, kmflag) );
    +    CHECK_MPI_OK( mp_read_unsigned_octets(&k, key->privateValue.data,
    +        (mp_size) len) );
    +
    +    rv = ec_points_mul(ecParams, &k, NULL, NULL, &(key->publicValue), kmflag);
    +    if (rv != SECSuccess) goto cleanup;
    +    *privKey = key;
    +
    +cleanup:
    +    mp_clear(&k);
    +    if (rv)
    +        PORT_FreeArena(arena, PR_TRUE);
    +
    +#if EC_DEBUG
    +    printf("ec_NewKey returning %s\n",
    +        (rv == SECSuccess) ? "success" : "failure");
    +#endif
    +
    +    return rv;
    +
    +}
    +
    +/* Generates a new EC key pair. The private key is a supplied
    + * random value (in seed) and the public key is the result of
    + * performing a scalar point multiplication of that value with
    + * the curve's base point.
    + */
    +SECStatus
    +EC_NewKeyFromSeed(ECParams *ecParams, ECPrivateKey **privKey,
    +    const unsigned char *seed, int seedlen, int kmflag)
    +{
    +    SECStatus rv = SECFailure;
    +    rv = ec_NewKey(ecParams, privKey, seed, seedlen, kmflag);
    +    return rv;
    +}
    +
    +/* Generate a random private key using the algorithm A.4.1 of ANSI X9.62,
    + * modified a la FIPS 186-2 Change Notice 1 to eliminate the bias in the
    + * random number generator.
    + *
    + * Parameters
    + * - order: a buffer that holds the curve's group order
    + * - len: the length in octets of the order buffer
    + * - random: a buffer of 2 * len random bytes
    + * - randomlen: the length in octets of the random buffer
    + *
    + * Return Value
    + * Returns a buffer of len octets that holds the private key. The caller
    + * is responsible for freeing the buffer with PORT_ZFree.
    + */
    +static unsigned char *
    +ec_GenerateRandomPrivateKey(const unsigned char *order, int len,
    +    const unsigned char *random, int randomlen, int kmflag)
    +{
    +    SECStatus rv = SECSuccess;
    +    mp_err err;
    +    unsigned char *privKeyBytes = NULL;
    +    mp_int privKeyVal, order_1, one;
    +
    +    MP_DIGITS(&privKeyVal) = 0;
    +    MP_DIGITS(&order_1) = 0;
    +    MP_DIGITS(&one) = 0;
    +    CHECK_MPI_OK( mp_init(&privKeyVal, kmflag) );
    +    CHECK_MPI_OK( mp_init(&order_1, kmflag) );
    +    CHECK_MPI_OK( mp_init(&one, kmflag) );
    +
    +    /*
    +     * Reduces the 2*len buffer of random bytes modulo the group order.
    +     */
    +    if ((privKeyBytes = PORT_Alloc(2*len, kmflag)) == NULL) goto cleanup;
    +    if (randomlen != 2 * len) {
    +        goto cleanup;
    +    }
    +    /* No need to generate - random bytes are now supplied */
    +    /* CHECK_SEC_OK( RNG_GenerateGlobalRandomBytes(privKeyBytes, 2*len) );*/
    +    memcpy(privKeyBytes, random, randomlen);
    +
    +    CHECK_MPI_OK( mp_read_unsigned_octets(&privKeyVal, privKeyBytes, 2*len) );
    +    CHECK_MPI_OK( mp_read_unsigned_octets(&order_1, order, len) );
    +    CHECK_MPI_OK( mp_set_int(&one, 1) );
    +    CHECK_MPI_OK( mp_sub(&order_1, &one, &order_1) );
    +    CHECK_MPI_OK( mp_mod(&privKeyVal, &order_1, &privKeyVal) );
    +    CHECK_MPI_OK( mp_add(&privKeyVal, &one, &privKeyVal) );
    +    CHECK_MPI_OK( mp_to_fixlen_octets(&privKeyVal, privKeyBytes, len) );
    +    memset(privKeyBytes+len, 0, len);
    +cleanup:
    +    mp_clear(&privKeyVal);
    +    mp_clear(&order_1);
    +    mp_clear(&one);
    +    if (err < MP_OKAY) {
    +        MP_TO_SEC_ERROR(err);
    +        rv = SECFailure;
    +    }
    +    if (rv != SECSuccess && privKeyBytes) {
    +#ifdef _KERNEL
    +        kmem_free(privKeyBytes, 2*len);
    +#else
    +        free(privKeyBytes);
    +#endif
    +        privKeyBytes = NULL;
    +    }
    +    return privKeyBytes;
    +}
    +
    +/* Generates a new EC key pair. The private key is a random value and
    + * the public key is the result of performing a scalar point multiplication
    + * of that value with the curve's base point.
    + */
    +SECStatus
    +EC_NewKey(ECParams *ecParams, ECPrivateKey **privKey,
    +    const unsigned char* random, int randomlen, int kmflag)
    +{
    +    SECStatus rv = SECFailure;
    +    int len;
    +    unsigned char *privKeyBytes = NULL;
    +
    +    if (!ecParams) {
    +        PORT_SetError(SEC_ERROR_INVALID_ARGS);
    +        return SECFailure;
    +    }
    +
    +    len = ecParams->order.len;
    +    privKeyBytes = ec_GenerateRandomPrivateKey(ecParams->order.data, len,
    +        random, randomlen, kmflag);
    +    if (privKeyBytes == NULL) goto cleanup;
    +    /* generate public key */
    +    CHECK_SEC_OK( ec_NewKey(ecParams, privKey, privKeyBytes, len, kmflag) );
    +
    +cleanup:
    +    if (privKeyBytes) {
    +        PORT_ZFree(privKeyBytes, len * 2);
    +    }
    +#if EC_DEBUG
    +    printf("EC_NewKey returning %s\n",
    +        (rv == SECSuccess) ? "success" : "failure");
    +#endif
    +
    +    return rv;
    +}
    +
    +/* Validates an EC public key as described in Section 5.2.2 of
    + * X9.62. The ECDH primitive when used without the cofactor does
    + * not address small subgroup attacks, which may occur when the
    + * public key is not valid. These attacks can be prevented by
    + * validating the public key before using ECDH.
    + */
    +SECStatus
    +EC_ValidatePublicKey(ECParams *ecParams, SECItem *publicValue, int kmflag)
    +{
    +    mp_int Px, Py;
    +    ECGroup *group = NULL;
    +    SECStatus rv = SECFailure;
    +    mp_err err = MP_OKAY;
    +    int len;
    +
    +    if (!ecParams || !publicValue) {
    +        PORT_SetError(SEC_ERROR_INVALID_ARGS);
    +        return SECFailure;
    +    }
    +
    +    /* NOTE: We only support uncompressed points for now */
    +    len = (ecParams->fieldID.size + 7) >> 3;
    +    if (publicValue->data[0] != EC_POINT_FORM_UNCOMPRESSED) {
    +        PORT_SetError(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM);
    +        return SECFailure;
    +    } else if (publicValue->len != (2 * len + 1)) {
    +        PORT_SetError(SEC_ERROR_BAD_KEY);
    +        return SECFailure;
    +    }
    +
    +    MP_DIGITS(&Px) = 0;
    +    MP_DIGITS(&Py) = 0;
    +    CHECK_MPI_OK( mp_init(&Px, kmflag) );
    +    CHECK_MPI_OK( mp_init(&Py, kmflag) );
    +
    +    /* Initialize Px and Py */
    +    CHECK_MPI_OK( mp_read_unsigned_octets(&Px, publicValue->data + 1, (mp_size) len) );
    +    CHECK_MPI_OK( mp_read_unsigned_octets(&Py, publicValue->data + 1 + len, (mp_size) len) );
    +
    +    /* construct from named params */
    +    group = ECGroup_fromName(ecParams->name, kmflag);
    +    if (group == NULL) {
    +        /*
    +         * ECGroup_fromName fails if ecParams->name is not a valid
    +         * ECCurveName value, or if we run out of memory, or perhaps
    +         * for other reasons.  Unfortunately if ecParams->name is a
    +         * valid ECCurveName value, we don't know what the right error
    +         * code should be because ECGroup_fromName doesn't return an
    +         * error code to the caller.  Set err to MP_UNDEF because
    +         * that's what ECGroup_fromName uses internally.
    +         */
    +        if ((ecParams->name <= ECCurve_noName) ||
    +            (ecParams->name >= ECCurve_pastLastCurve)) {
    +            err = MP_BADARG;
    +        } else {
    +            err = MP_UNDEF;
    +        }
    +        goto cleanup;
    +    }
    +
    +    /* validate public point */
    +    if ((err = ECPoint_validate(group, &Px, &Py)) < MP_YES) {
    +        if (err == MP_NO) {
    +            PORT_SetError(SEC_ERROR_BAD_KEY);
    +            rv = SECFailure;
    +            err = MP_OKAY;  /* don't change the error code */
    +        }
    +        goto cleanup;
    +    }
    +
    +    rv = SECSuccess;
    +
    +cleanup:
    +    ECGroup_free(group);
    +    mp_clear(&Px);
    +    mp_clear(&Py);
    +    if (err) {
    +        MP_TO_SEC_ERROR(err);
    +        rv = SECFailure;
    +    }
    +    return rv;
    +}
    +
    +/*
    +** Performs an ECDH key derivation by computing the scalar point
    +** multiplication of privateValue and publicValue (with or without the
    +** cofactor) and returns the x-coordinate of the resulting elliptic
    +** curve point in derived secret.  If successful, derivedSecret->data
    +** is set to the address of the newly allocated buffer containing the
    +** derived secret, and derivedSecret->len is the size of the secret
    +** produced. It is the caller's responsibility to free the allocated
    +** buffer containing the derived secret.
    +*/
    +SECStatus
    +ECDH_Derive(SECItem  *publicValue,
    +            ECParams *ecParams,
    +            SECItem  *privateValue,
    +            PRBool    withCofactor,
    +            SECItem  *derivedSecret,
    +            int kmflag)
    +{
    +    SECStatus rv = SECFailure;
    +    unsigned int len = 0;
    +    SECItem pointQ = {siBuffer, NULL, 0};
    +    mp_int k; /* to hold the private value */
    +    mp_int cofactor;
    +    mp_err err = MP_OKAY;
    +#if EC_DEBUG
    +    int i;
    +#endif
    +
    +    if (!publicValue || !ecParams || !privateValue ||
    +        !derivedSecret) {
    +        PORT_SetError(SEC_ERROR_INVALID_ARGS);
    +        return SECFailure;
    +    }
    +
    +    memset(derivedSecret, 0, sizeof *derivedSecret);
    +    len = (ecParams->fieldID.size + 7) >> 3;
    +    pointQ.len = 2*len + 1;
    +    if ((pointQ.data = PORT_Alloc(2*len + 1, kmflag)) == NULL) goto cleanup;
    +
    +    MP_DIGITS(&k) = 0;
    +    CHECK_MPI_OK( mp_init(&k, kmflag) );
    +    CHECK_MPI_OK( mp_read_unsigned_octets(&k, privateValue->data,
    +                                          (mp_size) privateValue->len) );
    +
    +    if (withCofactor && (ecParams->cofactor != 1)) {
    +            /* multiply k with the cofactor */
    +            MP_DIGITS(&cofactor) = 0;
    +            CHECK_MPI_OK( mp_init(&cofactor, kmflag) );
    +            mp_set(&cofactor, ecParams->cofactor);
    +            CHECK_MPI_OK( mp_mul(&k, &cofactor, &k) );
    +    }
    +
    +    /* Multiply our private key and peer's public point */
    +    if ((ec_points_mul(ecParams, NULL, &k, publicValue, &pointQ, kmflag) != SECSuccess) ||
    +        ec_point_at_infinity(&pointQ))
    +        goto cleanup;
    +
    +    /* Allocate memory for the derived secret and copy
    +     * the x co-ordinate of pointQ into it.
    +     */
    +    SECITEM_AllocItem(NULL, derivedSecret, len, kmflag);
    +    memcpy(derivedSecret->data, pointQ.data + 1, len);
    +
    +    rv = SECSuccess;
    +
    +#if EC_DEBUG
    +    printf("derived_secret:\n");
    +    for (i = 0; i < derivedSecret->len; i++)
    +        printf("%02x:", derivedSecret->data[i]);
    +    printf("\n");
    +#endif
    +
    +cleanup:
    +    mp_clear(&k);
    +
    +    if (pointQ.data) {
    +        PORT_ZFree(pointQ.data, 2*len + 1);
    +    }
    +
    +    return rv;
    +}
    +
    +/* Computes the ECDSA signature (a concatenation of two values r and s)
    + * on the digest using the given key and the random value kb (used in
    + * computing s).
    + */
    +SECStatus
    +ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature,
    +    const SECItem *digest, const unsigned char *kb, const int kblen, int kmflag)
    +{
    +    SECStatus rv = SECFailure;
    +    mp_int x1;
    +    mp_int d, k;     /* private key, random integer */
    +    mp_int r, s;     /* tuple (r, s) is the signature */
    +    mp_int n;
    +    mp_err err = MP_OKAY;
    +    ECParams *ecParams = NULL;
    +    SECItem kGpoint = { siBuffer, NULL, 0};
    +    int flen = 0;    /* length in bytes of the field size */
    +    unsigned olen;   /* length in bytes of the base point order */
    +
    +#if EC_DEBUG
    +    char mpstr[256];
    +#endif
    +
    +    /* Initialize MPI integers. */
    +    /* must happen before the first potential call to cleanup */
    +    MP_DIGITS(&x1) = 0;
    +    MP_DIGITS(&d) = 0;
    +    MP_DIGITS(&k) = 0;
    +    MP_DIGITS(&r) = 0;
    +    MP_DIGITS(&s) = 0;
    +    MP_DIGITS(&n) = 0;
    +
    +    /* Check args */
    +    if (!key || !signature || !digest || !kb || (kblen < 0)) {
    +        PORT_SetError(SEC_ERROR_INVALID_ARGS);
    +        goto cleanup;
    +    }
    +
    +    ecParams = &(key->ecParams);
    +    flen = (ecParams->fieldID.size + 7) >> 3;
    +    olen = ecParams->order.len;
    +    if (signature->data == NULL) {
    +        /* a call to get the signature length only */
    +        goto finish;
    +    }
    +    if (signature->len < 2*olen) {
    +        PORT_SetError(SEC_ERROR_OUTPUT_LEN);
    +        rv = SECBufferTooSmall;
    +        goto cleanup;
    +    }
    +
    +
    +    CHECK_MPI_OK( mp_init(&x1, kmflag) );
    +    CHECK_MPI_OK( mp_init(&d, kmflag) );
    +    CHECK_MPI_OK( mp_init(&k, kmflag) );
    +    CHECK_MPI_OK( mp_init(&r, kmflag) );
    +    CHECK_MPI_OK( mp_init(&s, kmflag) );
    +    CHECK_MPI_OK( mp_init(&n, kmflag) );
    +
    +    SECITEM_TO_MPINT( ecParams->order, &n );
    +    SECITEM_TO_MPINT( key->privateValue, &d );
    +    CHECK_MPI_OK( mp_read_unsigned_octets(&k, kb, kblen) );
    +    /* Make sure k is in the interval [1, n-1] */
    +    if ((mp_cmp_z(&k) <= 0) || (mp_cmp(&k, &n) >= 0)) {
    +#if EC_DEBUG
    +        printf("k is outside [1, n-1]\n");
    +        mp_tohex(&k, mpstr);
    +        printf("k : %s \n", mpstr);
    +        mp_tohex(&n, mpstr);
    +        printf("n : %s \n", mpstr);
    +#endif
    +        PORT_SetError(SEC_ERROR_NEED_RANDOM);
    +        goto cleanup;
    +    }
    +
    +    /*
    +    ** ANSI X9.62, Section 5.3.2, Step 2
    +    **
    +    ** Compute kG
    +    */
    +    kGpoint.len = 2*flen + 1;
    +    kGpoint.data = PORT_Alloc(2*flen + 1, kmflag);
    +    if ((kGpoint.data == NULL) ||
    +        (ec_points_mul(ecParams, &k, NULL, NULL, &kGpoint, kmflag)
    +            != SECSuccess))
    +        goto cleanup;
    +
    +    /*
    +    ** ANSI X9.62, Section 5.3.3, Step 1
    +    **
    +    ** Extract the x co-ordinate of kG into x1
    +    */
    +    CHECK_MPI_OK( mp_read_unsigned_octets(&x1, kGpoint.data + 1,
    +                                          (mp_size) flen) );
    +
    +    /*
    +    ** ANSI X9.62, Section 5.3.3, Step 2
    +    **
    +    ** r = x1 mod n  NOTE: n is the order of the curve
    +    */
    +    CHECK_MPI_OK( mp_mod(&x1, &n, &r) );
    +
    +    /*
    +    ** ANSI X9.62, Section 5.3.3, Step 3
    +    **
    +    ** verify r != 0
    +    */
    +    if (mp_cmp_z(&r) == 0) {
    +        PORT_SetError(SEC_ERROR_NEED_RANDOM);
    +        goto cleanup;
    +    }
    +
    +    /*
    +    ** ANSI X9.62, Section 5.3.3, Step 4
    +    **
    +    ** s = (k**-1 * (HASH(M) + d*r)) mod n
    +    */
    +    SECITEM_TO_MPINT(*digest, &s);        /* s = HASH(M)     */
    +
    +    /* In the definition of EC signing, digests are truncated
    +     * to the length of n in bits.
    +     * (see SEC 1 "Elliptic Curve Digit Signature Algorithm" section 4.1.*/
    +    if (digest->len*8 > ecParams->fieldID.size) {
    +        mpl_rsh(&s,&s,digest->len*8 - ecParams->fieldID.size);
    +    }
    +
    +#if EC_DEBUG
    +    mp_todecimal(&n, mpstr);
    +    printf("n : %s (dec)\n", mpstr);
    +    mp_todecimal(&d, mpstr);
    +    printf("d : %s (dec)\n", mpstr);
    +    mp_tohex(&x1, mpstr);
    +    printf("x1: %s\n", mpstr);
    +    mp_todecimal(&s, mpstr);
    +    printf("digest: %s (decimal)\n", mpstr);
    +    mp_todecimal(&r, mpstr);
    +    printf("r : %s (dec)\n", mpstr);
    +    mp_tohex(&r, mpstr);
    +    printf("r : %s\n", mpstr);
    +#endif
    +
    +    CHECK_MPI_OK( mp_invmod(&k, &n, &k) );      /* k = k**-1 mod n */
    +    CHECK_MPI_OK( mp_mulmod(&d, &r, &n, &d) );  /* d = d * r mod n */
    +    CHECK_MPI_OK( mp_addmod(&s, &d, &n, &s) );  /* s = s + d mod n */
    +    CHECK_MPI_OK( mp_mulmod(&s, &k, &n, &s) );  /* s = s * k mod n */
    +
    +#if EC_DEBUG
    +    mp_todecimal(&s, mpstr);
    +    printf("s : %s (dec)\n", mpstr);
    +    mp_tohex(&s, mpstr);
    +    printf("s : %s\n", mpstr);
    +#endif
    +
    +    /*
    +    ** ANSI X9.62, Section 5.3.3, Step 5
    +    **
    +    ** verify s != 0
    +    */
    +    if (mp_cmp_z(&s) == 0) {
    +        PORT_SetError(SEC_ERROR_NEED_RANDOM);
    +        goto cleanup;
    +    }
    +
    +   /*
    +    **
    +    ** Signature is tuple (r, s)
    +    */
    +    CHECK_MPI_OK( mp_to_fixlen_octets(&r, signature->data, olen) );
    +    CHECK_MPI_OK( mp_to_fixlen_octets(&s, signature->data + olen, olen) );
    +finish:
    +    signature->len = 2*olen;
    +
    +    rv = SECSuccess;
    +    err = MP_OKAY;
    +cleanup:
    +    mp_clear(&x1);
    +    mp_clear(&d);
    +    mp_clear(&k);
    +    mp_clear(&r);
    +    mp_clear(&s);
    +    mp_clear(&n);
    +
    +    if (kGpoint.data) {
    +        PORT_ZFree(kGpoint.data, 2*flen + 1);
    +    }
    +
    +    if (err) {
    +        MP_TO_SEC_ERROR(err);
    +        rv = SECFailure;
    +    }
    +
    +#if EC_DEBUG
    +    printf("ECDSA signing with seed %s\n",
    +        (rv == SECSuccess) ? "succeeded" : "failed");
    +#endif
    +
    +   return rv;
    +}
    +
    +/*
    +** Computes the ECDSA signature on the digest using the given key
    +** and a random seed.
    +*/
    +SECStatus
    +ECDSA_SignDigest(ECPrivateKey *key, SECItem *signature, const SECItem *digest,
    +    const unsigned char* random, int randomLen, int kmflag)
    +{
    +    SECStatus rv = SECFailure;
    +    int len;
    +    unsigned char *kBytes= NULL;
    +
    +    if (!key) {
    +        PORT_SetError(SEC_ERROR_INVALID_ARGS);
    +        return SECFailure;
    +    }
    +
    +    /* Generate random value k */
    +    len = key->ecParams.order.len;
    +    kBytes = ec_GenerateRandomPrivateKey(key->ecParams.order.data, len,
    +        random, randomLen, kmflag);
    +    if (kBytes == NULL) goto cleanup;
    +
    +    /* Generate ECDSA signature with the specified k value */
    +    rv = ECDSA_SignDigestWithSeed(key, signature, digest, kBytes, len, kmflag);
    +
    +cleanup:
    +    if (kBytes) {
    +        PORT_ZFree(kBytes, len * 2);
    +    }
    +
    +#if EC_DEBUG
    +    printf("ECDSA signing %s\n",
    +        (rv == SECSuccess) ? "succeeded" : "failed");
    +#endif
    +
    +    return rv;
    +}
    +
    +/*
    +** Checks the signature on the given digest using the key provided.
    +*/
    +SECStatus
    +ECDSA_VerifyDigest(ECPublicKey *key, const SECItem *signature,
    +                 const SECItem *digest, int kmflag)
    +{
    +    SECStatus rv = SECFailure;
    +    mp_int r_, s_;           /* tuple (r', s') is received signature) */
    +    mp_int c, u1, u2, v;     /* intermediate values used in verification */
    +    mp_int x1;
    +    mp_int n;
    +    mp_err err = MP_OKAY;
    +    ECParams *ecParams = NULL;
    +    SECItem pointC = { siBuffer, NULL, 0 };
    +    int slen;       /* length in bytes of a half signature (r or s) */
    +    int flen;       /* length in bytes of the field size */
    +    unsigned olen;  /* length in bytes of the base point order */
    +
    +#if EC_DEBUG
    +    char mpstr[256];
    +    printf("ECDSA verification called\n");
    +#endif
    +
    +    /* Initialize MPI integers. */
    +    /* must happen before the first potential call to cleanup */
    +    MP_DIGITS(&r_) = 0;
    +    MP_DIGITS(&s_) = 0;
    +    MP_DIGITS(&c) = 0;
    +    MP_DIGITS(&u1) = 0;
    +    MP_DIGITS(&u2) = 0;
    +    MP_DIGITS(&x1) = 0;
    +    MP_DIGITS(&v)  = 0;
    +    MP_DIGITS(&n)  = 0;
    +
    +    /* Check args */
    +    if (!key || !signature || !digest) {
    +        PORT_SetError(SEC_ERROR_INVALID_ARGS);
    +        goto cleanup;
    +    }
    +
    +    ecParams = &(key->ecParams);
    +    flen = (ecParams->fieldID.size + 7) >> 3;
    +    olen = ecParams->order.len;
    +    if (signature->len == 0 || signature->len%2 != 0 ||
    +        signature->len > 2*olen) {
    +        PORT_SetError(SEC_ERROR_INPUT_LEN);
    +        goto cleanup;
    +    }
    +    slen = signature->len/2;
    +
    +    SECITEM_AllocItem(NULL, &pointC, 2*flen + 1, kmflag);
    +    if (pointC.data == NULL)
    +        goto cleanup;
    +
    +    CHECK_MPI_OK( mp_init(&r_, kmflag) );
    +    CHECK_MPI_OK( mp_init(&s_, kmflag) );
    +    CHECK_MPI_OK( mp_init(&c, kmflag)  );
    +    CHECK_MPI_OK( mp_init(&u1, kmflag) );
    +    CHECK_MPI_OK( mp_init(&u2, kmflag) );
    +    CHECK_MPI_OK( mp_init(&x1, kmflag)  );
    +    CHECK_MPI_OK( mp_init(&v, kmflag)  );
    +    CHECK_MPI_OK( mp_init(&n, kmflag)  );
    +
    +    /*
    +    ** Convert received signature (r', s') into MPI integers.
    +    */
    +    CHECK_MPI_OK( mp_read_unsigned_octets(&r_, signature->data, slen) );
    +    CHECK_MPI_OK( mp_read_unsigned_octets(&s_, signature->data + slen, slen) );
    +
    +    /*
    +    ** ANSI X9.62, Section 5.4.2, Steps 1 and 2
    +    **
    +    ** Verify that 0 < r' < n and 0 < s' < n
    +    */
    +    SECITEM_TO_MPINT(ecParams->order, &n);
    +    if (mp_cmp_z(&r_) <= 0 || mp_cmp_z(&s_) <= 0 ||
    +        mp_cmp(&r_, &n) >= 0 || mp_cmp(&s_, &n) >= 0) {
    +        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
    +        goto cleanup; /* will return rv == SECFailure */
    +    }
    +
    +    /*
    +    ** ANSI X9.62, Section 5.4.2, Step 3
    +    **
    +    ** c = (s')**-1 mod n
    +    */
    +    CHECK_MPI_OK( mp_invmod(&s_, &n, &c) );      /* c = (s')**-1 mod n */
    +
    +    /*
    +    ** ANSI X9.62, Section 5.4.2, Step 4
    +    **
    +    ** u1 = ((HASH(M')) * c) mod n
    +    */
    +    SECITEM_TO_MPINT(*digest, &u1);                  /* u1 = HASH(M)     */
    +
    +    /* In the definition of EC signing, digests are truncated
    +     * to the length of n in bits.
    +     * (see SEC 1 "Elliptic Curve Digit Signature Algorithm" section 4.1.*/
    +    if (digest->len*8 > ecParams->fieldID.size) {  /* u1 = HASH(M')     */
    +        mpl_rsh(&u1,&u1,digest->len*8- ecParams->fieldID.size);
    +    }
    +
    +#if EC_DEBUG
    +    mp_todecimal(&r_, mpstr);
    +    printf("r_: %s (dec)\n", mpstr);
    +    mp_todecimal(&s_, mpstr);
    +    printf("s_: %s (dec)\n", mpstr);
    +    mp_todecimal(&c, mpstr);
    +    printf("c : %s (dec)\n", mpstr);
    +    mp_todecimal(&u1, mpstr);
    +    printf("digest: %s (dec)\n", mpstr);
    +#endif
    +
    +    CHECK_MPI_OK( mp_mulmod(&u1, &c, &n, &u1) );  /* u1 = u1 * c mod n */
    +
    +    /*
    +    ** ANSI X9.62, Section 5.4.2, Step 4
    +    **
    +    ** u2 = ((r') * c) mod n
    +    */
    +    CHECK_MPI_OK( mp_mulmod(&r_, &c, &n, &u2) );
    +
    +    /*
    +    ** ANSI X9.62, Section 5.4.3, Step 1
    +    **
    +    ** Compute u1*G + u2*Q
    +    ** Here, A = u1.G     B = u2.Q    and   C = A + B
    +    ** If the result, C, is the point at infinity, reject the signature
    +    */
    +    if (ec_points_mul(ecParams, &u1, &u2, &key->publicValue, &pointC, kmflag)
    +        != SECSuccess) {
    +        rv = SECFailure;
    +        goto cleanup;
    +    }
    +    if (ec_point_at_infinity(&pointC)) {
    +        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
    +        rv = SECFailure;
    +        goto cleanup;
    +    }
    +
    +    CHECK_MPI_OK( mp_read_unsigned_octets(&x1, pointC.data + 1, flen) );
    +
    +    /*
    +    ** ANSI X9.62, Section 5.4.4, Step 2
    +    **
    +    ** v = x1 mod n
    +    */
    +    CHECK_MPI_OK( mp_mod(&x1, &n, &v) );
    +
    +#if EC_DEBUG
    +    mp_todecimal(&r_, mpstr);
    +    printf("r_: %s (dec)\n", mpstr);
    +    mp_todecimal(&v, mpstr);
    +    printf("v : %s (dec)\n", mpstr);
    +#endif
    +
    +    /*
    +    ** ANSI X9.62, Section 5.4.4, Step 3
    +    **
    +    ** Verification:  v == r'
    +    */
    +    if (mp_cmp(&v, &r_)) {
    +        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
    +        rv = SECFailure; /* Signature failed to verify. */
    +    } else {
    +        rv = SECSuccess; /* Signature verified. */
    +    }
    +
    +#if EC_DEBUG
    +    mp_todecimal(&u1, mpstr);
    +    printf("u1: %s (dec)\n", mpstr);
    +    mp_todecimal(&u2, mpstr);
    +    printf("u2: %s (dec)\n", mpstr);
    +    mp_tohex(&x1, mpstr);
    +    printf("x1: %s\n", mpstr);
    +    mp_todecimal(&v, mpstr);
    +    printf("v : %s (dec)\n", mpstr);
    +#endif
    +
    +cleanup:
    +    mp_clear(&r_);
    +    mp_clear(&s_);
    +    mp_clear(&c);
    +    mp_clear(&u1);
    +    mp_clear(&u2);
    +    mp_clear(&x1);
    +    mp_clear(&v);
    +    mp_clear(&n);
    +
    +    if (pointC.data) SECITEM_FreeItem(&pointC, PR_FALSE);
    +    if (err) {
    +        MP_TO_SEC_ERROR(err);
    +        rv = SECFailure;
    +    }
    +
    +#if EC_DEBUG
    +    printf("ECDSA verification %s\n",
    +        (rv == SECSuccess) ? "succeeded" : "failed");
    +#endif
    +
    +    return rv;
    +}
    diff --git a/jdk/src/share/native/sun/security/ec/ec.h b/jdk/src/share/native/sun/security/ec/ec.h
    new file mode 100644
    index 00000000000..d472670913b
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/ec.h
    @@ -0,0 +1,72 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the Elliptic Curve Cryptography library.
    + *
    + * The Initial Developer of the Original Code is
    + * Sun Microsystems, Inc.
    + * Portions created by the Initial Developer are Copyright (C) 2003
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Dr Vipul Gupta , Sun Microsystems Laboratories
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#ifndef __ec_h_
    +#define __ec_h_
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +#define EC_DEBUG                          0
    +#define EC_POINT_FORM_COMPRESSED_Y0    0x02
    +#define EC_POINT_FORM_COMPRESSED_Y1    0x03
    +#define EC_POINT_FORM_UNCOMPRESSED     0x04
    +#define EC_POINT_FORM_HYBRID_Y0        0x06
    +#define EC_POINT_FORM_HYBRID_Y1        0x07
    +
    +#define ANSI_X962_CURVE_OID_TOTAL_LEN    10
    +#define SECG_CURVE_OID_TOTAL_LEN          7
    +
    +#endif /* __ec_h_ */
    diff --git a/jdk/src/share/native/sun/security/ec/ec2.h b/jdk/src/share/native/sun/security/ec/ec2.h
    new file mode 100644
    index 00000000000..c1b2d7965e5
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/ec2.h
    @@ -0,0 +1,146 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the elliptic curve math library for binary polynomial field curves.
    + *
    + * The Initial Developer of the Original Code is
    + * Sun Microsystems, Inc.
    + * Portions created by the Initial Developer are Copyright (C) 2003
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Douglas Stebila , Sun Microsystems Laboratories
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#ifndef _EC2_H
    +#define _EC2_H
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +#include "ecl-priv.h"
    +
    +/* Checks if point P(px, py) is at infinity.  Uses affine coordinates. */
    +mp_err ec_GF2m_pt_is_inf_aff(const mp_int *px, const mp_int *py);
    +
    +/* Sets P(px, py) to be the point at infinity.  Uses affine coordinates. */
    +mp_err ec_GF2m_pt_set_inf_aff(mp_int *px, mp_int *py);
    +
    +/* Computes R = P + Q where R is (rx, ry), P is (px, py) and Q is (qx,
    + * qy). Uses affine coordinates. */
    +mp_err ec_GF2m_pt_add_aff(const mp_int *px, const mp_int *py,
    +                                                  const mp_int *qx, const mp_int *qy, mp_int *rx,
    +                                                  mp_int *ry, const ECGroup *group);
    +
    +/* Computes R = P - Q.  Uses affine coordinates. */
    +mp_err ec_GF2m_pt_sub_aff(const mp_int *px, const mp_int *py,
    +                                                  const mp_int *qx, const mp_int *qy, mp_int *rx,
    +                                                  mp_int *ry, const ECGroup *group);
    +
    +/* Computes R = 2P.  Uses affine coordinates. */
    +mp_err ec_GF2m_pt_dbl_aff(const mp_int *px, const mp_int *py, mp_int *rx,
    +                                                  mp_int *ry, const ECGroup *group);
    +
    +/* Validates a point on a GF2m curve. */
    +mp_err ec_GF2m_validate_point(const mp_int *px, const mp_int *py, const ECGroup *group);
    +
    +/* by default, this routine is unused and thus doesn't need to be compiled */
    +#ifdef ECL_ENABLE_GF2M_PT_MUL_AFF
    +/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
    + * a, b and p are the elliptic curve coefficients and the irreducible that
    + * determines the field GF2m.  Uses affine coordinates. */
    +mp_err ec_GF2m_pt_mul_aff(const mp_int *n, const mp_int *px,
    +                                                  const mp_int *py, mp_int *rx, mp_int *ry,
    +                                                  const ECGroup *group);
    +#endif
    +
    +/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
    + * a, b and p are the elliptic curve coefficients and the irreducible that
    + * determines the field GF2m.  Uses Montgomery projective coordinates. */
    +mp_err ec_GF2m_pt_mul_mont(const mp_int *n, const mp_int *px,
    +                                                   const mp_int *py, mp_int *rx, mp_int *ry,
    +                                                   const ECGroup *group);
    +
    +#ifdef ECL_ENABLE_GF2M_PROJ
    +/* Converts a point P(px, py) from affine coordinates to projective
    + * coordinates R(rx, ry, rz). */
    +mp_err ec_GF2m_pt_aff2proj(const mp_int *px, const mp_int *py, mp_int *rx,
    +                                                   mp_int *ry, mp_int *rz, const ECGroup *group);
    +
    +/* Converts a point P(px, py, pz) from projective coordinates to affine
    + * coordinates R(rx, ry). */
    +mp_err ec_GF2m_pt_proj2aff(const mp_int *px, const mp_int *py,
    +                                                   const mp_int *pz, mp_int *rx, mp_int *ry,
    +                                                   const ECGroup *group);
    +
    +/* Checks if point P(px, py, pz) is at infinity.  Uses projective
    + * coordinates. */
    +mp_err ec_GF2m_pt_is_inf_proj(const mp_int *px, const mp_int *py,
    +                                                          const mp_int *pz);
    +
    +/* Sets P(px, py, pz) to be the point at infinity.  Uses projective
    + * coordinates. */
    +mp_err ec_GF2m_pt_set_inf_proj(mp_int *px, mp_int *py, mp_int *pz);
    +
    +/* Computes R = P + Q where R is (rx, ry, rz), P is (px, py, pz) and Q is
    + * (qx, qy, qz).  Uses projective coordinates. */
    +mp_err ec_GF2m_pt_add_proj(const mp_int *px, const mp_int *py,
    +                                                   const mp_int *pz, const mp_int *qx,
    +                                                   const mp_int *qy, mp_int *rx, mp_int *ry,
    +                                                   mp_int *rz, const ECGroup *group);
    +
    +/* Computes R = 2P.  Uses projective coordinates. */
    +mp_err ec_GF2m_pt_dbl_proj(const mp_int *px, const mp_int *py,
    +                                                   const mp_int *pz, mp_int *rx, mp_int *ry,
    +                                                   mp_int *rz, const ECGroup *group);
    +
    +/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
    + * a, b and p are the elliptic curve coefficients and the prime that
    + * determines the field GF2m.  Uses projective coordinates. */
    +mp_err ec_GF2m_pt_mul_proj(const mp_int *n, const mp_int *px,
    +                                                   const mp_int *py, mp_int *rx, mp_int *ry,
    +                                                   const ECGroup *group);
    +#endif
    +
    +#endif /* _EC2_H */
    diff --git a/jdk/src/share/native/sun/security/ec/ec2_163.c b/jdk/src/share/native/sun/security/ec/ec2_163.c
    new file mode 100644
    index 00000000000..ecdb5121063
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/ec2_163.c
    @@ -0,0 +1,281 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the elliptic curve math library for binary polynomial field curves.
    + *
    + * The Initial Developer of the Original Code is
    + * Sun Microsystems, Inc.
    + * Portions created by the Initial Developer are Copyright (C) 2003
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Sheueling Chang-Shantz ,
    + *   Stephen Fung , and
    + *   Douglas Stebila , Sun Microsystems Laboratories.
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +#include "ec2.h"
    +#include "mp_gf2m.h"
    +#include "mp_gf2m-priv.h"
    +#include "mpi.h"
    +#include "mpi-priv.h"
    +#ifndef _KERNEL
    +#include 
    +#endif
    +
    +/* Fast reduction for polynomials over a 163-bit curve. Assumes reduction
    + * polynomial with terms {163, 7, 6, 3, 0}. */
    +mp_err
    +ec_GF2m_163_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_digit *u, z;
    +
    +        if (a != r) {
    +                MP_CHECKOK(mp_copy(a, r));
    +        }
    +#ifdef ECL_SIXTY_FOUR_BIT
    +        if (MP_USED(r) < 6) {
    +                MP_CHECKOK(s_mp_pad(r, 6));
    +        }
    +        u = MP_DIGITS(r);
    +        MP_USED(r) = 6;
    +
    +        /* u[5] only has 6 significant bits */
    +        z = u[5];
    +        u[2] ^= (z << 36) ^ (z << 35) ^ (z << 32) ^ (z << 29);
    +        z = u[4];
    +        u[2] ^= (z >> 28) ^ (z >> 29) ^ (z >> 32) ^ (z >> 35);
    +        u[1] ^= (z << 36) ^ (z << 35) ^ (z << 32) ^ (z << 29);
    +        z = u[3];
    +        u[1] ^= (z >> 28) ^ (z >> 29) ^ (z >> 32) ^ (z >> 35);
    +        u[0] ^= (z << 36) ^ (z << 35) ^ (z << 32) ^ (z << 29);
    +        z = u[2] >> 35;                         /* z only has 29 significant bits */
    +        u[0] ^= (z << 7) ^ (z << 6) ^ (z << 3) ^ z;
    +        /* clear bits above 163 */
    +        u[5] = u[4] = u[3] = 0;
    +        u[2] ^= z << 35;
    +#else
    +        if (MP_USED(r) < 11) {
    +                MP_CHECKOK(s_mp_pad(r, 11));
    +        }
    +        u = MP_DIGITS(r);
    +        MP_USED(r) = 11;
    +
    +        /* u[11] only has 6 significant bits */
    +        z = u[10];
    +        u[5] ^= (z << 4) ^ (z << 3) ^ z ^ (z >> 3);
    +        u[4] ^= (z << 29);
    +        z = u[9];
    +        u[5] ^= (z >> 28) ^ (z >> 29);
    +        u[4] ^= (z << 4) ^ (z << 3) ^ z ^ (z >> 3);
    +        u[3] ^= (z << 29);
    +        z = u[8];
    +        u[4] ^= (z >> 28) ^ (z >> 29);
    +        u[3] ^= (z << 4) ^ (z << 3) ^ z ^ (z >> 3);
    +        u[2] ^= (z << 29);
    +        z = u[7];
    +        u[3] ^= (z >> 28) ^ (z >> 29);
    +        u[2] ^= (z << 4) ^ (z << 3) ^ z ^ (z >> 3);
    +        u[1] ^= (z << 29);
    +        z = u[6];
    +        u[2] ^= (z >> 28) ^ (z >> 29);
    +        u[1] ^= (z << 4) ^ (z << 3) ^ z ^ (z >> 3);
    +        u[0] ^= (z << 29);
    +        z = u[5] >> 3;                          /* z only has 29 significant bits */
    +        u[1] ^= (z >> 25) ^ (z >> 26);
    +        u[0] ^= (z << 7) ^ (z << 6) ^ (z << 3) ^ z;
    +        /* clear bits above 163 */
    +        u[11] = u[10] = u[9] = u[8] = u[7] = u[6] = 0;
    +        u[5] ^= z << 3;
    +#endif
    +        s_mp_clamp(r);
    +
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* Fast squaring for polynomials over a 163-bit curve. Assumes reduction
    + * polynomial with terms {163, 7, 6, 3, 0}. */
    +mp_err
    +ec_GF2m_163_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_digit *u, *v;
    +
    +        v = MP_DIGITS(a);
    +
    +#ifdef ECL_SIXTY_FOUR_BIT
    +        if (MP_USED(a) < 3) {
    +                return mp_bsqrmod(a, meth->irr_arr, r);
    +        }
    +        if (MP_USED(r) < 6) {
    +                MP_CHECKOK(s_mp_pad(r, 6));
    +        }
    +        MP_USED(r) = 6;
    +#else
    +        if (MP_USED(a) < 6) {
    +                return mp_bsqrmod(a, meth->irr_arr, r);
    +        }
    +        if (MP_USED(r) < 12) {
    +                MP_CHECKOK(s_mp_pad(r, 12));
    +        }
    +        MP_USED(r) = 12;
    +#endif
    +        u = MP_DIGITS(r);
    +
    +#ifdef ECL_THIRTY_TWO_BIT
    +        u[11] = gf2m_SQR1(v[5]);
    +        u[10] = gf2m_SQR0(v[5]);
    +        u[9] = gf2m_SQR1(v[4]);
    +        u[8] = gf2m_SQR0(v[4]);
    +        u[7] = gf2m_SQR1(v[3]);
    +        u[6] = gf2m_SQR0(v[3]);
    +#endif
    +        u[5] = gf2m_SQR1(v[2]);
    +        u[4] = gf2m_SQR0(v[2]);
    +        u[3] = gf2m_SQR1(v[1]);
    +        u[2] = gf2m_SQR0(v[1]);
    +        u[1] = gf2m_SQR1(v[0]);
    +        u[0] = gf2m_SQR0(v[0]);
    +        return ec_GF2m_163_mod(r, r, meth);
    +
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* Fast multiplication for polynomials over a 163-bit curve. Assumes
    + * reduction polynomial with terms {163, 7, 6, 3, 0}. */
    +mp_err
    +ec_GF2m_163_mul(const mp_int *a, const mp_int *b, mp_int *r,
    +                                const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_digit a2 = 0, a1 = 0, a0, b2 = 0, b1 = 0, b0;
    +
    +#ifdef ECL_THIRTY_TWO_BIT
    +        mp_digit a5 = 0, a4 = 0, a3 = 0, b5 = 0, b4 = 0, b3 = 0;
    +        mp_digit rm[6];
    +#endif
    +
    +        if (a == b) {
    +                return ec_GF2m_163_sqr(a, r, meth);
    +        } else {
    +                switch (MP_USED(a)) {
    +#ifdef ECL_THIRTY_TWO_BIT
    +                case 6:
    +                        a5 = MP_DIGIT(a, 5);
    +                case 5:
    +                        a4 = MP_DIGIT(a, 4);
    +                case 4:
    +                        a3 = MP_DIGIT(a, 3);
    +#endif
    +                case 3:
    +                        a2 = MP_DIGIT(a, 2);
    +                case 2:
    +                        a1 = MP_DIGIT(a, 1);
    +                default:
    +                        a0 = MP_DIGIT(a, 0);
    +                }
    +                switch (MP_USED(b)) {
    +#ifdef ECL_THIRTY_TWO_BIT
    +                case 6:
    +                        b5 = MP_DIGIT(b, 5);
    +                case 5:
    +                        b4 = MP_DIGIT(b, 4);
    +                case 4:
    +                        b3 = MP_DIGIT(b, 3);
    +#endif
    +                case 3:
    +                        b2 = MP_DIGIT(b, 2);
    +                case 2:
    +                        b1 = MP_DIGIT(b, 1);
    +                default:
    +                        b0 = MP_DIGIT(b, 0);
    +                }
    +#ifdef ECL_SIXTY_FOUR_BIT
    +                MP_CHECKOK(s_mp_pad(r, 6));
    +                s_bmul_3x3(MP_DIGITS(r), a2, a1, a0, b2, b1, b0);
    +                MP_USED(r) = 6;
    +                s_mp_clamp(r);
    +#else
    +                MP_CHECKOK(s_mp_pad(r, 12));
    +                s_bmul_3x3(MP_DIGITS(r) + 6, a5, a4, a3, b5, b4, b3);
    +                s_bmul_3x3(MP_DIGITS(r), a2, a1, a0, b2, b1, b0);
    +                s_bmul_3x3(rm, a5 ^ a2, a4 ^ a1, a3 ^ a0, b5 ^ b2, b4 ^ b1,
    +                                   b3 ^ b0);
    +                rm[5] ^= MP_DIGIT(r, 5) ^ MP_DIGIT(r, 11);
    +                rm[4] ^= MP_DIGIT(r, 4) ^ MP_DIGIT(r, 10);
    +                rm[3] ^= MP_DIGIT(r, 3) ^ MP_DIGIT(r, 9);
    +                rm[2] ^= MP_DIGIT(r, 2) ^ MP_DIGIT(r, 8);
    +                rm[1] ^= MP_DIGIT(r, 1) ^ MP_DIGIT(r, 7);
    +                rm[0] ^= MP_DIGIT(r, 0) ^ MP_DIGIT(r, 6);
    +                MP_DIGIT(r, 8) ^= rm[5];
    +                MP_DIGIT(r, 7) ^= rm[4];
    +                MP_DIGIT(r, 6) ^= rm[3];
    +                MP_DIGIT(r, 5) ^= rm[2];
    +                MP_DIGIT(r, 4) ^= rm[1];
    +                MP_DIGIT(r, 3) ^= rm[0];
    +                MP_USED(r) = 12;
    +                s_mp_clamp(r);
    +#endif
    +                return ec_GF2m_163_mod(r, r, meth);
    +        }
    +
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* Wire in fast field arithmetic for 163-bit curves. */
    +mp_err
    +ec_group_set_gf2m163(ECGroup *group, ECCurveName name)
    +{
    +        group->meth->field_mod = &ec_GF2m_163_mod;
    +        group->meth->field_mul = &ec_GF2m_163_mul;
    +        group->meth->field_sqr = &ec_GF2m_163_sqr;
    +        return MP_OKAY;
    +}
    diff --git a/jdk/src/share/native/sun/security/ec/ec2_193.c b/jdk/src/share/native/sun/security/ec/ec2_193.c
    new file mode 100644
    index 00000000000..f6187d35612
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/ec2_193.c
    @@ -0,0 +1,298 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the elliptic curve math library for binary polynomial field curves.
    + *
    + * The Initial Developer of the Original Code is
    + * Sun Microsystems, Inc.
    + * Portions created by the Initial Developer are Copyright (C) 2003
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Sheueling Chang-Shantz ,
    + *   Stephen Fung , and
    + *   Douglas Stebila , Sun Microsystems Laboratories.
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +#include "ec2.h"
    +#include "mp_gf2m.h"
    +#include "mp_gf2m-priv.h"
    +#include "mpi.h"
    +#include "mpi-priv.h"
    +#ifndef _KERNEL
    +#include 
    +#endif
    +
    +/* Fast reduction for polynomials over a 193-bit curve. Assumes reduction
    + * polynomial with terms {193, 15, 0}. */
    +mp_err
    +ec_GF2m_193_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_digit *u, z;
    +
    +        if (a != r) {
    +                MP_CHECKOK(mp_copy(a, r));
    +        }
    +#ifdef ECL_SIXTY_FOUR_BIT
    +        if (MP_USED(r) < 7) {
    +                MP_CHECKOK(s_mp_pad(r, 7));
    +        }
    +        u = MP_DIGITS(r);
    +        MP_USED(r) = 7;
    +
    +        /* u[6] only has 2 significant bits */
    +        z = u[6];
    +        u[3] ^= (z << 14) ^ (z >> 1);
    +        u[2] ^= (z << 63);
    +        z = u[5];
    +        u[3] ^= (z >> 50);
    +        u[2] ^= (z << 14) ^ (z >> 1);
    +        u[1] ^= (z << 63);
    +        z = u[4];
    +        u[2] ^= (z >> 50);
    +        u[1] ^= (z << 14) ^ (z >> 1);
    +        u[0] ^= (z << 63);
    +        z = u[3] >> 1;                          /* z only has 63 significant bits */
    +        u[1] ^= (z >> 49);
    +        u[0] ^= (z << 15) ^ z;
    +        /* clear bits above 193 */
    +        u[6] = u[5] = u[4] = 0;
    +        u[3] ^= z << 1;
    +#else
    +        if (MP_USED(r) < 13) {
    +                MP_CHECKOK(s_mp_pad(r, 13));
    +        }
    +        u = MP_DIGITS(r);
    +        MP_USED(r) = 13;
    +
    +        /* u[12] only has 2 significant bits */
    +        z = u[12];
    +        u[6] ^= (z << 14) ^ (z >> 1);
    +        u[5] ^= (z << 31);
    +        z = u[11];
    +        u[6] ^= (z >> 18);
    +        u[5] ^= (z << 14) ^ (z >> 1);
    +        u[4] ^= (z << 31);
    +        z = u[10];
    +        u[5] ^= (z >> 18);
    +        u[4] ^= (z << 14) ^ (z >> 1);
    +        u[3] ^= (z << 31);
    +        z = u[9];
    +        u[4] ^= (z >> 18);
    +        u[3] ^= (z << 14) ^ (z >> 1);
    +        u[2] ^= (z << 31);
    +        z = u[8];
    +        u[3] ^= (z >> 18);
    +        u[2] ^= (z << 14) ^ (z >> 1);
    +        u[1] ^= (z << 31);
    +        z = u[7];
    +        u[2] ^= (z >> 18);
    +        u[1] ^= (z << 14) ^ (z >> 1);
    +        u[0] ^= (z << 31);
    +        z = u[6] >> 1;                          /* z only has 31 significant bits */
    +        u[1] ^= (z >> 17);
    +        u[0] ^= (z << 15) ^ z;
    +        /* clear bits above 193 */
    +        u[12] = u[11] = u[10] = u[9] = u[8] = u[7] = 0;
    +        u[6] ^= z << 1;
    +#endif
    +        s_mp_clamp(r);
    +
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* Fast squaring for polynomials over a 193-bit curve. Assumes reduction
    + * polynomial with terms {193, 15, 0}. */
    +mp_err
    +ec_GF2m_193_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_digit *u, *v;
    +
    +        v = MP_DIGITS(a);
    +
    +#ifdef ECL_SIXTY_FOUR_BIT
    +        if (MP_USED(a) < 4) {
    +                return mp_bsqrmod(a, meth->irr_arr, r);
    +        }
    +        if (MP_USED(r) < 7) {
    +                MP_CHECKOK(s_mp_pad(r, 7));
    +        }
    +        MP_USED(r) = 7;
    +#else
    +        if (MP_USED(a) < 7) {
    +                return mp_bsqrmod(a, meth->irr_arr, r);
    +        }
    +        if (MP_USED(r) < 13) {
    +                MP_CHECKOK(s_mp_pad(r, 13));
    +        }
    +        MP_USED(r) = 13;
    +#endif
    +        u = MP_DIGITS(r);
    +
    +#ifdef ECL_THIRTY_TWO_BIT
    +        u[12] = gf2m_SQR0(v[6]);
    +        u[11] = gf2m_SQR1(v[5]);
    +        u[10] = gf2m_SQR0(v[5]);
    +        u[9] = gf2m_SQR1(v[4]);
    +        u[8] = gf2m_SQR0(v[4]);
    +        u[7] = gf2m_SQR1(v[3]);
    +#endif
    +        u[6] = gf2m_SQR0(v[3]);
    +        u[5] = gf2m_SQR1(v[2]);
    +        u[4] = gf2m_SQR0(v[2]);
    +        u[3] = gf2m_SQR1(v[1]);
    +        u[2] = gf2m_SQR0(v[1]);
    +        u[1] = gf2m_SQR1(v[0]);
    +        u[0] = gf2m_SQR0(v[0]);
    +        return ec_GF2m_193_mod(r, r, meth);
    +
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* Fast multiplication for polynomials over a 193-bit curve. Assumes
    + * reduction polynomial with terms {193, 15, 0}. */
    +mp_err
    +ec_GF2m_193_mul(const mp_int *a, const mp_int *b, mp_int *r,
    +                                const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_digit a3 = 0, a2 = 0, a1 = 0, a0, b3 = 0, b2 = 0, b1 = 0, b0;
    +
    +#ifdef ECL_THIRTY_TWO_BIT
    +        mp_digit a6 = 0, a5 = 0, a4 = 0, b6 = 0, b5 = 0, b4 = 0;
    +        mp_digit rm[8];
    +#endif
    +
    +        if (a == b) {
    +                return ec_GF2m_193_sqr(a, r, meth);
    +        } else {
    +                switch (MP_USED(a)) {
    +#ifdef ECL_THIRTY_TWO_BIT
    +                case 7:
    +                        a6 = MP_DIGIT(a, 6);
    +                case 6:
    +                        a5 = MP_DIGIT(a, 5);
    +                case 5:
    +                        a4 = MP_DIGIT(a, 4);
    +#endif
    +                case 4:
    +                        a3 = MP_DIGIT(a, 3);
    +                case 3:
    +                        a2 = MP_DIGIT(a, 2);
    +                case 2:
    +                        a1 = MP_DIGIT(a, 1);
    +                default:
    +                        a0 = MP_DIGIT(a, 0);
    +                }
    +                switch (MP_USED(b)) {
    +#ifdef ECL_THIRTY_TWO_BIT
    +                case 7:
    +                        b6 = MP_DIGIT(b, 6);
    +                case 6:
    +                        b5 = MP_DIGIT(b, 5);
    +                case 5:
    +                        b4 = MP_DIGIT(b, 4);
    +#endif
    +                case 4:
    +                        b3 = MP_DIGIT(b, 3);
    +                case 3:
    +                        b2 = MP_DIGIT(b, 2);
    +                case 2:
    +                        b1 = MP_DIGIT(b, 1);
    +                default:
    +                        b0 = MP_DIGIT(b, 0);
    +                }
    +#ifdef ECL_SIXTY_FOUR_BIT
    +                MP_CHECKOK(s_mp_pad(r, 8));
    +                s_bmul_4x4(MP_DIGITS(r), a3, a2, a1, a0, b3, b2, b1, b0);
    +                MP_USED(r) = 8;
    +                s_mp_clamp(r);
    +#else
    +                MP_CHECKOK(s_mp_pad(r, 14));
    +                s_bmul_3x3(MP_DIGITS(r) + 8, a6, a5, a4, b6, b5, b4);
    +                s_bmul_4x4(MP_DIGITS(r), a3, a2, a1, a0, b3, b2, b1, b0);
    +                s_bmul_4x4(rm, a3, a6 ^ a2, a5 ^ a1, a4 ^ a0, b3, b6 ^ b2, b5 ^ b1,
    +                                   b4 ^ b0);
    +                rm[7] ^= MP_DIGIT(r, 7);
    +                rm[6] ^= MP_DIGIT(r, 6);
    +                rm[5] ^= MP_DIGIT(r, 5) ^ MP_DIGIT(r, 13);
    +                rm[4] ^= MP_DIGIT(r, 4) ^ MP_DIGIT(r, 12);
    +                rm[3] ^= MP_DIGIT(r, 3) ^ MP_DIGIT(r, 11);
    +                rm[2] ^= MP_DIGIT(r, 2) ^ MP_DIGIT(r, 10);
    +                rm[1] ^= MP_DIGIT(r, 1) ^ MP_DIGIT(r, 9);
    +                rm[0] ^= MP_DIGIT(r, 0) ^ MP_DIGIT(r, 8);
    +                MP_DIGIT(r, 11) ^= rm[7];
    +                MP_DIGIT(r, 10) ^= rm[6];
    +                MP_DIGIT(r, 9) ^= rm[5];
    +                MP_DIGIT(r, 8) ^= rm[4];
    +                MP_DIGIT(r, 7) ^= rm[3];
    +                MP_DIGIT(r, 6) ^= rm[2];
    +                MP_DIGIT(r, 5) ^= rm[1];
    +                MP_DIGIT(r, 4) ^= rm[0];
    +                MP_USED(r) = 14;
    +                s_mp_clamp(r);
    +#endif
    +                return ec_GF2m_193_mod(r, r, meth);
    +        }
    +
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* Wire in fast field arithmetic for 193-bit curves. */
    +mp_err
    +ec_group_set_gf2m193(ECGroup *group, ECCurveName name)
    +{
    +        group->meth->field_mod = &ec_GF2m_193_mod;
    +        group->meth->field_mul = &ec_GF2m_193_mul;
    +        group->meth->field_sqr = &ec_GF2m_193_sqr;
    +        return MP_OKAY;
    +}
    diff --git a/jdk/src/share/native/sun/security/ec/ec2_233.c b/jdk/src/share/native/sun/security/ec/ec2_233.c
    new file mode 100644
    index 00000000000..2b29c46ea76
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/ec2_233.c
    @@ -0,0 +1,321 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the elliptic curve math library for binary polynomial field curves.
    + *
    + * The Initial Developer of the Original Code is
    + * Sun Microsystems, Inc.
    + * Portions created by the Initial Developer are Copyright (C) 2003
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Sheueling Chang-Shantz ,
    + *   Stephen Fung , and
    + *   Douglas Stebila , Sun Microsystems Laboratories.
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +#include "ec2.h"
    +#include "mp_gf2m.h"
    +#include "mp_gf2m-priv.h"
    +#include "mpi.h"
    +#include "mpi-priv.h"
    +#ifndef _KERNEL
    +#include 
    +#endif
    +
    +/* Fast reduction for polynomials over a 233-bit curve. Assumes reduction
    + * polynomial with terms {233, 74, 0}. */
    +mp_err
    +ec_GF2m_233_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_digit *u, z;
    +
    +        if (a != r) {
    +                MP_CHECKOK(mp_copy(a, r));
    +        }
    +#ifdef ECL_SIXTY_FOUR_BIT
    +        if (MP_USED(r) < 8) {
    +                MP_CHECKOK(s_mp_pad(r, 8));
    +        }
    +        u = MP_DIGITS(r);
    +        MP_USED(r) = 8;
    +
    +        /* u[7] only has 18 significant bits */
    +        z = u[7];
    +        u[4] ^= (z << 33) ^ (z >> 41);
    +        u[3] ^= (z << 23);
    +        z = u[6];
    +        u[4] ^= (z >> 31);
    +        u[3] ^= (z << 33) ^ (z >> 41);
    +        u[2] ^= (z << 23);
    +        z = u[5];
    +        u[3] ^= (z >> 31);
    +        u[2] ^= (z << 33) ^ (z >> 41);
    +        u[1] ^= (z << 23);
    +        z = u[4];
    +        u[2] ^= (z >> 31);
    +        u[1] ^= (z << 33) ^ (z >> 41);
    +        u[0] ^= (z << 23);
    +        z = u[3] >> 41;                         /* z only has 23 significant bits */
    +        u[1] ^= (z << 10);
    +        u[0] ^= z;
    +        /* clear bits above 233 */
    +        u[7] = u[6] = u[5] = u[4] = 0;
    +        u[3] ^= z << 41;
    +#else
    +        if (MP_USED(r) < 15) {
    +                MP_CHECKOK(s_mp_pad(r, 15));
    +        }
    +        u = MP_DIGITS(r);
    +        MP_USED(r) = 15;
    +
    +        /* u[14] only has 18 significant bits */
    +        z = u[14];
    +        u[9] ^= (z << 1);
    +        u[7] ^= (z >> 9);
    +        u[6] ^= (z << 23);
    +        z = u[13];
    +        u[9] ^= (z >> 31);
    +        u[8] ^= (z << 1);
    +        u[6] ^= (z >> 9);
    +        u[5] ^= (z << 23);
    +        z = u[12];
    +        u[8] ^= (z >> 31);
    +        u[7] ^= (z << 1);
    +        u[5] ^= (z >> 9);
    +        u[4] ^= (z << 23);
    +        z = u[11];
    +        u[7] ^= (z >> 31);
    +        u[6] ^= (z << 1);
    +        u[4] ^= (z >> 9);
    +        u[3] ^= (z << 23);
    +        z = u[10];
    +        u[6] ^= (z >> 31);
    +        u[5] ^= (z << 1);
    +        u[3] ^= (z >> 9);
    +        u[2] ^= (z << 23);
    +        z = u[9];
    +        u[5] ^= (z >> 31);
    +        u[4] ^= (z << 1);
    +        u[2] ^= (z >> 9);
    +        u[1] ^= (z << 23);
    +        z = u[8];
    +        u[4] ^= (z >> 31);
    +        u[3] ^= (z << 1);
    +        u[1] ^= (z >> 9);
    +        u[0] ^= (z << 23);
    +        z = u[7] >> 9;                          /* z only has 23 significant bits */
    +        u[3] ^= (z >> 22);
    +        u[2] ^= (z << 10);
    +        u[0] ^= z;
    +        /* clear bits above 233 */
    +        u[14] = u[13] = u[12] = u[11] = u[10] = u[9] = u[8] = 0;
    +        u[7] ^= z << 9;
    +#endif
    +        s_mp_clamp(r);
    +
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* Fast squaring for polynomials over a 233-bit curve. Assumes reduction
    + * polynomial with terms {233, 74, 0}. */
    +mp_err
    +ec_GF2m_233_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_digit *u, *v;
    +
    +        v = MP_DIGITS(a);
    +
    +#ifdef ECL_SIXTY_FOUR_BIT
    +        if (MP_USED(a) < 4) {
    +                return mp_bsqrmod(a, meth->irr_arr, r);
    +        }
    +        if (MP_USED(r) < 8) {
    +                MP_CHECKOK(s_mp_pad(r, 8));
    +        }
    +        MP_USED(r) = 8;
    +#else
    +        if (MP_USED(a) < 8) {
    +                return mp_bsqrmod(a, meth->irr_arr, r);
    +        }
    +        if (MP_USED(r) < 15) {
    +                MP_CHECKOK(s_mp_pad(r, 15));
    +        }
    +        MP_USED(r) = 15;
    +#endif
    +        u = MP_DIGITS(r);
    +
    +#ifdef ECL_THIRTY_TWO_BIT
    +        u[14] = gf2m_SQR0(v[7]);
    +        u[13] = gf2m_SQR1(v[6]);
    +        u[12] = gf2m_SQR0(v[6]);
    +        u[11] = gf2m_SQR1(v[5]);
    +        u[10] = gf2m_SQR0(v[5]);
    +        u[9] = gf2m_SQR1(v[4]);
    +        u[8] = gf2m_SQR0(v[4]);
    +#endif
    +        u[7] = gf2m_SQR1(v[3]);
    +        u[6] = gf2m_SQR0(v[3]);
    +        u[5] = gf2m_SQR1(v[2]);
    +        u[4] = gf2m_SQR0(v[2]);
    +        u[3] = gf2m_SQR1(v[1]);
    +        u[2] = gf2m_SQR0(v[1]);
    +        u[1] = gf2m_SQR1(v[0]);
    +        u[0] = gf2m_SQR0(v[0]);
    +        return ec_GF2m_233_mod(r, r, meth);
    +
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* Fast multiplication for polynomials over a 233-bit curve. Assumes
    + * reduction polynomial with terms {233, 74, 0}. */
    +mp_err
    +ec_GF2m_233_mul(const mp_int *a, const mp_int *b, mp_int *r,
    +                                const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_digit a3 = 0, a2 = 0, a1 = 0, a0, b3 = 0, b2 = 0, b1 = 0, b0;
    +
    +#ifdef ECL_THIRTY_TWO_BIT
    +        mp_digit a7 = 0, a6 = 0, a5 = 0, a4 = 0, b7 = 0, b6 = 0, b5 = 0, b4 =
    +                0;
    +        mp_digit rm[8];
    +#endif
    +
    +        if (a == b) {
    +                return ec_GF2m_233_sqr(a, r, meth);
    +        } else {
    +                switch (MP_USED(a)) {
    +#ifdef ECL_THIRTY_TWO_BIT
    +                case 8:
    +                        a7 = MP_DIGIT(a, 7);
    +                case 7:
    +                        a6 = MP_DIGIT(a, 6);
    +                case 6:
    +                        a5 = MP_DIGIT(a, 5);
    +                case 5:
    +                        a4 = MP_DIGIT(a, 4);
    +#endif
    +                case 4:
    +                        a3 = MP_DIGIT(a, 3);
    +                case 3:
    +                        a2 = MP_DIGIT(a, 2);
    +                case 2:
    +                        a1 = MP_DIGIT(a, 1);
    +                default:
    +                        a0 = MP_DIGIT(a, 0);
    +                }
    +                switch (MP_USED(b)) {
    +#ifdef ECL_THIRTY_TWO_BIT
    +                case 8:
    +                        b7 = MP_DIGIT(b, 7);
    +                case 7:
    +                        b6 = MP_DIGIT(b, 6);
    +                case 6:
    +                        b5 = MP_DIGIT(b, 5);
    +                case 5:
    +                        b4 = MP_DIGIT(b, 4);
    +#endif
    +                case 4:
    +                        b3 = MP_DIGIT(b, 3);
    +                case 3:
    +                        b2 = MP_DIGIT(b, 2);
    +                case 2:
    +                        b1 = MP_DIGIT(b, 1);
    +                default:
    +                        b0 = MP_DIGIT(b, 0);
    +                }
    +#ifdef ECL_SIXTY_FOUR_BIT
    +                MP_CHECKOK(s_mp_pad(r, 8));
    +                s_bmul_4x4(MP_DIGITS(r), a3, a2, a1, a0, b3, b2, b1, b0);
    +                MP_USED(r) = 8;
    +                s_mp_clamp(r);
    +#else
    +                MP_CHECKOK(s_mp_pad(r, 16));
    +                s_bmul_4x4(MP_DIGITS(r) + 8, a7, a6, a5, a4, b7, b6, b5, b4);
    +                s_bmul_4x4(MP_DIGITS(r), a3, a2, a1, a0, b3, b2, b1, b0);
    +                s_bmul_4x4(rm, a7 ^ a3, a6 ^ a2, a5 ^ a1, a4 ^ a0, b7 ^ b3,
    +                                   b6 ^ b2, b5 ^ b1, b4 ^ b0);
    +                rm[7] ^= MP_DIGIT(r, 7) ^ MP_DIGIT(r, 15);
    +                rm[6] ^= MP_DIGIT(r, 6) ^ MP_DIGIT(r, 14);
    +                rm[5] ^= MP_DIGIT(r, 5) ^ MP_DIGIT(r, 13);
    +                rm[4] ^= MP_DIGIT(r, 4) ^ MP_DIGIT(r, 12);
    +                rm[3] ^= MP_DIGIT(r, 3) ^ MP_DIGIT(r, 11);
    +                rm[2] ^= MP_DIGIT(r, 2) ^ MP_DIGIT(r, 10);
    +                rm[1] ^= MP_DIGIT(r, 1) ^ MP_DIGIT(r, 9);
    +                rm[0] ^= MP_DIGIT(r, 0) ^ MP_DIGIT(r, 8);
    +                MP_DIGIT(r, 11) ^= rm[7];
    +                MP_DIGIT(r, 10) ^= rm[6];
    +                MP_DIGIT(r, 9) ^= rm[5];
    +                MP_DIGIT(r, 8) ^= rm[4];
    +                MP_DIGIT(r, 7) ^= rm[3];
    +                MP_DIGIT(r, 6) ^= rm[2];
    +                MP_DIGIT(r, 5) ^= rm[1];
    +                MP_DIGIT(r, 4) ^= rm[0];
    +                MP_USED(r) = 16;
    +                s_mp_clamp(r);
    +#endif
    +                return ec_GF2m_233_mod(r, r, meth);
    +        }
    +
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* Wire in fast field arithmetic for 233-bit curves. */
    +mp_err
    +ec_group_set_gf2m233(ECGroup *group, ECCurveName name)
    +{
    +        group->meth->field_mod = &ec_GF2m_233_mod;
    +        group->meth->field_mul = &ec_GF2m_233_mul;
    +        group->meth->field_sqr = &ec_GF2m_233_sqr;
    +        return MP_OKAY;
    +}
    diff --git a/jdk/src/share/native/sun/security/ec/ec2_aff.c b/jdk/src/share/native/sun/security/ec/ec2_aff.c
    new file mode 100644
    index 00000000000..bb52cbc97f9
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/ec2_aff.c
    @@ -0,0 +1,368 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the elliptic curve math library for binary polynomial field curves.
    + *
    + * The Initial Developer of the Original Code is
    + * Sun Microsystems, Inc.
    + * Portions created by the Initial Developer are Copyright (C) 2003
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Douglas Stebila , Sun Microsystems Laboratories
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +#include "ec2.h"
    +#include "mplogic.h"
    +#include "mp_gf2m.h"
    +#ifndef _KERNEL
    +#include 
    +#endif
    +
    +/* Checks if point P(px, py) is at infinity.  Uses affine coordinates. */
    +mp_err
    +ec_GF2m_pt_is_inf_aff(const mp_int *px, const mp_int *py)
    +{
    +
    +        if ((mp_cmp_z(px) == 0) && (mp_cmp_z(py) == 0)) {
    +                return MP_YES;
    +        } else {
    +                return MP_NO;
    +        }
    +
    +}
    +
    +/* Sets P(px, py) to be the point at infinity.  Uses affine coordinates. */
    +mp_err
    +ec_GF2m_pt_set_inf_aff(mp_int *px, mp_int *py)
    +{
    +        mp_zero(px);
    +        mp_zero(py);
    +        return MP_OKAY;
    +}
    +
    +/* Computes R = P + Q based on IEEE P1363 A.10.2. Elliptic curve points P,
    + * Q, and R can all be identical. Uses affine coordinates. */
    +mp_err
    +ec_GF2m_pt_add_aff(const mp_int *px, const mp_int *py, const mp_int *qx,
    +                                   const mp_int *qy, mp_int *rx, mp_int *ry,
    +                                   const ECGroup *group)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_int lambda, tempx, tempy;
    +
    +        MP_DIGITS(&lambda) = 0;
    +        MP_DIGITS(&tempx) = 0;
    +        MP_DIGITS(&tempy) = 0;
    +        MP_CHECKOK(mp_init(&lambda, FLAG(px)));
    +        MP_CHECKOK(mp_init(&tempx, FLAG(px)));
    +        MP_CHECKOK(mp_init(&tempy, FLAG(px)));
    +        /* if P = inf, then R = Q */
    +        if (ec_GF2m_pt_is_inf_aff(px, py) == 0) {
    +                MP_CHECKOK(mp_copy(qx, rx));
    +                MP_CHECKOK(mp_copy(qy, ry));
    +                res = MP_OKAY;
    +                goto CLEANUP;
    +        }
    +        /* if Q = inf, then R = P */
    +        if (ec_GF2m_pt_is_inf_aff(qx, qy) == 0) {
    +                MP_CHECKOK(mp_copy(px, rx));
    +                MP_CHECKOK(mp_copy(py, ry));
    +                res = MP_OKAY;
    +                goto CLEANUP;
    +        }
    +        /* if px != qx, then lambda = (py+qy) / (px+qx), tempx = a + lambda^2
    +         * + lambda + px + qx */
    +        if (mp_cmp(px, qx) != 0) {
    +                MP_CHECKOK(group->meth->field_add(py, qy, &tempy, group->meth));
    +                MP_CHECKOK(group->meth->field_add(px, qx, &tempx, group->meth));
    +                MP_CHECKOK(group->meth->
    +                                   field_div(&tempy, &tempx, &lambda, group->meth));
    +                MP_CHECKOK(group->meth->field_sqr(&lambda, &tempx, group->meth));
    +                MP_CHECKOK(group->meth->
    +                                   field_add(&tempx, &lambda, &tempx, group->meth));
    +                MP_CHECKOK(group->meth->
    +                                   field_add(&tempx, &group->curvea, &tempx, group->meth));
    +                MP_CHECKOK(group->meth->
    +                                   field_add(&tempx, px, &tempx, group->meth));
    +                MP_CHECKOK(group->meth->
    +                                   field_add(&tempx, qx, &tempx, group->meth));
    +        } else {
    +                /* if py != qy or qx = 0, then R = inf */
    +                if (((mp_cmp(py, qy) != 0)) || (mp_cmp_z(qx) == 0)) {
    +                        mp_zero(rx);
    +                        mp_zero(ry);
    +                        res = MP_OKAY;
    +                        goto CLEANUP;
    +                }
    +                /* lambda = qx + qy / qx */
    +                MP_CHECKOK(group->meth->field_div(qy, qx, &lambda, group->meth));
    +                MP_CHECKOK(group->meth->
    +                                   field_add(&lambda, qx, &lambda, group->meth));
    +                /* tempx = a + lambda^2 + lambda */
    +                MP_CHECKOK(group->meth->field_sqr(&lambda, &tempx, group->meth));
    +                MP_CHECKOK(group->meth->
    +                                   field_add(&tempx, &lambda, &tempx, group->meth));
    +                MP_CHECKOK(group->meth->
    +                                   field_add(&tempx, &group->curvea, &tempx, group->meth));
    +        }
    +        /* ry = (qx + tempx) * lambda + tempx + qy */
    +        MP_CHECKOK(group->meth->field_add(qx, &tempx, &tempy, group->meth));
    +        MP_CHECKOK(group->meth->
    +                           field_mul(&tempy, &lambda, &tempy, group->meth));
    +        MP_CHECKOK(group->meth->
    +                           field_add(&tempy, &tempx, &tempy, group->meth));
    +        MP_CHECKOK(group->meth->field_add(&tempy, qy, ry, group->meth));
    +        /* rx = tempx */
    +        MP_CHECKOK(mp_copy(&tempx, rx));
    +
    +  CLEANUP:
    +        mp_clear(&lambda);
    +        mp_clear(&tempx);
    +        mp_clear(&tempy);
    +        return res;
    +}
    +
    +/* Computes R = P - Q. Elliptic curve points P, Q, and R can all be
    + * identical. Uses affine coordinates. */
    +mp_err
    +ec_GF2m_pt_sub_aff(const mp_int *px, const mp_int *py, const mp_int *qx,
    +                                   const mp_int *qy, mp_int *rx, mp_int *ry,
    +                                   const ECGroup *group)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_int nqy;
    +
    +        MP_DIGITS(&nqy) = 0;
    +        MP_CHECKOK(mp_init(&nqy, FLAG(px)));
    +        /* nqy = qx+qy */
    +        MP_CHECKOK(group->meth->field_add(qx, qy, &nqy, group->meth));
    +        MP_CHECKOK(group->point_add(px, py, qx, &nqy, rx, ry, group));
    +  CLEANUP:
    +        mp_clear(&nqy);
    +        return res;
    +}
    +
    +/* Computes R = 2P. Elliptic curve points P and R can be identical. Uses
    + * affine coordinates. */
    +mp_err
    +ec_GF2m_pt_dbl_aff(const mp_int *px, const mp_int *py, mp_int *rx,
    +                                   mp_int *ry, const ECGroup *group)
    +{
    +        return group->point_add(px, py, px, py, rx, ry, group);
    +}
    +
    +/* by default, this routine is unused and thus doesn't need to be compiled */
    +#ifdef ECL_ENABLE_GF2M_PT_MUL_AFF
    +/* Computes R = nP based on IEEE P1363 A.10.3. Elliptic curve points P and
    + * R can be identical. Uses affine coordinates. */
    +mp_err
    +ec_GF2m_pt_mul_aff(const mp_int *n, const mp_int *px, const mp_int *py,
    +                                   mp_int *rx, mp_int *ry, const ECGroup *group)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_int k, k3, qx, qy, sx, sy;
    +        int b1, b3, i, l;
    +
    +        MP_DIGITS(&k) = 0;
    +        MP_DIGITS(&k3) = 0;
    +        MP_DIGITS(&qx) = 0;
    +        MP_DIGITS(&qy) = 0;
    +        MP_DIGITS(&sx) = 0;
    +        MP_DIGITS(&sy) = 0;
    +        MP_CHECKOK(mp_init(&k));
    +        MP_CHECKOK(mp_init(&k3));
    +        MP_CHECKOK(mp_init(&qx));
    +        MP_CHECKOK(mp_init(&qy));
    +        MP_CHECKOK(mp_init(&sx));
    +        MP_CHECKOK(mp_init(&sy));
    +
    +        /* if n = 0 then r = inf */
    +        if (mp_cmp_z(n) == 0) {
    +                mp_zero(rx);
    +                mp_zero(ry);
    +                res = MP_OKAY;
    +                goto CLEANUP;
    +        }
    +        /* Q = P, k = n */
    +        MP_CHECKOK(mp_copy(px, &qx));
    +        MP_CHECKOK(mp_copy(py, &qy));
    +        MP_CHECKOK(mp_copy(n, &k));
    +        /* if n < 0 then Q = -Q, k = -k */
    +        if (mp_cmp_z(n) < 0) {
    +                MP_CHECKOK(group->meth->field_add(&qx, &qy, &qy, group->meth));
    +                MP_CHECKOK(mp_neg(&k, &k));
    +        }
    +#ifdef ECL_DEBUG                                /* basic double and add method */
    +        l = mpl_significant_bits(&k) - 1;
    +        MP_CHECKOK(mp_copy(&qx, &sx));
    +        MP_CHECKOK(mp_copy(&qy, &sy));
    +        for (i = l - 1; i >= 0; i--) {
    +                /* S = 2S */
    +                MP_CHECKOK(group->point_dbl(&sx, &sy, &sx, &sy, group));
    +                /* if k_i = 1, then S = S + Q */
    +                if (mpl_get_bit(&k, i) != 0) {
    +                        MP_CHECKOK(group->
    +                                           point_add(&sx, &sy, &qx, &qy, &sx, &sy, group));
    +                }
    +        }
    +#else                                                   /* double and add/subtract method from
    +                                                                 * standard */
    +        /* k3 = 3 * k */
    +        MP_CHECKOK(mp_set_int(&k3, 3));
    +        MP_CHECKOK(mp_mul(&k, &k3, &k3));
    +        /* S = Q */
    +        MP_CHECKOK(mp_copy(&qx, &sx));
    +        MP_CHECKOK(mp_copy(&qy, &sy));
    +        /* l = index of high order bit in binary representation of 3*k */
    +        l = mpl_significant_bits(&k3) - 1;
    +        /* for i = l-1 downto 1 */
    +        for (i = l - 1; i >= 1; i--) {
    +                /* S = 2S */
    +                MP_CHECKOK(group->point_dbl(&sx, &sy, &sx, &sy, group));
    +                b3 = MP_GET_BIT(&k3, i);
    +                b1 = MP_GET_BIT(&k, i);
    +                /* if k3_i = 1 and k_i = 0, then S = S + Q */
    +                if ((b3 == 1) && (b1 == 0)) {
    +                        MP_CHECKOK(group->
    +                                           point_add(&sx, &sy, &qx, &qy, &sx, &sy, group));
    +                        /* if k3_i = 0 and k_i = 1, then S = S - Q */
    +                } else if ((b3 == 0) && (b1 == 1)) {
    +                        MP_CHECKOK(group->
    +                                           point_sub(&sx, &sy, &qx, &qy, &sx, &sy, group));
    +                }
    +        }
    +#endif
    +        /* output S */
    +        MP_CHECKOK(mp_copy(&sx, rx));
    +        MP_CHECKOK(mp_copy(&sy, ry));
    +
    +  CLEANUP:
    +        mp_clear(&k);
    +        mp_clear(&k3);
    +        mp_clear(&qx);
    +        mp_clear(&qy);
    +        mp_clear(&sx);
    +        mp_clear(&sy);
    +        return res;
    +}
    +#endif
    +
    +/* Validates a point on a GF2m curve. */
    +mp_err
    +ec_GF2m_validate_point(const mp_int *px, const mp_int *py, const ECGroup *group)
    +{
    +        mp_err res = MP_NO;
    +        mp_int accl, accr, tmp, pxt, pyt;
    +
    +        MP_DIGITS(&accl) = 0;
    +        MP_DIGITS(&accr) = 0;
    +        MP_DIGITS(&tmp) = 0;
    +        MP_DIGITS(&pxt) = 0;
    +        MP_DIGITS(&pyt) = 0;
    +        MP_CHECKOK(mp_init(&accl, FLAG(px)));
    +        MP_CHECKOK(mp_init(&accr, FLAG(px)));
    +        MP_CHECKOK(mp_init(&tmp, FLAG(px)));
    +        MP_CHECKOK(mp_init(&pxt, FLAG(px)));
    +        MP_CHECKOK(mp_init(&pyt, FLAG(px)));
    +
    +    /* 1: Verify that publicValue is not the point at infinity */
    +        if (ec_GF2m_pt_is_inf_aff(px, py) == MP_YES) {
    +                res = MP_NO;
    +                goto CLEANUP;
    +        }
    +    /* 2: Verify that the coordinates of publicValue are elements
    +     *    of the field.
    +     */
    +        if ((MP_SIGN(px) == MP_NEG) || (mp_cmp(px, &group->meth->irr) >= 0) ||
    +                (MP_SIGN(py) == MP_NEG) || (mp_cmp(py, &group->meth->irr) >= 0)) {
    +                res = MP_NO;
    +                goto CLEANUP;
    +        }
    +    /* 3: Verify that publicValue is on the curve. */
    +        if (group->meth->field_enc) {
    +                group->meth->field_enc(px, &pxt, group->meth);
    +                group->meth->field_enc(py, &pyt, group->meth);
    +        } else {
    +                mp_copy(px, &pxt);
    +                mp_copy(py, &pyt);
    +        }
    +        /* left-hand side: y^2 + x*y  */
    +        MP_CHECKOK( group->meth->field_sqr(&pyt, &accl, group->meth) );
    +        MP_CHECKOK( group->meth->field_mul(&pxt, &pyt, &tmp, group->meth) );
    +        MP_CHECKOK( group->meth->field_add(&accl, &tmp, &accl, group->meth) );
    +        /* right-hand side: x^3 + a*x^2 + b */
    +        MP_CHECKOK( group->meth->field_sqr(&pxt, &tmp, group->meth) );
    +        MP_CHECKOK( group->meth->field_mul(&pxt, &tmp, &accr, group->meth) );
    +        MP_CHECKOK( group->meth->field_mul(&group->curvea, &tmp, &tmp, group->meth) );
    +        MP_CHECKOK( group->meth->field_add(&tmp, &accr, &accr, group->meth) );
    +        MP_CHECKOK( group->meth->field_add(&accr, &group->curveb, &accr, group->meth) );
    +        /* check LHS - RHS == 0 */
    +        MP_CHECKOK( group->meth->field_add(&accl, &accr, &accr, group->meth) );
    +        if (mp_cmp_z(&accr) != 0) {
    +                res = MP_NO;
    +                goto CLEANUP;
    +        }
    +    /* 4: Verify that the order of the curve times the publicValue
    +     *    is the point at infinity.
    +     */
    +        MP_CHECKOK( ECPoint_mul(group, &group->order, px, py, &pxt, &pyt) );
    +        if (ec_GF2m_pt_is_inf_aff(&pxt, &pyt) != MP_YES) {
    +                res = MP_NO;
    +                goto CLEANUP;
    +        }
    +
    +        res = MP_YES;
    +
    +CLEANUP:
    +        mp_clear(&accl);
    +        mp_clear(&accr);
    +        mp_clear(&tmp);
    +        mp_clear(&pxt);
    +        mp_clear(&pyt);
    +        return res;
    +}
    diff --git a/jdk/src/share/native/sun/security/ec/ec2_mont.c b/jdk/src/share/native/sun/security/ec/ec2_mont.c
    new file mode 100644
    index 00000000000..5cef20f5303
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/ec2_mont.c
    @@ -0,0 +1,296 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the elliptic curve math library for binary polynomial field curves.
    + *
    + * The Initial Developer of the Original Code is
    + * Sun Microsystems, Inc.
    + * Portions created by the Initial Developer are Copyright (C) 2003
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Sheueling Chang-Shantz ,
    + *   Stephen Fung , and
    + *   Douglas Stebila , Sun Microsystems Laboratories.
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +#include "ec2.h"
    +#include "mplogic.h"
    +#include "mp_gf2m.h"
    +#ifndef _KERNEL
    +#include 
    +#endif
    +
    +/* Compute the x-coordinate x/z for the point 2*(x/z) in Montgomery
    + * projective coordinates. Uses algorithm Mdouble in appendix of Lopez, J.
    + * and Dahab, R.  "Fast multiplication on elliptic curves over GF(2^m)
    + * without precomputation". modified to not require precomputation of
    + * c=b^{2^{m-1}}. */
    +static mp_err
    +gf2m_Mdouble(mp_int *x, mp_int *z, const ECGroup *group, int kmflag)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_int t1;
    +
    +        MP_DIGITS(&t1) = 0;
    +        MP_CHECKOK(mp_init(&t1, kmflag));
    +
    +        MP_CHECKOK(group->meth->field_sqr(x, x, group->meth));
    +        MP_CHECKOK(group->meth->field_sqr(z, &t1, group->meth));
    +        MP_CHECKOK(group->meth->field_mul(x, &t1, z, group->meth));
    +        MP_CHECKOK(group->meth->field_sqr(x, x, group->meth));
    +        MP_CHECKOK(group->meth->field_sqr(&t1, &t1, group->meth));
    +        MP_CHECKOK(group->meth->
    +                           field_mul(&group->curveb, &t1, &t1, group->meth));
    +        MP_CHECKOK(group->meth->field_add(x, &t1, x, group->meth));
    +
    +  CLEANUP:
    +        mp_clear(&t1);
    +        return res;
    +}
    +
    +/* Compute the x-coordinate x1/z1 for the point (x1/z1)+(x2/x2) in
    + * Montgomery projective coordinates. Uses algorithm Madd in appendix of
    + * Lopex, J. and Dahab, R.  "Fast multiplication on elliptic curves over
    + * GF(2^m) without precomputation". */
    +static mp_err
    +gf2m_Madd(const mp_int *x, mp_int *x1, mp_int *z1, mp_int *x2, mp_int *z2,
    +                  const ECGroup *group, int kmflag)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_int t1, t2;
    +
    +        MP_DIGITS(&t1) = 0;
    +        MP_DIGITS(&t2) = 0;
    +        MP_CHECKOK(mp_init(&t1, kmflag));
    +        MP_CHECKOK(mp_init(&t2, kmflag));
    +
    +        MP_CHECKOK(mp_copy(x, &t1));
    +        MP_CHECKOK(group->meth->field_mul(x1, z2, x1, group->meth));
    +        MP_CHECKOK(group->meth->field_mul(z1, x2, z1, group->meth));
    +        MP_CHECKOK(group->meth->field_mul(x1, z1, &t2, group->meth));
    +        MP_CHECKOK(group->meth->field_add(z1, x1, z1, group->meth));
    +        MP_CHECKOK(group->meth->field_sqr(z1, z1, group->meth));
    +        MP_CHECKOK(group->meth->field_mul(z1, &t1, x1, group->meth));
    +        MP_CHECKOK(group->meth->field_add(x1, &t2, x1, group->meth));
    +
    +  CLEANUP:
    +        mp_clear(&t1);
    +        mp_clear(&t2);
    +        return res;
    +}
    +
    +/* Compute the x, y affine coordinates from the point (x1, z1) (x2, z2)
    + * using Montgomery point multiplication algorithm Mxy() in appendix of
    + * Lopex, J. and Dahab, R.  "Fast multiplication on elliptic curves over
    + * GF(2^m) without precomputation". Returns: 0 on error 1 if return value
    + * should be the point at infinity 2 otherwise */
    +static int
    +gf2m_Mxy(const mp_int *x, const mp_int *y, mp_int *x1, mp_int *z1,
    +                 mp_int *x2, mp_int *z2, const ECGroup *group)
    +{
    +        mp_err res = MP_OKAY;
    +        int ret = 0;
    +        mp_int t3, t4, t5;
    +
    +        MP_DIGITS(&t3) = 0;
    +        MP_DIGITS(&t4) = 0;
    +        MP_DIGITS(&t5) = 0;
    +        MP_CHECKOK(mp_init(&t3, FLAG(x2)));
    +        MP_CHECKOK(mp_init(&t4, FLAG(x2)));
    +        MP_CHECKOK(mp_init(&t5, FLAG(x2)));
    +
    +        if (mp_cmp_z(z1) == 0) {
    +                mp_zero(x2);
    +                mp_zero(z2);
    +                ret = 1;
    +                goto CLEANUP;
    +        }
    +
    +        if (mp_cmp_z(z2) == 0) {
    +                MP_CHECKOK(mp_copy(x, x2));
    +                MP_CHECKOK(group->meth->field_add(x, y, z2, group->meth));
    +                ret = 2;
    +                goto CLEANUP;
    +        }
    +
    +        MP_CHECKOK(mp_set_int(&t5, 1));
    +        if (group->meth->field_enc) {
    +                MP_CHECKOK(group->meth->field_enc(&t5, &t5, group->meth));
    +        }
    +
    +        MP_CHECKOK(group->meth->field_mul(z1, z2, &t3, group->meth));
    +
    +        MP_CHECKOK(group->meth->field_mul(z1, x, z1, group->meth));
    +        MP_CHECKOK(group->meth->field_add(z1, x1, z1, group->meth));
    +        MP_CHECKOK(group->meth->field_mul(z2, x, z2, group->meth));
    +        MP_CHECKOK(group->meth->field_mul(z2, x1, x1, group->meth));
    +        MP_CHECKOK(group->meth->field_add(z2, x2, z2, group->meth));
    +
    +        MP_CHECKOK(group->meth->field_mul(z2, z1, z2, group->meth));
    +        MP_CHECKOK(group->meth->field_sqr(x, &t4, group->meth));
    +        MP_CHECKOK(group->meth->field_add(&t4, y, &t4, group->meth));
    +        MP_CHECKOK(group->meth->field_mul(&t4, &t3, &t4, group->meth));
    +        MP_CHECKOK(group->meth->field_add(&t4, z2, &t4, group->meth));
    +
    +        MP_CHECKOK(group->meth->field_mul(&t3, x, &t3, group->meth));
    +        MP_CHECKOK(group->meth->field_div(&t5, &t3, &t3, group->meth));
    +        MP_CHECKOK(group->meth->field_mul(&t3, &t4, &t4, group->meth));
    +        MP_CHECKOK(group->meth->field_mul(x1, &t3, x2, group->meth));
    +        MP_CHECKOK(group->meth->field_add(x2, x, z2, group->meth));
    +
    +        MP_CHECKOK(group->meth->field_mul(z2, &t4, z2, group->meth));
    +        MP_CHECKOK(group->meth->field_add(z2, y, z2, group->meth));
    +
    +        ret = 2;
    +
    +  CLEANUP:
    +        mp_clear(&t3);
    +        mp_clear(&t4);
    +        mp_clear(&t5);
    +        if (res == MP_OKAY) {
    +                return ret;
    +        } else {
    +                return 0;
    +        }
    +}
    +
    +/* Computes R = nP based on algorithm 2P of Lopex, J. and Dahab, R.  "Fast
    + * multiplication on elliptic curves over GF(2^m) without
    + * precomputation". Elliptic curve points P and R can be identical. Uses
    + * Montgomery projective coordinates. */
    +mp_err
    +ec_GF2m_pt_mul_mont(const mp_int *n, const mp_int *px, const mp_int *py,
    +                                        mp_int *rx, mp_int *ry, const ECGroup *group)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_int x1, x2, z1, z2;
    +        int i, j;
    +        mp_digit top_bit, mask;
    +
    +        MP_DIGITS(&x1) = 0;
    +        MP_DIGITS(&x2) = 0;
    +        MP_DIGITS(&z1) = 0;
    +        MP_DIGITS(&z2) = 0;
    +        MP_CHECKOK(mp_init(&x1, FLAG(n)));
    +        MP_CHECKOK(mp_init(&x2, FLAG(n)));
    +        MP_CHECKOK(mp_init(&z1, FLAG(n)));
    +        MP_CHECKOK(mp_init(&z2, FLAG(n)));
    +
    +        /* if result should be point at infinity */
    +        if ((mp_cmp_z(n) == 0) || (ec_GF2m_pt_is_inf_aff(px, py) == MP_YES)) {
    +                MP_CHECKOK(ec_GF2m_pt_set_inf_aff(rx, ry));
    +                goto CLEANUP;
    +        }
    +
    +        MP_CHECKOK(mp_copy(px, &x1));   /* x1 = px */
    +        MP_CHECKOK(mp_set_int(&z1, 1)); /* z1 = 1 */
    +        MP_CHECKOK(group->meth->field_sqr(&x1, &z2, group->meth));      /* z2 =
    +                                                                                                                                 * x1^2 =
    +                                                                                                                                 * px^2 */
    +        MP_CHECKOK(group->meth->field_sqr(&z2, &x2, group->meth));
    +        MP_CHECKOK(group->meth->field_add(&x2, &group->curveb, &x2, group->meth));      /* x2
    +                                                                                                                                                                 * =
    +                                                                                                                                                                 * px^4
    +                                                                                                                                                                 * +
    +                                                                                                                                                                 * b
    +                                                                                                                                                                 */
    +
    +        /* find top-most bit and go one past it */
    +        i = MP_USED(n) - 1;
    +        j = MP_DIGIT_BIT - 1;
    +        top_bit = 1;
    +        top_bit <<= MP_DIGIT_BIT - 1;
    +        mask = top_bit;
    +        while (!(MP_DIGITS(n)[i] & mask)) {
    +                mask >>= 1;
    +                j--;
    +        }
    +        mask >>= 1;
    +        j--;
    +
    +        /* if top most bit was at word break, go to next word */
    +        if (!mask) {
    +                i--;
    +                j = MP_DIGIT_BIT - 1;
    +                mask = top_bit;
    +        }
    +
    +        for (; i >= 0; i--) {
    +                for (; j >= 0; j--) {
    +                        if (MP_DIGITS(n)[i] & mask) {
    +                                MP_CHECKOK(gf2m_Madd(px, &x1, &z1, &x2, &z2, group, FLAG(n)));
    +                                MP_CHECKOK(gf2m_Mdouble(&x2, &z2, group, FLAG(n)));
    +                        } else {
    +                                MP_CHECKOK(gf2m_Madd(px, &x2, &z2, &x1, &z1, group, FLAG(n)));
    +                                MP_CHECKOK(gf2m_Mdouble(&x1, &z1, group, FLAG(n)));
    +                        }
    +                        mask >>= 1;
    +                }
    +                j = MP_DIGIT_BIT - 1;
    +                mask = top_bit;
    +        }
    +
    +        /* convert out of "projective" coordinates */
    +        i = gf2m_Mxy(px, py, &x1, &z1, &x2, &z2, group);
    +        if (i == 0) {
    +                res = MP_BADARG;
    +                goto CLEANUP;
    +        } else if (i == 1) {
    +                MP_CHECKOK(ec_GF2m_pt_set_inf_aff(rx, ry));
    +        } else {
    +                MP_CHECKOK(mp_copy(&x2, rx));
    +                MP_CHECKOK(mp_copy(&z2, ry));
    +        }
    +
    +  CLEANUP:
    +        mp_clear(&x1);
    +        mp_clear(&x2);
    +        mp_clear(&z1);
    +        mp_clear(&z2);
    +        return res;
    +}
    diff --git a/jdk/src/share/native/sun/security/ec/ec_naf.c b/jdk/src/share/native/sun/security/ec/ec_naf.c
    new file mode 100644
    index 00000000000..1d110904d29
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/ec_naf.c
    @@ -0,0 +1,123 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the elliptic curve math library.
    + *
    + * The Initial Developer of the Original Code is
    + * Sun Microsystems, Inc.
    + * Portions created by the Initial Developer are Copyright (C) 2003
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Stephen Fung , Sun Microsystems Laboratories
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +#include "ecl-priv.h"
    +
    +/* Returns 2^e as an integer. This is meant to be used for small powers of
    + * two. */
    +int
    +ec_twoTo(int e)
    +{
    +        int a = 1;
    +        int i;
    +
    +        for (i = 0; i < e; i++) {
    +                a *= 2;
    +        }
    +        return a;
    +}
    +
    +/* Computes the windowed non-adjacent-form (NAF) of a scalar. Out should
    + * be an array of signed char's to output to, bitsize should be the number
    + * of bits of out, in is the original scalar, and w is the window size.
    + * NAF is discussed in the paper: D. Hankerson, J. Hernandez and A.
    + * Menezes, "Software implementation of elliptic curve cryptography over
    + * binary fields", Proc. CHES 2000. */
    +mp_err
    +ec_compute_wNAF(signed char *out, int bitsize, const mp_int *in, int w)
    +{
    +        mp_int k;
    +        mp_err res = MP_OKAY;
    +        int i, twowm1, mask;
    +
    +        twowm1 = ec_twoTo(w - 1);
    +        mask = 2 * twowm1 - 1;
    +
    +        MP_DIGITS(&k) = 0;
    +        MP_CHECKOK(mp_init_copy(&k, in));
    +
    +        i = 0;
    +        /* Compute wNAF form */
    +        while (mp_cmp_z(&k) > 0) {
    +                if (mp_isodd(&k)) {
    +                        out[i] = MP_DIGIT(&k, 0) & mask;
    +                        if (out[i] >= twowm1)
    +                                out[i] -= 2 * twowm1;
    +
    +                        /* Subtract off out[i].  Note mp_sub_d only works with
    +                         * unsigned digits */
    +                        if (out[i] >= 0) {
    +                                mp_sub_d(&k, out[i], &k);
    +                        } else {
    +                                mp_add_d(&k, -(out[i]), &k);
    +                        }
    +                } else {
    +                        out[i] = 0;
    +                }
    +                mp_div_2(&k, &k);
    +                i++;
    +        }
    +        /* Zero out the remaining elements of the out array. */
    +        for (; i < bitsize + 1; i++) {
    +                out[i] = 0;
    +        }
    +  CLEANUP:
    +        mp_clear(&k);
    +        return res;
    +
    +}
    diff --git a/jdk/src/share/native/sun/security/ec/ecc_impl.h b/jdk/src/share/native/sun/security/ec/ecc_impl.h
    new file mode 100644
    index 00000000000..702ab1daeb7
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/ecc_impl.h
    @@ -0,0 +1,278 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the Netscape security libraries.
    + *
    + * The Initial Developer of the Original Code is
    + * Netscape Communications Corporation.
    + * Portions created by the Initial Developer are Copyright (C) 1994-2000
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Dr Vipul Gupta  and
    + *   Douglas Stebila , Sun Microsystems Laboratories
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#ifndef _ECC_IMPL_H
    +#define _ECC_IMPL_H
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +#ifdef __cplusplus
    +extern "C" {
    +#endif
    +
    +#include 
    +#include "ecl-exp.h"
    +
    +/*
    + * Multi-platform definitions
    + */
    +#ifdef __linux__
    +#define B_FALSE FALSE
    +#define B_TRUE TRUE
    +typedef unsigned char uint8_t;
    +typedef unsigned long ulong_t;
    +typedef enum { B_FALSE, B_TRUE } boolean_t;
    +#endif /* __linux__ */
    +
    +#ifdef _WIN32
    +typedef unsigned char uint8_t;
    +typedef unsigned long ulong_t;
    +typedef enum boolean { B_FALSE, B_TRUE } boolean_t;
    +#endif /* _WIN32 */
    +
    +#ifndef _KERNEL
    +#include 
    +#endif  /* _KERNEL */
    +
    +#define EC_MAX_DIGEST_LEN 1024  /* max digest that can be signed */
    +#define EC_MAX_POINT_LEN 145    /* max len of DER encoded Q */
    +#define EC_MAX_VALUE_LEN 72     /* max len of ANSI X9.62 private value d */
    +#define EC_MAX_SIG_LEN 144      /* max signature len for supported curves */
    +#define EC_MIN_KEY_LEN  112     /* min key length in bits */
    +#define EC_MAX_KEY_LEN  571     /* max key length in bits */
    +#define EC_MAX_OID_LEN 10       /* max length of OID buffer */
    +
    +/*
    + * Various structures and definitions from NSS are here.
    + */
    +
    +#ifdef _KERNEL
    +#define PORT_ArenaAlloc(a, n, f)        kmem_alloc((n), (f))
    +#define PORT_ArenaZAlloc(a, n, f)       kmem_zalloc((n), (f))
    +#define PORT_ArenaGrow(a, b, c, d)      NULL
    +#define PORT_ZAlloc(n, f)               kmem_zalloc((n), (f))
    +#define PORT_Alloc(n, f)                kmem_alloc((n), (f))
    +#else
    +#define PORT_ArenaAlloc(a, n, f)        malloc((n))
    +#define PORT_ArenaZAlloc(a, n, f)       calloc(1, (n))
    +#define PORT_ArenaGrow(a, b, c, d)      NULL
    +#define PORT_ZAlloc(n, f)               calloc(1, (n))
    +#define PORT_Alloc(n, f)                malloc((n))
    +#endif
    +
    +#define PORT_NewArena(b)                (char *)12345
    +#define PORT_ArenaMark(a)               NULL
    +#define PORT_ArenaUnmark(a, b)
    +#define PORT_ArenaRelease(a, m)
    +#define PORT_FreeArena(a, b)
    +#define PORT_Strlen(s)                  strlen((s))
    +#define PORT_SetError(e)
    +
    +#define PRBool                          boolean_t
    +#define PR_TRUE                         B_TRUE
    +#define PR_FALSE                        B_FALSE
    +
    +#ifdef _KERNEL
    +#define PORT_Assert                     ASSERT
    +#define PORT_Memcpy(t, f, l)            bcopy((f), (t), (l))
    +#else
    +#define PORT_Assert                     assert
    +#define PORT_Memcpy(t, f, l)            memcpy((t), (f), (l))
    +#endif
    +
    +#define CHECK_OK(func) if (func == NULL) goto cleanup
    +#define CHECK_SEC_OK(func) if (SECSuccess != (rv = func)) goto cleanup
    +
    +typedef enum {
    +        siBuffer = 0,
    +        siClearDataBuffer = 1,
    +        siCipherDataBuffer = 2,
    +        siDERCertBuffer = 3,
    +        siEncodedCertBuffer = 4,
    +        siDERNameBuffer = 5,
    +        siEncodedNameBuffer = 6,
    +        siAsciiNameString = 7,
    +        siAsciiString = 8,
    +        siDEROID = 9,
    +        siUnsignedInteger = 10,
    +        siUTCTime = 11,
    +        siGeneralizedTime = 12
    +} SECItemType;
    +
    +typedef struct SECItemStr SECItem;
    +
    +struct SECItemStr {
    +        SECItemType type;
    +        unsigned char *data;
    +        unsigned int len;
    +};
    +
    +typedef SECItem SECKEYECParams;
    +
    +typedef enum { ec_params_explicit,
    +               ec_params_named
    +} ECParamsType;
    +
    +typedef enum { ec_field_GFp = 1,
    +               ec_field_GF2m
    +} ECFieldType;
    +
    +struct ECFieldIDStr {
    +    int         size;   /* field size in bits */
    +    ECFieldType type;
    +    union {
    +        SECItem  prime; /* prime p for (GFp) */
    +        SECItem  poly;  /* irreducible binary polynomial for (GF2m) */
    +    } u;
    +    int         k1;     /* first coefficient of pentanomial or
    +                         * the only coefficient of trinomial
    +                         */
    +    int         k2;     /* two remaining coefficients of pentanomial */
    +    int         k3;
    +};
    +typedef struct ECFieldIDStr ECFieldID;
    +
    +struct ECCurveStr {
    +        SECItem a;      /* contains octet stream encoding of
    +                         * field element (X9.62 section 4.3.3)
    +                         */
    +        SECItem b;
    +        SECItem seed;
    +};
    +typedef struct ECCurveStr ECCurve;
    +
    +typedef void PRArenaPool;
    +
    +struct ECParamsStr {
    +    PRArenaPool * arena;
    +    ECParamsType  type;
    +    ECFieldID     fieldID;
    +    ECCurve       curve;
    +    SECItem       base;
    +    SECItem       order;
    +    int           cofactor;
    +    SECItem       DEREncoding;
    +    ECCurveName   name;
    +    SECItem       curveOID;
    +};
    +typedef struct ECParamsStr ECParams;
    +
    +struct ECPublicKeyStr {
    +    ECParams ecParams;
    +    SECItem publicValue;   /* elliptic curve point encoded as
    +                            * octet stream.
    +                            */
    +};
    +typedef struct ECPublicKeyStr ECPublicKey;
    +
    +struct ECPrivateKeyStr {
    +    ECParams ecParams;
    +    SECItem publicValue;   /* encoded ec point */
    +    SECItem privateValue;  /* private big integer */
    +    SECItem version;       /* As per SEC 1, Appendix C, Section C.4 */
    +};
    +typedef struct ECPrivateKeyStr ECPrivateKey;
    +
    +typedef enum _SECStatus {
    +        SECBufferTooSmall = -3,
    +        SECWouldBlock = -2,
    +        SECFailure = -1,
    +        SECSuccess = 0
    +} SECStatus;
    +
    +#ifdef _KERNEL
    +#define RNG_GenerateGlobalRandomBytes(p,l) ecc_knzero_random_generator((p), (l))
    +#else
    +/*
    + This function is no longer required because the random bytes are now
    + supplied by the caller. Force a failure.
    +VR
    +#define RNG_GenerateGlobalRandomBytes(p,l) SECFailure
    +*/
    +#define RNG_GenerateGlobalRandomBytes(p,l) SECSuccess
    +#endif
    +#define CHECK_MPI_OK(func) if (MP_OKAY > (err = func)) goto cleanup
    +#define MP_TO_SEC_ERROR(err)
    +
    +#define SECITEM_TO_MPINT(it, mp)                                        \
    +        CHECK_MPI_OK(mp_read_unsigned_octets((mp), (it).data, (it).len))
    +
    +extern int ecc_knzero_random_generator(uint8_t *, size_t);
    +extern ulong_t soft_nzero_random_generator(uint8_t *, ulong_t);
    +
    +extern SECStatus EC_DecodeParams(const SECItem *, ECParams **, int);
    +extern SECItem * SECITEM_AllocItem(PRArenaPool *, SECItem *, unsigned int, int);
    +extern SECStatus SECITEM_CopyItem(PRArenaPool *, SECItem *, const SECItem *,
    +    int);
    +extern void SECITEM_FreeItem(SECItem *, boolean_t);
    +extern SECStatus EC_NewKey(ECParams *ecParams, ECPrivateKey **privKey, const unsigned char* random, int randomlen, int);
    +extern SECStatus EC_NewKeyFromSeed(ECParams *ecParams, ECPrivateKey **privKey,
    +    const unsigned char *seed, int seedlen, int kmflag);
    +extern SECStatus ECDSA_SignDigest(ECPrivateKey *, SECItem *, const SECItem *,
    +    const unsigned char* randon, int randomlen, int);
    +extern SECStatus ECDSA_SignDigestWithSeed(ECPrivateKey *, SECItem *,
    +    const SECItem *, const unsigned char *seed, int seedlen, int kmflag);
    +extern SECStatus ECDSA_VerifyDigest(ECPublicKey *, const SECItem *,
    +    const SECItem *, int);
    +extern SECStatus ECDH_Derive(SECItem *, ECParams *, SECItem *, boolean_t,
    +    SECItem *, int);
    +
    +#ifdef  __cplusplus
    +}
    +#endif
    +
    +#endif /* _ECC_IMPL_H */
    diff --git a/jdk/src/share/native/sun/security/ec/ecdecode.c b/jdk/src/share/native/sun/security/ec/ecdecode.c
    new file mode 100644
    index 00000000000..d610f3b1b5a
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/ecdecode.c
    @@ -0,0 +1,632 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the Elliptic Curve Cryptography library.
    + *
    + * The Initial Developer of the Original Code is
    + * Sun Microsystems, Inc.
    + * Portions created by the Initial Developer are Copyright (C) 2003
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Dr Vipul Gupta  and
    + *   Douglas Stebila , Sun Microsystems Laboratories
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +#include 
    +
    +#ifndef _WIN32
    +#ifndef __linux__
    +#include 
    +#endif /* __linux__ */
    +#include 
    +#endif /* _WIN32 */
    +
    +#ifdef _KERNEL
    +#include 
    +#else
    +#include 
    +#endif
    +#include "ec.h"
    +#include "ecl-curve.h"
    +#include "ecc_impl.h"
    +
    +#define MAX_ECKEY_LEN           72
    +#define SEC_ASN1_OBJECT_ID      0x06
    +
    +/*
    + * Initializes a SECItem from a hexadecimal string
    + *
    + * Warning: This function ignores leading 00's, so any leading 00's
    + * in the hexadecimal string must be optional.
    + */
    +static SECItem *
    +hexString2SECItem(PRArenaPool *arena, SECItem *item, const char *str,
    +    int kmflag)
    +{
    +    int i = 0;
    +    int byteval = 0;
    +    int tmp = strlen(str);
    +
    +    if ((tmp % 2) != 0) return NULL;
    +
    +    /* skip leading 00's unless the hex string is "00" */
    +    while ((tmp > 2) && (str[0] == '0') && (str[1] == '0')) {
    +        str += 2;
    +        tmp -= 2;
    +    }
    +
    +    item->data = (unsigned char *) PORT_ArenaAlloc(arena, tmp/2, kmflag);
    +    if (item->data == NULL) return NULL;
    +    item->len = tmp/2;
    +
    +    while (str[i]) {
    +        if ((str[i] >= '0') && (str[i] <= '9'))
    +            tmp = str[i] - '0';
    +        else if ((str[i] >= 'a') && (str[i] <= 'f'))
    +            tmp = str[i] - 'a' + 10;
    +        else if ((str[i] >= 'A') && (str[i] <= 'F'))
    +            tmp = str[i] - 'A' + 10;
    +        else
    +            return NULL;
    +
    +        byteval = byteval * 16 + tmp;
    +        if ((i % 2) != 0) {
    +            item->data[i/2] = byteval;
    +            byteval = 0;
    +        }
    +        i++;
    +    }
    +
    +    return item;
    +}
    +
    +static SECStatus
    +gf_populate_params(ECCurveName name, ECFieldType field_type, ECParams *params,
    +    int kmflag)
    +{
    +    SECStatus rv = SECFailure;
    +    const ECCurveParams *curveParams;
    +    /* 2 ['0'+'4'] + MAX_ECKEY_LEN * 2 [x,y] * 2 [hex string] + 1 ['\0'] */
    +    char genenc[3 + 2 * 2 * MAX_ECKEY_LEN];
    +
    +    if ((name < ECCurve_noName) || (name > ECCurve_pastLastCurve)) goto cleanup;
    +    params->name = name;
    +    curveParams = ecCurve_map[params->name];
    +    CHECK_OK(curveParams);
    +    params->fieldID.size = curveParams->size;
    +    params->fieldID.type = field_type;
    +    if (field_type == ec_field_GFp) {
    +        CHECK_OK(hexString2SECItem(NULL, ¶ms->fieldID.u.prime,
    +            curveParams->irr, kmflag));
    +    } else {
    +        CHECK_OK(hexString2SECItem(NULL, ¶ms->fieldID.u.poly,
    +            curveParams->irr, kmflag));
    +    }
    +    CHECK_OK(hexString2SECItem(NULL, ¶ms->curve.a,
    +        curveParams->curvea, kmflag));
    +    CHECK_OK(hexString2SECItem(NULL, ¶ms->curve.b,
    +        curveParams->curveb, kmflag));
    +    genenc[0] = '0';
    +    genenc[1] = '4';
    +    genenc[2] = '\0';
    +    strcat(genenc, curveParams->genx);
    +    strcat(genenc, curveParams->geny);
    +    CHECK_OK(hexString2SECItem(NULL, ¶ms->base, genenc, kmflag));
    +    CHECK_OK(hexString2SECItem(NULL, ¶ms->order,
    +        curveParams->order, kmflag));
    +    params->cofactor = curveParams->cofactor;
    +
    +    rv = SECSuccess;
    +
    +cleanup:
    +    return rv;
    +}
    +
    +ECCurveName SECOID_FindOIDTag(const SECItem *);
    +
    +SECStatus
    +EC_FillParams(PRArenaPool *arena, const SECItem *encodedParams,
    +    ECParams *params, int kmflag)
    +{
    +    SECStatus rv = SECFailure;
    +    ECCurveName tag;
    +    SECItem oid = { siBuffer, NULL, 0};
    +
    +#if EC_DEBUG
    +    int i;
    +
    +    printf("Encoded params in EC_DecodeParams: ");
    +    for (i = 0; i < encodedParams->len; i++) {
    +            printf("%02x:", encodedParams->data[i]);
    +    }
    +    printf("\n");
    +#endif
    +
    +    if ((encodedParams->len != ANSI_X962_CURVE_OID_TOTAL_LEN) &&
    +        (encodedParams->len != SECG_CURVE_OID_TOTAL_LEN)) {
    +            PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
    +            return SECFailure;
    +    };
    +
    +    oid.len = encodedParams->len - 2;
    +    oid.data = encodedParams->data + 2;
    +    if ((encodedParams->data[0] != SEC_ASN1_OBJECT_ID) ||
    +        ((tag = SECOID_FindOIDTag(&oid)) == ECCurve_noName)) {
    +            PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
    +            return SECFailure;
    +    }
    +
    +    params->arena = arena;
    +    params->cofactor = 0;
    +    params->type = ec_params_named;
    +    params->name = ECCurve_noName;
    +
    +    /* For named curves, fill out curveOID */
    +    params->curveOID.len = oid.len;
    +    params->curveOID.data = (unsigned char *) PORT_ArenaAlloc(NULL, oid.len,
    +        kmflag);
    +    if (params->curveOID.data == NULL) goto cleanup;
    +    memcpy(params->curveOID.data, oid.data, oid.len);
    +
    +#if EC_DEBUG
    +#ifndef SECOID_FindOIDTagDescription
    +    printf("Curve: %s\n", ecCurve_map[tag]->text);
    +#else
    +    printf("Curve: %s\n", SECOID_FindOIDTagDescription(tag));
    +#endif
    +#endif
    +
    +    switch (tag) {
    +
    +    /* Binary curves */
    +
    +    case ECCurve_X9_62_CHAR2_PNB163V1:
    +        /* Populate params for c2pnb163v1 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V1, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_X9_62_CHAR2_PNB163V2:
    +        /* Populate params for c2pnb163v2 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V2, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_X9_62_CHAR2_PNB163V3:
    +        /* Populate params for c2pnb163v3 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V3, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_X9_62_CHAR2_PNB176V1:
    +        /* Populate params for c2pnb176v1 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB176V1, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_X9_62_CHAR2_TNB191V1:
    +        /* Populate params for c2tnb191v1 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V1, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_X9_62_CHAR2_TNB191V2:
    +        /* Populate params for c2tnb191v2 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V2, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_X9_62_CHAR2_TNB191V3:
    +        /* Populate params for c2tnb191v3 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V3, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_X9_62_CHAR2_PNB208W1:
    +        /* Populate params for c2pnb208w1 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB208W1, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_X9_62_CHAR2_TNB239V1:
    +        /* Populate params for c2tnb239v1 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V1, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_X9_62_CHAR2_TNB239V2:
    +        /* Populate params for c2tnb239v2 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V2, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_X9_62_CHAR2_TNB239V3:
    +        /* Populate params for c2tnb239v3 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V3, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_X9_62_CHAR2_PNB272W1:
    +        /* Populate params for c2pnb272w1 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB272W1, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_X9_62_CHAR2_PNB304W1:
    +        /* Populate params for c2pnb304w1 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB304W1, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_X9_62_CHAR2_TNB359V1:
    +        /* Populate params for c2tnb359v1 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB359V1, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_X9_62_CHAR2_PNB368W1:
    +        /* Populate params for c2pnb368w1 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB368W1, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_X9_62_CHAR2_TNB431R1:
    +        /* Populate params for c2tnb431r1 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB431R1, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_SECG_CHAR2_113R1:
    +        /* Populate params for sect113r1 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_113R1, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_SECG_CHAR2_113R2:
    +        /* Populate params for sect113r2 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_113R2, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_SECG_CHAR2_131R1:
    +        /* Populate params for sect131r1 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_131R1, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_SECG_CHAR2_131R2:
    +        /* Populate params for sect131r2 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_131R2, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_SECG_CHAR2_163K1:
    +        /* Populate params for sect163k1
    +         * (the NIST K-163 curve)
    +         */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163K1, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_SECG_CHAR2_163R1:
    +        /* Populate params for sect163r1 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163R1, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_SECG_CHAR2_163R2:
    +        /* Populate params for sect163r2
    +         * (the NIST B-163 curve)
    +         */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163R2, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_SECG_CHAR2_193R1:
    +        /* Populate params for sect193r1 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_193R1, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_SECG_CHAR2_193R2:
    +        /* Populate params for sect193r2 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_193R2, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_SECG_CHAR2_233K1:
    +        /* Populate params for sect233k1
    +         * (the NIST K-233 curve)
    +         */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_233K1, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_SECG_CHAR2_233R1:
    +        /* Populate params for sect233r1
    +         * (the NIST B-233 curve)
    +         */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_233R1, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_SECG_CHAR2_239K1:
    +        /* Populate params for sect239k1 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_239K1, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_SECG_CHAR2_283K1:
    +        /* Populate params for sect283k1
    +         * (the NIST K-283 curve)
    +         */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_283K1, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_SECG_CHAR2_283R1:
    +        /* Populate params for sect283r1
    +         * (the NIST B-283 curve)
    +         */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_283R1, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_SECG_CHAR2_409K1:
    +        /* Populate params for sect409k1
    +         * (the NIST K-409 curve)
    +         */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_409K1, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_SECG_CHAR2_409R1:
    +        /* Populate params for sect409r1
    +         * (the NIST B-409 curve)
    +         */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_409R1, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_SECG_CHAR2_571K1:
    +        /* Populate params for sect571k1
    +         * (the NIST K-571 curve)
    +         */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_571K1, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_SECG_CHAR2_571R1:
    +        /* Populate params for sect571r1
    +         * (the NIST B-571 curve)
    +         */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_571R1, ec_field_GF2m,
    +            params, kmflag) );
    +        break;
    +
    +    /* Prime curves */
    +
    +    case ECCurve_X9_62_PRIME_192V1:
    +        /* Populate params for prime192v1 aka secp192r1
    +         * (the NIST P-192 curve)
    +         */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V1, ec_field_GFp,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_X9_62_PRIME_192V2:
    +        /* Populate params for prime192v2 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V2, ec_field_GFp,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_X9_62_PRIME_192V3:
    +        /* Populate params for prime192v3 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V3, ec_field_GFp,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_X9_62_PRIME_239V1:
    +        /* Populate params for prime239v1 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V1, ec_field_GFp,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_X9_62_PRIME_239V2:
    +        /* Populate params for prime239v2 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V2, ec_field_GFp,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_X9_62_PRIME_239V3:
    +        /* Populate params for prime239v3 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V3, ec_field_GFp,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_X9_62_PRIME_256V1:
    +        /* Populate params for prime256v1 aka secp256r1
    +         * (the NIST P-256 curve)
    +         */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_256V1, ec_field_GFp,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_SECG_PRIME_112R1:
    +        /* Populate params for secp112r1 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_112R1, ec_field_GFp,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_SECG_PRIME_112R2:
    +        /* Populate params for secp112r2 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_112R2, ec_field_GFp,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_SECG_PRIME_128R1:
    +        /* Populate params for secp128r1 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_128R1, ec_field_GFp,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_SECG_PRIME_128R2:
    +        /* Populate params for secp128r2 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_128R2, ec_field_GFp,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_SECG_PRIME_160K1:
    +        /* Populate params for secp160k1 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160K1, ec_field_GFp,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_SECG_PRIME_160R1:
    +        /* Populate params for secp160r1 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160R1, ec_field_GFp,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_SECG_PRIME_160R2:
    +        /* Populate params for secp160r1 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160R2, ec_field_GFp,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_SECG_PRIME_192K1:
    +        /* Populate params for secp192k1 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_192K1, ec_field_GFp,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_SECG_PRIME_224K1:
    +        /* Populate params for secp224k1 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_224K1, ec_field_GFp,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_SECG_PRIME_224R1:
    +        /* Populate params for secp224r1
    +         * (the NIST P-224 curve)
    +         */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_224R1, ec_field_GFp,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_SECG_PRIME_256K1:
    +        /* Populate params for secp256k1 */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_256K1, ec_field_GFp,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_SECG_PRIME_384R1:
    +        /* Populate params for secp384r1
    +         * (the NIST P-384 curve)
    +         */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_384R1, ec_field_GFp,
    +            params, kmflag) );
    +        break;
    +
    +    case ECCurve_SECG_PRIME_521R1:
    +        /* Populate params for secp521r1
    +         * (the NIST P-521 curve)
    +         */
    +        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_521R1, ec_field_GFp,
    +            params, kmflag) );
    +        break;
    +
    +    default:
    +        break;
    +    };
    +
    +cleanup:
    +    if (!params->cofactor) {
    +        PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
    +#if EC_DEBUG
    +        printf("Unrecognized curve, returning NULL params\n");
    +#endif
    +    }
    +
    +    return rv;
    +}
    +
    +SECStatus
    +EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams, int kmflag)
    +{
    +    PRArenaPool *arena;
    +    ECParams *params;
    +    SECStatus rv = SECFailure;
    +
    +    /* Initialize an arena for the ECParams structure */
    +    if (!(arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE)))
    +        return SECFailure;
    +
    +    params = (ECParams *)PORT_ArenaZAlloc(NULL, sizeof(ECParams), kmflag);
    +    if (!params) {
    +        PORT_FreeArena(NULL, B_TRUE);
    +        return SECFailure;
    +    }
    +
    +    /* Copy the encoded params */
    +    SECITEM_AllocItem(arena, &(params->DEREncoding), encodedParams->len,
    +        kmflag);
    +    memcpy(params->DEREncoding.data, encodedParams->data, encodedParams->len);
    +
    +    /* Fill out the rest of the ECParams structure based on
    +     * the encoded params
    +     */
    +    rv = EC_FillParams(NULL, encodedParams, params, kmflag);
    +    if (rv == SECFailure) {
    +        PORT_FreeArena(NULL, B_TRUE);
    +        return SECFailure;
    +    } else {
    +        *ecparams = params;;
    +        return SECSuccess;
    +    }
    +}
    diff --git a/jdk/src/share/native/sun/security/ec/ecl-curve.h b/jdk/src/share/native/sun/security/ec/ecl-curve.h
    new file mode 100644
    index 00000000000..bb7f9a7d466
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/ecl-curve.h
    @@ -0,0 +1,710 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the elliptic curve math library.
    + *
    + * The Initial Developer of the Original Code is
    + * Sun Microsystems, Inc.
    + * Portions created by the Initial Developer are Copyright (C) 2003
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Douglas Stebila , Sun Microsystems Laboratories
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#ifndef _ECL_CURVE_H
    +#define _ECL_CURVE_H
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +#include "ecl-exp.h"
    +#ifndef _KERNEL
    +#include 
    +#endif
    +
    +/* NIST prime curves */
    +static const ECCurveParams ecCurve_NIST_P192 = {
    +        "NIST-P192", ECField_GFp, 192,
    +        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
    +        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
    +        "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1",
    +        "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012",
    +        "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811",
    +        "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", 1
    +};
    +
    +static const ECCurveParams ecCurve_NIST_P224 = {
    +        "NIST-P224", ECField_GFp, 224,
    +        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
    +        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
    +        "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
    +        "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
    +        "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
    +        "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", 1
    +};
    +
    +static const ECCurveParams ecCurve_NIST_P256 = {
    +        "NIST-P256", ECField_GFp, 256,
    +        "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
    +        "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
    +        "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
    +        "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
    +        "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
    +        "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", 1
    +};
    +
    +static const ECCurveParams ecCurve_NIST_P384 = {
    +        "NIST-P384", ECField_GFp, 384,
    +        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF",
    +        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC",
    +        "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF",
    +        "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7",
    +        "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F",
    +        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973",
    +        1
    +};
    +
    +static const ECCurveParams ecCurve_NIST_P521 = {
    +        "NIST-P521", ECField_GFp, 521,
    +        "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
    +        "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC",
    +        "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
    +        "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",
    +        "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650",
    +        "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",
    +        1
    +};
    +
    +/* NIST binary curves */
    +static const ECCurveParams ecCurve_NIST_K163 = {
    +        "NIST-K163", ECField_GF2m, 163,
    +        "0800000000000000000000000000000000000000C9",
    +        "000000000000000000000000000000000000000001",
    +        "000000000000000000000000000000000000000001",
    +        "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
    +        "0289070FB05D38FF58321F2E800536D538CCDAA3D9",
    +        "04000000000000000000020108A2E0CC0D99F8A5EF", 2
    +};
    +
    +static const ECCurveParams ecCurve_NIST_B163 = {
    +        "NIST-B163", ECField_GF2m, 163,
    +        "0800000000000000000000000000000000000000C9",
    +        "000000000000000000000000000000000000000001",
    +        "020A601907B8C953CA1481EB10512F78744A3205FD",
    +        "03F0EBA16286A2D57EA0991168D4994637E8343E36",
    +        "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
    +        "040000000000000000000292FE77E70C12A4234C33", 2
    +};
    +
    +static const ECCurveParams ecCurve_NIST_K233 = {
    +        "NIST-K233", ECField_GF2m, 233,
    +        "020000000000000000000000000000000000000004000000000000000001",
    +        "000000000000000000000000000000000000000000000000000000000000",
    +        "000000000000000000000000000000000000000000000000000000000001",
    +        "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
    +        "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
    +        "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF", 4
    +};
    +
    +static const ECCurveParams ecCurve_NIST_B233 = {
    +        "NIST-B233", ECField_GF2m, 233,
    +        "020000000000000000000000000000000000000004000000000000000001",
    +        "000000000000000000000000000000000000000000000000000000000001",
    +        "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
    +        "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
    +        "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
    +        "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7", 2
    +};
    +
    +static const ECCurveParams ecCurve_NIST_K283 = {
    +        "NIST-K283", ECField_GF2m, 283,
    +        "0800000000000000000000000000000000000000000000000000000000000000000010A1",
    +        "000000000000000000000000000000000000000000000000000000000000000000000000",
    +        "000000000000000000000000000000000000000000000000000000000000000000000001",
    +        "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
    +        "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
    +        "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61", 4
    +};
    +
    +static const ECCurveParams ecCurve_NIST_B283 = {
    +        "NIST-B283", ECField_GF2m, 283,
    +        "0800000000000000000000000000000000000000000000000000000000000000000010A1",
    +        "000000000000000000000000000000000000000000000000000000000000000000000001",
    +        "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
    +        "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
    +        "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
    +        "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307", 2
    +};
    +
    +static const ECCurveParams ecCurve_NIST_K409 = {
    +        "NIST-K409", ECField_GF2m, 409,
    +        "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
    +        "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    +        "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
    +        "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
    +        "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
    +        "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF", 4
    +};
    +
    +static const ECCurveParams ecCurve_NIST_B409 = {
    +        "NIST-B409", ECField_GF2m, 409,
    +        "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
    +        "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
    +        "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
    +        "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
    +        "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
    +        "010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173", 2
    +};
    +
    +static const ECCurveParams ecCurve_NIST_K571 = {
    +        "NIST-K571", ECField_GF2m, 571,
    +        "080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
    +        "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    +        "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
    +        "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
    +        "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
    +        "020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001", 4
    +};
    +
    +static const ECCurveParams ecCurve_NIST_B571 = {
    +        "NIST-B571", ECField_GF2m, 571,
    +        "080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
    +        "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
    +        "02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
    +        "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
    +        "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
    +        "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47", 2
    +};
    +
    +/* ANSI X9.62 prime curves */
    +static const ECCurveParams ecCurve_X9_62_PRIME_192V2 = {
    +        "X9.62 P-192V2", ECField_GFp, 192,
    +        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
    +        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
    +        "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953",
    +        "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A",
    +        "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15",
    +        "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31", 1
    +};
    +
    +static const ECCurveParams ecCurve_X9_62_PRIME_192V3 = {
    +        "X9.62 P-192V3", ECField_GFp, 192,
    +        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
    +        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
    +        "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916",
    +        "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896",
    +        "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0",
    +        "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13", 1
    +};
    +
    +static const ECCurveParams ecCurve_X9_62_PRIME_239V1 = {
    +        "X9.62 P-239V1", ECField_GFp, 239,
    +        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
    +        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
    +        "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A",
    +        "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF",
    +        "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE",
    +        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B", 1
    +};
    +
    +static const ECCurveParams ecCurve_X9_62_PRIME_239V2 = {
    +        "X9.62 P-239V2", ECField_GFp, 239,
    +        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
    +        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
    +        "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C",
    +        "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7",
    +        "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA",
    +        "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063", 1
    +};
    +
    +static const ECCurveParams ecCurve_X9_62_PRIME_239V3 = {
    +        "X9.62 P-239V3", ECField_GFp, 239,
    +        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
    +        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
    +        "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E",
    +        "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A",
    +        "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3",
    +        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551", 1
    +};
    +
    +/* ANSI X9.62 binary curves */
    +static const ECCurveParams ecCurve_X9_62_CHAR2_PNB163V1 = {
    +        "X9.62 C2-PNB163V1", ECField_GF2m, 163,
    +        "080000000000000000000000000000000000000107",
    +        "072546B5435234A422E0789675F432C89435DE5242",
    +        "00C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9",
    +        "07AF69989546103D79329FCC3D74880F33BBE803CB",
    +        "01EC23211B5966ADEA1D3F87F7EA5848AEF0B7CA9F",
    +        "0400000000000000000001E60FC8821CC74DAEAFC1", 2
    +};
    +
    +static const ECCurveParams ecCurve_X9_62_CHAR2_PNB163V2 = {
    +        "X9.62 C2-PNB163V2", ECField_GF2m, 163,
    +        "080000000000000000000000000000000000000107",
    +        "0108B39E77C4B108BED981ED0E890E117C511CF072",
    +        "0667ACEB38AF4E488C407433FFAE4F1C811638DF20",
    +        "0024266E4EB5106D0A964D92C4860E2671DB9B6CC5",
    +        "079F684DDF6684C5CD258B3890021B2386DFD19FC5",
    +        "03FFFFFFFFFFFFFFFFFFFDF64DE1151ADBB78F10A7", 2
    +};
    +
    +static const ECCurveParams ecCurve_X9_62_CHAR2_PNB163V3 = {
    +        "X9.62 C2-PNB163V3", ECField_GF2m, 163,
    +        "080000000000000000000000000000000000000107",
    +        "07A526C63D3E25A256A007699F5447E32AE456B50E",
    +        "03F7061798EB99E238FD6F1BF95B48FEEB4854252B",
    +        "02F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB",
    +        "05B935590C155E17EA48EB3FF3718B893DF59A05D0",
    +        "03FFFFFFFFFFFFFFFFFFFE1AEE140F110AFF961309", 2
    +};
    +
    +static const ECCurveParams ecCurve_X9_62_CHAR2_PNB176V1 = {
    +        "X9.62 C2-PNB176V1", ECField_GF2m, 176,
    +        "0100000000000000000000000000000000080000000007",
    +        "E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B",
    +        "5DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2",
    +        "8D16C2866798B600F9F08BB4A8E860F3298CE04A5798",
    +        "6FA4539C2DADDDD6BAB5167D61B436E1D92BB16A562C",
    +        "00010092537397ECA4F6145799D62B0A19CE06FE26AD", 0xFF6E
    +};
    +
    +static const ECCurveParams ecCurve_X9_62_CHAR2_TNB191V1 = {
    +        "X9.62 C2-TNB191V1", ECField_GF2m, 191,
    +        "800000000000000000000000000000000000000000000201",
    +        "2866537B676752636A68F56554E12640276B649EF7526267",
    +        "2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC",
    +        "36B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D",
    +        "765BE73433B3F95E332932E70EA245CA2418EA0EF98018FB",
    +        "40000000000000000000000004A20E90C39067C893BBB9A5", 2
    +};
    +
    +static const ECCurveParams ecCurve_X9_62_CHAR2_TNB191V2 = {
    +        "X9.62 C2-TNB191V2", ECField_GF2m, 191,
    +        "800000000000000000000000000000000000000000000201",
    +        "401028774D7777C7B7666D1366EA432071274F89FF01E718",
    +        "0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01",
    +        "3809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10",
    +        "17434386626D14F3DBF01760D9213A3E1CF37AEC437D668A",
    +        "20000000000000000000000050508CB89F652824E06B8173", 4
    +};
    +
    +static const ECCurveParams ecCurve_X9_62_CHAR2_TNB191V3 = {
    +        "X9.62 C2-TNB191V3", ECField_GF2m, 191,
    +        "800000000000000000000000000000000000000000000201",
    +        "6C01074756099122221056911C77D77E77A777E7E7E77FCB",
    +        "71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8",
    +        "375D4CE24FDE434489DE8746E71786015009E66E38A926DD",
    +        "545A39176196575D985999366E6AD34CE0A77CD7127B06BE",
    +        "155555555555555555555555610C0B196812BFB6288A3EA3", 6
    +};
    +
    +static const ECCurveParams ecCurve_X9_62_CHAR2_PNB208W1 = {
    +        "X9.62 C2-PNB208W1", ECField_GF2m, 208,
    +        "010000000000000000000000000000000800000000000000000007",
    +        "0000000000000000000000000000000000000000000000000000",
    +        "C8619ED45A62E6212E1160349E2BFA844439FAFC2A3FD1638F9E",
    +        "89FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A",
    +        "0F55B51A06E78E9AC38A035FF520D8B01781BEB1A6BB08617DE3",
    +        "000101BAF95C9723C57B6C21DA2EFF2D5ED588BDD5717E212F9D", 0xFE48
    +};
    +
    +static const ECCurveParams ecCurve_X9_62_CHAR2_TNB239V1 = {
    +        "X9.62 C2-TNB239V1", ECField_GF2m, 239,
    +        "800000000000000000000000000000000000000000000000001000000001",
    +        "32010857077C5431123A46B808906756F543423E8D27877578125778AC76",
    +        "790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16",
    +        "57927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D",
    +        "61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305",
    +        "2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447", 4
    +};
    +
    +static const ECCurveParams ecCurve_X9_62_CHAR2_TNB239V2 = {
    +        "X9.62 C2-TNB239V2", ECField_GF2m, 239,
    +        "800000000000000000000000000000000000000000000000001000000001",
    +        "4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F",
    +        "5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B",
    +        "28F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205",
    +        "5667334C45AFF3B5A03BAD9DD75E2C71A99362567D5453F7FA6E227EC833",
    +        "1555555555555555555555555555553C6F2885259C31E3FCDF154624522D", 6
    +};
    +
    +static const ECCurveParams ecCurve_X9_62_CHAR2_TNB239V3 = {
    +        "X9.62 C2-TNB239V3", ECField_GF2m, 239,
    +        "800000000000000000000000000000000000000000000000001000000001",
    +        "01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F",
    +        "6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40",
    +        "70F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92",
    +        "2E5A0EAF6E5E1305B9004DCE5C0ED7FE59A35608F33837C816D80B79F461",
    +        "0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCAC4912D2D9DF903EF9888B8A0E4CFF", 0xA
    +};
    +
    +static const ECCurveParams ecCurve_X9_62_CHAR2_PNB272W1 = {
    +        "X9.62 C2-PNB272W1", ECField_GF2m, 272,
    +        "010000000000000000000000000000000000000000000000000000010000000000000B",
    +        "91A091F03B5FBA4AB2CCF49C4EDD220FB028712D42BE752B2C40094DBACDB586FB20",
    +        "7167EFC92BB2E3CE7C8AAAFF34E12A9C557003D7C73A6FAF003F99F6CC8482E540F7",
    +        "6108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D",
    +        "10C7695716851EEF6BA7F6872E6142FBD241B830FF5EFCACECCAB05E02005DDE9D23",
    +        "000100FAF51354E0E39E4892DF6E319C72C8161603FA45AA7B998A167B8F1E629521",
    +        0xFF06
    +};
    +
    +static const ECCurveParams ecCurve_X9_62_CHAR2_PNB304W1 = {
    +        "X9.62 C2-PNB304W1", ECField_GF2m, 304,
    +        "010000000000000000000000000000000000000000000000000000000000000000000000000807",
    +        "FD0D693149A118F651E6DCE6802085377E5F882D1B510B44160074C1288078365A0396C8E681",
    +        "BDDB97E555A50A908E43B01C798EA5DAA6788F1EA2794EFCF57166B8C14039601E55827340BE",
    +        "197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F740A2614",
    +        "E19FBEB76E0DA171517ECF401B50289BF014103288527A9B416A105E80260B549FDC1B92C03B",
    +        "000101D556572AABAC800101D556572AABAC8001022D5C91DD173F8FB561DA6899164443051D", 0xFE2E
    +};
    +
    +static const ECCurveParams ecCurve_X9_62_CHAR2_TNB359V1 = {
    +        "X9.62 C2-TNB359V1", ECField_GF2m, 359,
    +        "800000000000000000000000000000000000000000000000000000000000000000000000100000000000000001",
    +        "5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223A5E05656FB549016A96656A557",
    +        "2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC345626089687742B6329E70680231988",
    +        "3C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE98E8E707C07A2239B1B097",
    +        "53D7E08529547048121E9C95F3791DD804963948F34FAE7BF44EA82365DC7868FE57E4AE2DE211305A407104BD",
    +        "01AF286BCA1AF286BCA1AF286BCA1AF286BCA1AF286BC9FB8F6B85C556892C20A7EB964FE7719E74F490758D3B", 0x4C
    +};
    +
    +static const ECCurveParams ecCurve_X9_62_CHAR2_PNB368W1 = {
    +        "X9.62 C2-PNB368W1", ECField_GF2m, 368,
    +        "0100000000000000000000000000000000000000000000000000000000000000000000002000000000000000000007",
    +        "E0D2EE25095206F5E2A4F9ED229F1F256E79A0E2B455970D8D0D865BD94778C576D62F0AB7519CCD2A1A906AE30D",
    +        "FC1217D4320A90452C760A58EDCD30C8DD069B3C34453837A34ED50CB54917E1C2112D84D164F444F8F74786046A",
    +        "1085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E789E927BE216F02E1FB136A5F",
    +        "7B3EB1BDDCBA62D5D8B2059B525797FC73822C59059C623A45FF3843CEE8F87CD1855ADAA81E2A0750B80FDA2310",
    +        "00010090512DA9AF72B08349D98A5DD4C7B0532ECA51CE03E2D10F3B7AC579BD87E909AE40A6F131E9CFCE5BD967", 0xFF70
    +};
    +
    +static const ECCurveParams ecCurve_X9_62_CHAR2_TNB431R1 = {
    +        "X9.62 C2-TNB431R1", ECField_GF2m, 431,
    +        "800000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000001",
    +        "1A827EF00DD6FC0E234CAF046C6A5D8A85395B236CC4AD2CF32A0CADBDC9DDF620B0EB9906D0957F6C6FEACD615468DF104DE296CD8F",
    +        "10D9B4A3D9047D8B154359ABFB1B7F5485B04CEB868237DDC9DEDA982A679A5A919B626D4E50A8DD731B107A9962381FB5D807BF2618",
    +        "120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C21E7C5EFE965361F6C2999C0C247B0DBD70CE6B7",
    +        "20D0AF8903A96F8D5FA2C255745D3C451B302C9346D9B7E485E7BCE41F6B591F3E8F6ADDCBB0BC4C2F947A7DE1A89B625D6A598B3760",
    +        "0340340340340340340340340340340340340340340340340340340323C313FAB50589703B5EC68D3587FEC60D161CC149C1AD4A91", 0x2760
    +};
    +
    +/* SEC2 prime curves */
    +static const ECCurveParams ecCurve_SECG_PRIME_112R1 = {
    +        "SECP-112R1", ECField_GFp, 112,
    +        "DB7C2ABF62E35E668076BEAD208B",
    +        "DB7C2ABF62E35E668076BEAD2088",
    +        "659EF8BA043916EEDE8911702B22",
    +        "09487239995A5EE76B55F9C2F098",
    +        "A89CE5AF8724C0A23E0E0FF77500",
    +        "DB7C2ABF62E35E7628DFAC6561C5", 1
    +};
    +
    +static const ECCurveParams ecCurve_SECG_PRIME_112R2 = {
    +        "SECP-112R2", ECField_GFp, 112,
    +        "DB7C2ABF62E35E668076BEAD208B",
    +        "6127C24C05F38A0AAAF65C0EF02C",
    +        "51DEF1815DB5ED74FCC34C85D709",
    +        "4BA30AB5E892B4E1649DD0928643",
    +        "adcd46f5882e3747def36e956e97",
    +        "36DF0AAFD8B8D7597CA10520D04B", 4
    +};
    +
    +static const ECCurveParams ecCurve_SECG_PRIME_128R1 = {
    +        "SECP-128R1", ECField_GFp, 128,
    +        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
    +        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC",
    +        "E87579C11079F43DD824993C2CEE5ED3",
    +        "161FF7528B899B2D0C28607CA52C5B86",
    +        "CF5AC8395BAFEB13C02DA292DDED7A83",
    +        "FFFFFFFE0000000075A30D1B9038A115", 1
    +};
    +
    +static const ECCurveParams ecCurve_SECG_PRIME_128R2 = {
    +        "SECP-128R2", ECField_GFp, 128,
    +        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
    +        "D6031998D1B3BBFEBF59CC9BBFF9AEE1",
    +        "5EEEFCA380D02919DC2C6558BB6D8A5D",
    +        "7B6AA5D85E572983E6FB32A7CDEBC140",
    +        "27B6916A894D3AEE7106FE805FC34B44",
    +        "3FFFFFFF7FFFFFFFBE0024720613B5A3", 4
    +};
    +
    +static const ECCurveParams ecCurve_SECG_PRIME_160K1 = {
    +        "SECP-160K1", ECField_GFp, 160,
    +        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73",
    +        "0000000000000000000000000000000000000000",
    +        "0000000000000000000000000000000000000007",
    +        "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB",
    +        "938CF935318FDCED6BC28286531733C3F03C4FEE",
    +        "0100000000000000000001B8FA16DFAB9ACA16B6B3", 1
    +};
    +
    +static const ECCurveParams ecCurve_SECG_PRIME_160R1 = {
    +        "SECP-160R1", ECField_GFp, 160,
    +        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF",
    +        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC",
    +        "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45",
    +        "4A96B5688EF573284664698968C38BB913CBFC82",
    +        "23A628553168947D59DCC912042351377AC5FB32",
    +        "0100000000000000000001F4C8F927AED3CA752257", 1
    +};
    +
    +static const ECCurveParams ecCurve_SECG_PRIME_160R2 = {
    +        "SECP-160R2", ECField_GFp, 160,
    +        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73",
    +        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70",
    +        "B4E134D3FB59EB8BAB57274904664D5AF50388BA",
    +        "52DCB034293A117E1F4FF11B30F7199D3144CE6D",
    +        "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E",
    +        "0100000000000000000000351EE786A818F3A1A16B", 1
    +};
    +
    +static const ECCurveParams ecCurve_SECG_PRIME_192K1 = {
    +        "SECP-192K1", ECField_GFp, 192,
    +        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37",
    +        "000000000000000000000000000000000000000000000000",
    +        "000000000000000000000000000000000000000000000003",
    +        "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D",
    +        "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D",
    +        "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", 1
    +};
    +
    +static const ECCurveParams ecCurve_SECG_PRIME_224K1 = {
    +        "SECP-224K1", ECField_GFp, 224,
    +        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D",
    +        "00000000000000000000000000000000000000000000000000000000",
    +        "00000000000000000000000000000000000000000000000000000005",
    +        "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C",
    +        "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5",
    +        "010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7", 1
    +};
    +
    +static const ECCurveParams ecCurve_SECG_PRIME_256K1 = {
    +        "SECP-256K1", ECField_GFp, 256,
    +        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F",
    +        "0000000000000000000000000000000000000000000000000000000000000000",
    +        "0000000000000000000000000000000000000000000000000000000000000007",
    +        "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798",
    +        "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8",
    +        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 1
    +};
    +
    +/* SEC2 binary curves */
    +static const ECCurveParams ecCurve_SECG_CHAR2_113R1 = {
    +        "SECT-113R1", ECField_GF2m, 113,
    +        "020000000000000000000000000201",
    +        "003088250CA6E7C7FE649CE85820F7",
    +        "00E8BEE4D3E2260744188BE0E9C723",
    +        "009D73616F35F4AB1407D73562C10F",
    +        "00A52830277958EE84D1315ED31886",
    +        "0100000000000000D9CCEC8A39E56F", 2
    +};
    +
    +static const ECCurveParams ecCurve_SECG_CHAR2_113R2 = {
    +        "SECT-113R2", ECField_GF2m, 113,
    +        "020000000000000000000000000201",
    +        "00689918DBEC7E5A0DD6DFC0AA55C7",
    +        "0095E9A9EC9B297BD4BF36E059184F",
    +        "01A57A6A7B26CA5EF52FCDB8164797",
    +        "00B3ADC94ED1FE674C06E695BABA1D",
    +        "010000000000000108789B2496AF93", 2
    +};
    +
    +static const ECCurveParams ecCurve_SECG_CHAR2_131R1 = {
    +        "SECT-131R1", ECField_GF2m, 131,
    +        "080000000000000000000000000000010D",
    +        "07A11B09A76B562144418FF3FF8C2570B8",
    +        "0217C05610884B63B9C6C7291678F9D341",
    +        "0081BAF91FDF9833C40F9C181343638399",
    +        "078C6E7EA38C001F73C8134B1B4EF9E150",
    +        "0400000000000000023123953A9464B54D", 2
    +};
    +
    +static const ECCurveParams ecCurve_SECG_CHAR2_131R2 = {
    +        "SECT-131R2", ECField_GF2m, 131,
    +        "080000000000000000000000000000010D",
    +        "03E5A88919D7CAFCBF415F07C2176573B2",
    +        "04B8266A46C55657AC734CE38F018F2192",
    +        "0356DCD8F2F95031AD652D23951BB366A8",
    +        "0648F06D867940A5366D9E265DE9EB240F",
    +        "0400000000000000016954A233049BA98F", 2
    +};
    +
    +static const ECCurveParams ecCurve_SECG_CHAR2_163R1 = {
    +        "SECT-163R1", ECField_GF2m, 163,
    +        "0800000000000000000000000000000000000000C9",
    +        "07B6882CAAEFA84F9554FF8428BD88E246D2782AE2",
    +        "0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9",
    +        "0369979697AB43897789566789567F787A7876A654",
    +        "00435EDB42EFAFB2989D51FEFCE3C80988F41FF883",
    +        "03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B", 2
    +};
    +
    +static const ECCurveParams ecCurve_SECG_CHAR2_193R1 = {
    +        "SECT-193R1", ECField_GF2m, 193,
    +        "02000000000000000000000000000000000000000000008001",
    +        "0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01",
    +        "00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814",
    +        "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1",
    +        "0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05",
    +        "01000000000000000000000000C7F34A778F443ACC920EBA49", 2
    +};
    +
    +static const ECCurveParams ecCurve_SECG_CHAR2_193R2 = {
    +        "SECT-193R2", ECField_GF2m, 193,
    +        "02000000000000000000000000000000000000000000008001",
    +        "0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B",
    +        "00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE",
    +        "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F",
    +        "01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C",
    +        "010000000000000000000000015AAB561B005413CCD4EE99D5", 2
    +};
    +
    +static const ECCurveParams ecCurve_SECG_CHAR2_239K1 = {
    +        "SECT-239K1", ECField_GF2m, 239,
    +        "800000000000000000004000000000000000000000000000000000000001",
    +        "000000000000000000000000000000000000000000000000000000000000",
    +        "000000000000000000000000000000000000000000000000000000000001",
    +        "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC",
    +        "76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA",
    +        "2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5", 4
    +};
    +
    +/* WTLS curves */
    +static const ECCurveParams ecCurve_WTLS_1 = {
    +        "WTLS-1", ECField_GF2m, 113,
    +        "020000000000000000000000000201",
    +        "000000000000000000000000000001",
    +        "000000000000000000000000000001",
    +        "01667979A40BA497E5D5C270780617",
    +        "00F44B4AF1ECC2630E08785CEBCC15",
    +        "00FFFFFFFFFFFFFFFDBF91AF6DEA73", 2
    +};
    +
    +static const ECCurveParams ecCurve_WTLS_8 = {
    +        "WTLS-8", ECField_GFp, 112,
    +        "FFFFFFFFFFFFFFFFFFFFFFFFFDE7",
    +        "0000000000000000000000000000",
    +        "0000000000000000000000000003",
    +        "0000000000000000000000000001",
    +        "0000000000000000000000000002",
    +        "0100000000000001ECEA551AD837E9", 1
    +};
    +
    +static const ECCurveParams ecCurve_WTLS_9 = {
    +        "WTLS-9", ECField_GFp, 160,
    +        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC808F",
    +        "0000000000000000000000000000000000000000",
    +        "0000000000000000000000000000000000000003",
    +        "0000000000000000000000000000000000000001",
    +        "0000000000000000000000000000000000000002",
    +        "0100000000000000000001CDC98AE0E2DE574ABF33", 1
    +};
    +
    +/* mapping between ECCurveName enum and pointers to ECCurveParams */
    +static const ECCurveParams *ecCurve_map[] = {
    +    NULL,                               /* ECCurve_noName */
    +    &ecCurve_NIST_P192,                 /* ECCurve_NIST_P192 */
    +    &ecCurve_NIST_P224,                 /* ECCurve_NIST_P224 */
    +    &ecCurve_NIST_P256,                 /* ECCurve_NIST_P256 */
    +    &ecCurve_NIST_P384,                 /* ECCurve_NIST_P384 */
    +    &ecCurve_NIST_P521,                 /* ECCurve_NIST_P521 */
    +    &ecCurve_NIST_K163,                 /* ECCurve_NIST_K163 */
    +    &ecCurve_NIST_B163,                 /* ECCurve_NIST_B163 */
    +    &ecCurve_NIST_K233,                 /* ECCurve_NIST_K233 */
    +    &ecCurve_NIST_B233,                 /* ECCurve_NIST_B233 */
    +    &ecCurve_NIST_K283,                 /* ECCurve_NIST_K283 */
    +    &ecCurve_NIST_B283,                 /* ECCurve_NIST_B283 */
    +    &ecCurve_NIST_K409,                 /* ECCurve_NIST_K409 */
    +    &ecCurve_NIST_B409,                 /* ECCurve_NIST_B409 */
    +    &ecCurve_NIST_K571,                 /* ECCurve_NIST_K571 */
    +    &ecCurve_NIST_B571,                 /* ECCurve_NIST_B571 */
    +    &ecCurve_X9_62_PRIME_192V2,         /* ECCurve_X9_62_PRIME_192V2 */
    +    &ecCurve_X9_62_PRIME_192V3,         /* ECCurve_X9_62_PRIME_192V3 */
    +    &ecCurve_X9_62_PRIME_239V1,         /* ECCurve_X9_62_PRIME_239V1 */
    +    &ecCurve_X9_62_PRIME_239V2,         /* ECCurve_X9_62_PRIME_239V2 */
    +    &ecCurve_X9_62_PRIME_239V3,         /* ECCurve_X9_62_PRIME_239V3 */
    +    &ecCurve_X9_62_CHAR2_PNB163V1,      /* ECCurve_X9_62_CHAR2_PNB163V1 */
    +    &ecCurve_X9_62_CHAR2_PNB163V2,      /* ECCurve_X9_62_CHAR2_PNB163V2 */
    +    &ecCurve_X9_62_CHAR2_PNB163V3,      /* ECCurve_X9_62_CHAR2_PNB163V3 */
    +    &ecCurve_X9_62_CHAR2_PNB176V1,      /* ECCurve_X9_62_CHAR2_PNB176V1 */
    +    &ecCurve_X9_62_CHAR2_TNB191V1,      /* ECCurve_X9_62_CHAR2_TNB191V1 */
    +    &ecCurve_X9_62_CHAR2_TNB191V2,      /* ECCurve_X9_62_CHAR2_TNB191V2 */
    +    &ecCurve_X9_62_CHAR2_TNB191V3,      /* ECCurve_X9_62_CHAR2_TNB191V3 */
    +    &ecCurve_X9_62_CHAR2_PNB208W1,      /* ECCurve_X9_62_CHAR2_PNB208W1 */
    +    &ecCurve_X9_62_CHAR2_TNB239V1,      /* ECCurve_X9_62_CHAR2_TNB239V1 */
    +    &ecCurve_X9_62_CHAR2_TNB239V2,      /* ECCurve_X9_62_CHAR2_TNB239V2 */
    +    &ecCurve_X9_62_CHAR2_TNB239V3,      /* ECCurve_X9_62_CHAR2_TNB239V3 */
    +    &ecCurve_X9_62_CHAR2_PNB272W1,      /* ECCurve_X9_62_CHAR2_PNB272W1 */
    +    &ecCurve_X9_62_CHAR2_PNB304W1,      /* ECCurve_X9_62_CHAR2_PNB304W1 */
    +    &ecCurve_X9_62_CHAR2_TNB359V1,      /* ECCurve_X9_62_CHAR2_TNB359V1 */
    +    &ecCurve_X9_62_CHAR2_PNB368W1,      /* ECCurve_X9_62_CHAR2_PNB368W1 */
    +    &ecCurve_X9_62_CHAR2_TNB431R1,      /* ECCurve_X9_62_CHAR2_TNB431R1 */
    +    &ecCurve_SECG_PRIME_112R1,          /* ECCurve_SECG_PRIME_112R1 */
    +    &ecCurve_SECG_PRIME_112R2,          /* ECCurve_SECG_PRIME_112R2 */
    +    &ecCurve_SECG_PRIME_128R1,          /* ECCurve_SECG_PRIME_128R1 */
    +    &ecCurve_SECG_PRIME_128R2,          /* ECCurve_SECG_PRIME_128R2 */
    +    &ecCurve_SECG_PRIME_160K1,          /* ECCurve_SECG_PRIME_160K1 */
    +    &ecCurve_SECG_PRIME_160R1,          /* ECCurve_SECG_PRIME_160R1 */
    +    &ecCurve_SECG_PRIME_160R2,          /* ECCurve_SECG_PRIME_160R2 */
    +    &ecCurve_SECG_PRIME_192K1,          /* ECCurve_SECG_PRIME_192K1 */
    +    &ecCurve_SECG_PRIME_224K1,          /* ECCurve_SECG_PRIME_224K1 */
    +    &ecCurve_SECG_PRIME_256K1,          /* ECCurve_SECG_PRIME_256K1 */
    +    &ecCurve_SECG_CHAR2_113R1,          /* ECCurve_SECG_CHAR2_113R1 */
    +    &ecCurve_SECG_CHAR2_113R2,          /* ECCurve_SECG_CHAR2_113R2 */
    +    &ecCurve_SECG_CHAR2_131R1,          /* ECCurve_SECG_CHAR2_131R1 */
    +    &ecCurve_SECG_CHAR2_131R2,          /* ECCurve_SECG_CHAR2_131R2 */
    +    &ecCurve_SECG_CHAR2_163R1,          /* ECCurve_SECG_CHAR2_163R1 */
    +    &ecCurve_SECG_CHAR2_193R1,          /* ECCurve_SECG_CHAR2_193R1 */
    +    &ecCurve_SECG_CHAR2_193R2,          /* ECCurve_SECG_CHAR2_193R2 */
    +    &ecCurve_SECG_CHAR2_239K1,          /* ECCurve_SECG_CHAR2_239K1 */
    +    &ecCurve_WTLS_1,                    /* ECCurve_WTLS_1 */
    +    &ecCurve_WTLS_8,                    /* ECCurve_WTLS_8 */
    +    &ecCurve_WTLS_9,                    /* ECCurve_WTLS_9 */
    +    NULL                                /* ECCurve_pastLastCurve */
    +};
    +
    +#endif /* _ECL_CURVE_H */
    diff --git a/jdk/src/share/native/sun/security/ec/ecl-exp.h b/jdk/src/share/native/sun/security/ec/ecl-exp.h
    new file mode 100644
    index 00000000000..ce9a2cf803c
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/ecl-exp.h
    @@ -0,0 +1,216 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the elliptic curve math library.
    + *
    + * The Initial Developer of the Original Code is
    + * Sun Microsystems, Inc.
    + * Portions created by the Initial Developer are Copyright (C) 2003
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Douglas Stebila , Sun Microsystems Laboratories
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#ifndef _ECL_EXP_H
    +#define _ECL_EXP_H
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +/* Curve field type */
    +typedef enum {
    +        ECField_GFp,
    +        ECField_GF2m
    +} ECField;
    +
    +/* Hexadecimal encoding of curve parameters */
    +struct ECCurveParamsStr {
    +        char *text;
    +        ECField field;
    +        unsigned int size;
    +        char *irr;
    +        char *curvea;
    +        char *curveb;
    +        char *genx;
    +        char *geny;
    +        char *order;
    +        int cofactor;
    +};
    +typedef struct ECCurveParamsStr ECCurveParams;
    +
    +/* Named curve parameters */
    +typedef enum {
    +
    +        ECCurve_noName = 0,
    +
    +        /* NIST prime curves */
    +        ECCurve_NIST_P192,
    +        ECCurve_NIST_P224,
    +        ECCurve_NIST_P256,
    +        ECCurve_NIST_P384,
    +        ECCurve_NIST_P521,
    +
    +        /* NIST binary curves */
    +        ECCurve_NIST_K163,
    +        ECCurve_NIST_B163,
    +        ECCurve_NIST_K233,
    +        ECCurve_NIST_B233,
    +        ECCurve_NIST_K283,
    +        ECCurve_NIST_B283,
    +        ECCurve_NIST_K409,
    +        ECCurve_NIST_B409,
    +        ECCurve_NIST_K571,
    +        ECCurve_NIST_B571,
    +
    +        /* ANSI X9.62 prime curves */
    +        /* ECCurve_X9_62_PRIME_192V1 == ECCurve_NIST_P192 */
    +        ECCurve_X9_62_PRIME_192V2,
    +        ECCurve_X9_62_PRIME_192V3,
    +        ECCurve_X9_62_PRIME_239V1,
    +        ECCurve_X9_62_PRIME_239V2,
    +        ECCurve_X9_62_PRIME_239V3,
    +        /* ECCurve_X9_62_PRIME_256V1 == ECCurve_NIST_P256 */
    +
    +        /* ANSI X9.62 binary curves */
    +        ECCurve_X9_62_CHAR2_PNB163V1,
    +        ECCurve_X9_62_CHAR2_PNB163V2,
    +        ECCurve_X9_62_CHAR2_PNB163V3,
    +        ECCurve_X9_62_CHAR2_PNB176V1,
    +        ECCurve_X9_62_CHAR2_TNB191V1,
    +        ECCurve_X9_62_CHAR2_TNB191V2,
    +        ECCurve_X9_62_CHAR2_TNB191V3,
    +        ECCurve_X9_62_CHAR2_PNB208W1,
    +        ECCurve_X9_62_CHAR2_TNB239V1,
    +        ECCurve_X9_62_CHAR2_TNB239V2,
    +        ECCurve_X9_62_CHAR2_TNB239V3,
    +        ECCurve_X9_62_CHAR2_PNB272W1,
    +        ECCurve_X9_62_CHAR2_PNB304W1,
    +        ECCurve_X9_62_CHAR2_TNB359V1,
    +        ECCurve_X9_62_CHAR2_PNB368W1,
    +        ECCurve_X9_62_CHAR2_TNB431R1,
    +
    +        /* SEC2 prime curves */
    +        ECCurve_SECG_PRIME_112R1,
    +        ECCurve_SECG_PRIME_112R2,
    +        ECCurve_SECG_PRIME_128R1,
    +        ECCurve_SECG_PRIME_128R2,
    +        ECCurve_SECG_PRIME_160K1,
    +        ECCurve_SECG_PRIME_160R1,
    +        ECCurve_SECG_PRIME_160R2,
    +        ECCurve_SECG_PRIME_192K1,
    +        /* ECCurve_SECG_PRIME_192R1 == ECCurve_NIST_P192 */
    +        ECCurve_SECG_PRIME_224K1,
    +        /* ECCurve_SECG_PRIME_224R1 == ECCurve_NIST_P224 */
    +        ECCurve_SECG_PRIME_256K1,
    +        /* ECCurve_SECG_PRIME_256R1 == ECCurve_NIST_P256 */
    +        /* ECCurve_SECG_PRIME_384R1 == ECCurve_NIST_P384 */
    +        /* ECCurve_SECG_PRIME_521R1 == ECCurve_NIST_P521 */
    +
    +        /* SEC2 binary curves */
    +        ECCurve_SECG_CHAR2_113R1,
    +        ECCurve_SECG_CHAR2_113R2,
    +        ECCurve_SECG_CHAR2_131R1,
    +        ECCurve_SECG_CHAR2_131R2,
    +        /* ECCurve_SECG_CHAR2_163K1 == ECCurve_NIST_K163 */
    +        ECCurve_SECG_CHAR2_163R1,
    +        /* ECCurve_SECG_CHAR2_163R2 == ECCurve_NIST_B163 */
    +        ECCurve_SECG_CHAR2_193R1,
    +        ECCurve_SECG_CHAR2_193R2,
    +        /* ECCurve_SECG_CHAR2_233K1 == ECCurve_NIST_K233 */
    +        /* ECCurve_SECG_CHAR2_233R1 == ECCurve_NIST_B233 */
    +        ECCurve_SECG_CHAR2_239K1,
    +        /* ECCurve_SECG_CHAR2_283K1 == ECCurve_NIST_K283 */
    +        /* ECCurve_SECG_CHAR2_283R1 == ECCurve_NIST_B283 */
    +        /* ECCurve_SECG_CHAR2_409K1 == ECCurve_NIST_K409 */
    +        /* ECCurve_SECG_CHAR2_409R1 == ECCurve_NIST_B409 */
    +        /* ECCurve_SECG_CHAR2_571K1 == ECCurve_NIST_K571 */
    +        /* ECCurve_SECG_CHAR2_571R1 == ECCurve_NIST_B571 */
    +
    +        /* WTLS curves */
    +        ECCurve_WTLS_1,
    +        /* there is no WTLS 2 curve */
    +        /* ECCurve_WTLS_3 == ECCurve_NIST_K163 */
    +        /* ECCurve_WTLS_4 == ECCurve_SECG_CHAR2_113R1 */
    +        /* ECCurve_WTLS_5 == ECCurve_X9_62_CHAR2_PNB163V1 */
    +        /* ECCurve_WTLS_6 == ECCurve_SECG_PRIME_112R1 */
    +        /* ECCurve_WTLS_7 == ECCurve_SECG_PRIME_160R1 */
    +        ECCurve_WTLS_8,
    +        ECCurve_WTLS_9,
    +        /* ECCurve_WTLS_10 == ECCurve_NIST_K233 */
    +        /* ECCurve_WTLS_11 == ECCurve_NIST_B233 */
    +        /* ECCurve_WTLS_12 == ECCurve_NIST_P224 */
    +
    +        ECCurve_pastLastCurve
    +} ECCurveName;
    +
    +/* Aliased named curves */
    +
    +#define ECCurve_X9_62_PRIME_192V1 ECCurve_NIST_P192
    +#define ECCurve_X9_62_PRIME_256V1 ECCurve_NIST_P256
    +#define ECCurve_SECG_PRIME_192R1 ECCurve_NIST_P192
    +#define ECCurve_SECG_PRIME_224R1 ECCurve_NIST_P224
    +#define ECCurve_SECG_PRIME_256R1 ECCurve_NIST_P256
    +#define ECCurve_SECG_PRIME_384R1 ECCurve_NIST_P384
    +#define ECCurve_SECG_PRIME_521R1 ECCurve_NIST_P521
    +#define ECCurve_SECG_CHAR2_163K1 ECCurve_NIST_K163
    +#define ECCurve_SECG_CHAR2_163R2 ECCurve_NIST_B163
    +#define ECCurve_SECG_CHAR2_233K1 ECCurve_NIST_K233
    +#define ECCurve_SECG_CHAR2_233R1 ECCurve_NIST_B233
    +#define ECCurve_SECG_CHAR2_283K1 ECCurve_NIST_K283
    +#define ECCurve_SECG_CHAR2_283R1 ECCurve_NIST_B283
    +#define ECCurve_SECG_CHAR2_409K1 ECCurve_NIST_K409
    +#define ECCurve_SECG_CHAR2_409R1 ECCurve_NIST_B409
    +#define ECCurve_SECG_CHAR2_571K1 ECCurve_NIST_K571
    +#define ECCurve_SECG_CHAR2_571R1 ECCurve_NIST_B571
    +#define ECCurve_WTLS_3 ECCurve_NIST_K163
    +#define ECCurve_WTLS_4 ECCurve_SECG_CHAR2_113R1
    +#define ECCurve_WTLS_5 ECCurve_X9_62_CHAR2_PNB163V1
    +#define ECCurve_WTLS_6 ECCurve_SECG_PRIME_112R1
    +#define ECCurve_WTLS_7 ECCurve_SECG_PRIME_160R1
    +#define ECCurve_WTLS_10 ECCurve_NIST_K233
    +#define ECCurve_WTLS_11 ECCurve_NIST_B233
    +#define ECCurve_WTLS_12 ECCurve_NIST_P224
    +
    +#endif /* _ECL_EXP_H */
    diff --git a/jdk/src/share/native/sun/security/ec/ecl-priv.h b/jdk/src/share/native/sun/security/ec/ecl-priv.h
    new file mode 100644
    index 00000000000..12caaf70577
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/ecl-priv.h
    @@ -0,0 +1,304 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the elliptic curve math library.
    + *
    + * The Initial Developer of the Original Code is
    + * Sun Microsystems, Inc.
    + * Portions created by the Initial Developer are Copyright (C) 2003
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Stephen Fung  and
    + *   Douglas Stebila , Sun Microsystems Laboratories
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#ifndef _ECL_PRIV_H
    +#define _ECL_PRIV_H
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +#include "ecl.h"
    +#include "mpi.h"
    +#include "mplogic.h"
    +
    +/* MAX_FIELD_SIZE_DIGITS is the maximum size of field element supported */
    +/* the following needs to go away... */
    +#if defined(MP_USE_LONG_LONG_DIGIT) || defined(MP_USE_LONG_DIGIT)
    +#define ECL_SIXTY_FOUR_BIT
    +#else
    +#define ECL_THIRTY_TWO_BIT
    +#endif
    +
    +#define ECL_CURVE_DIGITS(curve_size_in_bits) \
    +        (((curve_size_in_bits)+(sizeof(mp_digit)*8-1))/(sizeof(mp_digit)*8))
    +#define ECL_BITS (sizeof(mp_digit)*8)
    +#define ECL_MAX_FIELD_SIZE_DIGITS (80/sizeof(mp_digit))
    +
    +/* Gets the i'th bit in the binary representation of a. If i >= length(a),
    + * then return 0. (The above behaviour differs from mpl_get_bit, which
    + * causes an error if i >= length(a).) */
    +#define MP_GET_BIT(a, i) \
    +        ((i) >= mpl_significant_bits((a))) ? 0 : mpl_get_bit((a), (i))
    +
    +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
    +#define MP_ADD_CARRY(a1, a2, s, cin, cout)   \
    +    { mp_word w; \
    +    w = ((mp_word)(cin)) + (a1) + (a2); \
    +    s = ACCUM(w); \
    +    cout = CARRYOUT(w); }
    +
    +#define MP_SUB_BORROW(a1, a2, s, bin, bout)   \
    +    { mp_word w; \
    +    w = ((mp_word)(a1)) - (a2) - (bin); \
    +    s = ACCUM(w); \
    +    bout = (w >> MP_DIGIT_BIT) & 1; }
    +
    +#else
    +/* NOTE,
    + * cin and cout could be the same variable.
    + * bin and bout could be the same variable.
    + * a1 or a2 and s could be the same variable.
    + * don't trash those outputs until their respective inputs have
    + * been read. */
    +#define MP_ADD_CARRY(a1, a2, s, cin, cout)   \
    +    { mp_digit tmp,sum; \
    +    tmp = (a1); \
    +    sum = tmp + (a2); \
    +    tmp = (sum < tmp);                     /* detect overflow */ \
    +    s = sum += (cin); \
    +    cout = tmp + (sum < (cin)); }
    +
    +#define MP_SUB_BORROW(a1, a2, s, bin, bout)   \
    +    { mp_digit tmp; \
    +    tmp = (a1); \
    +    s = tmp - (a2); \
    +    tmp = (s > tmp);                    /* detect borrow */ \
    +    if ((bin) && !s--) tmp++;   \
    +    bout = tmp; }
    +#endif
    +
    +
    +struct GFMethodStr;
    +typedef struct GFMethodStr GFMethod;
    +struct GFMethodStr {
    +        /* Indicates whether the structure was constructed from dynamic memory
    +         * or statically created. */
    +        int constructed;
    +        /* Irreducible that defines the field. For prime fields, this is the
    +         * prime p. For binary polynomial fields, this is the bitstring
    +         * representation of the irreducible polynomial. */
    +        mp_int irr;
    +        /* For prime fields, the value irr_arr[0] is the number of bits in the
    +         * field. For binary polynomial fields, the irreducible polynomial
    +         * f(t) is represented as an array of unsigned int[], where f(t) is
    +         * of the form: f(t) = t^p[0] + t^p[1] + ... + t^p[4] where m = p[0]
    +         * > p[1] > ... > p[4] = 0. */
    +        unsigned int irr_arr[5];
    +        /* Field arithmetic methods. All methods (except field_enc and
    +         * field_dec) are assumed to take field-encoded parameters and return
    +         * field-encoded values. All methods (except field_enc and field_dec)
    +         * are required to be implemented. */
    +        mp_err (*field_add) (const mp_int *a, const mp_int *b, mp_int *r,
    +                                                 const GFMethod *meth);
    +        mp_err (*field_neg) (const mp_int *a, mp_int *r, const GFMethod *meth);
    +        mp_err (*field_sub) (const mp_int *a, const mp_int *b, mp_int *r,
    +                                                 const GFMethod *meth);
    +        mp_err (*field_mod) (const mp_int *a, mp_int *r, const GFMethod *meth);
    +        mp_err (*field_mul) (const mp_int *a, const mp_int *b, mp_int *r,
    +                                                 const GFMethod *meth);
    +        mp_err (*field_sqr) (const mp_int *a, mp_int *r, const GFMethod *meth);
    +        mp_err (*field_div) (const mp_int *a, const mp_int *b, mp_int *r,
    +                                                 const GFMethod *meth);
    +        mp_err (*field_enc) (const mp_int *a, mp_int *r, const GFMethod *meth);
    +        mp_err (*field_dec) (const mp_int *a, mp_int *r, const GFMethod *meth);
    +        /* Extra storage for implementation-specific data.  Any memory
    +         * allocated to these extra fields will be cleared by extra_free. */
    +        void *extra1;
    +        void *extra2;
    +        void (*extra_free) (GFMethod *meth);
    +};
    +
    +/* Construct generic GFMethods. */
    +GFMethod *GFMethod_consGFp(const mp_int *irr);
    +GFMethod *GFMethod_consGFp_mont(const mp_int *irr);
    +GFMethod *GFMethod_consGF2m(const mp_int *irr,
    +                                                        const unsigned int irr_arr[5]);
    +/* Free the memory allocated (if any) to a GFMethod object. */
    +void GFMethod_free(GFMethod *meth);
    +
    +struct ECGroupStr {
    +        /* Indicates whether the structure was constructed from dynamic memory
    +         * or statically created. */
    +        int constructed;
    +        /* Field definition and arithmetic. */
    +        GFMethod *meth;
    +        /* Textual representation of curve name, if any. */
    +        char *text;
    +#ifdef _KERNEL
    +        int text_len;
    +#endif
    +        /* Curve parameters, field-encoded. */
    +        mp_int curvea, curveb;
    +        /* x and y coordinates of the base point, field-encoded. */
    +        mp_int genx, geny;
    +        /* Order and cofactor of the base point. */
    +        mp_int order;
    +        int cofactor;
    +        /* Point arithmetic methods. All methods are assumed to take
    +         * field-encoded parameters and return field-encoded values. All
    +         * methods (except base_point_mul and points_mul) are required to be
    +         * implemented. */
    +        mp_err (*point_add) (const mp_int *px, const mp_int *py,
    +                                                 const mp_int *qx, const mp_int *qy, mp_int *rx,
    +                                                 mp_int *ry, const ECGroup *group);
    +        mp_err (*point_sub) (const mp_int *px, const mp_int *py,
    +                                                 const mp_int *qx, const mp_int *qy, mp_int *rx,
    +                                                 mp_int *ry, const ECGroup *group);
    +        mp_err (*point_dbl) (const mp_int *px, const mp_int *py, mp_int *rx,
    +                                                 mp_int *ry, const ECGroup *group);
    +        mp_err (*point_mul) (const mp_int *n, const mp_int *px,
    +                                                 const mp_int *py, mp_int *rx, mp_int *ry,
    +                                                 const ECGroup *group);
    +        mp_err (*base_point_mul) (const mp_int *n, mp_int *rx, mp_int *ry,
    +                                                          const ECGroup *group);
    +        mp_err (*points_mul) (const mp_int *k1, const mp_int *k2,
    +                                                  const mp_int *px, const mp_int *py, mp_int *rx,
    +                                                  mp_int *ry, const ECGroup *group);
    +        mp_err (*validate_point) (const mp_int *px, const mp_int *py, const ECGroup *group);
    +        /* Extra storage for implementation-specific data.  Any memory
    +         * allocated to these extra fields will be cleared by extra_free. */
    +        void *extra1;
    +        void *extra2;
    +        void (*extra_free) (ECGroup *group);
    +};
    +
    +/* Wrapper functions for generic prime field arithmetic. */
    +mp_err ec_GFp_add(const mp_int *a, const mp_int *b, mp_int *r,
    +                                  const GFMethod *meth);
    +mp_err ec_GFp_neg(const mp_int *a, mp_int *r, const GFMethod *meth);
    +mp_err ec_GFp_sub(const mp_int *a, const mp_int *b, mp_int *r,
    +                                  const GFMethod *meth);
    +
    +/* fixed length in-line adds. Count is in words */
    +mp_err ec_GFp_add_3(const mp_int *a, const mp_int *b, mp_int *r,
    +                                  const GFMethod *meth);
    +mp_err ec_GFp_add_4(const mp_int *a, const mp_int *b, mp_int *r,
    +                                  const GFMethod *meth);
    +mp_err ec_GFp_add_5(const mp_int *a, const mp_int *b, mp_int *r,
    +                                  const GFMethod *meth);
    +mp_err ec_GFp_add_6(const mp_int *a, const mp_int *b, mp_int *r,
    +                                  const GFMethod *meth);
    +mp_err ec_GFp_sub_3(const mp_int *a, const mp_int *b, mp_int *r,
    +                                  const GFMethod *meth);
    +mp_err ec_GFp_sub_4(const mp_int *a, const mp_int *b, mp_int *r,
    +                                  const GFMethod *meth);
    +mp_err ec_GFp_sub_5(const mp_int *a, const mp_int *b, mp_int *r,
    +                                  const GFMethod *meth);
    +mp_err ec_GFp_sub_6(const mp_int *a, const mp_int *b, mp_int *r,
    +                                  const GFMethod *meth);
    +
    +mp_err ec_GFp_mod(const mp_int *a, mp_int *r, const GFMethod *meth);
    +mp_err ec_GFp_mul(const mp_int *a, const mp_int *b, mp_int *r,
    +                                  const GFMethod *meth);
    +mp_err ec_GFp_sqr(const mp_int *a, mp_int *r, const GFMethod *meth);
    +mp_err ec_GFp_div(const mp_int *a, const mp_int *b, mp_int *r,
    +                                  const GFMethod *meth);
    +/* Wrapper functions for generic binary polynomial field arithmetic. */
    +mp_err ec_GF2m_add(const mp_int *a, const mp_int *b, mp_int *r,
    +                                   const GFMethod *meth);
    +mp_err ec_GF2m_neg(const mp_int *a, mp_int *r, const GFMethod *meth);
    +mp_err ec_GF2m_mod(const mp_int *a, mp_int *r, const GFMethod *meth);
    +mp_err ec_GF2m_mul(const mp_int *a, const mp_int *b, mp_int *r,
    +                                   const GFMethod *meth);
    +mp_err ec_GF2m_sqr(const mp_int *a, mp_int *r, const GFMethod *meth);
    +mp_err ec_GF2m_div(const mp_int *a, const mp_int *b, mp_int *r,
    +                                   const GFMethod *meth);
    +
    +/* Montgomery prime field arithmetic. */
    +mp_err ec_GFp_mul_mont(const mp_int *a, const mp_int *b, mp_int *r,
    +                                           const GFMethod *meth);
    +mp_err ec_GFp_sqr_mont(const mp_int *a, mp_int *r, const GFMethod *meth);
    +mp_err ec_GFp_div_mont(const mp_int *a, const mp_int *b, mp_int *r,
    +                                           const GFMethod *meth);
    +mp_err ec_GFp_enc_mont(const mp_int *a, mp_int *r, const GFMethod *meth);
    +mp_err ec_GFp_dec_mont(const mp_int *a, mp_int *r, const GFMethod *meth);
    +void ec_GFp_extra_free_mont(GFMethod *meth);
    +
    +/* point multiplication */
    +mp_err ec_pts_mul_basic(const mp_int *k1, const mp_int *k2,
    +                                                const mp_int *px, const mp_int *py, mp_int *rx,
    +                                                mp_int *ry, const ECGroup *group);
    +mp_err ec_pts_mul_simul_w2(const mp_int *k1, const mp_int *k2,
    +                                                   const mp_int *px, const mp_int *py, mp_int *rx,
    +                                                   mp_int *ry, const ECGroup *group);
    +
    +/* Computes the windowed non-adjacent-form (NAF) of a scalar. Out should
    + * be an array of signed char's to output to, bitsize should be the number
    + * of bits of out, in is the original scalar, and w is the window size.
    + * NAF is discussed in the paper: D. Hankerson, J. Hernandez and A.
    + * Menezes, "Software implementation of elliptic curve cryptography over
    + * binary fields", Proc. CHES 2000. */
    +mp_err ec_compute_wNAF(signed char *out, int bitsize, const mp_int *in,
    +                                           int w);
    +
    +/* Optimized field arithmetic */
    +mp_err ec_group_set_gfp192(ECGroup *group, ECCurveName);
    +mp_err ec_group_set_gfp224(ECGroup *group, ECCurveName);
    +mp_err ec_group_set_gfp256(ECGroup *group, ECCurveName);
    +mp_err ec_group_set_gfp384(ECGroup *group, ECCurveName);
    +mp_err ec_group_set_gfp521(ECGroup *group, ECCurveName);
    +mp_err ec_group_set_gf2m163(ECGroup *group, ECCurveName name);
    +mp_err ec_group_set_gf2m193(ECGroup *group, ECCurveName name);
    +mp_err ec_group_set_gf2m233(ECGroup *group, ECCurveName name);
    +
    +/* Optimized floating-point arithmetic */
    +#ifdef ECL_USE_FP
    +mp_err ec_group_set_secp160r1_fp(ECGroup *group);
    +mp_err ec_group_set_nistp192_fp(ECGroup *group);
    +mp_err ec_group_set_nistp224_fp(ECGroup *group);
    +#endif
    +
    +#endif /* _ECL_PRIV_H */
    diff --git a/jdk/src/share/native/sun/security/ec/ecl.c b/jdk/src/share/native/sun/security/ec/ecl.c
    new file mode 100644
    index 00000000000..7089a6d0e9d
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/ecl.c
    @@ -0,0 +1,475 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the elliptic curve math library.
    + *
    + * The Initial Developer of the Original Code is
    + * Sun Microsystems, Inc.
    + * Portions created by the Initial Developer are Copyright (C) 2003
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Douglas Stebila , Sun Microsystems Laboratories
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +#include "mpi.h"
    +#include "mplogic.h"
    +#include "ecl.h"
    +#include "ecl-priv.h"
    +#include "ec2.h"
    +#include "ecp.h"
    +#ifndef _KERNEL
    +#include 
    +#include 
    +#endif
    +
    +/* Allocate memory for a new ECGroup object. */
    +ECGroup *
    +ECGroup_new(int kmflag)
    +{
    +        mp_err res = MP_OKAY;
    +        ECGroup *group;
    +#ifdef _KERNEL
    +        group = (ECGroup *) kmem_alloc(sizeof(ECGroup), kmflag);
    +#else
    +        group = (ECGroup *) malloc(sizeof(ECGroup));
    +#endif
    +        if (group == NULL)
    +                return NULL;
    +        group->constructed = MP_YES;
    +        group->meth = NULL;
    +        group->text = NULL;
    +        MP_DIGITS(&group->curvea) = 0;
    +        MP_DIGITS(&group->curveb) = 0;
    +        MP_DIGITS(&group->genx) = 0;
    +        MP_DIGITS(&group->geny) = 0;
    +        MP_DIGITS(&group->order) = 0;
    +        group->base_point_mul = NULL;
    +        group->points_mul = NULL;
    +        group->validate_point = NULL;
    +        group->extra1 = NULL;
    +        group->extra2 = NULL;
    +        group->extra_free = NULL;
    +        MP_CHECKOK(mp_init(&group->curvea, kmflag));
    +        MP_CHECKOK(mp_init(&group->curveb, kmflag));
    +        MP_CHECKOK(mp_init(&group->genx, kmflag));
    +        MP_CHECKOK(mp_init(&group->geny, kmflag));
    +        MP_CHECKOK(mp_init(&group->order, kmflag));
    +
    +  CLEANUP:
    +        if (res != MP_OKAY) {
    +                ECGroup_free(group);
    +                return NULL;
    +        }
    +        return group;
    +}
    +
    +/* Construct a generic ECGroup for elliptic curves over prime fields. */
    +ECGroup *
    +ECGroup_consGFp(const mp_int *irr, const mp_int *curvea,
    +                                const mp_int *curveb, const mp_int *genx,
    +                                const mp_int *geny, const mp_int *order, int cofactor)
    +{
    +        mp_err res = MP_OKAY;
    +        ECGroup *group = NULL;
    +
    +        group = ECGroup_new(FLAG(irr));
    +        if (group == NULL)
    +                return NULL;
    +
    +        group->meth = GFMethod_consGFp(irr);
    +        if (group->meth == NULL) {
    +                res = MP_MEM;
    +                goto CLEANUP;
    +        }
    +        MP_CHECKOK(mp_copy(curvea, &group->curvea));
    +        MP_CHECKOK(mp_copy(curveb, &group->curveb));
    +        MP_CHECKOK(mp_copy(genx, &group->genx));
    +        MP_CHECKOK(mp_copy(geny, &group->geny));
    +        MP_CHECKOK(mp_copy(order, &group->order));
    +        group->cofactor = cofactor;
    +        group->point_add = &ec_GFp_pt_add_aff;
    +        group->point_sub = &ec_GFp_pt_sub_aff;
    +        group->point_dbl = &ec_GFp_pt_dbl_aff;
    +        group->point_mul = &ec_GFp_pt_mul_jm_wNAF;
    +        group->base_point_mul = NULL;
    +        group->points_mul = &ec_GFp_pts_mul_jac;
    +        group->validate_point = &ec_GFp_validate_point;
    +
    +  CLEANUP:
    +        if (res != MP_OKAY) {
    +                ECGroup_free(group);
    +                return NULL;
    +        }
    +        return group;
    +}
    +
    +/* Construct a generic ECGroup for elliptic curves over prime fields with
    + * field arithmetic implemented in Montgomery coordinates. */
    +ECGroup *
    +ECGroup_consGFp_mont(const mp_int *irr, const mp_int *curvea,
    +                                         const mp_int *curveb, const mp_int *genx,
    +                                         const mp_int *geny, const mp_int *order, int cofactor)
    +{
    +        mp_err res = MP_OKAY;
    +        ECGroup *group = NULL;
    +
    +        group = ECGroup_new(FLAG(irr));
    +        if (group == NULL)
    +                return NULL;
    +
    +        group->meth = GFMethod_consGFp_mont(irr);
    +        if (group->meth == NULL) {
    +                res = MP_MEM;
    +                goto CLEANUP;
    +        }
    +        MP_CHECKOK(group->meth->
    +                           field_enc(curvea, &group->curvea, group->meth));
    +        MP_CHECKOK(group->meth->
    +                           field_enc(curveb, &group->curveb, group->meth));
    +        MP_CHECKOK(group->meth->field_enc(genx, &group->genx, group->meth));
    +        MP_CHECKOK(group->meth->field_enc(geny, &group->geny, group->meth));
    +        MP_CHECKOK(mp_copy(order, &group->order));
    +        group->cofactor = cofactor;
    +        group->point_add = &ec_GFp_pt_add_aff;
    +        group->point_sub = &ec_GFp_pt_sub_aff;
    +        group->point_dbl = &ec_GFp_pt_dbl_aff;
    +        group->point_mul = &ec_GFp_pt_mul_jm_wNAF;
    +        group->base_point_mul = NULL;
    +        group->points_mul = &ec_GFp_pts_mul_jac;
    +        group->validate_point = &ec_GFp_validate_point;
    +
    +  CLEANUP:
    +        if (res != MP_OKAY) {
    +                ECGroup_free(group);
    +                return NULL;
    +        }
    +        return group;
    +}
    +
    +#ifdef NSS_ECC_MORE_THAN_SUITE_B
    +/* Construct a generic ECGroup for elliptic curves over binary polynomial
    + * fields. */
    +ECGroup *
    +ECGroup_consGF2m(const mp_int *irr, const unsigned int irr_arr[5],
    +                                 const mp_int *curvea, const mp_int *curveb,
    +                                 const mp_int *genx, const mp_int *geny,
    +                                 const mp_int *order, int cofactor)
    +{
    +        mp_err res = MP_OKAY;
    +        ECGroup *group = NULL;
    +
    +        group = ECGroup_new(FLAG(irr));
    +        if (group == NULL)
    +                return NULL;
    +
    +        group->meth = GFMethod_consGF2m(irr, irr_arr);
    +        if (group->meth == NULL) {
    +                res = MP_MEM;
    +                goto CLEANUP;
    +        }
    +        MP_CHECKOK(mp_copy(curvea, &group->curvea));
    +        MP_CHECKOK(mp_copy(curveb, &group->curveb));
    +        MP_CHECKOK(mp_copy(genx, &group->genx));
    +        MP_CHECKOK(mp_copy(geny, &group->geny));
    +        MP_CHECKOK(mp_copy(order, &group->order));
    +        group->cofactor = cofactor;
    +        group->point_add = &ec_GF2m_pt_add_aff;
    +        group->point_sub = &ec_GF2m_pt_sub_aff;
    +        group->point_dbl = &ec_GF2m_pt_dbl_aff;
    +        group->point_mul = &ec_GF2m_pt_mul_mont;
    +        group->base_point_mul = NULL;
    +        group->points_mul = &ec_pts_mul_basic;
    +        group->validate_point = &ec_GF2m_validate_point;
    +
    +  CLEANUP:
    +        if (res != MP_OKAY) {
    +                ECGroup_free(group);
    +                return NULL;
    +        }
    +        return group;
    +}
    +#endif
    +
    +/* Construct ECGroup from hex parameters and name, if any. Called by
    + * ECGroup_fromHex and ECGroup_fromName. */
    +ECGroup *
    +ecgroup_fromNameAndHex(const ECCurveName name,
    +                                   const ECCurveParams * params, int kmflag)
    +{
    +        mp_int irr, curvea, curveb, genx, geny, order;
    +        int bits;
    +        ECGroup *group = NULL;
    +        mp_err res = MP_OKAY;
    +
    +        /* initialize values */
    +        MP_DIGITS(&irr) = 0;
    +        MP_DIGITS(&curvea) = 0;
    +        MP_DIGITS(&curveb) = 0;
    +        MP_DIGITS(&genx) = 0;
    +        MP_DIGITS(&geny) = 0;
    +        MP_DIGITS(&order) = 0;
    +        MP_CHECKOK(mp_init(&irr, kmflag));
    +        MP_CHECKOK(mp_init(&curvea, kmflag));
    +        MP_CHECKOK(mp_init(&curveb, kmflag));
    +        MP_CHECKOK(mp_init(&genx, kmflag));
    +        MP_CHECKOK(mp_init(&geny, kmflag));
    +        MP_CHECKOK(mp_init(&order, kmflag));
    +        MP_CHECKOK(mp_read_radix(&irr, params->irr, 16));
    +        MP_CHECKOK(mp_read_radix(&curvea, params->curvea, 16));
    +        MP_CHECKOK(mp_read_radix(&curveb, params->curveb, 16));
    +        MP_CHECKOK(mp_read_radix(&genx, params->genx, 16));
    +        MP_CHECKOK(mp_read_radix(&geny, params->geny, 16));
    +        MP_CHECKOK(mp_read_radix(&order, params->order, 16));
    +
    +        /* determine number of bits */
    +        bits = mpl_significant_bits(&irr) - 1;
    +        if (bits < MP_OKAY) {
    +                res = bits;
    +                goto CLEANUP;
    +        }
    +
    +        /* determine which optimizations (if any) to use */
    +        if (params->field == ECField_GFp) {
    +#ifdef NSS_ECC_MORE_THAN_SUITE_B
    +            switch (name) {
    +#ifdef ECL_USE_FP
    +                case ECCurve_SECG_PRIME_160R1:
    +                        group =
    +                                ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
    +                                                                &order, params->cofactor);
    +                        if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
    +                        MP_CHECKOK(ec_group_set_secp160r1_fp(group));
    +                        break;
    +#endif
    +                case ECCurve_SECG_PRIME_192R1:
    +#ifdef ECL_USE_FP
    +                        group =
    +                                ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
    +                                                                &order, params->cofactor);
    +                        if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
    +                        MP_CHECKOK(ec_group_set_nistp192_fp(group));
    +#else
    +                        group =
    +                                ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
    +                                                                &order, params->cofactor);
    +                        if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
    +                        MP_CHECKOK(ec_group_set_gfp192(group, name));
    +#endif
    +                        break;
    +                case ECCurve_SECG_PRIME_224R1:
    +#ifdef ECL_USE_FP
    +                        group =
    +                                ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
    +                                                                &order, params->cofactor);
    +                        if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
    +                        MP_CHECKOK(ec_group_set_nistp224_fp(group));
    +#else
    +                        group =
    +                                ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
    +                                                                &order, params->cofactor);
    +                        if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
    +                        MP_CHECKOK(ec_group_set_gfp224(group, name));
    +#endif
    +                        break;
    +                case ECCurve_SECG_PRIME_256R1:
    +                        group =
    +                                ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
    +                                                                &order, params->cofactor);
    +                        if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
    +                        MP_CHECKOK(ec_group_set_gfp256(group, name));
    +                        break;
    +                case ECCurve_SECG_PRIME_521R1:
    +                        group =
    +                                ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
    +                                                                &order, params->cofactor);
    +                        if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
    +                        MP_CHECKOK(ec_group_set_gfp521(group, name));
    +                        break;
    +                default:
    +                        /* use generic arithmetic */
    +#endif
    +                        group =
    +                                ECGroup_consGFp_mont(&irr, &curvea, &curveb, &genx, &geny,
    +                                                                         &order, params->cofactor);
    +                        if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
    +#ifdef NSS_ECC_MORE_THAN_SUITE_B
    +                }
    +        } else if (params->field == ECField_GF2m) {
    +                group = ECGroup_consGF2m(&irr, NULL, &curvea, &curveb, &genx, &geny, &order, params->cofactor);
    +                if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
    +                if ((name == ECCurve_NIST_K163) ||
    +                    (name == ECCurve_NIST_B163) ||
    +                    (name == ECCurve_SECG_CHAR2_163R1)) {
    +                        MP_CHECKOK(ec_group_set_gf2m163(group, name));
    +                } else if ((name == ECCurve_SECG_CHAR2_193R1) ||
    +                           (name == ECCurve_SECG_CHAR2_193R2)) {
    +                        MP_CHECKOK(ec_group_set_gf2m193(group, name));
    +                } else if ((name == ECCurve_NIST_K233) ||
    +                           (name == ECCurve_NIST_B233)) {
    +                        MP_CHECKOK(ec_group_set_gf2m233(group, name));
    +                }
    +#endif
    +        } else {
    +                res = MP_UNDEF;
    +                goto CLEANUP;
    +        }
    +
    +        /* set name, if any */
    +        if ((group != NULL) && (params->text != NULL)) {
    +#ifdef _KERNEL
    +                int n = strlen(params->text) + 1;
    +
    +                group->text = kmem_alloc(n, kmflag);
    +                if (group->text == NULL) {
    +                        res = MP_MEM;
    +                        goto CLEANUP;
    +                }
    +                bcopy(params->text, group->text, n);
    +                group->text_len = n;
    +#else
    +                group->text = strdup(params->text);
    +                if (group->text == NULL) {
    +                        res = MP_MEM;
    +                }
    +#endif
    +        }
    +
    +  CLEANUP:
    +        mp_clear(&irr);
    +        mp_clear(&curvea);
    +        mp_clear(&curveb);
    +        mp_clear(&genx);
    +        mp_clear(&geny);
    +        mp_clear(&order);
    +        if (res != MP_OKAY) {
    +                ECGroup_free(group);
    +                return NULL;
    +        }
    +        return group;
    +}
    +
    +/* Construct ECGroup from hexadecimal representations of parameters. */
    +ECGroup *
    +ECGroup_fromHex(const ECCurveParams * params, int kmflag)
    +{
    +        return ecgroup_fromNameAndHex(ECCurve_noName, params, kmflag);
    +}
    +
    +/* Construct ECGroup from named parameters. */
    +ECGroup *
    +ECGroup_fromName(const ECCurveName name, int kmflag)
    +{
    +        ECGroup *group = NULL;
    +        ECCurveParams *params = NULL;
    +        mp_err res = MP_OKAY;
    +
    +        params = EC_GetNamedCurveParams(name, kmflag);
    +        if (params == NULL) {
    +                res = MP_UNDEF;
    +                goto CLEANUP;
    +        }
    +
    +        /* construct actual group */
    +        group = ecgroup_fromNameAndHex(name, params, kmflag);
    +        if (group == NULL) {
    +                res = MP_UNDEF;
    +                goto CLEANUP;
    +        }
    +
    +  CLEANUP:
    +        EC_FreeCurveParams(params);
    +        if (res != MP_OKAY) {
    +                ECGroup_free(group);
    +                return NULL;
    +        }
    +        return group;
    +}
    +
    +/* Validates an EC public key as described in Section 5.2.2 of X9.62. */
    +mp_err ECPoint_validate(const ECGroup *group, const mp_int *px, const
    +                                        mp_int *py)
    +{
    +    /* 1: Verify that publicValue is not the point at infinity */
    +    /* 2: Verify that the coordinates of publicValue are elements
    +     *    of the field.
    +     */
    +    /* 3: Verify that publicValue is on the curve. */
    +    /* 4: Verify that the order of the curve times the publicValue
    +     *    is the point at infinity.
    +     */
    +        return group->validate_point(px, py, group);
    +}
    +
    +/* Free the memory allocated (if any) to an ECGroup object. */
    +void
    +ECGroup_free(ECGroup *group)
    +{
    +        if (group == NULL)
    +                return;
    +        GFMethod_free(group->meth);
    +        if (group->constructed == MP_NO)
    +                return;
    +        mp_clear(&group->curvea);
    +        mp_clear(&group->curveb);
    +        mp_clear(&group->genx);
    +        mp_clear(&group->geny);
    +        mp_clear(&group->order);
    +        if (group->text != NULL)
    +#ifdef _KERNEL
    +                kmem_free(group->text, group->text_len);
    +#else
    +                free(group->text);
    +#endif
    +        if (group->extra_free != NULL)
    +                group->extra_free(group);
    +#ifdef _KERNEL
    +        kmem_free(group, sizeof (ECGroup));
    +#else
    +        free(group);
    +#endif
    +}
    diff --git a/jdk/src/share/native/sun/security/ec/ecl.h b/jdk/src/share/native/sun/security/ec/ecl.h
    new file mode 100644
    index 00000000000..9dcdbc677ce
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/ecl.h
    @@ -0,0 +1,111 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the elliptic curve math library.
    + *
    + * The Initial Developer of the Original Code is
    + * Sun Microsystems, Inc.
    + * Portions created by the Initial Developer are Copyright (C) 2003
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Douglas Stebila , Sun Microsystems Laboratories
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#ifndef _ECL_H
    +#define _ECL_H
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +/* Although this is not an exported header file, code which uses elliptic
    + * curve point operations will need to include it. */
    +
    +#include "ecl-exp.h"
    +#include "mpi.h"
    +
    +struct ECGroupStr;
    +typedef struct ECGroupStr ECGroup;
    +
    +/* Construct ECGroup from hexadecimal representations of parameters. */
    +ECGroup *ECGroup_fromHex(const ECCurveParams * params, int kmflag);
    +
    +/* Construct ECGroup from named parameters. */
    +ECGroup *ECGroup_fromName(const ECCurveName name, int kmflag);
    +
    +/* Free an allocated ECGroup. */
    +void ECGroup_free(ECGroup *group);
    +
    +/* Construct ECCurveParams from an ECCurveName */
    +ECCurveParams *EC_GetNamedCurveParams(const ECCurveName name, int kmflag);
    +
    +/* Duplicates an ECCurveParams */
    +ECCurveParams *ECCurveParams_dup(const ECCurveParams * params, int kmflag);
    +
    +/* Free an allocated ECCurveParams */
    +void EC_FreeCurveParams(ECCurveParams * params);
    +
    +/* Elliptic curve scalar-point multiplication. Computes Q(x, y) = k * P(x,
    + * y).  If x, y = NULL, then P is assumed to be the generator (base point)
    + * of the group of points on the elliptic curve. Input and output values
    + * are assumed to be NOT field-encoded. */
    +mp_err ECPoint_mul(const ECGroup *group, const mp_int *k, const mp_int *px,
    +                                   const mp_int *py, mp_int *qx, mp_int *qy);
    +
    +/* Elliptic curve scalar-point multiplication. Computes Q(x, y) = k1 * G +
    + * k2 * P(x, y), where G is the generator (base point) of the group of
    + * points on the elliptic curve. Input and output values are assumed to
    + * be NOT field-encoded. */
    +mp_err ECPoints_mul(const ECGroup *group, const mp_int *k1,
    +                                        const mp_int *k2, const mp_int *px, const mp_int *py,
    +                                        mp_int *qx, mp_int *qy);
    +
    +/* Validates an EC public key as described in Section 5.2.2 of X9.62.
    + * Returns MP_YES if the public key is valid, MP_NO if the public key
    + * is invalid, or an error code if the validation could not be
    + * performed. */
    +mp_err ECPoint_validate(const ECGroup *group, const mp_int *px, const
    +                                        mp_int *py);
    +
    +#endif /* _ECL_H */
    diff --git a/jdk/src/share/native/sun/security/ec/ecl_curve.c b/jdk/src/share/native/sun/security/ec/ecl_curve.c
    new file mode 100644
    index 00000000000..d2d2d82291c
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/ecl_curve.c
    @@ -0,0 +1,216 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the elliptic curve math library.
    + *
    + * The Initial Developer of the Original Code is
    + * Sun Microsystems, Inc.
    + * Portions created by the Initial Developer are Copyright (C) 2003
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Douglas Stebila , Sun Microsystems Laboratories
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +#include "ecl.h"
    +#include "ecl-curve.h"
    +#include "ecl-priv.h"
    +#ifndef _KERNEL
    +#include 
    +#include 
    +#endif
    +
    +#define CHECK(func) if ((func) == NULL) { res = 0; goto CLEANUP; }
    +
    +/* Duplicates an ECCurveParams */
    +ECCurveParams *
    +ECCurveParams_dup(const ECCurveParams * params, int kmflag)
    +{
    +        int res = 1;
    +        ECCurveParams *ret = NULL;
    +
    +#ifdef _KERNEL
    +        ret = (ECCurveParams *) kmem_zalloc(sizeof(ECCurveParams), kmflag);
    +#else
    +        CHECK(ret = (ECCurveParams *) calloc(1, sizeof(ECCurveParams)));
    +#endif
    +        if (params->text != NULL) {
    +#ifdef _KERNEL
    +                ret->text = kmem_alloc(strlen(params->text) + 1, kmflag);
    +                bcopy(params->text, ret->text, strlen(params->text) + 1);
    +#else
    +                CHECK(ret->text = strdup(params->text));
    +#endif
    +        }
    +        ret->field = params->field;
    +        ret->size = params->size;
    +        if (params->irr != NULL) {
    +#ifdef _KERNEL
    +                ret->irr = kmem_alloc(strlen(params->irr) + 1, kmflag);
    +                bcopy(params->irr, ret->irr, strlen(params->irr) + 1);
    +#else
    +                CHECK(ret->irr = strdup(params->irr));
    +#endif
    +        }
    +        if (params->curvea != NULL) {
    +#ifdef _KERNEL
    +                ret->curvea = kmem_alloc(strlen(params->curvea) + 1, kmflag);
    +                bcopy(params->curvea, ret->curvea, strlen(params->curvea) + 1);
    +#else
    +                CHECK(ret->curvea = strdup(params->curvea));
    +#endif
    +        }
    +        if (params->curveb != NULL) {
    +#ifdef _KERNEL
    +                ret->curveb = kmem_alloc(strlen(params->curveb) + 1, kmflag);
    +                bcopy(params->curveb, ret->curveb, strlen(params->curveb) + 1);
    +#else
    +                CHECK(ret->curveb = strdup(params->curveb));
    +#endif
    +        }
    +        if (params->genx != NULL) {
    +#ifdef _KERNEL
    +                ret->genx = kmem_alloc(strlen(params->genx) + 1, kmflag);
    +                bcopy(params->genx, ret->genx, strlen(params->genx) + 1);
    +#else
    +                CHECK(ret->genx = strdup(params->genx));
    +#endif
    +        }
    +        if (params->geny != NULL) {
    +#ifdef _KERNEL
    +                ret->geny = kmem_alloc(strlen(params->geny) + 1, kmflag);
    +                bcopy(params->geny, ret->geny, strlen(params->geny) + 1);
    +#else
    +                CHECK(ret->geny = strdup(params->geny));
    +#endif
    +        }
    +        if (params->order != NULL) {
    +#ifdef _KERNEL
    +                ret->order = kmem_alloc(strlen(params->order) + 1, kmflag);
    +                bcopy(params->order, ret->order, strlen(params->order) + 1);
    +#else
    +                CHECK(ret->order = strdup(params->order));
    +#endif
    +        }
    +        ret->cofactor = params->cofactor;
    +
    +  CLEANUP:
    +        if (res != 1) {
    +                EC_FreeCurveParams(ret);
    +                return NULL;
    +        }
    +        return ret;
    +}
    +
    +#undef CHECK
    +
    +/* Construct ECCurveParams from an ECCurveName */
    +ECCurveParams *
    +EC_GetNamedCurveParams(const ECCurveName name, int kmflag)
    +{
    +        if ((name <= ECCurve_noName) || (ECCurve_pastLastCurve <= name) ||
    +                                        (ecCurve_map[name] == NULL)) {
    +                return NULL;
    +        } else {
    +                return ECCurveParams_dup(ecCurve_map[name], kmflag);
    +        }
    +}
    +
    +/* Free the memory allocated (if any) to an ECCurveParams object. */
    +void
    +EC_FreeCurveParams(ECCurveParams * params)
    +{
    +        if (params == NULL)
    +                return;
    +        if (params->text != NULL)
    +#ifdef _KERNEL
    +                kmem_free(params->text, strlen(params->text) + 1);
    +#else
    +                free(params->text);
    +#endif
    +        if (params->irr != NULL)
    +#ifdef _KERNEL
    +                kmem_free(params->irr, strlen(params->irr) + 1);
    +#else
    +                free(params->irr);
    +#endif
    +        if (params->curvea != NULL)
    +#ifdef _KERNEL
    +                kmem_free(params->curvea, strlen(params->curvea) + 1);
    +#else
    +                free(params->curvea);
    +#endif
    +        if (params->curveb != NULL)
    +#ifdef _KERNEL
    +                kmem_free(params->curveb, strlen(params->curveb) + 1);
    +#else
    +                free(params->curveb);
    +#endif
    +        if (params->genx != NULL)
    +#ifdef _KERNEL
    +                kmem_free(params->genx, strlen(params->genx) + 1);
    +#else
    +                free(params->genx);
    +#endif
    +        if (params->geny != NULL)
    +#ifdef _KERNEL
    +                kmem_free(params->geny, strlen(params->geny) + 1);
    +#else
    +                free(params->geny);
    +#endif
    +        if (params->order != NULL)
    +#ifdef _KERNEL
    +                kmem_free(params->order, strlen(params->order) + 1);
    +#else
    +                free(params->order);
    +#endif
    +#ifdef _KERNEL
    +        kmem_free(params, sizeof(ECCurveParams));
    +#else
    +        free(params);
    +#endif
    +}
    diff --git a/jdk/src/share/native/sun/security/ec/ecl_gf.c b/jdk/src/share/native/sun/security/ec/ecl_gf.c
    new file mode 100644
    index 00000000000..a651fa84e7c
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/ecl_gf.c
    @@ -0,0 +1,1062 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the elliptic curve math library.
    + *
    + * The Initial Developer of the Original Code is
    + * Sun Microsystems, Inc.
    + * Portions created by the Initial Developer are Copyright (C) 2003
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Stephen Fung  and
    + *   Douglas Stebila , Sun Microsystems Laboratories
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +#include "mpi.h"
    +#include "mp_gf2m.h"
    +#include "ecl-priv.h"
    +#include "mpi-priv.h"
    +#ifndef _KERNEL
    +#include 
    +#endif
    +
    +/* Allocate memory for a new GFMethod object. */
    +GFMethod *
    +GFMethod_new(int kmflag)
    +{
    +        mp_err res = MP_OKAY;
    +        GFMethod *meth;
    +#ifdef _KERNEL
    +        meth = (GFMethod *) kmem_alloc(sizeof(GFMethod), kmflag);
    +#else
    +        meth = (GFMethod *) malloc(sizeof(GFMethod));
    +        if (meth == NULL)
    +                return NULL;
    +#endif
    +        meth->constructed = MP_YES;
    +        MP_DIGITS(&meth->irr) = 0;
    +        meth->extra_free = NULL;
    +        MP_CHECKOK(mp_init(&meth->irr, kmflag));
    +
    +  CLEANUP:
    +        if (res != MP_OKAY) {
    +                GFMethod_free(meth);
    +                return NULL;
    +        }
    +        return meth;
    +}
    +
    +/* Construct a generic GFMethod for arithmetic over prime fields with
    + * irreducible irr. */
    +GFMethod *
    +GFMethod_consGFp(const mp_int *irr)
    +{
    +        mp_err res = MP_OKAY;
    +        GFMethod *meth = NULL;
    +
    +        meth = GFMethod_new(FLAG(irr));
    +        if (meth == NULL)
    +                return NULL;
    +
    +        MP_CHECKOK(mp_copy(irr, &meth->irr));
    +        meth->irr_arr[0] = mpl_significant_bits(irr);
    +        meth->irr_arr[1] = meth->irr_arr[2] = meth->irr_arr[3] =
    +                meth->irr_arr[4] = 0;
    +        switch(MP_USED(&meth->irr)) {
    +        /* maybe we need 1 and 2 words here as well?*/
    +        case 3:
    +                meth->field_add = &ec_GFp_add_3;
    +                meth->field_sub = &ec_GFp_sub_3;
    +                break;
    +        case 4:
    +                meth->field_add = &ec_GFp_add_4;
    +                meth->field_sub = &ec_GFp_sub_4;
    +                break;
    +        case 5:
    +                meth->field_add = &ec_GFp_add_5;
    +                meth->field_sub = &ec_GFp_sub_5;
    +                break;
    +        case 6:
    +                meth->field_add = &ec_GFp_add_6;
    +                meth->field_sub = &ec_GFp_sub_6;
    +                break;
    +        default:
    +                meth->field_add = &ec_GFp_add;
    +                meth->field_sub = &ec_GFp_sub;
    +        }
    +        meth->field_neg = &ec_GFp_neg;
    +        meth->field_mod = &ec_GFp_mod;
    +        meth->field_mul = &ec_GFp_mul;
    +        meth->field_sqr = &ec_GFp_sqr;
    +        meth->field_div = &ec_GFp_div;
    +        meth->field_enc = NULL;
    +        meth->field_dec = NULL;
    +        meth->extra1 = NULL;
    +        meth->extra2 = NULL;
    +        meth->extra_free = NULL;
    +
    +  CLEANUP:
    +        if (res != MP_OKAY) {
    +                GFMethod_free(meth);
    +                return NULL;
    +        }
    +        return meth;
    +}
    +
    +/* Construct a generic GFMethod for arithmetic over binary polynomial
    + * fields with irreducible irr that has array representation irr_arr (see
    + * ecl-priv.h for description of the representation).  If irr_arr is NULL,
    + * then it is constructed from the bitstring representation. */
    +GFMethod *
    +GFMethod_consGF2m(const mp_int *irr, const unsigned int irr_arr[5])
    +{
    +        mp_err res = MP_OKAY;
    +        int ret;
    +        GFMethod *meth = NULL;
    +
    +        meth = GFMethod_new(FLAG(irr));
    +        if (meth == NULL)
    +                return NULL;
    +
    +        MP_CHECKOK(mp_copy(irr, &meth->irr));
    +        if (irr_arr != NULL) {
    +                /* Irreducible polynomials are either trinomials or pentanomials. */
    +                meth->irr_arr[0] = irr_arr[0];
    +                meth->irr_arr[1] = irr_arr[1];
    +                meth->irr_arr[2] = irr_arr[2];
    +                if (irr_arr[2] > 0) {
    +                        meth->irr_arr[3] = irr_arr[3];
    +                        meth->irr_arr[4] = irr_arr[4];
    +                } else {
    +                        meth->irr_arr[3] = meth->irr_arr[4] = 0;
    +                }
    +        } else {
    +                ret = mp_bpoly2arr(irr, meth->irr_arr, 5);
    +                /* Irreducible polynomials are either trinomials or pentanomials. */
    +                if ((ret != 5) && (ret != 3)) {
    +                        res = MP_UNDEF;
    +                        goto CLEANUP;
    +                }
    +        }
    +        meth->field_add = &ec_GF2m_add;
    +        meth->field_neg = &ec_GF2m_neg;
    +        meth->field_sub = &ec_GF2m_add;
    +        meth->field_mod = &ec_GF2m_mod;
    +        meth->field_mul = &ec_GF2m_mul;
    +        meth->field_sqr = &ec_GF2m_sqr;
    +        meth->field_div = &ec_GF2m_div;
    +        meth->field_enc = NULL;
    +        meth->field_dec = NULL;
    +        meth->extra1 = NULL;
    +        meth->extra2 = NULL;
    +        meth->extra_free = NULL;
    +
    +  CLEANUP:
    +        if (res != MP_OKAY) {
    +                GFMethod_free(meth);
    +                return NULL;
    +        }
    +        return meth;
    +}
    +
    +/* Free the memory allocated (if any) to a GFMethod object. */
    +void
    +GFMethod_free(GFMethod *meth)
    +{
    +        if (meth == NULL)
    +                return;
    +        if (meth->constructed == MP_NO)
    +                return;
    +        mp_clear(&meth->irr);
    +        if (meth->extra_free != NULL)
    +                meth->extra_free(meth);
    +#ifdef _KERNEL
    +        kmem_free(meth, sizeof(GFMethod));
    +#else
    +        free(meth);
    +#endif
    +}
    +
    +/* Wrapper functions for generic prime field arithmetic. */
    +
    +/* Add two field elements.  Assumes that 0 <= a, b < meth->irr */
    +mp_err
    +ec_GFp_add(const mp_int *a, const mp_int *b, mp_int *r,
    +                   const GFMethod *meth)
    +{
    +        /* PRE: 0 <= a, b < p = meth->irr POST: 0 <= r < p, r = a + b (mod p) */
    +        mp_err res;
    +
    +        if ((res = mp_add(a, b, r)) != MP_OKAY) {
    +                return res;
    +        }
    +        if (mp_cmp(r, &meth->irr) >= 0) {
    +                return mp_sub(r, &meth->irr, r);
    +        }
    +        return res;
    +}
    +
    +/* Negates a field element.  Assumes that 0 <= a < meth->irr */
    +mp_err
    +ec_GFp_neg(const mp_int *a, mp_int *r, const GFMethod *meth)
    +{
    +        /* PRE: 0 <= a < p = meth->irr POST: 0 <= r < p, r = -a (mod p) */
    +
    +        if (mp_cmp_z(a) == 0) {
    +                mp_zero(r);
    +                return MP_OKAY;
    +        }
    +        return mp_sub(&meth->irr, a, r);
    +}
    +
    +/* Subtracts two field elements.  Assumes that 0 <= a, b < meth->irr */
    +mp_err
    +ec_GFp_sub(const mp_int *a, const mp_int *b, mp_int *r,
    +                   const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +
    +        /* PRE: 0 <= a, b < p = meth->irr POST: 0 <= r < p, r = a - b (mod p) */
    +        res = mp_sub(a, b, r);
    +        if (res == MP_RANGE) {
    +                MP_CHECKOK(mp_sub(b, a, r));
    +                if (mp_cmp_z(r) < 0) {
    +                        MP_CHECKOK(mp_add(r, &meth->irr, r));
    +                }
    +                MP_CHECKOK(ec_GFp_neg(r, r, meth));
    +        }
    +        if (mp_cmp_z(r) < 0) {
    +                MP_CHECKOK(mp_add(r, &meth->irr, r));
    +        }
    +  CLEANUP:
    +        return res;
    +}
    +/*
    + * Inline adds for small curve lengths.
    + */
    +/* 3 words */
    +mp_err
    +ec_GFp_add_3(const mp_int *a, const mp_int *b, mp_int *r,
    +                        const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_digit a0 = 0, a1 = 0, a2 = 0;
    +        mp_digit r0 = 0, r1 = 0, r2 = 0;
    +        mp_digit carry;
    +
    +        switch(MP_USED(a)) {
    +        case 3:
    +                a2 = MP_DIGIT(a,2);
    +        case 2:
    +                a1 = MP_DIGIT(a,1);
    +        case 1:
    +                a0 = MP_DIGIT(a,0);
    +        }
    +        switch(MP_USED(b)) {
    +        case 3:
    +                r2 = MP_DIGIT(b,2);
    +        case 2:
    +                r1 = MP_DIGIT(b,1);
    +        case 1:
    +                r0 = MP_DIGIT(b,0);
    +        }
    +
    +#ifndef MPI_AMD64_ADD
    +        MP_ADD_CARRY(a0, r0, r0, 0,     carry);
    +        MP_ADD_CARRY(a1, r1, r1, carry, carry);
    +        MP_ADD_CARRY(a2, r2, r2, carry, carry);
    +#else
    +        __asm__ (
    +                "xorq   %3,%3           \n\t"
    +                "addq   %4,%0           \n\t"
    +                "adcq   %5,%1           \n\t"
    +                "adcq   %6,%2           \n\t"
    +                "adcq   $0,%3           \n\t"
    +                : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(carry)
    +                : "r" (a0), "r" (a1), "r" (a2),
    +                  "0" (r0), "1" (r1), "2" (r2)
    +                : "%cc" );
    +#endif
    +
    +        MP_CHECKOK(s_mp_pad(r, 3));
    +        MP_DIGIT(r, 2) = r2;
    +        MP_DIGIT(r, 1) = r1;
    +        MP_DIGIT(r, 0) = r0;
    +        MP_SIGN(r) = MP_ZPOS;
    +        MP_USED(r) = 3;
    +
    +        /* Do quick 'subract' if we've gone over
    +         * (add the 2's complement of the curve field) */
    +         a2 = MP_DIGIT(&meth->irr,2);
    +        if (carry ||  r2 >  a2 ||
    +                ((r2 == a2) && mp_cmp(r,&meth->irr) != MP_LT)) {
    +                a1 = MP_DIGIT(&meth->irr,1);
    +                a0 = MP_DIGIT(&meth->irr,0);
    +#ifndef MPI_AMD64_ADD
    +                MP_SUB_BORROW(r0, a0, r0, 0,     carry);
    +                MP_SUB_BORROW(r1, a1, r1, carry, carry);
    +                MP_SUB_BORROW(r2, a2, r2, carry, carry);
    +#else
    +                __asm__ (
    +                        "subq   %3,%0           \n\t"
    +                        "sbbq   %4,%1           \n\t"
    +                        "sbbq   %5,%2           \n\t"
    +                        : "=r"(r0), "=r"(r1), "=r"(r2)
    +                        : "r" (a0), "r" (a1), "r" (a2),
    +                          "0" (r0), "1" (r1), "2" (r2)
    +                        : "%cc" );
    +#endif
    +                MP_DIGIT(r, 2) = r2;
    +                MP_DIGIT(r, 1) = r1;
    +                MP_DIGIT(r, 0) = r0;
    +        }
    +
    +        s_mp_clamp(r);
    +
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* 4 words */
    +mp_err
    +ec_GFp_add_4(const mp_int *a, const mp_int *b, mp_int *r,
    +                        const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_digit a0 = 0, a1 = 0, a2 = 0, a3 = 0;
    +        mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0;
    +        mp_digit carry;
    +
    +        switch(MP_USED(a)) {
    +        case 4:
    +                a3 = MP_DIGIT(a,3);
    +        case 3:
    +                a2 = MP_DIGIT(a,2);
    +        case 2:
    +                a1 = MP_DIGIT(a,1);
    +        case 1:
    +                a0 = MP_DIGIT(a,0);
    +        }
    +        switch(MP_USED(b)) {
    +        case 4:
    +                r3 = MP_DIGIT(b,3);
    +        case 3:
    +                r2 = MP_DIGIT(b,2);
    +        case 2:
    +                r1 = MP_DIGIT(b,1);
    +        case 1:
    +                r0 = MP_DIGIT(b,0);
    +        }
    +
    +#ifndef MPI_AMD64_ADD
    +        MP_ADD_CARRY(a0, r0, r0, 0,     carry);
    +        MP_ADD_CARRY(a1, r1, r1, carry, carry);
    +        MP_ADD_CARRY(a2, r2, r2, carry, carry);
    +        MP_ADD_CARRY(a3, r3, r3, carry, carry);
    +#else
    +        __asm__ (
    +                "xorq   %4,%4           \n\t"
    +                "addq   %5,%0           \n\t"
    +                "adcq   %6,%1           \n\t"
    +                "adcq   %7,%2           \n\t"
    +                "adcq   %8,%3           \n\t"
    +                "adcq   $0,%4           \n\t"
    +                : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3), "=r"(carry)
    +                : "r" (a0), "r" (a1), "r" (a2), "r" (a3),
    +                  "0" (r0), "1" (r1), "2" (r2), "3" (r3)
    +                : "%cc" );
    +#endif
    +
    +        MP_CHECKOK(s_mp_pad(r, 4));
    +        MP_DIGIT(r, 3) = r3;
    +        MP_DIGIT(r, 2) = r2;
    +        MP_DIGIT(r, 1) = r1;
    +        MP_DIGIT(r, 0) = r0;
    +        MP_SIGN(r) = MP_ZPOS;
    +        MP_USED(r) = 4;
    +
    +        /* Do quick 'subract' if we've gone over
    +         * (add the 2's complement of the curve field) */
    +         a3 = MP_DIGIT(&meth->irr,3);
    +        if (carry ||  r3 >  a3 ||
    +                ((r3 == a3) && mp_cmp(r,&meth->irr) != MP_LT)) {
    +                a2 = MP_DIGIT(&meth->irr,2);
    +                a1 = MP_DIGIT(&meth->irr,1);
    +                a0 = MP_DIGIT(&meth->irr,0);
    +#ifndef MPI_AMD64_ADD
    +                MP_SUB_BORROW(r0, a0, r0, 0,     carry);
    +                MP_SUB_BORROW(r1, a1, r1, carry, carry);
    +                MP_SUB_BORROW(r2, a2, r2, carry, carry);
    +                MP_SUB_BORROW(r3, a3, r3, carry, carry);
    +#else
    +                __asm__ (
    +                        "subq   %4,%0           \n\t"
    +                        "sbbq   %5,%1           \n\t"
    +                        "sbbq   %6,%2           \n\t"
    +                        "sbbq   %7,%3           \n\t"
    +                        : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3)
    +                        : "r" (a0), "r" (a1), "r" (a2), "r" (a3),
    +                          "0" (r0), "1" (r1), "2" (r2), "3" (r3)
    +                        : "%cc" );
    +#endif
    +                MP_DIGIT(r, 3) = r3;
    +                MP_DIGIT(r, 2) = r2;
    +                MP_DIGIT(r, 1) = r1;
    +                MP_DIGIT(r, 0) = r0;
    +        }
    +
    +        s_mp_clamp(r);
    +
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* 5 words */
    +mp_err
    +ec_GFp_add_5(const mp_int *a, const mp_int *b, mp_int *r,
    +                        const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_digit a0 = 0, a1 = 0, a2 = 0, a3 = 0, a4 = 0;
    +        mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0;
    +        mp_digit carry;
    +
    +        switch(MP_USED(a)) {
    +        case 5:
    +                a4 = MP_DIGIT(a,4);
    +        case 4:
    +                a3 = MP_DIGIT(a,3);
    +        case 3:
    +                a2 = MP_DIGIT(a,2);
    +        case 2:
    +                a1 = MP_DIGIT(a,1);
    +        case 1:
    +                a0 = MP_DIGIT(a,0);
    +        }
    +        switch(MP_USED(b)) {
    +        case 5:
    +                r4 = MP_DIGIT(b,4);
    +        case 4:
    +                r3 = MP_DIGIT(b,3);
    +        case 3:
    +                r2 = MP_DIGIT(b,2);
    +        case 2:
    +                r1 = MP_DIGIT(b,1);
    +        case 1:
    +                r0 = MP_DIGIT(b,0);
    +        }
    +
    +        MP_ADD_CARRY(a0, r0, r0, 0,     carry);
    +        MP_ADD_CARRY(a1, r1, r1, carry, carry);
    +        MP_ADD_CARRY(a2, r2, r2, carry, carry);
    +        MP_ADD_CARRY(a3, r3, r3, carry, carry);
    +        MP_ADD_CARRY(a4, r4, r4, carry, carry);
    +
    +        MP_CHECKOK(s_mp_pad(r, 5));
    +        MP_DIGIT(r, 4) = r4;
    +        MP_DIGIT(r, 3) = r3;
    +        MP_DIGIT(r, 2) = r2;
    +        MP_DIGIT(r, 1) = r1;
    +        MP_DIGIT(r, 0) = r0;
    +        MP_SIGN(r) = MP_ZPOS;
    +        MP_USED(r) = 5;
    +
    +        /* Do quick 'subract' if we've gone over
    +         * (add the 2's complement of the curve field) */
    +         a4 = MP_DIGIT(&meth->irr,4);
    +        if (carry ||  r4 >  a4 ||
    +                ((r4 == a4) && mp_cmp(r,&meth->irr) != MP_LT)) {
    +                a3 = MP_DIGIT(&meth->irr,3);
    +                a2 = MP_DIGIT(&meth->irr,2);
    +                a1 = MP_DIGIT(&meth->irr,1);
    +                a0 = MP_DIGIT(&meth->irr,0);
    +                MP_SUB_BORROW(r0, a0, r0, 0,     carry);
    +                MP_SUB_BORROW(r1, a1, r1, carry, carry);
    +                MP_SUB_BORROW(r2, a2, r2, carry, carry);
    +                MP_SUB_BORROW(r3, a3, r3, carry, carry);
    +                MP_SUB_BORROW(r4, a4, r4, carry, carry);
    +                MP_DIGIT(r, 4) = r4;
    +                MP_DIGIT(r, 3) = r3;
    +                MP_DIGIT(r, 2) = r2;
    +                MP_DIGIT(r, 1) = r1;
    +                MP_DIGIT(r, 0) = r0;
    +        }
    +
    +        s_mp_clamp(r);
    +
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* 6 words */
    +mp_err
    +ec_GFp_add_6(const mp_int *a, const mp_int *b, mp_int *r,
    +                        const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_digit a0 = 0, a1 = 0, a2 = 0, a3 = 0, a4 = 0, a5 = 0;
    +        mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0, r5 = 0;
    +        mp_digit carry;
    +
    +        switch(MP_USED(a)) {
    +        case 6:
    +                a5 = MP_DIGIT(a,5);
    +        case 5:
    +                a4 = MP_DIGIT(a,4);
    +        case 4:
    +                a3 = MP_DIGIT(a,3);
    +        case 3:
    +                a2 = MP_DIGIT(a,2);
    +        case 2:
    +                a1 = MP_DIGIT(a,1);
    +        case 1:
    +                a0 = MP_DIGIT(a,0);
    +        }
    +        switch(MP_USED(b)) {
    +        case 6:
    +                r5 = MP_DIGIT(b,5);
    +        case 5:
    +                r4 = MP_DIGIT(b,4);
    +        case 4:
    +                r3 = MP_DIGIT(b,3);
    +        case 3:
    +                r2 = MP_DIGIT(b,2);
    +        case 2:
    +                r1 = MP_DIGIT(b,1);
    +        case 1:
    +                r0 = MP_DIGIT(b,0);
    +        }
    +
    +        MP_ADD_CARRY(a0, r0, r0, 0,     carry);
    +        MP_ADD_CARRY(a1, r1, r1, carry, carry);
    +        MP_ADD_CARRY(a2, r2, r2, carry, carry);
    +        MP_ADD_CARRY(a3, r3, r3, carry, carry);
    +        MP_ADD_CARRY(a4, r4, r4, carry, carry);
    +        MP_ADD_CARRY(a5, r5, r5, carry, carry);
    +
    +        MP_CHECKOK(s_mp_pad(r, 6));
    +        MP_DIGIT(r, 5) = r5;
    +        MP_DIGIT(r, 4) = r4;
    +        MP_DIGIT(r, 3) = r3;
    +        MP_DIGIT(r, 2) = r2;
    +        MP_DIGIT(r, 1) = r1;
    +        MP_DIGIT(r, 0) = r0;
    +        MP_SIGN(r) = MP_ZPOS;
    +        MP_USED(r) = 6;
    +
    +        /* Do quick 'subract' if we've gone over
    +         * (add the 2's complement of the curve field) */
    +        a5 = MP_DIGIT(&meth->irr,5);
    +        if (carry ||  r5 >  a5 ||
    +                ((r5 == a5) && mp_cmp(r,&meth->irr) != MP_LT)) {
    +                a4 = MP_DIGIT(&meth->irr,4);
    +                a3 = MP_DIGIT(&meth->irr,3);
    +                a2 = MP_DIGIT(&meth->irr,2);
    +                a1 = MP_DIGIT(&meth->irr,1);
    +                a0 = MP_DIGIT(&meth->irr,0);
    +                MP_SUB_BORROW(r0, a0, r0, 0,     carry);
    +                MP_SUB_BORROW(r1, a1, r1, carry, carry);
    +                MP_SUB_BORROW(r2, a2, r2, carry, carry);
    +                MP_SUB_BORROW(r3, a3, r3, carry, carry);
    +                MP_SUB_BORROW(r4, a4, r4, carry, carry);
    +                MP_SUB_BORROW(r5, a5, r5, carry, carry);
    +                MP_DIGIT(r, 5) = r5;
    +                MP_DIGIT(r, 4) = r4;
    +                MP_DIGIT(r, 3) = r3;
    +                MP_DIGIT(r, 2) = r2;
    +                MP_DIGIT(r, 1) = r1;
    +                MP_DIGIT(r, 0) = r0;
    +        }
    +
    +        s_mp_clamp(r);
    +
    +  CLEANUP:
    +        return res;
    +}
    +
    +/*
    + * The following subraction functions do in-line subractions based
    + * on our curve size.
    + *
    + * ... 3 words
    + */
    +mp_err
    +ec_GFp_sub_3(const mp_int *a, const mp_int *b, mp_int *r,
    +                        const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_digit b0 = 0, b1 = 0, b2 = 0;
    +        mp_digit r0 = 0, r1 = 0, r2 = 0;
    +        mp_digit borrow;
    +
    +        switch(MP_USED(a)) {
    +        case 3:
    +                r2 = MP_DIGIT(a,2);
    +        case 2:
    +                r1 = MP_DIGIT(a,1);
    +        case 1:
    +                r0 = MP_DIGIT(a,0);
    +        }
    +        switch(MP_USED(b)) {
    +        case 3:
    +                b2 = MP_DIGIT(b,2);
    +        case 2:
    +                b1 = MP_DIGIT(b,1);
    +        case 1:
    +                b0 = MP_DIGIT(b,0);
    +        }
    +
    +#ifndef MPI_AMD64_ADD
    +        MP_SUB_BORROW(r0, b0, r0, 0,     borrow);
    +        MP_SUB_BORROW(r1, b1, r1, borrow, borrow);
    +        MP_SUB_BORROW(r2, b2, r2, borrow, borrow);
    +#else
    +        __asm__ (
    +                "xorq   %3,%3           \n\t"
    +                "subq   %4,%0           \n\t"
    +                "sbbq   %5,%1           \n\t"
    +                "sbbq   %6,%2           \n\t"
    +                "adcq   $0,%3           \n\t"
    +                : "=r"(r0), "=r"(r1), "=r"(r2), "=r" (borrow)
    +                : "r" (b0), "r" (b1), "r" (b2),
    +                  "0" (r0), "1" (r1), "2" (r2)
    +                : "%cc" );
    +#endif
    +
    +        /* Do quick 'add' if we've gone under 0
    +         * (subtract the 2's complement of the curve field) */
    +        if (borrow) {
    +                b2 = MP_DIGIT(&meth->irr,2);
    +                b1 = MP_DIGIT(&meth->irr,1);
    +                b0 = MP_DIGIT(&meth->irr,0);
    +#ifndef MPI_AMD64_ADD
    +                MP_ADD_CARRY(b0, r0, r0, 0,      borrow);
    +                MP_ADD_CARRY(b1, r1, r1, borrow, borrow);
    +                MP_ADD_CARRY(b2, r2, r2, borrow, borrow);
    +#else
    +                __asm__ (
    +                        "addq   %3,%0           \n\t"
    +                        "adcq   %4,%1           \n\t"
    +                        "adcq   %5,%2           \n\t"
    +                        : "=r"(r0), "=r"(r1), "=r"(r2)
    +                        : "r" (b0), "r" (b1), "r" (b2),
    +                          "0" (r0), "1" (r1), "2" (r2)
    +                        : "%cc" );
    +#endif
    +        }
    +
    +#ifdef MPI_AMD64_ADD
    +        /* compiler fakeout? */
    +        if ((r2 == b0) && (r1 == b0) && (r0 == b0)) {
    +                MP_CHECKOK(s_mp_pad(r, 4));
    +        }
    +#endif
    +        MP_CHECKOK(s_mp_pad(r, 3));
    +        MP_DIGIT(r, 2) = r2;
    +        MP_DIGIT(r, 1) = r1;
    +        MP_DIGIT(r, 0) = r0;
    +        MP_SIGN(r) = MP_ZPOS;
    +        MP_USED(r) = 3;
    +        s_mp_clamp(r);
    +
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* 4 words */
    +mp_err
    +ec_GFp_sub_4(const mp_int *a, const mp_int *b, mp_int *r,
    +                        const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_digit b0 = 0, b1 = 0, b2 = 0, b3 = 0;
    +        mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0;
    +        mp_digit borrow;
    +
    +        switch(MP_USED(a)) {
    +        case 4:
    +                r3 = MP_DIGIT(a,3);
    +        case 3:
    +                r2 = MP_DIGIT(a,2);
    +        case 2:
    +                r1 = MP_DIGIT(a,1);
    +        case 1:
    +                r0 = MP_DIGIT(a,0);
    +        }
    +        switch(MP_USED(b)) {
    +        case 4:
    +                b3 = MP_DIGIT(b,3);
    +        case 3:
    +                b2 = MP_DIGIT(b,2);
    +        case 2:
    +                b1 = MP_DIGIT(b,1);
    +        case 1:
    +                b0 = MP_DIGIT(b,0);
    +        }
    +
    +#ifndef MPI_AMD64_ADD
    +        MP_SUB_BORROW(r0, b0, r0, 0,     borrow);
    +        MP_SUB_BORROW(r1, b1, r1, borrow, borrow);
    +        MP_SUB_BORROW(r2, b2, r2, borrow, borrow);
    +        MP_SUB_BORROW(r3, b3, r3, borrow, borrow);
    +#else
    +        __asm__ (
    +                "xorq   %4,%4           \n\t"
    +                "subq   %5,%0           \n\t"
    +                "sbbq   %6,%1           \n\t"
    +                "sbbq   %7,%2           \n\t"
    +                "sbbq   %8,%3           \n\t"
    +                "adcq   $0,%4           \n\t"
    +                : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3), "=r" (borrow)
    +                : "r" (b0), "r" (b1), "r" (b2), "r" (b3),
    +                  "0" (r0), "1" (r1), "2" (r2), "3" (r3)
    +                : "%cc" );
    +#endif
    +
    +        /* Do quick 'add' if we've gone under 0
    +         * (subtract the 2's complement of the curve field) */
    +        if (borrow) {
    +                b3 = MP_DIGIT(&meth->irr,3);
    +                b2 = MP_DIGIT(&meth->irr,2);
    +                b1 = MP_DIGIT(&meth->irr,1);
    +                b0 = MP_DIGIT(&meth->irr,0);
    +#ifndef MPI_AMD64_ADD
    +                MP_ADD_CARRY(b0, r0, r0, 0,      borrow);
    +                MP_ADD_CARRY(b1, r1, r1, borrow, borrow);
    +                MP_ADD_CARRY(b2, r2, r2, borrow, borrow);
    +                MP_ADD_CARRY(b3, r3, r3, borrow, borrow);
    +#else
    +                __asm__ (
    +                        "addq   %4,%0           \n\t"
    +                        "adcq   %5,%1           \n\t"
    +                        "adcq   %6,%2           \n\t"
    +                        "adcq   %7,%3           \n\t"
    +                        : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3)
    +                        : "r" (b0), "r" (b1), "r" (b2), "r" (b3),
    +                          "0" (r0), "1" (r1), "2" (r2), "3" (r3)
    +                        : "%cc" );
    +#endif
    +        }
    +#ifdef MPI_AMD64_ADD
    +        /* compiler fakeout? */
    +        if ((r3 == b0) && (r1 == b0) && (r0 == b0)) {
    +                MP_CHECKOK(s_mp_pad(r, 4));
    +        }
    +#endif
    +        MP_CHECKOK(s_mp_pad(r, 4));
    +        MP_DIGIT(r, 3) = r3;
    +        MP_DIGIT(r, 2) = r2;
    +        MP_DIGIT(r, 1) = r1;
    +        MP_DIGIT(r, 0) = r0;
    +        MP_SIGN(r) = MP_ZPOS;
    +        MP_USED(r) = 4;
    +        s_mp_clamp(r);
    +
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* 5 words */
    +mp_err
    +ec_GFp_sub_5(const mp_int *a, const mp_int *b, mp_int *r,
    +                        const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_digit b0 = 0, b1 = 0, b2 = 0, b3 = 0, b4 = 0;
    +        mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0;
    +        mp_digit borrow;
    +
    +        switch(MP_USED(a)) {
    +        case 5:
    +                r4 = MP_DIGIT(a,4);
    +        case 4:
    +                r3 = MP_DIGIT(a,3);
    +        case 3:
    +                r2 = MP_DIGIT(a,2);
    +        case 2:
    +                r1 = MP_DIGIT(a,1);
    +        case 1:
    +                r0 = MP_DIGIT(a,0);
    +        }
    +        switch(MP_USED(b)) {
    +        case 5:
    +                b4 = MP_DIGIT(b,4);
    +        case 4:
    +                b3 = MP_DIGIT(b,3);
    +        case 3:
    +                b2 = MP_DIGIT(b,2);
    +        case 2:
    +                b1 = MP_DIGIT(b,1);
    +        case 1:
    +                b0 = MP_DIGIT(b,0);
    +        }
    +
    +        MP_SUB_BORROW(r0, b0, r0, 0,     borrow);
    +        MP_SUB_BORROW(r1, b1, r1, borrow, borrow);
    +        MP_SUB_BORROW(r2, b2, r2, borrow, borrow);
    +        MP_SUB_BORROW(r3, b3, r3, borrow, borrow);
    +        MP_SUB_BORROW(r4, b4, r4, borrow, borrow);
    +
    +        /* Do quick 'add' if we've gone under 0
    +         * (subtract the 2's complement of the curve field) */
    +        if (borrow) {
    +                b4 = MP_DIGIT(&meth->irr,4);
    +                b3 = MP_DIGIT(&meth->irr,3);
    +                b2 = MP_DIGIT(&meth->irr,2);
    +                b1 = MP_DIGIT(&meth->irr,1);
    +                b0 = MP_DIGIT(&meth->irr,0);
    +                MP_ADD_CARRY(b0, r0, r0, 0,      borrow);
    +                MP_ADD_CARRY(b1, r1, r1, borrow, borrow);
    +                MP_ADD_CARRY(b2, r2, r2, borrow, borrow);
    +                MP_ADD_CARRY(b3, r3, r3, borrow, borrow);
    +        }
    +        MP_CHECKOK(s_mp_pad(r, 5));
    +        MP_DIGIT(r, 4) = r4;
    +        MP_DIGIT(r, 3) = r3;
    +        MP_DIGIT(r, 2) = r2;
    +        MP_DIGIT(r, 1) = r1;
    +        MP_DIGIT(r, 0) = r0;
    +        MP_SIGN(r) = MP_ZPOS;
    +        MP_USED(r) = 5;
    +        s_mp_clamp(r);
    +
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* 6 words */
    +mp_err
    +ec_GFp_sub_6(const mp_int *a, const mp_int *b, mp_int *r,
    +                        const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_digit b0 = 0, b1 = 0, b2 = 0, b3 = 0, b4 = 0, b5 = 0;
    +        mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0, r5 = 0;
    +        mp_digit borrow;
    +
    +        switch(MP_USED(a)) {
    +        case 6:
    +                r5 = MP_DIGIT(a,5);
    +        case 5:
    +                r4 = MP_DIGIT(a,4);
    +        case 4:
    +                r3 = MP_DIGIT(a,3);
    +        case 3:
    +                r2 = MP_DIGIT(a,2);
    +        case 2:
    +                r1 = MP_DIGIT(a,1);
    +        case 1:
    +                r0 = MP_DIGIT(a,0);
    +        }
    +        switch(MP_USED(b)) {
    +        case 6:
    +                b5 = MP_DIGIT(b,5);
    +        case 5:
    +                b4 = MP_DIGIT(b,4);
    +        case 4:
    +                b3 = MP_DIGIT(b,3);
    +        case 3:
    +                b2 = MP_DIGIT(b,2);
    +        case 2:
    +                b1 = MP_DIGIT(b,1);
    +        case 1:
    +                b0 = MP_DIGIT(b,0);
    +        }
    +
    +        MP_SUB_BORROW(r0, b0, r0, 0,     borrow);
    +        MP_SUB_BORROW(r1, b1, r1, borrow, borrow);
    +        MP_SUB_BORROW(r2, b2, r2, borrow, borrow);
    +        MP_SUB_BORROW(r3, b3, r3, borrow, borrow);
    +        MP_SUB_BORROW(r4, b4, r4, borrow, borrow);
    +        MP_SUB_BORROW(r5, b5, r5, borrow, borrow);
    +
    +        /* Do quick 'add' if we've gone under 0
    +         * (subtract the 2's complement of the curve field) */
    +        if (borrow) {
    +                b5 = MP_DIGIT(&meth->irr,5);
    +                b4 = MP_DIGIT(&meth->irr,4);
    +                b3 = MP_DIGIT(&meth->irr,3);
    +                b2 = MP_DIGIT(&meth->irr,2);
    +                b1 = MP_DIGIT(&meth->irr,1);
    +                b0 = MP_DIGIT(&meth->irr,0);
    +                MP_ADD_CARRY(b0, r0, r0, 0,      borrow);
    +                MP_ADD_CARRY(b1, r1, r1, borrow, borrow);
    +                MP_ADD_CARRY(b2, r2, r2, borrow, borrow);
    +                MP_ADD_CARRY(b3, r3, r3, borrow, borrow);
    +                MP_ADD_CARRY(b4, r4, r4, borrow, borrow);
    +        }
    +
    +        MP_CHECKOK(s_mp_pad(r, 6));
    +        MP_DIGIT(r, 5) = r5;
    +        MP_DIGIT(r, 4) = r4;
    +        MP_DIGIT(r, 3) = r3;
    +        MP_DIGIT(r, 2) = r2;
    +        MP_DIGIT(r, 1) = r1;
    +        MP_DIGIT(r, 0) = r0;
    +        MP_SIGN(r) = MP_ZPOS;
    +        MP_USED(r) = 6;
    +        s_mp_clamp(r);
    +
    +  CLEANUP:
    +        return res;
    +}
    +
    +
    +/* Reduces an integer to a field element. */
    +mp_err
    +ec_GFp_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
    +{
    +        return mp_mod(a, &meth->irr, r);
    +}
    +
    +/* Multiplies two field elements. */
    +mp_err
    +ec_GFp_mul(const mp_int *a, const mp_int *b, mp_int *r,
    +                   const GFMethod *meth)
    +{
    +        return mp_mulmod(a, b, &meth->irr, r);
    +}
    +
    +/* Squares a field element. */
    +mp_err
    +ec_GFp_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
    +{
    +        return mp_sqrmod(a, &meth->irr, r);
    +}
    +
    +/* Divides two field elements. If a is NULL, then returns the inverse of
    + * b. */
    +mp_err
    +ec_GFp_div(const mp_int *a, const mp_int *b, mp_int *r,
    +                   const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_int t;
    +
    +        /* If a is NULL, then return the inverse of b, otherwise return a/b. */
    +        if (a == NULL) {
    +                return mp_invmod(b, &meth->irr, r);
    +        } else {
    +                /* MPI doesn't support divmod, so we implement it using invmod and
    +                 * mulmod. */
    +                MP_CHECKOK(mp_init(&t, FLAG(b)));
    +                MP_CHECKOK(mp_invmod(b, &meth->irr, &t));
    +                MP_CHECKOK(mp_mulmod(a, &t, &meth->irr, r));
    +          CLEANUP:
    +                mp_clear(&t);
    +                return res;
    +        }
    +}
    +
    +/* Wrapper functions for generic binary polynomial field arithmetic. */
    +
    +/* Adds two field elements. */
    +mp_err
    +ec_GF2m_add(const mp_int *a, const mp_int *b, mp_int *r,
    +                        const GFMethod *meth)
    +{
    +        return mp_badd(a, b, r);
    +}
    +
    +/* Negates a field element. Note that for binary polynomial fields, the
    + * negation of a field element is the field element itself. */
    +mp_err
    +ec_GF2m_neg(const mp_int *a, mp_int *r, const GFMethod *meth)
    +{
    +        if (a == r) {
    +                return MP_OKAY;
    +        } else {
    +                return mp_copy(a, r);
    +        }
    +}
    +
    +/* Reduces a binary polynomial to a field element. */
    +mp_err
    +ec_GF2m_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
    +{
    +        return mp_bmod(a, meth->irr_arr, r);
    +}
    +
    +/* Multiplies two field elements. */
    +mp_err
    +ec_GF2m_mul(const mp_int *a, const mp_int *b, mp_int *r,
    +                        const GFMethod *meth)
    +{
    +        return mp_bmulmod(a, b, meth->irr_arr, r);
    +}
    +
    +/* Squares a field element. */
    +mp_err
    +ec_GF2m_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
    +{
    +        return mp_bsqrmod(a, meth->irr_arr, r);
    +}
    +
    +/* Divides two field elements. If a is NULL, then returns the inverse of
    + * b. */
    +mp_err
    +ec_GF2m_div(const mp_int *a, const mp_int *b, mp_int *r,
    +                        const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_int t;
    +
    +        /* If a is NULL, then return the inverse of b, otherwise return a/b. */
    +        if (a == NULL) {
    +                /* The GF(2^m) portion of MPI doesn't support invmod, so we
    +                 * compute 1/b. */
    +                MP_CHECKOK(mp_init(&t, FLAG(b)));
    +                MP_CHECKOK(mp_set_int(&t, 1));
    +                MP_CHECKOK(mp_bdivmod(&t, b, &meth->irr, meth->irr_arr, r));
    +          CLEANUP:
    +                mp_clear(&t);
    +                return res;
    +        } else {
    +                return mp_bdivmod(a, b, &meth->irr, meth->irr_arr, r);
    +        }
    +}
    diff --git a/jdk/src/share/native/sun/security/ec/ecl_mult.c b/jdk/src/share/native/sun/security/ec/ecl_mult.c
    new file mode 100644
    index 00000000000..c5a01fabad3
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/ecl_mult.c
    @@ -0,0 +1,378 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the elliptic curve math library.
    + *
    + * The Initial Developer of the Original Code is
    + * Sun Microsystems, Inc.
    + * Portions created by the Initial Developer are Copyright (C) 2003
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Douglas Stebila , Sun Microsystems Laboratories
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +#include "mpi.h"
    +#include "mplogic.h"
    +#include "ecl.h"
    +#include "ecl-priv.h"
    +#ifndef _KERNEL
    +#include 
    +#endif
    +
    +/* Elliptic curve scalar-point multiplication. Computes R(x, y) = k * P(x,
    + * y).  If x, y = NULL, then P is assumed to be the generator (base point)
    + * of the group of points on the elliptic curve. Input and output values
    + * are assumed to be NOT field-encoded. */
    +mp_err
    +ECPoint_mul(const ECGroup *group, const mp_int *k, const mp_int *px,
    +                        const mp_int *py, mp_int *rx, mp_int *ry)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_int kt;
    +
    +        ARGCHK((k != NULL) && (group != NULL), MP_BADARG);
    +        MP_DIGITS(&kt) = 0;
    +
    +        /* want scalar to be less than or equal to group order */
    +        if (mp_cmp(k, &group->order) > 0) {
    +                MP_CHECKOK(mp_init(&kt, FLAG(k)));
    +                MP_CHECKOK(mp_mod(k, &group->order, &kt));
    +        } else {
    +                MP_SIGN(&kt) = MP_ZPOS;
    +                MP_USED(&kt) = MP_USED(k);
    +                MP_ALLOC(&kt) = MP_ALLOC(k);
    +                MP_DIGITS(&kt) = MP_DIGITS(k);
    +        }
    +
    +        if ((px == NULL) || (py == NULL)) {
    +                if (group->base_point_mul) {
    +                        MP_CHECKOK(group->base_point_mul(&kt, rx, ry, group));
    +                } else {
    +                        MP_CHECKOK(group->
    +                                           point_mul(&kt, &group->genx, &group->geny, rx, ry,
    +                                                                 group));
    +                }
    +        } else {
    +                if (group->meth->field_enc) {
    +                        MP_CHECKOK(group->meth->field_enc(px, rx, group->meth));
    +                        MP_CHECKOK(group->meth->field_enc(py, ry, group->meth));
    +                        MP_CHECKOK(group->point_mul(&kt, rx, ry, rx, ry, group));
    +                } else {
    +                        MP_CHECKOK(group->point_mul(&kt, px, py, rx, ry, group));
    +                }
    +        }
    +        if (group->meth->field_dec) {
    +                MP_CHECKOK(group->meth->field_dec(rx, rx, group->meth));
    +                MP_CHECKOK(group->meth->field_dec(ry, ry, group->meth));
    +        }
    +
    +  CLEANUP:
    +        if (MP_DIGITS(&kt) != MP_DIGITS(k)) {
    +                mp_clear(&kt);
    +        }
    +        return res;
    +}
    +
    +/* Elliptic curve scalar-point multiplication. Computes R(x, y) = k1 * G +
    + * k2 * P(x, y), where G is the generator (base point) of the group of
    + * points on the elliptic curve. Allows k1 = NULL or { k2, P } = NULL.
    + * Input and output values are assumed to be NOT field-encoded. */
    +mp_err
    +ec_pts_mul_basic(const mp_int *k1, const mp_int *k2, const mp_int *px,
    +                                 const mp_int *py, mp_int *rx, mp_int *ry,
    +                                 const ECGroup *group)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_int sx, sy;
    +
    +        ARGCHK(group != NULL, MP_BADARG);
    +        ARGCHK(!((k1 == NULL)
    +                         && ((k2 == NULL) || (px == NULL)
    +                                 || (py == NULL))), MP_BADARG);
    +
    +        /* if some arguments are not defined used ECPoint_mul */
    +        if (k1 == NULL) {
    +                return ECPoint_mul(group, k2, px, py, rx, ry);
    +        } else if ((k2 == NULL) || (px == NULL) || (py == NULL)) {
    +                return ECPoint_mul(group, k1, NULL, NULL, rx, ry);
    +        }
    +
    +        MP_DIGITS(&sx) = 0;
    +        MP_DIGITS(&sy) = 0;
    +        MP_CHECKOK(mp_init(&sx, FLAG(k1)));
    +        MP_CHECKOK(mp_init(&sy, FLAG(k1)));
    +
    +        MP_CHECKOK(ECPoint_mul(group, k1, NULL, NULL, &sx, &sy));
    +        MP_CHECKOK(ECPoint_mul(group, k2, px, py, rx, ry));
    +
    +        if (group->meth->field_enc) {
    +                MP_CHECKOK(group->meth->field_enc(&sx, &sx, group->meth));
    +                MP_CHECKOK(group->meth->field_enc(&sy, &sy, group->meth));
    +                MP_CHECKOK(group->meth->field_enc(rx, rx, group->meth));
    +                MP_CHECKOK(group->meth->field_enc(ry, ry, group->meth));
    +        }
    +
    +        MP_CHECKOK(group->point_add(&sx, &sy, rx, ry, rx, ry, group));
    +
    +        if (group->meth->field_dec) {
    +                MP_CHECKOK(group->meth->field_dec(rx, rx, group->meth));
    +                MP_CHECKOK(group->meth->field_dec(ry, ry, group->meth));
    +        }
    +
    +  CLEANUP:
    +        mp_clear(&sx);
    +        mp_clear(&sy);
    +        return res;
    +}
    +
    +/* Elliptic curve scalar-point multiplication. Computes R(x, y) = k1 * G +
    + * k2 * P(x, y), where G is the generator (base point) of the group of
    + * points on the elliptic curve. Allows k1 = NULL or { k2, P } = NULL.
    + * Input and output values are assumed to be NOT field-encoded. Uses
    + * algorithm 15 (simultaneous multiple point multiplication) from Brown,
    + * Hankerson, Lopez, Menezes. Software Implementation of the NIST
    + * Elliptic Curves over Prime Fields. */
    +mp_err
    +ec_pts_mul_simul_w2(const mp_int *k1, const mp_int *k2, const mp_int *px,
    +                                        const mp_int *py, mp_int *rx, mp_int *ry,
    +                                        const ECGroup *group)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_int precomp[4][4][2];
    +        const mp_int *a, *b;
    +        int i, j;
    +        int ai, bi, d;
    +
    +        ARGCHK(group != NULL, MP_BADARG);
    +        ARGCHK(!((k1 == NULL)
    +                         && ((k2 == NULL) || (px == NULL)
    +                                 || (py == NULL))), MP_BADARG);
    +
    +        /* if some arguments are not defined used ECPoint_mul */
    +        if (k1 == NULL) {
    +                return ECPoint_mul(group, k2, px, py, rx, ry);
    +        } else if ((k2 == NULL) || (px == NULL) || (py == NULL)) {
    +                return ECPoint_mul(group, k1, NULL, NULL, rx, ry);
    +        }
    +
    +        /* initialize precomputation table */
    +        for (i = 0; i < 4; i++) {
    +                for (j = 0; j < 4; j++) {
    +                        MP_DIGITS(&precomp[i][j][0]) = 0;
    +                        MP_DIGITS(&precomp[i][j][1]) = 0;
    +                }
    +        }
    +        for (i = 0; i < 4; i++) {
    +                for (j = 0; j < 4; j++) {
    +                         MP_CHECKOK( mp_init_size(&precomp[i][j][0],
    +                                         ECL_MAX_FIELD_SIZE_DIGITS, FLAG(k1)) );
    +                         MP_CHECKOK( mp_init_size(&precomp[i][j][1],
    +                                         ECL_MAX_FIELD_SIZE_DIGITS, FLAG(k1)) );
    +                }
    +        }
    +
    +        /* fill precomputation table */
    +        /* assign {k1, k2} = {a, b} such that len(a) >= len(b) */
    +        if (mpl_significant_bits(k1) < mpl_significant_bits(k2)) {
    +                a = k2;
    +                b = k1;
    +                if (group->meth->field_enc) {
    +                        MP_CHECKOK(group->meth->
    +                                           field_enc(px, &precomp[1][0][0], group->meth));
    +                        MP_CHECKOK(group->meth->
    +                                           field_enc(py, &precomp[1][0][1], group->meth));
    +                } else {
    +                        MP_CHECKOK(mp_copy(px, &precomp[1][0][0]));
    +                        MP_CHECKOK(mp_copy(py, &precomp[1][0][1]));
    +                }
    +                MP_CHECKOK(mp_copy(&group->genx, &precomp[0][1][0]));
    +                MP_CHECKOK(mp_copy(&group->geny, &precomp[0][1][1]));
    +        } else {
    +                a = k1;
    +                b = k2;
    +                MP_CHECKOK(mp_copy(&group->genx, &precomp[1][0][0]));
    +                MP_CHECKOK(mp_copy(&group->geny, &precomp[1][0][1]));
    +                if (group->meth->field_enc) {
    +                        MP_CHECKOK(group->meth->
    +                                           field_enc(px, &precomp[0][1][0], group->meth));
    +                        MP_CHECKOK(group->meth->
    +                                           field_enc(py, &precomp[0][1][1], group->meth));
    +                } else {
    +                        MP_CHECKOK(mp_copy(px, &precomp[0][1][0]));
    +                        MP_CHECKOK(mp_copy(py, &precomp[0][1][1]));
    +                }
    +        }
    +        /* precompute [*][0][*] */
    +        mp_zero(&precomp[0][0][0]);
    +        mp_zero(&precomp[0][0][1]);
    +        MP_CHECKOK(group->
    +                           point_dbl(&precomp[1][0][0], &precomp[1][0][1],
    +                                                 &precomp[2][0][0], &precomp[2][0][1], group));
    +        MP_CHECKOK(group->
    +                           point_add(&precomp[1][0][0], &precomp[1][0][1],
    +                                                 &precomp[2][0][0], &precomp[2][0][1],
    +                                                 &precomp[3][0][0], &precomp[3][0][1], group));
    +        /* precompute [*][1][*] */
    +        for (i = 1; i < 4; i++) {
    +                MP_CHECKOK(group->
    +                                   point_add(&precomp[0][1][0], &precomp[0][1][1],
    +                                                         &precomp[i][0][0], &precomp[i][0][1],
    +                                                         &precomp[i][1][0], &precomp[i][1][1], group));
    +        }
    +        /* precompute [*][2][*] */
    +        MP_CHECKOK(group->
    +                           point_dbl(&precomp[0][1][0], &precomp[0][1][1],
    +                                                 &precomp[0][2][0], &precomp[0][2][1], group));
    +        for (i = 1; i < 4; i++) {
    +                MP_CHECKOK(group->
    +                                   point_add(&precomp[0][2][0], &precomp[0][2][1],
    +                                                         &precomp[i][0][0], &precomp[i][0][1],
    +                                                         &precomp[i][2][0], &precomp[i][2][1], group));
    +        }
    +        /* precompute [*][3][*] */
    +        MP_CHECKOK(group->
    +                           point_add(&precomp[0][1][0], &precomp[0][1][1],
    +                                                 &precomp[0][2][0], &precomp[0][2][1],
    +                                                 &precomp[0][3][0], &precomp[0][3][1], group));
    +        for (i = 1; i < 4; i++) {
    +                MP_CHECKOK(group->
    +                                   point_add(&precomp[0][3][0], &precomp[0][3][1],
    +                                                         &precomp[i][0][0], &precomp[i][0][1],
    +                                                         &precomp[i][3][0], &precomp[i][3][1], group));
    +        }
    +
    +        d = (mpl_significant_bits(a) + 1) / 2;
    +
    +        /* R = inf */
    +        mp_zero(rx);
    +        mp_zero(ry);
    +
    +        for (i = d - 1; i >= 0; i--) {
    +                ai = MP_GET_BIT(a, 2 * i + 1);
    +                ai <<= 1;
    +                ai |= MP_GET_BIT(a, 2 * i);
    +                bi = MP_GET_BIT(b, 2 * i + 1);
    +                bi <<= 1;
    +                bi |= MP_GET_BIT(b, 2 * i);
    +                /* R = 2^2 * R */
    +                MP_CHECKOK(group->point_dbl(rx, ry, rx, ry, group));
    +                MP_CHECKOK(group->point_dbl(rx, ry, rx, ry, group));
    +                /* R = R + (ai * A + bi * B) */
    +                MP_CHECKOK(group->
    +                                   point_add(rx, ry, &precomp[ai][bi][0],
    +                                                         &precomp[ai][bi][1], rx, ry, group));
    +        }
    +
    +        if (group->meth->field_dec) {
    +                MP_CHECKOK(group->meth->field_dec(rx, rx, group->meth));
    +                MP_CHECKOK(group->meth->field_dec(ry, ry, group->meth));
    +        }
    +
    +  CLEANUP:
    +        for (i = 0; i < 4; i++) {
    +                for (j = 0; j < 4; j++) {
    +                        mp_clear(&precomp[i][j][0]);
    +                        mp_clear(&precomp[i][j][1]);
    +                }
    +        }
    +        return res;
    +}
    +
    +/* Elliptic curve scalar-point multiplication. Computes R(x, y) = k1 * G +
    + * k2 * P(x, y), where G is the generator (base point) of the group of
    + * points on the elliptic curve. Allows k1 = NULL or { k2, P } = NULL.
    + * Input and output values are assumed to be NOT field-encoded. */
    +mp_err
    +ECPoints_mul(const ECGroup *group, const mp_int *k1, const mp_int *k2,
    +                         const mp_int *px, const mp_int *py, mp_int *rx, mp_int *ry)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_int k1t, k2t;
    +        const mp_int *k1p, *k2p;
    +
    +        MP_DIGITS(&k1t) = 0;
    +        MP_DIGITS(&k2t) = 0;
    +
    +        ARGCHK(group != NULL, MP_BADARG);
    +
    +        /* want scalar to be less than or equal to group order */
    +        if (k1 != NULL) {
    +                if (mp_cmp(k1, &group->order) >= 0) {
    +                        MP_CHECKOK(mp_init(&k1t, FLAG(k1)));
    +                        MP_CHECKOK(mp_mod(k1, &group->order, &k1t));
    +                        k1p = &k1t;
    +                } else {
    +                        k1p = k1;
    +                }
    +        } else {
    +                k1p = k1;
    +        }
    +        if (k2 != NULL) {
    +                if (mp_cmp(k2, &group->order) >= 0) {
    +                        MP_CHECKOK(mp_init(&k2t, FLAG(k2)));
    +                        MP_CHECKOK(mp_mod(k2, &group->order, &k2t));
    +                        k2p = &k2t;
    +                } else {
    +                        k2p = k2;
    +                }
    +        } else {
    +                k2p = k2;
    +        }
    +
    +        /* if points_mul is defined, then use it */
    +        if (group->points_mul) {
    +                res = group->points_mul(k1p, k2p, px, py, rx, ry, group);
    +        } else {
    +                res = ec_pts_mul_simul_w2(k1p, k2p, px, py, rx, ry, group);
    +        }
    +
    +  CLEANUP:
    +        mp_clear(&k1t);
    +        mp_clear(&k2t);
    +        return res;
    +}
    diff --git a/jdk/src/share/native/sun/security/ec/ecp.h b/jdk/src/share/native/sun/security/ec/ecp.h
    new file mode 100644
    index 00000000000..5e045ba6320
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/ecp.h
    @@ -0,0 +1,160 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the elliptic curve math library for prime field curves.
    + *
    + * The Initial Developer of the Original Code is
    + * Sun Microsystems, Inc.
    + * Portions created by the Initial Developer are Copyright (C) 2003
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Douglas Stebila , Sun Microsystems Laboratories
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#ifndef _ECP_H
    +#define _ECP_H
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +#include "ecl-priv.h"
    +
    +/* Checks if point P(px, py) is at infinity.  Uses affine coordinates. */
    +mp_err ec_GFp_pt_is_inf_aff(const mp_int *px, const mp_int *py);
    +
    +/* Sets P(px, py) to be the point at infinity.  Uses affine coordinates. */
    +mp_err ec_GFp_pt_set_inf_aff(mp_int *px, mp_int *py);
    +
    +/* Computes R = P + Q where R is (rx, ry), P is (px, py) and Q is (qx,
    + * qy). Uses affine coordinates. */
    +mp_err ec_GFp_pt_add_aff(const mp_int *px, const mp_int *py,
    +                                                 const mp_int *qx, const mp_int *qy, mp_int *rx,
    +                                                 mp_int *ry, const ECGroup *group);
    +
    +/* Computes R = P - Q.  Uses affine coordinates. */
    +mp_err ec_GFp_pt_sub_aff(const mp_int *px, const mp_int *py,
    +                                                 const mp_int *qx, const mp_int *qy, mp_int *rx,
    +                                                 mp_int *ry, const ECGroup *group);
    +
    +/* Computes R = 2P.  Uses affine coordinates. */
    +mp_err ec_GFp_pt_dbl_aff(const mp_int *px, const mp_int *py, mp_int *rx,
    +                                                 mp_int *ry, const ECGroup *group);
    +
    +/* Validates a point on a GFp curve. */
    +mp_err ec_GFp_validate_point(const mp_int *px, const mp_int *py, const ECGroup *group);
    +
    +#ifdef ECL_ENABLE_GFP_PT_MUL_AFF
    +/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
    + * a, b and p are the elliptic curve coefficients and the prime that
    + * determines the field GFp.  Uses affine coordinates. */
    +mp_err ec_GFp_pt_mul_aff(const mp_int *n, const mp_int *px,
    +                                                 const mp_int *py, mp_int *rx, mp_int *ry,
    +                                                 const ECGroup *group);
    +#endif
    +
    +/* Converts a point P(px, py) from affine coordinates to Jacobian
    + * projective coordinates R(rx, ry, rz). */
    +mp_err ec_GFp_pt_aff2jac(const mp_int *px, const mp_int *py, mp_int *rx,
    +                                                 mp_int *ry, mp_int *rz, const ECGroup *group);
    +
    +/* Converts a point P(px, py, pz) from Jacobian projective coordinates to
    + * affine coordinates R(rx, ry). */
    +mp_err ec_GFp_pt_jac2aff(const mp_int *px, const mp_int *py,
    +                                                 const mp_int *pz, mp_int *rx, mp_int *ry,
    +                                                 const ECGroup *group);
    +
    +/* Checks if point P(px, py, pz) is at infinity.  Uses Jacobian
    + * coordinates. */
    +mp_err ec_GFp_pt_is_inf_jac(const mp_int *px, const mp_int *py,
    +                                                        const mp_int *pz);
    +
    +/* Sets P(px, py, pz) to be the point at infinity.  Uses Jacobian
    + * coordinates. */
    +mp_err ec_GFp_pt_set_inf_jac(mp_int *px, mp_int *py, mp_int *pz);
    +
    +/* Computes R = P + Q where R is (rx, ry, rz), P is (px, py, pz) and Q is
    + * (qx, qy, qz).  Uses Jacobian coordinates. */
    +mp_err ec_GFp_pt_add_jac_aff(const mp_int *px, const mp_int *py,
    +                                                         const mp_int *pz, const mp_int *qx,
    +                                                         const mp_int *qy, mp_int *rx, mp_int *ry,
    +                                                         mp_int *rz, const ECGroup *group);
    +
    +/* Computes R = 2P.  Uses Jacobian coordinates. */
    +mp_err ec_GFp_pt_dbl_jac(const mp_int *px, const mp_int *py,
    +                                                 const mp_int *pz, mp_int *rx, mp_int *ry,
    +                                                 mp_int *rz, const ECGroup *group);
    +
    +#ifdef ECL_ENABLE_GFP_PT_MUL_JAC
    +/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
    + * a, b and p are the elliptic curve coefficients and the prime that
    + * determines the field GFp.  Uses Jacobian coordinates. */
    +mp_err ec_GFp_pt_mul_jac(const mp_int *n, const mp_int *px,
    +                                                 const mp_int *py, mp_int *rx, mp_int *ry,
    +                                                 const ECGroup *group);
    +#endif
    +
    +/* Computes R(x, y) = k1 * G + k2 * P(x, y), where G is the generator
    + * (base point) of the group of points on the elliptic curve. Allows k1 =
    + * NULL or { k2, P } = NULL.  Implemented using mixed Jacobian-affine
    + * coordinates. Input and output values are assumed to be NOT
    + * field-encoded and are in affine form. */
    +mp_err
    + ec_GFp_pts_mul_jac(const mp_int *k1, const mp_int *k2, const mp_int *px,
    +                                        const mp_int *py, mp_int *rx, mp_int *ry,
    +                                        const ECGroup *group);
    +
    +/* Computes R = nP where R is (rx, ry) and P is the base point. Elliptic
    + * curve points P and R can be identical. Uses mixed Modified-Jacobian
    + * co-ordinates for doubling and Chudnovsky Jacobian coordinates for
    + * additions. Assumes input is already field-encoded using field_enc, and
    + * returns output that is still field-encoded. Uses 5-bit window NAF
    + * method (algorithm 11) for scalar-point multiplication from Brown,
    + * Hankerson, Lopez, Menezes. Software Implementation of the NIST Elliptic
    + * Curves Over Prime Fields. */
    +mp_err
    + ec_GFp_pt_mul_jm_wNAF(const mp_int *n, const mp_int *px, const mp_int *py,
    +                                           mp_int *rx, mp_int *ry, const ECGroup *group);
    +
    +#endif /* _ECP_H */
    diff --git a/jdk/src/share/native/sun/security/ec/ecp_192.c b/jdk/src/share/native/sun/security/ec/ecp_192.c
    new file mode 100644
    index 00000000000..f2c62a40e90
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/ecp_192.c
    @@ -0,0 +1,538 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the elliptic curve math library for prime field curves.
    + *
    + * The Initial Developer of the Original Code is
    + * Sun Microsystems, Inc.
    + * Portions created by the Initial Developer are Copyright (C) 2003
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Douglas Stebila , Sun Microsystems Laboratories
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +#include "ecp.h"
    +#include "mpi.h"
    +#include "mplogic.h"
    +#include "mpi-priv.h"
    +#ifndef _KERNEL
    +#include 
    +#endif
    +
    +#define ECP192_DIGITS ECL_CURVE_DIGITS(192)
    +
    +/* Fast modular reduction for p192 = 2^192 - 2^64 - 1.  a can be r. Uses
    + * algorithm 7 from Brown, Hankerson, Lopez, Menezes. Software
    + * Implementation of the NIST Elliptic Curves over Prime Fields. */
    +mp_err
    +ec_GFp_nistp192_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_size a_used = MP_USED(a);
    +        mp_digit r3;
    +#ifndef MPI_AMD64_ADD
    +        mp_digit carry;
    +#endif
    +#ifdef ECL_THIRTY_TWO_BIT
    +        mp_digit a5a = 0, a5b = 0, a4a = 0, a4b = 0, a3a = 0, a3b = 0;
    +        mp_digit r0a, r0b, r1a, r1b, r2a, r2b;
    +#else
    +        mp_digit a5 = 0, a4 = 0, a3 = 0;
    +        mp_digit r0, r1, r2;
    +#endif
    +
    +        /* reduction not needed if a is not larger than field size */
    +        if (a_used < ECP192_DIGITS) {
    +                if (a == r) {
    +                        return MP_OKAY;
    +                }
    +                return mp_copy(a, r);
    +        }
    +
    +        /* for polynomials larger than twice the field size, use regular
    +         * reduction */
    +        if (a_used > ECP192_DIGITS*2) {
    +                MP_CHECKOK(mp_mod(a, &meth->irr, r));
    +        } else {
    +                /* copy out upper words of a */
    +
    +#ifdef ECL_THIRTY_TWO_BIT
    +
    +                /* in all the math below,
    +                 * nXb is most signifiant, nXa is least significant */
    +                switch (a_used) {
    +                case 12:
    +                        a5b = MP_DIGIT(a, 11);
    +                case 11:
    +                        a5a = MP_DIGIT(a, 10);
    +                case 10:
    +                        a4b = MP_DIGIT(a, 9);
    +                case 9:
    +                        a4a = MP_DIGIT(a, 8);
    +                case 8:
    +                        a3b = MP_DIGIT(a, 7);
    +                case 7:
    +                        a3a = MP_DIGIT(a, 6);
    +                }
    +
    +
    +                r2b= MP_DIGIT(a, 5);
    +                r2a= MP_DIGIT(a, 4);
    +                r1b = MP_DIGIT(a, 3);
    +                r1a = MP_DIGIT(a, 2);
    +                r0b = MP_DIGIT(a, 1);
    +                r0a = MP_DIGIT(a, 0);
    +
    +                /* implement r = (a2,a1,a0)+(a5,a5,a5)+(a4,a4,0)+(0,a3,a3) */
    +                MP_ADD_CARRY(r0a, a3a, r0a, 0,    carry);
    +                MP_ADD_CARRY(r0b, a3b, r0b, carry, carry);
    +                MP_ADD_CARRY(r1a, a3a, r1a, carry, carry);
    +                MP_ADD_CARRY(r1b, a3b, r1b, carry, carry);
    +                MP_ADD_CARRY(r2a, a4a, r2a, carry, carry);
    +                MP_ADD_CARRY(r2b, a4b, r2b, carry, carry);
    +                r3 = carry; carry = 0;
    +                MP_ADD_CARRY(r0a, a5a, r0a, 0,     carry);
    +                MP_ADD_CARRY(r0b, a5b, r0b, carry, carry);
    +                MP_ADD_CARRY(r1a, a5a, r1a, carry, carry);
    +                MP_ADD_CARRY(r1b, a5b, r1b, carry, carry);
    +                MP_ADD_CARRY(r2a, a5a, r2a, carry, carry);
    +                MP_ADD_CARRY(r2b, a5b, r2b, carry, carry);
    +                r3 += carry;
    +                MP_ADD_CARRY(r1a, a4a, r1a, 0,     carry);
    +                MP_ADD_CARRY(r1b, a4b, r1b, carry, carry);
    +                MP_ADD_CARRY(r2a,   0, r2a, carry, carry);
    +                MP_ADD_CARRY(r2b,   0, r2b, carry, carry);
    +                r3 += carry;
    +
    +                /* reduce out the carry */
    +                while (r3) {
    +                        MP_ADD_CARRY(r0a, r3, r0a, 0,     carry);
    +                        MP_ADD_CARRY(r0b,  0, r0b, carry, carry);
    +                        MP_ADD_CARRY(r1a, r3, r1a, carry, carry);
    +                        MP_ADD_CARRY(r1b,  0, r1b, carry, carry);
    +                        MP_ADD_CARRY(r2a,  0, r2a, carry, carry);
    +                        MP_ADD_CARRY(r2b,  0, r2b, carry, carry);
    +                        r3 = carry;
    +                }
    +
    +                /* check for final reduction */
    +                /*
    +                 * our field is 0xffffffffffffffff, 0xfffffffffffffffe,
    +                 * 0xffffffffffffffff. That means we can only be over and need
    +                 * one more reduction
    +                 *  if r2 == 0xffffffffffffffffff (same as r2+1 == 0)
    +                 *     and
    +                 *     r1 == 0xffffffffffffffffff   or
    +                 *     r1 == 0xfffffffffffffffffe and r0 = 0xfffffffffffffffff
    +                 * In all cases, we subtract the field (or add the 2's
    +                 * complement value (1,1,0)).  (r0, r1, r2)
    +                 */
    +                if (((r2b == 0xffffffff) && (r2a == 0xffffffff)
    +                        && (r1b == 0xffffffff) ) &&
    +                           ((r1a == 0xffffffff) ||
    +                            (r1a == 0xfffffffe) && (r0a == 0xffffffff) &&
    +                                        (r0b == 0xffffffff)) ) {
    +                        /* do a quick subtract */
    +                        MP_ADD_CARRY(r0a, 1, r0a, 0, carry);
    +                        r0b += carry;
    +                        r1a = r1b = r2a = r2b = 0;
    +                }
    +
    +                /* set the lower words of r */
    +                if (a != r) {
    +                        MP_CHECKOK(s_mp_pad(r, 6));
    +                }
    +                MP_DIGIT(r, 5) = r2b;
    +                MP_DIGIT(r, 4) = r2a;
    +                MP_DIGIT(r, 3) = r1b;
    +                MP_DIGIT(r, 2) = r1a;
    +                MP_DIGIT(r, 1) = r0b;
    +                MP_DIGIT(r, 0) = r0a;
    +                MP_USED(r) = 6;
    +#else
    +                switch (a_used) {
    +                case 6:
    +                        a5 = MP_DIGIT(a, 5);
    +                case 5:
    +                        a4 = MP_DIGIT(a, 4);
    +                case 4:
    +                        a3 = MP_DIGIT(a, 3);
    +                }
    +
    +                r2 = MP_DIGIT(a, 2);
    +                r1 = MP_DIGIT(a, 1);
    +                r0 = MP_DIGIT(a, 0);
    +
    +                /* implement r = (a2,a1,a0)+(a5,a5,a5)+(a4,a4,0)+(0,a3,a3) */
    +#ifndef MPI_AMD64_ADD
    +                MP_ADD_CARRY(r0, a3, r0, 0,     carry);
    +                MP_ADD_CARRY(r1, a3, r1, carry, carry);
    +                MP_ADD_CARRY(r2, a4, r2, carry, carry);
    +                r3 = carry;
    +                MP_ADD_CARRY(r0, a5, r0, 0,     carry);
    +                MP_ADD_CARRY(r1, a5, r1, carry, carry);
    +                MP_ADD_CARRY(r2, a5, r2, carry, carry);
    +                r3 += carry;
    +                MP_ADD_CARRY(r1, a4, r1, 0,     carry);
    +                MP_ADD_CARRY(r2,  0, r2, carry, carry);
    +                r3 += carry;
    +
    +#else
    +                r2 = MP_DIGIT(a, 2);
    +                r1 = MP_DIGIT(a, 1);
    +                r0 = MP_DIGIT(a, 0);
    +
    +                /* set the lower words of r */
    +                __asm__ (
    +                "xorq   %3,%3           \n\t"
    +                "addq   %4,%0           \n\t"
    +                "adcq   %4,%1           \n\t"
    +                "adcq   %5,%2           \n\t"
    +                "adcq   $0,%3           \n\t"
    +                "addq   %6,%0           \n\t"
    +                "adcq   %6,%1           \n\t"
    +                "adcq   %6,%2           \n\t"
    +                "adcq   $0,%3           \n\t"
    +                "addq   %5,%1           \n\t"
    +                "adcq   $0,%2           \n\t"
    +                "adcq   $0,%3           \n\t"
    +                : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3), "=r"(a3),
    +                  "=r"(a4), "=r"(a5)
    +                : "0" (r0), "1" (r1), "2" (r2), "3" (r3),
    +                  "4" (a3), "5" (a4), "6"(a5)
    +                : "%cc" );
    +#endif
    +
    +                /* reduce out the carry */
    +                while (r3) {
    +#ifndef MPI_AMD64_ADD
    +                        MP_ADD_CARRY(r0, r3, r0, 0,     carry);
    +                        MP_ADD_CARRY(r1, r3, r1, carry, carry);
    +                        MP_ADD_CARRY(r2,  0, r2, carry, carry);
    +                        r3 = carry;
    +#else
    +                        a3=r3;
    +                        __asm__ (
    +                        "xorq   %3,%3           \n\t"
    +                        "addq   %4,%0           \n\t"
    +                        "adcq   %4,%1           \n\t"
    +                        "adcq   $0,%2           \n\t"
    +                        "adcq   $0,%3           \n\t"
    +                        : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3), "=r"(a3)
    +                        : "0" (r0), "1" (r1), "2" (r2), "3" (r3), "4"(a3)
    +                        : "%cc" );
    +#endif
    +                }
    +
    +                /* check for final reduction */
    +                /*
    +                 * our field is 0xffffffffffffffff, 0xfffffffffffffffe,
    +                 * 0xffffffffffffffff. That means we can only be over and need
    +                 * one more reduction
    +                 *  if r2 == 0xffffffffffffffffff (same as r2+1 == 0)
    +                 *     and
    +                 *     r1 == 0xffffffffffffffffff   or
    +                 *     r1 == 0xfffffffffffffffffe and r0 = 0xfffffffffffffffff
    +                 * In all cases, we subtract the field (or add the 2's
    +                 * complement value (1,1,0)).  (r0, r1, r2)
    +                 */
    +                if (r3 || ((r2 == MP_DIGIT_MAX) &&
    +                      ((r1 == MP_DIGIT_MAX) ||
    +                        ((r1 == (MP_DIGIT_MAX-1)) && (r0 == MP_DIGIT_MAX))))) {
    +                        /* do a quick subtract */
    +                        r0++;
    +                        r1 = r2 = 0;
    +                }
    +                /* set the lower words of r */
    +                if (a != r) {
    +                        MP_CHECKOK(s_mp_pad(r, 3));
    +                }
    +                MP_DIGIT(r, 2) = r2;
    +                MP_DIGIT(r, 1) = r1;
    +                MP_DIGIT(r, 0) = r0;
    +                MP_USED(r) = 3;
    +#endif
    +        }
    +
    +  CLEANUP:
    +        return res;
    +}
    +
    +#ifndef ECL_THIRTY_TWO_BIT
    +/* Compute the sum of 192 bit curves. Do the work in-line since the
    + * number of words are so small, we don't want to overhead of mp function
    + * calls.  Uses optimized modular reduction for p192.
    + */
    +mp_err
    +ec_GFp_nistp192_add(const mp_int *a, const mp_int *b, mp_int *r,
    +                        const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_digit a0 = 0, a1 = 0, a2 = 0;
    +        mp_digit r0 = 0, r1 = 0, r2 = 0;
    +        mp_digit carry;
    +
    +        switch(MP_USED(a)) {
    +        case 3:
    +                a2 = MP_DIGIT(a,2);
    +        case 2:
    +                a1 = MP_DIGIT(a,1);
    +        case 1:
    +                a0 = MP_DIGIT(a,0);
    +        }
    +        switch(MP_USED(b)) {
    +        case 3:
    +                r2 = MP_DIGIT(b,2);
    +        case 2:
    +                r1 = MP_DIGIT(b,1);
    +        case 1:
    +                r0 = MP_DIGIT(b,0);
    +        }
    +
    +#ifndef MPI_AMD64_ADD
    +        MP_ADD_CARRY(a0, r0, r0, 0,     carry);
    +        MP_ADD_CARRY(a1, r1, r1, carry, carry);
    +        MP_ADD_CARRY(a2, r2, r2, carry, carry);
    +#else
    +        __asm__ (
    +                "xorq   %3,%3           \n\t"
    +                "addq   %4,%0           \n\t"
    +                "adcq   %5,%1           \n\t"
    +                "adcq   %6,%2           \n\t"
    +                "adcq   $0,%3           \n\t"
    +                : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(carry)
    +                : "r" (a0), "r" (a1), "r" (a2), "0" (r0),
    +                  "1" (r1), "2" (r2)
    +                : "%cc" );
    +#endif
    +
    +        /* Do quick 'subract' if we've gone over
    +         * (add the 2's complement of the curve field) */
    +        if (carry || ((r2 == MP_DIGIT_MAX) &&
    +                      ((r1 == MP_DIGIT_MAX) ||
    +                        ((r1 == (MP_DIGIT_MAX-1)) && (r0 == MP_DIGIT_MAX))))) {
    +#ifndef MPI_AMD64_ADD
    +                MP_ADD_CARRY(r0, 1, r0, 0,     carry);
    +                MP_ADD_CARRY(r1, 1, r1, carry, carry);
    +                MP_ADD_CARRY(r2, 0, r2, carry, carry);
    +#else
    +                __asm__ (
    +                        "addq   $1,%0           \n\t"
    +                        "adcq   $1,%1           \n\t"
    +                        "adcq   $0,%2           \n\t"
    +                        : "=r"(r0), "=r"(r1), "=r"(r2)
    +                        : "0" (r0), "1" (r1), "2" (r2)
    +                        : "%cc" );
    +#endif
    +        }
    +
    +
    +        MP_CHECKOK(s_mp_pad(r, 3));
    +        MP_DIGIT(r, 2) = r2;
    +        MP_DIGIT(r, 1) = r1;
    +        MP_DIGIT(r, 0) = r0;
    +        MP_SIGN(r) = MP_ZPOS;
    +        MP_USED(r) = 3;
    +        s_mp_clamp(r);
    +
    +
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* Compute the diff of 192 bit curves. Do the work in-line since the
    + * number of words are so small, we don't want to overhead of mp function
    + * calls.  Uses optimized modular reduction for p192.
    + */
    +mp_err
    +ec_GFp_nistp192_sub(const mp_int *a, const mp_int *b, mp_int *r,
    +                        const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_digit b0 = 0, b1 = 0, b2 = 0;
    +        mp_digit r0 = 0, r1 = 0, r2 = 0;
    +        mp_digit borrow;
    +
    +        switch(MP_USED(a)) {
    +        case 3:
    +                r2 = MP_DIGIT(a,2);
    +        case 2:
    +                r1 = MP_DIGIT(a,1);
    +        case 1:
    +                r0 = MP_DIGIT(a,0);
    +        }
    +
    +        switch(MP_USED(b)) {
    +        case 3:
    +                b2 = MP_DIGIT(b,2);
    +        case 2:
    +                b1 = MP_DIGIT(b,1);
    +        case 1:
    +                b0 = MP_DIGIT(b,0);
    +        }
    +
    +#ifndef MPI_AMD64_ADD
    +        MP_SUB_BORROW(r0, b0, r0, 0,     borrow);
    +        MP_SUB_BORROW(r1, b1, r1, borrow, borrow);
    +        MP_SUB_BORROW(r2, b2, r2, borrow, borrow);
    +#else
    +        __asm__ (
    +                "xorq   %3,%3           \n\t"
    +                "subq   %4,%0           \n\t"
    +                "sbbq   %5,%1           \n\t"
    +                "sbbq   %6,%2           \n\t"
    +                "adcq   $0,%3           \n\t"
    +                : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(borrow)
    +                : "r" (b0), "r" (b1), "r" (b2), "0" (r0),
    +                  "1" (r1), "2" (r2)
    +                : "%cc" );
    +#endif
    +
    +        /* Do quick 'add' if we've gone under 0
    +         * (subtract the 2's complement of the curve field) */
    +        if (borrow) {
    +#ifndef MPI_AMD64_ADD
    +                MP_SUB_BORROW(r0, 1, r0, 0,     borrow);
    +                MP_SUB_BORROW(r1, 1, r1, borrow, borrow);
    +                MP_SUB_BORROW(r2,  0, r2, borrow, borrow);
    +#else
    +                __asm__ (
    +                        "subq   $1,%0           \n\t"
    +                        "sbbq   $1,%1           \n\t"
    +                        "sbbq   $0,%2           \n\t"
    +                        : "=r"(r0), "=r"(r1), "=r"(r2)
    +                        : "0" (r0), "1" (r1), "2" (r2)
    +                        : "%cc" );
    +#endif
    +        }
    +
    +        MP_CHECKOK(s_mp_pad(r, 3));
    +        MP_DIGIT(r, 2) = r2;
    +        MP_DIGIT(r, 1) = r1;
    +        MP_DIGIT(r, 0) = r0;
    +        MP_SIGN(r) = MP_ZPOS;
    +        MP_USED(r) = 3;
    +        s_mp_clamp(r);
    +
    +  CLEANUP:
    +        return res;
    +}
    +
    +#endif
    +
    +/* Compute the square of polynomial a, reduce modulo p192. Store the
    + * result in r.  r could be a.  Uses optimized modular reduction for p192.
    + */
    +mp_err
    +ec_GFp_nistp192_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +
    +        MP_CHECKOK(mp_sqr(a, r));
    +        MP_CHECKOK(ec_GFp_nistp192_mod(r, r, meth));
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* Compute the product of two polynomials a and b, reduce modulo p192.
    + * Store the result in r.  r could be a or b; a could be b.  Uses
    + * optimized modular reduction for p192. */
    +mp_err
    +ec_GFp_nistp192_mul(const mp_int *a, const mp_int *b, mp_int *r,
    +                                        const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +
    +        MP_CHECKOK(mp_mul(a, b, r));
    +        MP_CHECKOK(ec_GFp_nistp192_mod(r, r, meth));
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* Divides two field elements. If a is NULL, then returns the inverse of
    + * b. */
    +mp_err
    +ec_GFp_nistp192_div(const mp_int *a, const mp_int *b, mp_int *r,
    +                   const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_int t;
    +
    +        /* If a is NULL, then return the inverse of b, otherwise return a/b. */
    +        if (a == NULL) {
    +                return  mp_invmod(b, &meth->irr, r);
    +        } else {
    +                /* MPI doesn't support divmod, so we implement it using invmod and
    +                 * mulmod. */
    +                MP_CHECKOK(mp_init(&t, FLAG(b)));
    +                MP_CHECKOK(mp_invmod(b, &meth->irr, &t));
    +                MP_CHECKOK(mp_mul(a, &t, r));
    +                MP_CHECKOK(ec_GFp_nistp192_mod(r, r, meth));
    +          CLEANUP:
    +                mp_clear(&t);
    +                return res;
    +        }
    +}
    +
    +/* Wire in fast field arithmetic and precomputation of base point for
    + * named curves. */
    +mp_err
    +ec_group_set_gfp192(ECGroup *group, ECCurveName name)
    +{
    +        if (name == ECCurve_NIST_P192) {
    +                group->meth->field_mod = &ec_GFp_nistp192_mod;
    +                group->meth->field_mul = &ec_GFp_nistp192_mul;
    +                group->meth->field_sqr = &ec_GFp_nistp192_sqr;
    +                group->meth->field_div = &ec_GFp_nistp192_div;
    +#ifndef ECL_THIRTY_TWO_BIT
    +                group->meth->field_add = &ec_GFp_nistp192_add;
    +                group->meth->field_sub = &ec_GFp_nistp192_sub;
    +#endif
    +        }
    +        return MP_OKAY;
    +}
    diff --git a/jdk/src/share/native/sun/security/ec/ecp_224.c b/jdk/src/share/native/sun/security/ec/ecp_224.c
    new file mode 100644
    index 00000000000..1ea82fd78d7
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/ecp_224.c
    @@ -0,0 +1,394 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the elliptic curve math library for prime field curves.
    + *
    + * The Initial Developer of the Original Code is
    + * Sun Microsystems, Inc.
    + * Portions created by the Initial Developer are Copyright (C) 2003
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Douglas Stebila , Sun Microsystems Laboratories
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +#include "ecp.h"
    +#include "mpi.h"
    +#include "mplogic.h"
    +#include "mpi-priv.h"
    +#ifndef _KERNEL
    +#include 
    +#endif
    +
    +#define ECP224_DIGITS ECL_CURVE_DIGITS(224)
    +
    +/* Fast modular reduction for p224 = 2^224 - 2^96 + 1.  a can be r. Uses
    + * algorithm 7 from Brown, Hankerson, Lopez, Menezes. Software
    + * Implementation of the NIST Elliptic Curves over Prime Fields. */
    +mp_err
    +ec_GFp_nistp224_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_size a_used = MP_USED(a);
    +
    +        int    r3b;
    +        mp_digit carry;
    +#ifdef ECL_THIRTY_TWO_BIT
    +        mp_digit a6a = 0, a6b = 0,
    +                a5a = 0, a5b = 0, a4a = 0, a4b = 0, a3a = 0, a3b = 0;
    +        mp_digit r0a, r0b, r1a, r1b, r2a, r2b, r3a;
    +#else
    +        mp_digit a6 = 0, a5 = 0, a4 = 0, a3b = 0, a5a = 0;
    +        mp_digit a6b = 0, a6a_a5b = 0, a5b = 0, a5a_a4b = 0, a4a_a3b = 0;
    +        mp_digit r0, r1, r2, r3;
    +#endif
    +
    +        /* reduction not needed if a is not larger than field size */
    +        if (a_used < ECP224_DIGITS) {
    +                if (a == r) return MP_OKAY;
    +                return mp_copy(a, r);
    +        }
    +        /* for polynomials larger than twice the field size, use regular
    +         * reduction */
    +        if (a_used > ECL_CURVE_DIGITS(224*2)) {
    +                MP_CHECKOK(mp_mod(a, &meth->irr, r));
    +        } else {
    +#ifdef ECL_THIRTY_TWO_BIT
    +                /* copy out upper words of a */
    +                switch (a_used) {
    +                case 14:
    +                        a6b = MP_DIGIT(a, 13);
    +                case 13:
    +                        a6a = MP_DIGIT(a, 12);
    +                case 12:
    +                        a5b = MP_DIGIT(a, 11);
    +                case 11:
    +                        a5a = MP_DIGIT(a, 10);
    +                case 10:
    +                        a4b = MP_DIGIT(a, 9);
    +                case 9:
    +                        a4a = MP_DIGIT(a, 8);
    +                case 8:
    +                        a3b = MP_DIGIT(a, 7);
    +                }
    +                r3a = MP_DIGIT(a, 6);
    +                r2b= MP_DIGIT(a, 5);
    +                r2a= MP_DIGIT(a, 4);
    +                r1b = MP_DIGIT(a, 3);
    +                r1a = MP_DIGIT(a, 2);
    +                r0b = MP_DIGIT(a, 1);
    +                r0a = MP_DIGIT(a, 0);
    +
    +
    +                /* implement r = (a3a,a2,a1,a0)
    +                        +(a5a, a4,a3b,  0)
    +                        +(  0, a6,a5b,  0)
    +                        -(  0    0,    0|a6b, a6a|a5b )
    +                        -(  a6b, a6a|a5b, a5a|a4b, a4a|a3b ) */
    +                MP_ADD_CARRY (r1b, a3b, r1b, 0,     carry);
    +                MP_ADD_CARRY (r2a, a4a, r2a, carry, carry);
    +                MP_ADD_CARRY (r2b, a4b, r2b, carry, carry);
    +                MP_ADD_CARRY (r3a, a5a, r3a, carry, carry);
    +                r3b = carry;
    +                MP_ADD_CARRY (r1b, a5b, r1b, 0,     carry);
    +                MP_ADD_CARRY (r2a, a6a, r2a, carry, carry);
    +                MP_ADD_CARRY (r2b, a6b, r2b, carry, carry);
    +                MP_ADD_CARRY (r3a,   0, r3a, carry, carry);
    +                r3b += carry;
    +                MP_SUB_BORROW(r0a, a3b, r0a, 0,     carry);
    +                MP_SUB_BORROW(r0b, a4a, r0b, carry, carry);
    +                MP_SUB_BORROW(r1a, a4b, r1a, carry, carry);
    +                MP_SUB_BORROW(r1b, a5a, r1b, carry, carry);
    +                MP_SUB_BORROW(r2a, a5b, r2a, carry, carry);
    +                MP_SUB_BORROW(r2b, a6a, r2b, carry, carry);
    +                MP_SUB_BORROW(r3a, a6b, r3a, carry, carry);
    +                r3b -= carry;
    +                MP_SUB_BORROW(r0a, a5b, r0a, 0,     carry);
    +                MP_SUB_BORROW(r0b, a6a, r0b, carry, carry);
    +                MP_SUB_BORROW(r1a, a6b, r1a, carry, carry);
    +                if (carry) {
    +                        MP_SUB_BORROW(r1b, 0, r1b, carry, carry);
    +                        MP_SUB_BORROW(r2a, 0, r2a, carry, carry);
    +                        MP_SUB_BORROW(r2b, 0, r2b, carry, carry);
    +                        MP_SUB_BORROW(r3a, 0, r3a, carry, carry);
    +                        r3b -= carry;
    +                }
    +
    +                while (r3b > 0) {
    +                        int tmp;
    +                        MP_ADD_CARRY(r1b, r3b, r1b, 0,     carry);
    +                        if (carry) {
    +                                MP_ADD_CARRY(r2a,  0, r2a, carry, carry);
    +                                MP_ADD_CARRY(r2b,  0, r2b, carry, carry);
    +                                MP_ADD_CARRY(r3a,  0, r3a, carry, carry);
    +                        }
    +                        tmp = carry;
    +                        MP_SUB_BORROW(r0a, r3b, r0a, 0,     carry);
    +                        if (carry) {
    +                                MP_SUB_BORROW(r0b, 0, r0b, carry, carry);
    +                                MP_SUB_BORROW(r1a, 0, r1a, carry, carry);
    +                                MP_SUB_BORROW(r1b, 0, r1b, carry, carry);
    +                                MP_SUB_BORROW(r2a, 0, r2a, carry, carry);
    +                                MP_SUB_BORROW(r2b, 0, r2b, carry, carry);
    +                                MP_SUB_BORROW(r3a, 0, r3a, carry, carry);
    +                                tmp -= carry;
    +                        }
    +                        r3b = tmp;
    +                }
    +
    +                while (r3b < 0) {
    +                        mp_digit maxInt = MP_DIGIT_MAX;
    +                        MP_ADD_CARRY (r0a, 1, r0a, 0,     carry);
    +                        MP_ADD_CARRY (r0b, 0, r0b, carry, carry);
    +                        MP_ADD_CARRY (r1a, 0, r1a, carry, carry);
    +                        MP_ADD_CARRY (r1b, maxInt, r1b, carry, carry);
    +                        MP_ADD_CARRY (r2a, maxInt, r2a, carry, carry);
    +                        MP_ADD_CARRY (r2b, maxInt, r2b, carry, carry);
    +                        MP_ADD_CARRY (r3a, maxInt, r3a, carry, carry);
    +                        r3b += carry;
    +                }
    +                /* check for final reduction */
    +                /* now the only way we are over is if the top 4 words are all ones */
    +                if ((r3a == MP_DIGIT_MAX) && (r2b == MP_DIGIT_MAX)
    +                        && (r2a == MP_DIGIT_MAX) && (r1b == MP_DIGIT_MAX) &&
    +                         ((r1a != 0) || (r0b != 0) || (r0a != 0)) ) {
    +                        /* one last subraction */
    +                        MP_SUB_BORROW(r0a, 1, r0a, 0,     carry);
    +                        MP_SUB_BORROW(r0b, 0, r0b, carry, carry);
    +                        MP_SUB_BORROW(r1a, 0, r1a, carry, carry);
    +                        r1b = r2a = r2b = r3a = 0;
    +                }
    +
    +
    +                if (a != r) {
    +                        MP_CHECKOK(s_mp_pad(r, 7));
    +                }
    +                /* set the lower words of r */
    +                MP_SIGN(r) = MP_ZPOS;
    +                MP_USED(r) = 7;
    +                MP_DIGIT(r, 6) = r3a;
    +                MP_DIGIT(r, 5) = r2b;
    +                MP_DIGIT(r, 4) = r2a;
    +                MP_DIGIT(r, 3) = r1b;
    +                MP_DIGIT(r, 2) = r1a;
    +                MP_DIGIT(r, 1) = r0b;
    +                MP_DIGIT(r, 0) = r0a;
    +#else
    +                /* copy out upper words of a */
    +                switch (a_used) {
    +                case 7:
    +                        a6 = MP_DIGIT(a, 6);
    +                        a6b = a6 >> 32;
    +                        a6a_a5b = a6 << 32;
    +                case 6:
    +                        a5 = MP_DIGIT(a, 5);
    +                        a5b = a5 >> 32;
    +                        a6a_a5b |= a5b;
    +                        a5b = a5b << 32;
    +                        a5a_a4b = a5 << 32;
    +                        a5a = a5 & 0xffffffff;
    +                case 5:
    +                        a4 = MP_DIGIT(a, 4);
    +                        a5a_a4b |= a4 >> 32;
    +                        a4a_a3b = a4 << 32;
    +                case 4:
    +                        a3b = MP_DIGIT(a, 3) >> 32;
    +                        a4a_a3b |= a3b;
    +                        a3b = a3b << 32;
    +                }
    +
    +                r3 = MP_DIGIT(a, 3) & 0xffffffff;
    +                r2 = MP_DIGIT(a, 2);
    +                r1 = MP_DIGIT(a, 1);
    +                r0 = MP_DIGIT(a, 0);
    +
    +                /* implement r = (a3a,a2,a1,a0)
    +                        +(a5a, a4,a3b,  0)
    +                        +(  0, a6,a5b,  0)
    +                        -(  0    0,    0|a6b, a6a|a5b )
    +                        -(  a6b, a6a|a5b, a5a|a4b, a4a|a3b ) */
    +                MP_ADD_CARRY (r1, a3b, r1, 0,     carry);
    +                MP_ADD_CARRY (r2, a4 , r2, carry, carry);
    +                MP_ADD_CARRY (r3, a5a, r3, carry, carry);
    +                MP_ADD_CARRY (r1, a5b, r1, 0,     carry);
    +                MP_ADD_CARRY (r2, a6 , r2, carry, carry);
    +                MP_ADD_CARRY (r3,   0, r3, carry, carry);
    +
    +                MP_SUB_BORROW(r0, a4a_a3b, r0, 0,     carry);
    +                MP_SUB_BORROW(r1, a5a_a4b, r1, carry, carry);
    +                MP_SUB_BORROW(r2, a6a_a5b, r2, carry, carry);
    +                MP_SUB_BORROW(r3, a6b    , r3, carry, carry);
    +                MP_SUB_BORROW(r0, a6a_a5b, r0, 0,     carry);
    +                MP_SUB_BORROW(r1, a6b    , r1, carry, carry);
    +                if (carry) {
    +                        MP_SUB_BORROW(r2, 0, r2, carry, carry);
    +                        MP_SUB_BORROW(r3, 0, r3, carry, carry);
    +                }
    +
    +
    +                /* if the value is negative, r3 has a 2's complement
    +                 * high value */
    +                r3b = (int)(r3 >>32);
    +                while (r3b > 0) {
    +                        r3 &= 0xffffffff;
    +                        MP_ADD_CARRY(r1,((mp_digit)r3b) << 32, r1, 0, carry);
    +                        if (carry) {
    +                                MP_ADD_CARRY(r2,  0, r2, carry, carry);
    +                                MP_ADD_CARRY(r3,  0, r3, carry, carry);
    +                        }
    +                        MP_SUB_BORROW(r0, r3b, r0, 0, carry);
    +                        if (carry) {
    +                                MP_SUB_BORROW(r1, 0, r1, carry, carry);
    +                                MP_SUB_BORROW(r2, 0, r2, carry, carry);
    +                                MP_SUB_BORROW(r3, 0, r3, carry, carry);
    +                        }
    +                        r3b = (int)(r3 >>32);
    +                }
    +
    +                while (r3b < 0) {
    +                        MP_ADD_CARRY (r0, 1, r0, 0,     carry);
    +                        MP_ADD_CARRY (r1, MP_DIGIT_MAX <<32, r1, carry, carry);
    +                        MP_ADD_CARRY (r2, MP_DIGIT_MAX, r2, carry, carry);
    +                        MP_ADD_CARRY (r3, MP_DIGIT_MAX >> 32, r3, carry, carry);
    +                        r3b = (int)(r3 >>32);
    +                }
    +                /* check for final reduction */
    +                /* now the only way we are over is if the top 4 words are all ones */
    +                if ((r3 == (MP_DIGIT_MAX >> 32)) && (r2 == MP_DIGIT_MAX)
    +                        && ((r1 & MP_DIGIT_MAX << 32)== MP_DIGIT_MAX << 32) &&
    +                         ((r1 != MP_DIGIT_MAX << 32 ) || (r0 != 0)) ) {
    +                        /* one last subraction */
    +                        MP_SUB_BORROW(r0, 1, r0, 0,     carry);
    +                        MP_SUB_BORROW(r1, 0, r1, carry, carry);
    +                        r2 = r3 = 0;
    +                }
    +
    +
    +                if (a != r) {
    +                        MP_CHECKOK(s_mp_pad(r, 4));
    +                }
    +                /* set the lower words of r */
    +                MP_SIGN(r) = MP_ZPOS;
    +                MP_USED(r) = 4;
    +                MP_DIGIT(r, 3) = r3;
    +                MP_DIGIT(r, 2) = r2;
    +                MP_DIGIT(r, 1) = r1;
    +                MP_DIGIT(r, 0) = r0;
    +#endif
    +        }
    +
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* Compute the square of polynomial a, reduce modulo p224. Store the
    + * result in r.  r could be a.  Uses optimized modular reduction for p224.
    + */
    +mp_err
    +ec_GFp_nistp224_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +
    +        MP_CHECKOK(mp_sqr(a, r));
    +        MP_CHECKOK(ec_GFp_nistp224_mod(r, r, meth));
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* Compute the product of two polynomials a and b, reduce modulo p224.
    + * Store the result in r.  r could be a or b; a could be b.  Uses
    + * optimized modular reduction for p224. */
    +mp_err
    +ec_GFp_nistp224_mul(const mp_int *a, const mp_int *b, mp_int *r,
    +                                        const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +
    +        MP_CHECKOK(mp_mul(a, b, r));
    +        MP_CHECKOK(ec_GFp_nistp224_mod(r, r, meth));
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* Divides two field elements. If a is NULL, then returns the inverse of
    + * b. */
    +mp_err
    +ec_GFp_nistp224_div(const mp_int *a, const mp_int *b, mp_int *r,
    +                   const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_int t;
    +
    +        /* If a is NULL, then return the inverse of b, otherwise return a/b. */
    +        if (a == NULL) {
    +                return  mp_invmod(b, &meth->irr, r);
    +        } else {
    +                /* MPI doesn't support divmod, so we implement it using invmod and
    +                 * mulmod. */
    +                MP_CHECKOK(mp_init(&t, FLAG(b)));
    +                MP_CHECKOK(mp_invmod(b, &meth->irr, &t));
    +                MP_CHECKOK(mp_mul(a, &t, r));
    +                MP_CHECKOK(ec_GFp_nistp224_mod(r, r, meth));
    +          CLEANUP:
    +                mp_clear(&t);
    +                return res;
    +        }
    +}
    +
    +/* Wire in fast field arithmetic and precomputation of base point for
    + * named curves. */
    +mp_err
    +ec_group_set_gfp224(ECGroup *group, ECCurveName name)
    +{
    +        if (name == ECCurve_NIST_P224) {
    +                group->meth->field_mod = &ec_GFp_nistp224_mod;
    +                group->meth->field_mul = &ec_GFp_nistp224_mul;
    +                group->meth->field_sqr = &ec_GFp_nistp224_sqr;
    +                group->meth->field_div = &ec_GFp_nistp224_div;
    +        }
    +        return MP_OKAY;
    +}
    diff --git a/jdk/src/share/native/sun/security/ec/ecp_256.c b/jdk/src/share/native/sun/security/ec/ecp_256.c
    new file mode 100644
    index 00000000000..6f4de5be0ee
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/ecp_256.c
    @@ -0,0 +1,451 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the elliptic curve math library for prime field curves.
    + *
    + * The Initial Developer of the Original Code is
    + * Sun Microsystems, Inc.
    + * Portions created by the Initial Developer are Copyright (C) 2003
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Douglas Stebila 
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +#include "ecp.h"
    +#include "mpi.h"
    +#include "mplogic.h"
    +#include "mpi-priv.h"
    +#ifndef _KERNEL
    +#include 
    +#endif
    +
    +/* Fast modular reduction for p256 = 2^256 - 2^224 + 2^192+ 2^96 - 1.  a can be r.
    + * Uses algorithm 2.29 from Hankerson, Menezes, Vanstone. Guide to
    + * Elliptic Curve Cryptography. */
    +mp_err
    +ec_GFp_nistp256_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_size a_used = MP_USED(a);
    +        int a_bits = mpl_significant_bits(a);
    +        mp_digit carry;
    +
    +#ifdef ECL_THIRTY_TWO_BIT
    +        mp_digit a8=0, a9=0, a10=0, a11=0, a12=0, a13=0, a14=0, a15=0;
    +        mp_digit r0, r1, r2, r3, r4, r5, r6, r7;
    +        int r8; /* must be a signed value ! */
    +#else
    +        mp_digit a4=0, a5=0, a6=0, a7=0;
    +        mp_digit a4h, a4l, a5h, a5l, a6h, a6l, a7h, a7l;
    +        mp_digit r0, r1, r2, r3;
    +        int r4; /* must be a signed value ! */
    +#endif
    +        /* for polynomials larger than twice the field size
    +         * use regular reduction */
    +        if (a_bits < 256) {
    +                if (a == r) return MP_OKAY;
    +                return mp_copy(a,r);
    +        }
    +        if (a_bits > 512)  {
    +                MP_CHECKOK(mp_mod(a, &meth->irr, r));
    +        } else {
    +
    +#ifdef ECL_THIRTY_TWO_BIT
    +                switch (a_used) {
    +                case 16:
    +                        a15 = MP_DIGIT(a,15);
    +                case 15:
    +                        a14 = MP_DIGIT(a,14);
    +                case 14:
    +                        a13 = MP_DIGIT(a,13);
    +                case 13:
    +                        a12 = MP_DIGIT(a,12);
    +                case 12:
    +                        a11 = MP_DIGIT(a,11);
    +                case 11:
    +                        a10 = MP_DIGIT(a,10);
    +                case 10:
    +                        a9 = MP_DIGIT(a,9);
    +                case 9:
    +                        a8 = MP_DIGIT(a,8);
    +                }
    +
    +                r0 = MP_DIGIT(a,0);
    +                r1 = MP_DIGIT(a,1);
    +                r2 = MP_DIGIT(a,2);
    +                r3 = MP_DIGIT(a,3);
    +                r4 = MP_DIGIT(a,4);
    +                r5 = MP_DIGIT(a,5);
    +                r6 = MP_DIGIT(a,6);
    +                r7 = MP_DIGIT(a,7);
    +
    +                /* sum 1 */
    +                MP_ADD_CARRY(r3, a11, r3, 0,     carry);
    +                MP_ADD_CARRY(r4, a12, r4, carry, carry);
    +                MP_ADD_CARRY(r5, a13, r5, carry, carry);
    +                MP_ADD_CARRY(r6, a14, r6, carry, carry);
    +                MP_ADD_CARRY(r7, a15, r7, carry, carry);
    +                r8 = carry;
    +                MP_ADD_CARRY(r3, a11, r3, 0,     carry);
    +                MP_ADD_CARRY(r4, a12, r4, carry, carry);
    +                MP_ADD_CARRY(r5, a13, r5, carry, carry);
    +                MP_ADD_CARRY(r6, a14, r6, carry, carry);
    +                MP_ADD_CARRY(r7, a15, r7, carry, carry);
    +                r8 += carry;
    +                /* sum 2 */
    +                MP_ADD_CARRY(r3, a12, r3, 0,     carry);
    +                MP_ADD_CARRY(r4, a13, r4, carry, carry);
    +                MP_ADD_CARRY(r5, a14, r5, carry, carry);
    +                MP_ADD_CARRY(r6, a15, r6, carry, carry);
    +                MP_ADD_CARRY(r7,   0, r7, carry, carry);
    +                r8 += carry;
    +                /* combine last bottom of sum 3 with second sum 2 */
    +                MP_ADD_CARRY(r0, a8,  r0, 0,     carry);
    +                MP_ADD_CARRY(r1, a9,  r1, carry, carry);
    +                MP_ADD_CARRY(r2, a10, r2, carry, carry);
    +                MP_ADD_CARRY(r3, a12, r3, carry, carry);
    +                MP_ADD_CARRY(r4, a13, r4, carry, carry);
    +                MP_ADD_CARRY(r5, a14, r5, carry, carry);
    +                MP_ADD_CARRY(r6, a15, r6, carry, carry);
    +                MP_ADD_CARRY(r7, a15, r7, carry, carry); /* from sum 3 */
    +                r8 += carry;
    +                /* sum 3 (rest of it)*/
    +                MP_ADD_CARRY(r6, a14, r6, 0,     carry);
    +                MP_ADD_CARRY(r7,   0, r7, carry, carry);
    +                r8 += carry;
    +                /* sum 4 (rest of it)*/
    +                MP_ADD_CARRY(r0, a9,  r0, 0,     carry);
    +                MP_ADD_CARRY(r1, a10, r1, carry, carry);
    +                MP_ADD_CARRY(r2, a11, r2, carry, carry);
    +                MP_ADD_CARRY(r3, a13, r3, carry, carry);
    +                MP_ADD_CARRY(r4, a14, r4, carry, carry);
    +                MP_ADD_CARRY(r5, a15, r5, carry, carry);
    +                MP_ADD_CARRY(r6, a13, r6, carry, carry);
    +                MP_ADD_CARRY(r7, a8,  r7, carry, carry);
    +                r8 += carry;
    +                /* diff 5 */
    +                MP_SUB_BORROW(r0, a11, r0, 0,     carry);
    +                MP_SUB_BORROW(r1, a12, r1, carry, carry);
    +                MP_SUB_BORROW(r2, a13, r2, carry, carry);
    +                MP_SUB_BORROW(r3,   0, r3, carry, carry);
    +                MP_SUB_BORROW(r4,   0, r4, carry, carry);
    +                MP_SUB_BORROW(r5,   0, r5, carry, carry);
    +                MP_SUB_BORROW(r6, a8,  r6, carry, carry);
    +                MP_SUB_BORROW(r7, a10, r7, carry, carry);
    +                r8 -= carry;
    +                /* diff 6 */
    +                MP_SUB_BORROW(r0, a12, r0, 0,     carry);
    +                MP_SUB_BORROW(r1, a13, r1, carry, carry);
    +                MP_SUB_BORROW(r2, a14, r2, carry, carry);
    +                MP_SUB_BORROW(r3, a15, r3, carry, carry);
    +                MP_SUB_BORROW(r4,   0, r4, carry, carry);
    +                MP_SUB_BORROW(r5,   0, r5, carry, carry);
    +                MP_SUB_BORROW(r6, a9,  r6, carry, carry);
    +                MP_SUB_BORROW(r7, a11, r7, carry, carry);
    +                r8 -= carry;
    +                /* diff 7 */
    +                MP_SUB_BORROW(r0, a13, r0, 0,     carry);
    +                MP_SUB_BORROW(r1, a14, r1, carry, carry);
    +                MP_SUB_BORROW(r2, a15, r2, carry, carry);
    +                MP_SUB_BORROW(r3, a8,  r3, carry, carry);
    +                MP_SUB_BORROW(r4, a9,  r4, carry, carry);
    +                MP_SUB_BORROW(r5, a10, r5, carry, carry);
    +                MP_SUB_BORROW(r6, 0,   r6, carry, carry);
    +                MP_SUB_BORROW(r7, a12, r7, carry, carry);
    +                r8 -= carry;
    +                /* diff 8 */
    +                MP_SUB_BORROW(r0, a14, r0, 0,     carry);
    +                MP_SUB_BORROW(r1, a15, r1, carry, carry);
    +                MP_SUB_BORROW(r2, 0,   r2, carry, carry);
    +                MP_SUB_BORROW(r3, a9,  r3, carry, carry);
    +                MP_SUB_BORROW(r4, a10, r4, carry, carry);
    +                MP_SUB_BORROW(r5, a11, r5, carry, carry);
    +                MP_SUB_BORROW(r6, 0,   r6, carry, carry);
    +                MP_SUB_BORROW(r7, a13, r7, carry, carry);
    +                r8 -= carry;
    +
    +                /* reduce the overflows */
    +                while (r8 > 0) {
    +                        mp_digit r8_d = r8;
    +                        MP_ADD_CARRY(r0, r8_d,         r0, 0,     carry);
    +                        MP_ADD_CARRY(r1, 0,            r1, carry, carry);
    +                        MP_ADD_CARRY(r2, 0,            r2, carry, carry);
    +                        MP_ADD_CARRY(r3, -r8_d,        r3, carry, carry);
    +                        MP_ADD_CARRY(r4, MP_DIGIT_MAX, r4, carry, carry);
    +                        MP_ADD_CARRY(r5, MP_DIGIT_MAX, r5, carry, carry);
    +                        MP_ADD_CARRY(r6, -(r8_d+1),    r6, carry, carry);
    +                        MP_ADD_CARRY(r7, (r8_d-1),     r7, carry, carry);
    +                        r8 = carry;
    +                }
    +
    +                /* reduce the underflows */
    +                while (r8 < 0) {
    +                        mp_digit r8_d = -r8;
    +                        MP_SUB_BORROW(r0, r8_d,         r0, 0,     carry);
    +                        MP_SUB_BORROW(r1, 0,            r1, carry, carry);
    +                        MP_SUB_BORROW(r2, 0,            r2, carry, carry);
    +                        MP_SUB_BORROW(r3, -r8_d,        r3, carry, carry);
    +                        MP_SUB_BORROW(r4, MP_DIGIT_MAX, r4, carry, carry);
    +                        MP_SUB_BORROW(r5, MP_DIGIT_MAX, r5, carry, carry);
    +                        MP_SUB_BORROW(r6, -(r8_d+1),    r6, carry, carry);
    +                        MP_SUB_BORROW(r7, (r8_d-1),     r7, carry, carry);
    +                        r8 = -carry;
    +                }
    +                if (a != r) {
    +                        MP_CHECKOK(s_mp_pad(r,8));
    +                }
    +                MP_SIGN(r) = MP_ZPOS;
    +                MP_USED(r) = 8;
    +
    +                MP_DIGIT(r,7) = r7;
    +                MP_DIGIT(r,6) = r6;
    +                MP_DIGIT(r,5) = r5;
    +                MP_DIGIT(r,4) = r4;
    +                MP_DIGIT(r,3) = r3;
    +                MP_DIGIT(r,2) = r2;
    +                MP_DIGIT(r,1) = r1;
    +                MP_DIGIT(r,0) = r0;
    +
    +                /* final reduction if necessary */
    +                if ((r7 == MP_DIGIT_MAX) &&
    +                        ((r6 > 1) || ((r6 == 1) &&
    +                        (r5 || r4 || r3 ||
    +                                ((r2 == MP_DIGIT_MAX) && (r1 == MP_DIGIT_MAX)
    +                                  && (r0 == MP_DIGIT_MAX)))))) {
    +                        MP_CHECKOK(mp_sub(r, &meth->irr, r));
    +                }
    +#ifdef notdef
    +
    +
    +                /* smooth the negatives */
    +                while (MP_SIGN(r) != MP_ZPOS) {
    +                        MP_CHECKOK(mp_add(r, &meth->irr, r));
    +                }
    +                while (MP_USED(r) > 8) {
    +                        MP_CHECKOK(mp_sub(r, &meth->irr, r));
    +                }
    +
    +                /* final reduction if necessary */
    +                if (MP_DIGIT(r,7) >= MP_DIGIT(&meth->irr,7)) {
    +                    if (mp_cmp(r,&meth->irr) != MP_LT) {
    +                        MP_CHECKOK(mp_sub(r, &meth->irr, r));
    +                    }
    +                }
    +#endif
    +                s_mp_clamp(r);
    +#else
    +                switch (a_used) {
    +                case 8:
    +                        a7 = MP_DIGIT(a,7);
    +                case 7:
    +                        a6 = MP_DIGIT(a,6);
    +                case 6:
    +                        a5 = MP_DIGIT(a,5);
    +                case 5:
    +                        a4 = MP_DIGIT(a,4);
    +                }
    +                a7l = a7 << 32;
    +                a7h = a7 >> 32;
    +                a6l = a6 << 32;
    +                a6h = a6 >> 32;
    +                a5l = a5 << 32;
    +                a5h = a5 >> 32;
    +                a4l = a4 << 32;
    +                a4h = a4 >> 32;
    +                r3 = MP_DIGIT(a,3);
    +                r2 = MP_DIGIT(a,2);
    +                r1 = MP_DIGIT(a,1);
    +                r0 = MP_DIGIT(a,0);
    +
    +                /* sum 1 */
    +                MP_ADD_CARRY(r1, a5h << 32, r1, 0,     carry);
    +                MP_ADD_CARRY(r2, a6,        r2, carry, carry);
    +                MP_ADD_CARRY(r3, a7,        r3, carry, carry);
    +                r4 = carry;
    +                MP_ADD_CARRY(r1, a5h << 32, r1, 0,     carry);
    +                MP_ADD_CARRY(r2, a6,        r2, carry, carry);
    +                MP_ADD_CARRY(r3, a7,        r3, carry, carry);
    +                r4 += carry;
    +                /* sum 2 */
    +                MP_ADD_CARRY(r1, a6l,       r1, 0,     carry);
    +                MP_ADD_CARRY(r2, a6h | a7l, r2, carry, carry);
    +                MP_ADD_CARRY(r3, a7h,       r3, carry, carry);
    +                r4 += carry;
    +                MP_ADD_CARRY(r1, a6l,       r1, 0,     carry);
    +                MP_ADD_CARRY(r2, a6h | a7l, r2, carry, carry);
    +                MP_ADD_CARRY(r3, a7h,       r3, carry, carry);
    +                r4 += carry;
    +
    +                /* sum 3 */
    +                MP_ADD_CARRY(r0, a4,        r0, 0,     carry);
    +                MP_ADD_CARRY(r1, a5l >> 32, r1, carry, carry);
    +                MP_ADD_CARRY(r2, 0,         r2, carry, carry);
    +                MP_ADD_CARRY(r3, a7,        r3, carry, carry);
    +                r4 += carry;
    +                /* sum 4 */
    +                MP_ADD_CARRY(r0, a4h | a5l,     r0, 0,     carry);
    +                MP_ADD_CARRY(r1, a5h|(a6h<<32), r1, carry, carry);
    +                MP_ADD_CARRY(r2, a7,            r2, carry, carry);
    +                MP_ADD_CARRY(r3, a6h | a4l,     r3, carry, carry);
    +                r4 += carry;
    +                /* diff 5 */
    +                MP_SUB_BORROW(r0, a5h | a6l,    r0, 0,     carry);
    +                MP_SUB_BORROW(r1, a6h,          r1, carry, carry);
    +                MP_SUB_BORROW(r2, 0,            r2, carry, carry);
    +                MP_SUB_BORROW(r3, (a4l>>32)|a5l,r3, carry, carry);
    +                r4 -= carry;
    +                /* diff 6 */
    +                MP_SUB_BORROW(r0, a6,           r0, 0,     carry);
    +                MP_SUB_BORROW(r1, a7,           r1, carry, carry);
    +                MP_SUB_BORROW(r2, 0,            r2, carry, carry);
    +                MP_SUB_BORROW(r3, a4h|(a5h<<32),r3, carry, carry);
    +                r4 -= carry;
    +                /* diff 7 */
    +                MP_SUB_BORROW(r0, a6h|a7l,      r0, 0,     carry);
    +                MP_SUB_BORROW(r1, a7h|a4l,      r1, carry, carry);
    +                MP_SUB_BORROW(r2, a4h|a5l,      r2, carry, carry);
    +                MP_SUB_BORROW(r3, a6l,          r3, carry, carry);
    +                r4 -= carry;
    +                /* diff 8 */
    +                MP_SUB_BORROW(r0, a7,           r0, 0,     carry);
    +                MP_SUB_BORROW(r1, a4h<<32,      r1, carry, carry);
    +                MP_SUB_BORROW(r2, a5,           r2, carry, carry);
    +                MP_SUB_BORROW(r3, a6h<<32,      r3, carry, carry);
    +                r4 -= carry;
    +
    +                /* reduce the overflows */
    +                while (r4 > 0) {
    +                        mp_digit r4_long = r4;
    +                        mp_digit r4l = (r4_long << 32);
    +                        MP_ADD_CARRY(r0, r4_long,      r0, 0,     carry);
    +                        MP_ADD_CARRY(r1, -r4l,         r1, carry, carry);
    +                        MP_ADD_CARRY(r2, MP_DIGIT_MAX, r2, carry, carry);
    +                        MP_ADD_CARRY(r3, r4l-r4_long-1,r3, carry, carry);
    +                        r4 = carry;
    +                }
    +
    +                /* reduce the underflows */
    +                while (r4 < 0) {
    +                        mp_digit r4_long = -r4;
    +                        mp_digit r4l = (r4_long << 32);
    +                        MP_SUB_BORROW(r0, r4_long,      r0, 0,     carry);
    +                        MP_SUB_BORROW(r1, -r4l,         r1, carry, carry);
    +                        MP_SUB_BORROW(r2, MP_DIGIT_MAX, r2, carry, carry);
    +                        MP_SUB_BORROW(r3, r4l-r4_long-1,r3, carry, carry);
    +                        r4 = -carry;
    +                }
    +
    +                if (a != r) {
    +                        MP_CHECKOK(s_mp_pad(r,4));
    +                }
    +                MP_SIGN(r) = MP_ZPOS;
    +                MP_USED(r) = 4;
    +
    +                MP_DIGIT(r,3) = r3;
    +                MP_DIGIT(r,2) = r2;
    +                MP_DIGIT(r,1) = r1;
    +                MP_DIGIT(r,0) = r0;
    +
    +                /* final reduction if necessary */
    +                if ((r3 > 0xFFFFFFFF00000001ULL) ||
    +                        ((r3 == 0xFFFFFFFF00000001ULL) &&
    +                        (r2 || (r1 >> 32)||
    +                               (r1 == 0xFFFFFFFFULL && r0 == MP_DIGIT_MAX)))) {
    +                        /* very rare, just use mp_sub */
    +                        MP_CHECKOK(mp_sub(r, &meth->irr, r));
    +                }
    +
    +                s_mp_clamp(r);
    +#endif
    +        }
    +
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* Compute the square of polynomial a, reduce modulo p256. Store the
    + * result in r.  r could be a.  Uses optimized modular reduction for p256.
    + */
    +mp_err
    +ec_GFp_nistp256_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +
    +        MP_CHECKOK(mp_sqr(a, r));
    +        MP_CHECKOK(ec_GFp_nistp256_mod(r, r, meth));
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* Compute the product of two polynomials a and b, reduce modulo p256.
    + * Store the result in r.  r could be a or b; a could be b.  Uses
    + * optimized modular reduction for p256. */
    +mp_err
    +ec_GFp_nistp256_mul(const mp_int *a, const mp_int *b, mp_int *r,
    +                                        const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +
    +        MP_CHECKOK(mp_mul(a, b, r));
    +        MP_CHECKOK(ec_GFp_nistp256_mod(r, r, meth));
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* Wire in fast field arithmetic and precomputation of base point for
    + * named curves. */
    +mp_err
    +ec_group_set_gfp256(ECGroup *group, ECCurveName name)
    +{
    +        if (name == ECCurve_NIST_P256) {
    +                group->meth->field_mod = &ec_GFp_nistp256_mod;
    +                group->meth->field_mul = &ec_GFp_nistp256_mul;
    +                group->meth->field_sqr = &ec_GFp_nistp256_sqr;
    +        }
    +        return MP_OKAY;
    +}
    diff --git a/jdk/src/share/native/sun/security/ec/ecp_384.c b/jdk/src/share/native/sun/security/ec/ecp_384.c
    new file mode 100644
    index 00000000000..93b9259da6b
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/ecp_384.c
    @@ -0,0 +1,315 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the elliptic curve math library for prime field curves.
    + *
    + * The Initial Developer of the Original Code is
    + * Sun Microsystems, Inc.
    + * Portions created by the Initial Developer are Copyright (C) 2003
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Douglas Stebila 
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +#include "ecp.h"
    +#include "mpi.h"
    +#include "mplogic.h"
    +#include "mpi-priv.h"
    +#ifndef _KERNEL
    +#include 
    +#endif
    +
    +/* Fast modular reduction for p384 = 2^384 - 2^128 - 2^96 + 2^32 - 1.  a can be r.
    + * Uses algorithm 2.30 from Hankerson, Menezes, Vanstone. Guide to
    + * Elliptic Curve Cryptography. */
    +mp_err
    +ec_GFp_nistp384_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +        int a_bits = mpl_significant_bits(a);
    +        int i;
    +
    +        /* m1, m2 are statically-allocated mp_int of exactly the size we need */
    +        mp_int m[10];
    +
    +#ifdef ECL_THIRTY_TWO_BIT
    +        mp_digit s[10][12];
    +        for (i = 0; i < 10; i++) {
    +                MP_SIGN(&m[i]) = MP_ZPOS;
    +                MP_ALLOC(&m[i]) = 12;
    +                MP_USED(&m[i]) = 12;
    +                MP_DIGITS(&m[i]) = s[i];
    +        }
    +#else
    +        mp_digit s[10][6];
    +        for (i = 0; i < 10; i++) {
    +                MP_SIGN(&m[i]) = MP_ZPOS;
    +                MP_ALLOC(&m[i]) = 6;
    +                MP_USED(&m[i]) = 6;
    +                MP_DIGITS(&m[i]) = s[i];
    +        }
    +#endif
    +
    +#ifdef ECL_THIRTY_TWO_BIT
    +        /* for polynomials larger than twice the field size or polynomials
    +         * not using all words, use regular reduction */
    +        if ((a_bits > 768) || (a_bits <= 736)) {
    +                MP_CHECKOK(mp_mod(a, &meth->irr, r));
    +        } else {
    +                for (i = 0; i < 12; i++) {
    +                        s[0][i] = MP_DIGIT(a, i);
    +                }
    +                s[1][0] = 0;
    +                s[1][1] = 0;
    +                s[1][2] = 0;
    +                s[1][3] = 0;
    +                s[1][4] = MP_DIGIT(a, 21);
    +                s[1][5] = MP_DIGIT(a, 22);
    +                s[1][6] = MP_DIGIT(a, 23);
    +                s[1][7] = 0;
    +                s[1][8] = 0;
    +                s[1][9] = 0;
    +                s[1][10] = 0;
    +                s[1][11] = 0;
    +                for (i = 0; i < 12; i++) {
    +                        s[2][i] = MP_DIGIT(a, i+12);
    +                }
    +                s[3][0] = MP_DIGIT(a, 21);
    +                s[3][1] = MP_DIGIT(a, 22);
    +                s[3][2] = MP_DIGIT(a, 23);
    +                for (i = 3; i < 12; i++) {
    +                        s[3][i] = MP_DIGIT(a, i+9);
    +                }
    +                s[4][0] = 0;
    +                s[4][1] = MP_DIGIT(a, 23);
    +                s[4][2] = 0;
    +                s[4][3] = MP_DIGIT(a, 20);
    +                for (i = 4; i < 12; i++) {
    +                        s[4][i] = MP_DIGIT(a, i+8);
    +                }
    +                s[5][0] = 0;
    +                s[5][1] = 0;
    +                s[5][2] = 0;
    +                s[5][3] = 0;
    +                s[5][4] = MP_DIGIT(a, 20);
    +                s[5][5] = MP_DIGIT(a, 21);
    +                s[5][6] = MP_DIGIT(a, 22);
    +                s[5][7] = MP_DIGIT(a, 23);
    +                s[5][8] = 0;
    +                s[5][9] = 0;
    +                s[5][10] = 0;
    +                s[5][11] = 0;
    +                s[6][0] = MP_DIGIT(a, 20);
    +                s[6][1] = 0;
    +                s[6][2] = 0;
    +                s[6][3] = MP_DIGIT(a, 21);
    +                s[6][4] = MP_DIGIT(a, 22);
    +                s[6][5] = MP_DIGIT(a, 23);
    +                s[6][6] = 0;
    +                s[6][7] = 0;
    +                s[6][8] = 0;
    +                s[6][9] = 0;
    +                s[6][10] = 0;
    +                s[6][11] = 0;
    +                s[7][0] = MP_DIGIT(a, 23);
    +                for (i = 1; i < 12; i++) {
    +                        s[7][i] = MP_DIGIT(a, i+11);
    +                }
    +                s[8][0] = 0;
    +                s[8][1] = MP_DIGIT(a, 20);
    +                s[8][2] = MP_DIGIT(a, 21);
    +                s[8][3] = MP_DIGIT(a, 22);
    +                s[8][4] = MP_DIGIT(a, 23);
    +                s[8][5] = 0;
    +                s[8][6] = 0;
    +                s[8][7] = 0;
    +                s[8][8] = 0;
    +                s[8][9] = 0;
    +                s[8][10] = 0;
    +                s[8][11] = 0;
    +                s[9][0] = 0;
    +                s[9][1] = 0;
    +                s[9][2] = 0;
    +                s[9][3] = MP_DIGIT(a, 23);
    +                s[9][4] = MP_DIGIT(a, 23);
    +                s[9][5] = 0;
    +                s[9][6] = 0;
    +                s[9][7] = 0;
    +                s[9][8] = 0;
    +                s[9][9] = 0;
    +                s[9][10] = 0;
    +                s[9][11] = 0;
    +
    +                MP_CHECKOK(mp_add(&m[0], &m[1], r));
    +                MP_CHECKOK(mp_add(r, &m[1], r));
    +                MP_CHECKOK(mp_add(r, &m[2], r));
    +                MP_CHECKOK(mp_add(r, &m[3], r));
    +                MP_CHECKOK(mp_add(r, &m[4], r));
    +                MP_CHECKOK(mp_add(r, &m[5], r));
    +                MP_CHECKOK(mp_add(r, &m[6], r));
    +                MP_CHECKOK(mp_sub(r, &m[7], r));
    +                MP_CHECKOK(mp_sub(r, &m[8], r));
    +                MP_CHECKOK(mp_submod(r, &m[9], &meth->irr, r));
    +                s_mp_clamp(r);
    +        }
    +#else
    +        /* for polynomials larger than twice the field size or polynomials
    +         * not using all words, use regular reduction */
    +        if ((a_bits > 768) || (a_bits <= 736)) {
    +                MP_CHECKOK(mp_mod(a, &meth->irr, r));
    +        } else {
    +                for (i = 0; i < 6; i++) {
    +                        s[0][i] = MP_DIGIT(a, i);
    +                }
    +                s[1][0] = 0;
    +                s[1][1] = 0;
    +                s[1][2] = (MP_DIGIT(a, 10) >> 32) | (MP_DIGIT(a, 11) << 32);
    +                s[1][3] = MP_DIGIT(a, 11) >> 32;
    +                s[1][4] = 0;
    +                s[1][5] = 0;
    +                for (i = 0; i < 6; i++) {
    +                        s[2][i] = MP_DIGIT(a, i+6);
    +                }
    +                s[3][0] = (MP_DIGIT(a, 10) >> 32) | (MP_DIGIT(a, 11) << 32);
    +                s[3][1] = (MP_DIGIT(a, 11) >> 32) | (MP_DIGIT(a, 6) << 32);
    +                for (i = 2; i < 6; i++) {
    +                        s[3][i] = (MP_DIGIT(a, i+4) >> 32) | (MP_DIGIT(a, i+5) << 32);
    +                }
    +                s[4][0] = (MP_DIGIT(a, 11) >> 32) << 32;
    +                s[4][1] = MP_DIGIT(a, 10) << 32;
    +                for (i = 2; i < 6; i++) {
    +                        s[4][i] = MP_DIGIT(a, i+4);
    +                }
    +                s[5][0] = 0;
    +                s[5][1] = 0;
    +                s[5][2] = MP_DIGIT(a, 10);
    +                s[5][3] = MP_DIGIT(a, 11);
    +                s[5][4] = 0;
    +                s[5][5] = 0;
    +                s[6][0] = (MP_DIGIT(a, 10) << 32) >> 32;
    +                s[6][1] = (MP_DIGIT(a, 10) >> 32) << 32;
    +                s[6][2] = MP_DIGIT(a, 11);
    +                s[6][3] = 0;
    +                s[6][4] = 0;
    +                s[6][5] = 0;
    +                s[7][0] = (MP_DIGIT(a, 11) >> 32) | (MP_DIGIT(a, 6) << 32);
    +                for (i = 1; i < 6; i++) {
    +                        s[7][i] = (MP_DIGIT(a, i+5) >> 32) | (MP_DIGIT(a, i+6) << 32);
    +                }
    +                s[8][0] = MP_DIGIT(a, 10) << 32;
    +                s[8][1] = (MP_DIGIT(a, 10) >> 32) | (MP_DIGIT(a, 11) << 32);
    +                s[8][2] = MP_DIGIT(a, 11) >> 32;
    +                s[8][3] = 0;
    +                s[8][4] = 0;
    +                s[8][5] = 0;
    +                s[9][0] = 0;
    +                s[9][1] = (MP_DIGIT(a, 11) >> 32) << 32;
    +                s[9][2] = MP_DIGIT(a, 11) >> 32;
    +                s[9][3] = 0;
    +                s[9][4] = 0;
    +                s[9][5] = 0;
    +
    +                MP_CHECKOK(mp_add(&m[0], &m[1], r));
    +                MP_CHECKOK(mp_add(r, &m[1], r));
    +                MP_CHECKOK(mp_add(r, &m[2], r));
    +                MP_CHECKOK(mp_add(r, &m[3], r));
    +                MP_CHECKOK(mp_add(r, &m[4], r));
    +                MP_CHECKOK(mp_add(r, &m[5], r));
    +                MP_CHECKOK(mp_add(r, &m[6], r));
    +                MP_CHECKOK(mp_sub(r, &m[7], r));
    +                MP_CHECKOK(mp_sub(r, &m[8], r));
    +                MP_CHECKOK(mp_submod(r, &m[9], &meth->irr, r));
    +                s_mp_clamp(r);
    +        }
    +#endif
    +
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* Compute the square of polynomial a, reduce modulo p384. Store the
    + * result in r.  r could be a.  Uses optimized modular reduction for p384.
    + */
    +mp_err
    +ec_GFp_nistp384_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +
    +        MP_CHECKOK(mp_sqr(a, r));
    +        MP_CHECKOK(ec_GFp_nistp384_mod(r, r, meth));
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* Compute the product of two polynomials a and b, reduce modulo p384.
    + * Store the result in r.  r could be a or b; a could be b.  Uses
    + * optimized modular reduction for p384. */
    +mp_err
    +ec_GFp_nistp384_mul(const mp_int *a, const mp_int *b, mp_int *r,
    +                                        const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +
    +        MP_CHECKOK(mp_mul(a, b, r));
    +        MP_CHECKOK(ec_GFp_nistp384_mod(r, r, meth));
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* Wire in fast field arithmetic and precomputation of base point for
    + * named curves. */
    +mp_err
    +ec_group_set_gfp384(ECGroup *group, ECCurveName name)
    +{
    +        if (name == ECCurve_NIST_P384) {
    +                group->meth->field_mod = &ec_GFp_nistp384_mod;
    +                group->meth->field_mul = &ec_GFp_nistp384_mul;
    +                group->meth->field_sqr = &ec_GFp_nistp384_sqr;
    +        }
    +        return MP_OKAY;
    +}
    diff --git a/jdk/src/share/native/sun/security/ec/ecp_521.c b/jdk/src/share/native/sun/security/ec/ecp_521.c
    new file mode 100644
    index 00000000000..68dca16a774
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/ecp_521.c
    @@ -0,0 +1,192 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the elliptic curve math library for prime field curves.
    + *
    + * The Initial Developer of the Original Code is
    + * Sun Microsystems, Inc.
    + * Portions created by the Initial Developer are Copyright (C) 2003
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Douglas Stebila 
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +#include "ecp.h"
    +#include "mpi.h"
    +#include "mplogic.h"
    +#include "mpi-priv.h"
    +#ifndef _KERNEL
    +#include 
    +#endif
    +
    +#define ECP521_DIGITS ECL_CURVE_DIGITS(521)
    +
    +/* Fast modular reduction for p521 = 2^521 - 1.  a can be r. Uses
    + * algorithm 2.31 from Hankerson, Menezes, Vanstone. Guide to
    + * Elliptic Curve Cryptography. */
    +mp_err
    +ec_GFp_nistp521_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +        int a_bits = mpl_significant_bits(a);
    +        int i;
    +
    +        /* m1, m2 are statically-allocated mp_int of exactly the size we need */
    +        mp_int m1;
    +
    +        mp_digit s1[ECP521_DIGITS] = { 0 };
    +
    +        MP_SIGN(&m1) = MP_ZPOS;
    +        MP_ALLOC(&m1) = ECP521_DIGITS;
    +        MP_USED(&m1) = ECP521_DIGITS;
    +        MP_DIGITS(&m1) = s1;
    +
    +        if (a_bits < 521) {
    +                if (a==r) return MP_OKAY;
    +                return mp_copy(a, r);
    +        }
    +        /* for polynomials larger than twice the field size or polynomials
    +         * not using all words, use regular reduction */
    +        if (a_bits > (521*2)) {
    +                MP_CHECKOK(mp_mod(a, &meth->irr, r));
    +        } else {
    +#define FIRST_DIGIT (ECP521_DIGITS-1)
    +                for (i = FIRST_DIGIT; i < MP_USED(a)-1; i++) {
    +                        s1[i-FIRST_DIGIT] = (MP_DIGIT(a, i) >> 9)
    +                                | (MP_DIGIT(a, 1+i) << (MP_DIGIT_BIT-9));
    +                }
    +                s1[i-FIRST_DIGIT] = MP_DIGIT(a, i) >> 9;
    +
    +                if ( a != r ) {
    +                        MP_CHECKOK(s_mp_pad(r,ECP521_DIGITS));
    +                        for (i = 0; i < ECP521_DIGITS; i++) {
    +                                MP_DIGIT(r,i) = MP_DIGIT(a, i);
    +                        }
    +                }
    +                MP_USED(r) = ECP521_DIGITS;
    +                MP_DIGIT(r,FIRST_DIGIT) &=  0x1FF;
    +
    +                MP_CHECKOK(s_mp_add(r, &m1));
    +                if (MP_DIGIT(r, FIRST_DIGIT) & 0x200) {
    +                        MP_CHECKOK(s_mp_add_d(r,1));
    +                        MP_DIGIT(r,FIRST_DIGIT) &=  0x1FF;
    +                }
    +                s_mp_clamp(r);
    +        }
    +
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* Compute the square of polynomial a, reduce modulo p521. Store the
    + * result in r.  r could be a.  Uses optimized modular reduction for p521.
    + */
    +mp_err
    +ec_GFp_nistp521_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +
    +        MP_CHECKOK(mp_sqr(a, r));
    +        MP_CHECKOK(ec_GFp_nistp521_mod(r, r, meth));
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* Compute the product of two polynomials a and b, reduce modulo p521.
    + * Store the result in r.  r could be a or b; a could be b.  Uses
    + * optimized modular reduction for p521. */
    +mp_err
    +ec_GFp_nistp521_mul(const mp_int *a, const mp_int *b, mp_int *r,
    +                                        const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +
    +        MP_CHECKOK(mp_mul(a, b, r));
    +        MP_CHECKOK(ec_GFp_nistp521_mod(r, r, meth));
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* Divides two field elements. If a is NULL, then returns the inverse of
    + * b. */
    +mp_err
    +ec_GFp_nistp521_div(const mp_int *a, const mp_int *b, mp_int *r,
    +                   const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_int t;
    +
    +        /* If a is NULL, then return the inverse of b, otherwise return a/b. */
    +        if (a == NULL) {
    +                return mp_invmod(b, &meth->irr, r);
    +        } else {
    +                /* MPI doesn't support divmod, so we implement it using invmod and
    +                 * mulmod. */
    +                MP_CHECKOK(mp_init(&t, FLAG(b)));
    +                MP_CHECKOK(mp_invmod(b, &meth->irr, &t));
    +                MP_CHECKOK(mp_mul(a, &t, r));
    +                MP_CHECKOK(ec_GFp_nistp521_mod(r, r, meth));
    +          CLEANUP:
    +                mp_clear(&t);
    +                return res;
    +        }
    +}
    +
    +/* Wire in fast field arithmetic and precomputation of base point for
    + * named curves. */
    +mp_err
    +ec_group_set_gfp521(ECGroup *group, ECCurveName name)
    +{
    +        if (name == ECCurve_NIST_P521) {
    +                group->meth->field_mod = &ec_GFp_nistp521_mod;
    +                group->meth->field_mul = &ec_GFp_nistp521_mul;
    +                group->meth->field_sqr = &ec_GFp_nistp521_sqr;
    +                group->meth->field_div = &ec_GFp_nistp521_div;
    +        }
    +        return MP_OKAY;
    +}
    diff --git a/jdk/src/share/native/sun/security/ec/ecp_aff.c b/jdk/src/share/native/sun/security/ec/ecp_aff.c
    new file mode 100644
    index 00000000000..f8d88d4dcbc
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/ecp_aff.c
    @@ -0,0 +1,379 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the elliptic curve math library for prime field curves.
    + *
    + * The Initial Developer of the Original Code is
    + * Sun Microsystems, Inc.
    + * Portions created by the Initial Developer are Copyright (C) 2003
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Sheueling Chang-Shantz ,
    + *   Stephen Fung , and
    + *   Douglas Stebila , Sun Microsystems Laboratories.
    + *   Bodo Moeller ,
    + *   Nils Larsch , and
    + *   Lenka Fibikova , the OpenSSL Project
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +#include "ecp.h"
    +#include "mplogic.h"
    +#ifndef _KERNEL
    +#include 
    +#endif
    +
    +/* Checks if point P(px, py) is at infinity.  Uses affine coordinates. */
    +mp_err
    +ec_GFp_pt_is_inf_aff(const mp_int *px, const mp_int *py)
    +{
    +
    +        if ((mp_cmp_z(px) == 0) && (mp_cmp_z(py) == 0)) {
    +                return MP_YES;
    +        } else {
    +                return MP_NO;
    +        }
    +
    +}
    +
    +/* Sets P(px, py) to be the point at infinity.  Uses affine coordinates. */
    +mp_err
    +ec_GFp_pt_set_inf_aff(mp_int *px, mp_int *py)
    +{
    +        mp_zero(px);
    +        mp_zero(py);
    +        return MP_OKAY;
    +}
    +
    +/* Computes R = P + Q based on IEEE P1363 A.10.1. Elliptic curve points P,
    + * Q, and R can all be identical. Uses affine coordinates. Assumes input
    + * is already field-encoded using field_enc, and returns output that is
    + * still field-encoded. */
    +mp_err
    +ec_GFp_pt_add_aff(const mp_int *px, const mp_int *py, const mp_int *qx,
    +                                  const mp_int *qy, mp_int *rx, mp_int *ry,
    +                                  const ECGroup *group)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_int lambda, temp, tempx, tempy;
    +
    +        MP_DIGITS(&lambda) = 0;
    +        MP_DIGITS(&temp) = 0;
    +        MP_DIGITS(&tempx) = 0;
    +        MP_DIGITS(&tempy) = 0;
    +        MP_CHECKOK(mp_init(&lambda, FLAG(px)));
    +        MP_CHECKOK(mp_init(&temp, FLAG(px)));
    +        MP_CHECKOK(mp_init(&tempx, FLAG(px)));
    +        MP_CHECKOK(mp_init(&tempy, FLAG(px)));
    +        /* if P = inf, then R = Q */
    +        if (ec_GFp_pt_is_inf_aff(px, py) == 0) {
    +                MP_CHECKOK(mp_copy(qx, rx));
    +                MP_CHECKOK(mp_copy(qy, ry));
    +                res = MP_OKAY;
    +                goto CLEANUP;
    +        }
    +        /* if Q = inf, then R = P */
    +        if (ec_GFp_pt_is_inf_aff(qx, qy) == 0) {
    +                MP_CHECKOK(mp_copy(px, rx));
    +                MP_CHECKOK(mp_copy(py, ry));
    +                res = MP_OKAY;
    +                goto CLEANUP;
    +        }
    +        /* if px != qx, then lambda = (py-qy) / (px-qx) */
    +        if (mp_cmp(px, qx) != 0) {
    +                MP_CHECKOK(group->meth->field_sub(py, qy, &tempy, group->meth));
    +                MP_CHECKOK(group->meth->field_sub(px, qx, &tempx, group->meth));
    +                MP_CHECKOK(group->meth->
    +                                   field_div(&tempy, &tempx, &lambda, group->meth));
    +        } else {
    +                /* if py != qy or qy = 0, then R = inf */
    +                if (((mp_cmp(py, qy) != 0)) || (mp_cmp_z(qy) == 0)) {
    +                        mp_zero(rx);
    +                        mp_zero(ry);
    +                        res = MP_OKAY;
    +                        goto CLEANUP;
    +                }
    +                /* lambda = (3qx^2+a) / (2qy) */
    +                MP_CHECKOK(group->meth->field_sqr(qx, &tempx, group->meth));
    +                MP_CHECKOK(mp_set_int(&temp, 3));
    +                if (group->meth->field_enc) {
    +                        MP_CHECKOK(group->meth->field_enc(&temp, &temp, group->meth));
    +                }
    +                MP_CHECKOK(group->meth->
    +                                   field_mul(&tempx, &temp, &tempx, group->meth));
    +                MP_CHECKOK(group->meth->
    +                                   field_add(&tempx, &group->curvea, &tempx, group->meth));
    +                MP_CHECKOK(mp_set_int(&temp, 2));
    +                if (group->meth->field_enc) {
    +                        MP_CHECKOK(group->meth->field_enc(&temp, &temp, group->meth));
    +                }
    +                MP_CHECKOK(group->meth->field_mul(qy, &temp, &tempy, group->meth));
    +                MP_CHECKOK(group->meth->
    +                                   field_div(&tempx, &tempy, &lambda, group->meth));
    +        }
    +        /* rx = lambda^2 - px - qx */
    +        MP_CHECKOK(group->meth->field_sqr(&lambda, &tempx, group->meth));
    +        MP_CHECKOK(group->meth->field_sub(&tempx, px, &tempx, group->meth));
    +        MP_CHECKOK(group->meth->field_sub(&tempx, qx, &tempx, group->meth));
    +        /* ry = (x1-x2) * lambda - y1 */
    +        MP_CHECKOK(group->meth->field_sub(qx, &tempx, &tempy, group->meth));
    +        MP_CHECKOK(group->meth->
    +                           field_mul(&tempy, &lambda, &tempy, group->meth));
    +        MP_CHECKOK(group->meth->field_sub(&tempy, qy, &tempy, group->meth));
    +        MP_CHECKOK(mp_copy(&tempx, rx));
    +        MP_CHECKOK(mp_copy(&tempy, ry));
    +
    +  CLEANUP:
    +        mp_clear(&lambda);
    +        mp_clear(&temp);
    +        mp_clear(&tempx);
    +        mp_clear(&tempy);
    +        return res;
    +}
    +
    +/* Computes R = P - Q. Elliptic curve points P, Q, and R can all be
    + * identical. Uses affine coordinates. Assumes input is already
    + * field-encoded using field_enc, and returns output that is still
    + * field-encoded. */
    +mp_err
    +ec_GFp_pt_sub_aff(const mp_int *px, const mp_int *py, const mp_int *qx,
    +                                  const mp_int *qy, mp_int *rx, mp_int *ry,
    +                                  const ECGroup *group)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_int nqy;
    +
    +        MP_DIGITS(&nqy) = 0;
    +        MP_CHECKOK(mp_init(&nqy, FLAG(px)));
    +        /* nqy = -qy */
    +        MP_CHECKOK(group->meth->field_neg(qy, &nqy, group->meth));
    +        res = group->point_add(px, py, qx, &nqy, rx, ry, group);
    +  CLEANUP:
    +        mp_clear(&nqy);
    +        return res;
    +}
    +
    +/* Computes R = 2P. Elliptic curve points P and R can be identical. Uses
    + * affine coordinates. Assumes input is already field-encoded using
    + * field_enc, and returns output that is still field-encoded. */
    +mp_err
    +ec_GFp_pt_dbl_aff(const mp_int *px, const mp_int *py, mp_int *rx,
    +                                  mp_int *ry, const ECGroup *group)
    +{
    +        return ec_GFp_pt_add_aff(px, py, px, py, rx, ry, group);
    +}
    +
    +/* by default, this routine is unused and thus doesn't need to be compiled */
    +#ifdef ECL_ENABLE_GFP_PT_MUL_AFF
    +/* Computes R = nP based on IEEE P1363 A.10.3. Elliptic curve points P and
    + * R can be identical. Uses affine coordinates. Assumes input is already
    + * field-encoded using field_enc, and returns output that is still
    + * field-encoded. */
    +mp_err
    +ec_GFp_pt_mul_aff(const mp_int *n, const mp_int *px, const mp_int *py,
    +                                  mp_int *rx, mp_int *ry, const ECGroup *group)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_int k, k3, qx, qy, sx, sy;
    +        int b1, b3, i, l;
    +
    +        MP_DIGITS(&k) = 0;
    +        MP_DIGITS(&k3) = 0;
    +        MP_DIGITS(&qx) = 0;
    +        MP_DIGITS(&qy) = 0;
    +        MP_DIGITS(&sx) = 0;
    +        MP_DIGITS(&sy) = 0;
    +        MP_CHECKOK(mp_init(&k));
    +        MP_CHECKOK(mp_init(&k3));
    +        MP_CHECKOK(mp_init(&qx));
    +        MP_CHECKOK(mp_init(&qy));
    +        MP_CHECKOK(mp_init(&sx));
    +        MP_CHECKOK(mp_init(&sy));
    +
    +        /* if n = 0 then r = inf */
    +        if (mp_cmp_z(n) == 0) {
    +                mp_zero(rx);
    +                mp_zero(ry);
    +                res = MP_OKAY;
    +                goto CLEANUP;
    +        }
    +        /* Q = P, k = n */
    +        MP_CHECKOK(mp_copy(px, &qx));
    +        MP_CHECKOK(mp_copy(py, &qy));
    +        MP_CHECKOK(mp_copy(n, &k));
    +        /* if n < 0 then Q = -Q, k = -k */
    +        if (mp_cmp_z(n) < 0) {
    +                MP_CHECKOK(group->meth->field_neg(&qy, &qy, group->meth));
    +                MP_CHECKOK(mp_neg(&k, &k));
    +        }
    +#ifdef ECL_DEBUG                                /* basic double and add method */
    +        l = mpl_significant_bits(&k) - 1;
    +        MP_CHECKOK(mp_copy(&qx, &sx));
    +        MP_CHECKOK(mp_copy(&qy, &sy));
    +        for (i = l - 1; i >= 0; i--) {
    +                /* S = 2S */
    +                MP_CHECKOK(group->point_dbl(&sx, &sy, &sx, &sy, group));
    +                /* if k_i = 1, then S = S + Q */
    +                if (mpl_get_bit(&k, i) != 0) {
    +                        MP_CHECKOK(group->
    +                                           point_add(&sx, &sy, &qx, &qy, &sx, &sy, group));
    +                }
    +        }
    +#else                                                   /* double and add/subtract method from
    +                                                                 * standard */
    +        /* k3 = 3 * k */
    +        MP_CHECKOK(mp_set_int(&k3, 3));
    +        MP_CHECKOK(mp_mul(&k, &k3, &k3));
    +        /* S = Q */
    +        MP_CHECKOK(mp_copy(&qx, &sx));
    +        MP_CHECKOK(mp_copy(&qy, &sy));
    +        /* l = index of high order bit in binary representation of 3*k */
    +        l = mpl_significant_bits(&k3) - 1;
    +        /* for i = l-1 downto 1 */
    +        for (i = l - 1; i >= 1; i--) {
    +                /* S = 2S */
    +                MP_CHECKOK(group->point_dbl(&sx, &sy, &sx, &sy, group));
    +                b3 = MP_GET_BIT(&k3, i);
    +                b1 = MP_GET_BIT(&k, i);
    +                /* if k3_i = 1 and k_i = 0, then S = S + Q */
    +                if ((b3 == 1) && (b1 == 0)) {
    +                        MP_CHECKOK(group->
    +                                           point_add(&sx, &sy, &qx, &qy, &sx, &sy, group));
    +                        /* if k3_i = 0 and k_i = 1, then S = S - Q */
    +                } else if ((b3 == 0) && (b1 == 1)) {
    +                        MP_CHECKOK(group->
    +                                           point_sub(&sx, &sy, &qx, &qy, &sx, &sy, group));
    +                }
    +        }
    +#endif
    +        /* output S */
    +        MP_CHECKOK(mp_copy(&sx, rx));
    +        MP_CHECKOK(mp_copy(&sy, ry));
    +
    +  CLEANUP:
    +        mp_clear(&k);
    +        mp_clear(&k3);
    +        mp_clear(&qx);
    +        mp_clear(&qy);
    +        mp_clear(&sx);
    +        mp_clear(&sy);
    +        return res;
    +}
    +#endif
    +
    +/* Validates a point on a GFp curve. */
    +mp_err
    +ec_GFp_validate_point(const mp_int *px, const mp_int *py, const ECGroup *group)
    +{
    +        mp_err res = MP_NO;
    +        mp_int accl, accr, tmp, pxt, pyt;
    +
    +        MP_DIGITS(&accl) = 0;
    +        MP_DIGITS(&accr) = 0;
    +        MP_DIGITS(&tmp) = 0;
    +        MP_DIGITS(&pxt) = 0;
    +        MP_DIGITS(&pyt) = 0;
    +        MP_CHECKOK(mp_init(&accl, FLAG(px)));
    +        MP_CHECKOK(mp_init(&accr, FLAG(px)));
    +        MP_CHECKOK(mp_init(&tmp, FLAG(px)));
    +        MP_CHECKOK(mp_init(&pxt, FLAG(px)));
    +        MP_CHECKOK(mp_init(&pyt, FLAG(px)));
    +
    +    /* 1: Verify that publicValue is not the point at infinity */
    +        if (ec_GFp_pt_is_inf_aff(px, py) == MP_YES) {
    +                res = MP_NO;
    +                goto CLEANUP;
    +        }
    +    /* 2: Verify that the coordinates of publicValue are elements
    +     *    of the field.
    +     */
    +        if ((MP_SIGN(px) == MP_NEG) || (mp_cmp(px, &group->meth->irr) >= 0) ||
    +                (MP_SIGN(py) == MP_NEG) || (mp_cmp(py, &group->meth->irr) >= 0)) {
    +                res = MP_NO;
    +                goto CLEANUP;
    +        }
    +    /* 3: Verify that publicValue is on the curve. */
    +        if (group->meth->field_enc) {
    +                group->meth->field_enc(px, &pxt, group->meth);
    +                group->meth->field_enc(py, &pyt, group->meth);
    +        } else {
    +                mp_copy(px, &pxt);
    +                mp_copy(py, &pyt);
    +        }
    +        /* left-hand side: y^2  */
    +        MP_CHECKOK( group->meth->field_sqr(&pyt, &accl, group->meth) );
    +        /* right-hand side: x^3 + a*x + b */
    +        MP_CHECKOK( group->meth->field_sqr(&pxt, &tmp, group->meth) );
    +        MP_CHECKOK( group->meth->field_mul(&pxt, &tmp, &accr, group->meth) );
    +        MP_CHECKOK( group->meth->field_mul(&group->curvea, &pxt, &tmp, group->meth) );
    +        MP_CHECKOK( group->meth->field_add(&tmp, &accr, &accr, group->meth) );
    +        MP_CHECKOK( group->meth->field_add(&accr, &group->curveb, &accr, group->meth) );
    +        /* check LHS - RHS == 0 */
    +        MP_CHECKOK( group->meth->field_sub(&accl, &accr, &accr, group->meth) );
    +        if (mp_cmp_z(&accr) != 0) {
    +                res = MP_NO;
    +                goto CLEANUP;
    +        }
    +    /* 4: Verify that the order of the curve times the publicValue
    +     *    is the point at infinity.
    +     */
    +        MP_CHECKOK( ECPoint_mul(group, &group->order, px, py, &pxt, &pyt) );
    +        if (ec_GFp_pt_is_inf_aff(&pxt, &pyt) != MP_YES) {
    +                res = MP_NO;
    +                goto CLEANUP;
    +        }
    +
    +        res = MP_YES;
    +
    +CLEANUP:
    +        mp_clear(&accl);
    +        mp_clear(&accr);
    +        mp_clear(&tmp);
    +        mp_clear(&pxt);
    +        mp_clear(&pyt);
    +        return res;
    +}
    diff --git a/jdk/src/share/native/sun/security/ec/ecp_jac.c b/jdk/src/share/native/sun/security/ec/ecp_jac.c
    new file mode 100644
    index 00000000000..47c0e195dc1
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/ecp_jac.c
    @@ -0,0 +1,575 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the elliptic curve math library for prime field curves.
    + *
    + * The Initial Developer of the Original Code is
    + * Sun Microsystems, Inc.
    + * Portions created by the Initial Developer are Copyright (C) 2003
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Sheueling Chang-Shantz ,
    + *   Stephen Fung , and
    + *   Douglas Stebila , Sun Microsystems Laboratories.
    + *   Bodo Moeller ,
    + *   Nils Larsch , and
    + *   Lenka Fibikova , the OpenSSL Project
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +#include "ecp.h"
    +#include "mplogic.h"
    +#ifndef _KERNEL
    +#include 
    +#endif
    +#ifdef ECL_DEBUG
    +#include 
    +#endif
    +
    +/* Converts a point P(px, py) from affine coordinates to Jacobian
    + * projective coordinates R(rx, ry, rz). Assumes input is already
    + * field-encoded using field_enc, and returns output that is still
    + * field-encoded. */
    +mp_err
    +ec_GFp_pt_aff2jac(const mp_int *px, const mp_int *py, mp_int *rx,
    +                                  mp_int *ry, mp_int *rz, const ECGroup *group)
    +{
    +        mp_err res = MP_OKAY;
    +
    +        if (ec_GFp_pt_is_inf_aff(px, py) == MP_YES) {
    +                MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, rz));
    +        } else {
    +                MP_CHECKOK(mp_copy(px, rx));
    +                MP_CHECKOK(mp_copy(py, ry));
    +                MP_CHECKOK(mp_set_int(rz, 1));
    +                if (group->meth->field_enc) {
    +                        MP_CHECKOK(group->meth->field_enc(rz, rz, group->meth));
    +                }
    +        }
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* Converts a point P(px, py, pz) from Jacobian projective coordinates to
    + * affine coordinates R(rx, ry).  P and R can share x and y coordinates.
    + * Assumes input is already field-encoded using field_enc, and returns
    + * output that is still field-encoded. */
    +mp_err
    +ec_GFp_pt_jac2aff(const mp_int *px, const mp_int *py, const mp_int *pz,
    +                                  mp_int *rx, mp_int *ry, const ECGroup *group)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_int z1, z2, z3;
    +
    +        MP_DIGITS(&z1) = 0;
    +        MP_DIGITS(&z2) = 0;
    +        MP_DIGITS(&z3) = 0;
    +        MP_CHECKOK(mp_init(&z1, FLAG(px)));
    +        MP_CHECKOK(mp_init(&z2, FLAG(px)));
    +        MP_CHECKOK(mp_init(&z3, FLAG(px)));
    +
    +        /* if point at infinity, then set point at infinity and exit */
    +        if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES) {
    +                MP_CHECKOK(ec_GFp_pt_set_inf_aff(rx, ry));
    +                goto CLEANUP;
    +        }
    +
    +        /* transform (px, py, pz) into (px / pz^2, py / pz^3) */
    +        if (mp_cmp_d(pz, 1) == 0) {
    +                MP_CHECKOK(mp_copy(px, rx));
    +                MP_CHECKOK(mp_copy(py, ry));
    +        } else {
    +                MP_CHECKOK(group->meth->field_div(NULL, pz, &z1, group->meth));
    +                MP_CHECKOK(group->meth->field_sqr(&z1, &z2, group->meth));
    +                MP_CHECKOK(group->meth->field_mul(&z1, &z2, &z3, group->meth));
    +                MP_CHECKOK(group->meth->field_mul(px, &z2, rx, group->meth));
    +                MP_CHECKOK(group->meth->field_mul(py, &z3, ry, group->meth));
    +        }
    +
    +  CLEANUP:
    +        mp_clear(&z1);
    +        mp_clear(&z2);
    +        mp_clear(&z3);
    +        return res;
    +}
    +
    +/* Checks if point P(px, py, pz) is at infinity. Uses Jacobian
    + * coordinates. */
    +mp_err
    +ec_GFp_pt_is_inf_jac(const mp_int *px, const mp_int *py, const mp_int *pz)
    +{
    +        return mp_cmp_z(pz);
    +}
    +
    +/* Sets P(px, py, pz) to be the point at infinity.  Uses Jacobian
    + * coordinates. */
    +mp_err
    +ec_GFp_pt_set_inf_jac(mp_int *px, mp_int *py, mp_int *pz)
    +{
    +        mp_zero(pz);
    +        return MP_OKAY;
    +}
    +
    +/* Computes R = P + Q where R is (rx, ry, rz), P is (px, py, pz) and Q is
    + * (qx, qy, 1).  Elliptic curve points P, Q, and R can all be identical.
    + * Uses mixed Jacobian-affine coordinates. Assumes input is already
    + * field-encoded using field_enc, and returns output that is still
    + * field-encoded. Uses equation (2) from Brown, Hankerson, Lopez, and
    + * Menezes. Software Implementation of the NIST Elliptic Curves Over Prime
    + * Fields. */
    +mp_err
    +ec_GFp_pt_add_jac_aff(const mp_int *px, const mp_int *py, const mp_int *pz,
    +                                          const mp_int *qx, const mp_int *qy, mp_int *rx,
    +                                          mp_int *ry, mp_int *rz, const ECGroup *group)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_int A, B, C, D, C2, C3;
    +
    +        MP_DIGITS(&A) = 0;
    +        MP_DIGITS(&B) = 0;
    +        MP_DIGITS(&C) = 0;
    +        MP_DIGITS(&D) = 0;
    +        MP_DIGITS(&C2) = 0;
    +        MP_DIGITS(&C3) = 0;
    +        MP_CHECKOK(mp_init(&A, FLAG(px)));
    +        MP_CHECKOK(mp_init(&B, FLAG(px)));
    +        MP_CHECKOK(mp_init(&C, FLAG(px)));
    +        MP_CHECKOK(mp_init(&D, FLAG(px)));
    +        MP_CHECKOK(mp_init(&C2, FLAG(px)));
    +        MP_CHECKOK(mp_init(&C3, FLAG(px)));
    +
    +        /* If either P or Q is the point at infinity, then return the other
    +         * point */
    +        if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES) {
    +                MP_CHECKOK(ec_GFp_pt_aff2jac(qx, qy, rx, ry, rz, group));
    +                goto CLEANUP;
    +        }
    +        if (ec_GFp_pt_is_inf_aff(qx, qy) == MP_YES) {
    +                MP_CHECKOK(mp_copy(px, rx));
    +                MP_CHECKOK(mp_copy(py, ry));
    +                MP_CHECKOK(mp_copy(pz, rz));
    +                goto CLEANUP;
    +        }
    +
    +        /* A = qx * pz^2, B = qy * pz^3 */
    +        MP_CHECKOK(group->meth->field_sqr(pz, &A, group->meth));
    +        MP_CHECKOK(group->meth->field_mul(&A, pz, &B, group->meth));
    +        MP_CHECKOK(group->meth->field_mul(&A, qx, &A, group->meth));
    +        MP_CHECKOK(group->meth->field_mul(&B, qy, &B, group->meth));
    +
    +        /* C = A - px, D = B - py */
    +        MP_CHECKOK(group->meth->field_sub(&A, px, &C, group->meth));
    +        MP_CHECKOK(group->meth->field_sub(&B, py, &D, group->meth));
    +
    +        /* C2 = C^2, C3 = C^3 */
    +        MP_CHECKOK(group->meth->field_sqr(&C, &C2, group->meth));
    +        MP_CHECKOK(group->meth->field_mul(&C, &C2, &C3, group->meth));
    +
    +        /* rz = pz * C */
    +        MP_CHECKOK(group->meth->field_mul(pz, &C, rz, group->meth));
    +
    +        /* C = px * C^2 */
    +        MP_CHECKOK(group->meth->field_mul(px, &C2, &C, group->meth));
    +        /* A = D^2 */
    +        MP_CHECKOK(group->meth->field_sqr(&D, &A, group->meth));
    +
    +        /* rx = D^2 - (C^3 + 2 * (px * C^2)) */
    +        MP_CHECKOK(group->meth->field_add(&C, &C, rx, group->meth));
    +        MP_CHECKOK(group->meth->field_add(&C3, rx, rx, group->meth));
    +        MP_CHECKOK(group->meth->field_sub(&A, rx, rx, group->meth));
    +
    +        /* C3 = py * C^3 */
    +        MP_CHECKOK(group->meth->field_mul(py, &C3, &C3, group->meth));
    +
    +        /* ry = D * (px * C^2 - rx) - py * C^3 */
    +        MP_CHECKOK(group->meth->field_sub(&C, rx, ry, group->meth));
    +        MP_CHECKOK(group->meth->field_mul(&D, ry, ry, group->meth));
    +        MP_CHECKOK(group->meth->field_sub(ry, &C3, ry, group->meth));
    +
    +  CLEANUP:
    +        mp_clear(&A);
    +        mp_clear(&B);
    +        mp_clear(&C);
    +        mp_clear(&D);
    +        mp_clear(&C2);
    +        mp_clear(&C3);
    +        return res;
    +}
    +
    +/* Computes R = 2P.  Elliptic curve points P and R can be identical.  Uses
    + * Jacobian coordinates.
    + *
    + * Assumes input is already field-encoded using field_enc, and returns
    + * output that is still field-encoded.
    + *
    + * This routine implements Point Doubling in the Jacobian Projective
    + * space as described in the paper "Efficient elliptic curve exponentiation
    + * using mixed coordinates", by H. Cohen, A Miyaji, T. Ono.
    + */
    +mp_err
    +ec_GFp_pt_dbl_jac(const mp_int *px, const mp_int *py, const mp_int *pz,
    +                                  mp_int *rx, mp_int *ry, mp_int *rz, const ECGroup *group)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_int t0, t1, M, S;
    +
    +        MP_DIGITS(&t0) = 0;
    +        MP_DIGITS(&t1) = 0;
    +        MP_DIGITS(&M) = 0;
    +        MP_DIGITS(&S) = 0;
    +        MP_CHECKOK(mp_init(&t0, FLAG(px)));
    +        MP_CHECKOK(mp_init(&t1, FLAG(px)));
    +        MP_CHECKOK(mp_init(&M, FLAG(px)));
    +        MP_CHECKOK(mp_init(&S, FLAG(px)));
    +
    +        if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES) {
    +                MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, rz));
    +                goto CLEANUP;
    +        }
    +
    +        if (mp_cmp_d(pz, 1) == 0) {
    +                /* M = 3 * px^2 + a */
    +                MP_CHECKOK(group->meth->field_sqr(px, &t0, group->meth));
    +                MP_CHECKOK(group->meth->field_add(&t0, &t0, &M, group->meth));
    +                MP_CHECKOK(group->meth->field_add(&t0, &M, &t0, group->meth));
    +                MP_CHECKOK(group->meth->
    +                                   field_add(&t0, &group->curvea, &M, group->meth));
    +        } else if (mp_cmp_int(&group->curvea, -3, FLAG(px)) == 0) {
    +                /* M = 3 * (px + pz^2) * (px - pz^2) */
    +                MP_CHECKOK(group->meth->field_sqr(pz, &M, group->meth));
    +                MP_CHECKOK(group->meth->field_add(px, &M, &t0, group->meth));
    +                MP_CHECKOK(group->meth->field_sub(px, &M, &t1, group->meth));
    +                MP_CHECKOK(group->meth->field_mul(&t0, &t1, &M, group->meth));
    +                MP_CHECKOK(group->meth->field_add(&M, &M, &t0, group->meth));
    +                MP_CHECKOK(group->meth->field_add(&t0, &M, &M, group->meth));
    +        } else {
    +                /* M = 3 * (px^2) + a * (pz^4) */
    +                MP_CHECKOK(group->meth->field_sqr(px, &t0, group->meth));
    +                MP_CHECKOK(group->meth->field_add(&t0, &t0, &M, group->meth));
    +                MP_CHECKOK(group->meth->field_add(&t0, &M, &t0, group->meth));
    +                MP_CHECKOK(group->meth->field_sqr(pz, &M, group->meth));
    +                MP_CHECKOK(group->meth->field_sqr(&M, &M, group->meth));
    +                MP_CHECKOK(group->meth->
    +                                   field_mul(&M, &group->curvea, &M, group->meth));
    +                MP_CHECKOK(group->meth->field_add(&M, &t0, &M, group->meth));
    +        }
    +
    +        /* rz = 2 * py * pz */
    +        /* t0 = 4 * py^2 */
    +        if (mp_cmp_d(pz, 1) == 0) {
    +                MP_CHECKOK(group->meth->field_add(py, py, rz, group->meth));
    +                MP_CHECKOK(group->meth->field_sqr(rz, &t0, group->meth));
    +        } else {
    +                MP_CHECKOK(group->meth->field_add(py, py, &t0, group->meth));
    +                MP_CHECKOK(group->meth->field_mul(&t0, pz, rz, group->meth));
    +                MP_CHECKOK(group->meth->field_sqr(&t0, &t0, group->meth));
    +        }
    +
    +        /* S = 4 * px * py^2 = px * (2 * py)^2 */
    +        MP_CHECKOK(group->meth->field_mul(px, &t0, &S, group->meth));
    +
    +        /* rx = M^2 - 2 * S */
    +        MP_CHECKOK(group->meth->field_add(&S, &S, &t1, group->meth));
    +        MP_CHECKOK(group->meth->field_sqr(&M, rx, group->meth));
    +        MP_CHECKOK(group->meth->field_sub(rx, &t1, rx, group->meth));
    +
    +        /* ry = M * (S - rx) - 8 * py^4 */
    +        MP_CHECKOK(group->meth->field_sqr(&t0, &t1, group->meth));
    +        if (mp_isodd(&t1)) {
    +                MP_CHECKOK(mp_add(&t1, &group->meth->irr, &t1));
    +        }
    +        MP_CHECKOK(mp_div_2(&t1, &t1));
    +        MP_CHECKOK(group->meth->field_sub(&S, rx, &S, group->meth));
    +        MP_CHECKOK(group->meth->field_mul(&M, &S, &M, group->meth));
    +        MP_CHECKOK(group->meth->field_sub(&M, &t1, ry, group->meth));
    +
    +  CLEANUP:
    +        mp_clear(&t0);
    +        mp_clear(&t1);
    +        mp_clear(&M);
    +        mp_clear(&S);
    +        return res;
    +}
    +
    +/* by default, this routine is unused and thus doesn't need to be compiled */
    +#ifdef ECL_ENABLE_GFP_PT_MUL_JAC
    +/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
    + * a, b and p are the elliptic curve coefficients and the prime that
    + * determines the field GFp.  Elliptic curve points P and R can be
    + * identical.  Uses mixed Jacobian-affine coordinates. Assumes input is
    + * already field-encoded using field_enc, and returns output that is still
    + * field-encoded. Uses 4-bit window method. */
    +mp_err
    +ec_GFp_pt_mul_jac(const mp_int *n, const mp_int *px, const mp_int *py,
    +                                  mp_int *rx, mp_int *ry, const ECGroup *group)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_int precomp[16][2], rz;
    +        int i, ni, d;
    +
    +        MP_DIGITS(&rz) = 0;
    +        for (i = 0; i < 16; i++) {
    +                MP_DIGITS(&precomp[i][0]) = 0;
    +                MP_DIGITS(&precomp[i][1]) = 0;
    +        }
    +
    +        ARGCHK(group != NULL, MP_BADARG);
    +        ARGCHK((n != NULL) && (px != NULL) && (py != NULL), MP_BADARG);
    +
    +        /* initialize precomputation table */
    +        for (i = 0; i < 16; i++) {
    +                MP_CHECKOK(mp_init(&precomp[i][0]));
    +                MP_CHECKOK(mp_init(&precomp[i][1]));
    +        }
    +
    +        /* fill precomputation table */
    +        mp_zero(&precomp[0][0]);
    +        mp_zero(&precomp[0][1]);
    +        MP_CHECKOK(mp_copy(px, &precomp[1][0]));
    +        MP_CHECKOK(mp_copy(py, &precomp[1][1]));
    +        for (i = 2; i < 16; i++) {
    +                MP_CHECKOK(group->
    +                                   point_add(&precomp[1][0], &precomp[1][1],
    +                                                         &precomp[i - 1][0], &precomp[i - 1][1],
    +                                                         &precomp[i][0], &precomp[i][1], group));
    +        }
    +
    +        d = (mpl_significant_bits(n) + 3) / 4;
    +
    +        /* R = inf */
    +        MP_CHECKOK(mp_init(&rz));
    +        MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, &rz));
    +
    +        for (i = d - 1; i >= 0; i--) {
    +                /* compute window ni */
    +                ni = MP_GET_BIT(n, 4 * i + 3);
    +                ni <<= 1;
    +                ni |= MP_GET_BIT(n, 4 * i + 2);
    +                ni <<= 1;
    +                ni |= MP_GET_BIT(n, 4 * i + 1);
    +                ni <<= 1;
    +                ni |= MP_GET_BIT(n, 4 * i);
    +                /* R = 2^4 * R */
    +                MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
    +                MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
    +                MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
    +                MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
    +                /* R = R + (ni * P) */
    +                MP_CHECKOK(ec_GFp_pt_add_jac_aff
    +                                   (rx, ry, &rz, &precomp[ni][0], &precomp[ni][1], rx, ry,
    +                                        &rz, group));
    +        }
    +
    +        /* convert result S to affine coordinates */
    +        MP_CHECKOK(ec_GFp_pt_jac2aff(rx, ry, &rz, rx, ry, group));
    +
    +  CLEANUP:
    +        mp_clear(&rz);
    +        for (i = 0; i < 16; i++) {
    +                mp_clear(&precomp[i][0]);
    +                mp_clear(&precomp[i][1]);
    +        }
    +        return res;
    +}
    +#endif
    +
    +/* Elliptic curve scalar-point multiplication. Computes R(x, y) = k1 * G +
    + * k2 * P(x, y), where G is the generator (base point) of the group of
    + * points on the elliptic curve. Allows k1 = NULL or { k2, P } = NULL.
    + * Uses mixed Jacobian-affine coordinates. Input and output values are
    + * assumed to be NOT field-encoded. Uses algorithm 15 (simultaneous
    + * multiple point multiplication) from Brown, Hankerson, Lopez, Menezes.
    + * Software Implementation of the NIST Elliptic Curves over Prime Fields. */
    +mp_err
    +ec_GFp_pts_mul_jac(const mp_int *k1, const mp_int *k2, const mp_int *px,
    +                                   const mp_int *py, mp_int *rx, mp_int *ry,
    +                                   const ECGroup *group)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_int precomp[4][4][2];
    +        mp_int rz;
    +        const mp_int *a, *b;
    +        int i, j;
    +        int ai, bi, d;
    +
    +        for (i = 0; i < 4; i++) {
    +                for (j = 0; j < 4; j++) {
    +                        MP_DIGITS(&precomp[i][j][0]) = 0;
    +                        MP_DIGITS(&precomp[i][j][1]) = 0;
    +                }
    +        }
    +        MP_DIGITS(&rz) = 0;
    +
    +        ARGCHK(group != NULL, MP_BADARG);
    +        ARGCHK(!((k1 == NULL)
    +                         && ((k2 == NULL) || (px == NULL)
    +                                 || (py == NULL))), MP_BADARG);
    +
    +        /* if some arguments are not defined used ECPoint_mul */
    +        if (k1 == NULL) {
    +                return ECPoint_mul(group, k2, px, py, rx, ry);
    +        } else if ((k2 == NULL) || (px == NULL) || (py == NULL)) {
    +                return ECPoint_mul(group, k1, NULL, NULL, rx, ry);
    +        }
    +
    +        /* initialize precomputation table */
    +        for (i = 0; i < 4; i++) {
    +                for (j = 0; j < 4; j++) {
    +                        MP_CHECKOK(mp_init(&precomp[i][j][0], FLAG(k1)));
    +                        MP_CHECKOK(mp_init(&precomp[i][j][1], FLAG(k1)));
    +                }
    +        }
    +
    +        /* fill precomputation table */
    +        /* assign {k1, k2} = {a, b} such that len(a) >= len(b) */
    +        if (mpl_significant_bits(k1) < mpl_significant_bits(k2)) {
    +                a = k2;
    +                b = k1;
    +                if (group->meth->field_enc) {
    +                        MP_CHECKOK(group->meth->
    +                                           field_enc(px, &precomp[1][0][0], group->meth));
    +                        MP_CHECKOK(group->meth->
    +                                           field_enc(py, &precomp[1][0][1], group->meth));
    +                } else {
    +                        MP_CHECKOK(mp_copy(px, &precomp[1][0][0]));
    +                        MP_CHECKOK(mp_copy(py, &precomp[1][0][1]));
    +                }
    +                MP_CHECKOK(mp_copy(&group->genx, &precomp[0][1][0]));
    +                MP_CHECKOK(mp_copy(&group->geny, &precomp[0][1][1]));
    +        } else {
    +                a = k1;
    +                b = k2;
    +                MP_CHECKOK(mp_copy(&group->genx, &precomp[1][0][0]));
    +                MP_CHECKOK(mp_copy(&group->geny, &precomp[1][0][1]));
    +                if (group->meth->field_enc) {
    +                        MP_CHECKOK(group->meth->
    +                                           field_enc(px, &precomp[0][1][0], group->meth));
    +                        MP_CHECKOK(group->meth->
    +                                           field_enc(py, &precomp[0][1][1], group->meth));
    +                } else {
    +                        MP_CHECKOK(mp_copy(px, &precomp[0][1][0]));
    +                        MP_CHECKOK(mp_copy(py, &precomp[0][1][1]));
    +                }
    +        }
    +        /* precompute [*][0][*] */
    +        mp_zero(&precomp[0][0][0]);
    +        mp_zero(&precomp[0][0][1]);
    +        MP_CHECKOK(group->
    +                           point_dbl(&precomp[1][0][0], &precomp[1][0][1],
    +                                                 &precomp[2][0][0], &precomp[2][0][1], group));
    +        MP_CHECKOK(group->
    +                           point_add(&precomp[1][0][0], &precomp[1][0][1],
    +                                                 &precomp[2][0][0], &precomp[2][0][1],
    +                                                 &precomp[3][0][0], &precomp[3][0][1], group));
    +        /* precompute [*][1][*] */
    +        for (i = 1; i < 4; i++) {
    +                MP_CHECKOK(group->
    +                                   point_add(&precomp[0][1][0], &precomp[0][1][1],
    +                                                         &precomp[i][0][0], &precomp[i][0][1],
    +                                                         &precomp[i][1][0], &precomp[i][1][1], group));
    +        }
    +        /* precompute [*][2][*] */
    +        MP_CHECKOK(group->
    +                           point_dbl(&precomp[0][1][0], &precomp[0][1][1],
    +                                                 &precomp[0][2][0], &precomp[0][2][1], group));
    +        for (i = 1; i < 4; i++) {
    +                MP_CHECKOK(group->
    +                                   point_add(&precomp[0][2][0], &precomp[0][2][1],
    +                                                         &precomp[i][0][0], &precomp[i][0][1],
    +                                                         &precomp[i][2][0], &precomp[i][2][1], group));
    +        }
    +        /* precompute [*][3][*] */
    +        MP_CHECKOK(group->
    +                           point_add(&precomp[0][1][0], &precomp[0][1][1],
    +                                                 &precomp[0][2][0], &precomp[0][2][1],
    +                                                 &precomp[0][3][0], &precomp[0][3][1], group));
    +        for (i = 1; i < 4; i++) {
    +                MP_CHECKOK(group->
    +                                   point_add(&precomp[0][3][0], &precomp[0][3][1],
    +                                                         &precomp[i][0][0], &precomp[i][0][1],
    +                                                         &precomp[i][3][0], &precomp[i][3][1], group));
    +        }
    +
    +        d = (mpl_significant_bits(a) + 1) / 2;
    +
    +        /* R = inf */
    +        MP_CHECKOK(mp_init(&rz, FLAG(k1)));
    +        MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, &rz));
    +
    +        for (i = d - 1; i >= 0; i--) {
    +                ai = MP_GET_BIT(a, 2 * i + 1);
    +                ai <<= 1;
    +                ai |= MP_GET_BIT(a, 2 * i);
    +                bi = MP_GET_BIT(b, 2 * i + 1);
    +                bi <<= 1;
    +                bi |= MP_GET_BIT(b, 2 * i);
    +                /* R = 2^2 * R */
    +                MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
    +                MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
    +                /* R = R + (ai * A + bi * B) */
    +                MP_CHECKOK(ec_GFp_pt_add_jac_aff
    +                                   (rx, ry, &rz, &precomp[ai][bi][0], &precomp[ai][bi][1],
    +                                        rx, ry, &rz, group));
    +        }
    +
    +        MP_CHECKOK(ec_GFp_pt_jac2aff(rx, ry, &rz, rx, ry, group));
    +
    +        if (group->meth->field_dec) {
    +                MP_CHECKOK(group->meth->field_dec(rx, rx, group->meth));
    +                MP_CHECKOK(group->meth->field_dec(ry, ry, group->meth));
    +        }
    +
    +  CLEANUP:
    +        mp_clear(&rz);
    +        for (i = 0; i < 4; i++) {
    +                for (j = 0; j < 4; j++) {
    +                        mp_clear(&precomp[i][j][0]);
    +                        mp_clear(&precomp[i][j][1]);
    +                }
    +        }
    +        return res;
    +}
    diff --git a/jdk/src/share/native/sun/security/ec/ecp_jm.c b/jdk/src/share/native/sun/security/ec/ecp_jm.c
    new file mode 100644
    index 00000000000..a5e38db21da
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/ecp_jm.c
    @@ -0,0 +1,353 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the elliptic curve math library for prime field curves.
    + *
    + * The Initial Developer of the Original Code is
    + * Sun Microsystems, Inc.
    + * Portions created by the Initial Developer are Copyright (C) 2003
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Stephen Fung , Sun Microsystems Laboratories
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +#include "ecp.h"
    +#include "ecl-priv.h"
    +#include "mplogic.h"
    +#ifndef _KERNEL
    +#include 
    +#endif
    +
    +#define MAX_SCRATCH 6
    +
    +/* Computes R = 2P.  Elliptic curve points P and R can be identical.  Uses
    + * Modified Jacobian coordinates.
    + *
    + * Assumes input is already field-encoded using field_enc, and returns
    + * output that is still field-encoded.
    + *
    + */
    +mp_err
    +ec_GFp_pt_dbl_jm(const mp_int *px, const mp_int *py, const mp_int *pz,
    +                                 const mp_int *paz4, mp_int *rx, mp_int *ry, mp_int *rz,
    +                                 mp_int *raz4, mp_int scratch[], const ECGroup *group)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_int *t0, *t1, *M, *S;
    +
    +        t0 = &scratch[0];
    +        t1 = &scratch[1];
    +        M = &scratch[2];
    +        S = &scratch[3];
    +
    +#if MAX_SCRATCH < 4
    +#error "Scratch array defined too small "
    +#endif
    +
    +        /* Check for point at infinity */
    +        if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES) {
    +                /* Set r = pt at infinity by setting rz = 0 */
    +
    +                MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, rz));
    +                goto CLEANUP;
    +        }
    +
    +        /* M = 3 (px^2) + a*(pz^4) */
    +        MP_CHECKOK(group->meth->field_sqr(px, t0, group->meth));
    +        MP_CHECKOK(group->meth->field_add(t0, t0, M, group->meth));
    +        MP_CHECKOK(group->meth->field_add(t0, M, t0, group->meth));
    +        MP_CHECKOK(group->meth->field_add(t0, paz4, M, group->meth));
    +
    +        /* rz = 2 * py * pz */
    +        MP_CHECKOK(group->meth->field_mul(py, pz, S, group->meth));
    +        MP_CHECKOK(group->meth->field_add(S, S, rz, group->meth));
    +
    +        /* t0 = 2y^2 , t1 = 8y^4 */
    +        MP_CHECKOK(group->meth->field_sqr(py, t0, group->meth));
    +        MP_CHECKOK(group->meth->field_add(t0, t0, t0, group->meth));
    +        MP_CHECKOK(group->meth->field_sqr(t0, t1, group->meth));
    +        MP_CHECKOK(group->meth->field_add(t1, t1, t1, group->meth));
    +
    +        /* S = 4 * px * py^2 = 2 * px * t0 */
    +        MP_CHECKOK(group->meth->field_mul(px, t0, S, group->meth));
    +        MP_CHECKOK(group->meth->field_add(S, S, S, group->meth));
    +
    +
    +        /* rx = M^2 - 2S */
    +        MP_CHECKOK(group->meth->field_sqr(M, rx, group->meth));
    +        MP_CHECKOK(group->meth->field_sub(rx, S, rx, group->meth));
    +        MP_CHECKOK(group->meth->field_sub(rx, S, rx, group->meth));
    +
    +        /* ry = M * (S - rx) - t1 */
    +        MP_CHECKOK(group->meth->field_sub(S, rx, S, group->meth));
    +        MP_CHECKOK(group->meth->field_mul(S, M, ry, group->meth));
    +        MP_CHECKOK(group->meth->field_sub(ry, t1, ry, group->meth));
    +
    +        /* ra*z^4 = 2*t1*(apz4) */
    +        MP_CHECKOK(group->meth->field_mul(paz4, t1, raz4, group->meth));
    +        MP_CHECKOK(group->meth->field_add(raz4, raz4, raz4, group->meth));
    +
    +
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* Computes R = P + Q where R is (rx, ry, rz), P is (px, py, pz) and Q is
    + * (qx, qy, 1).  Elliptic curve points P, Q, and R can all be identical.
    + * Uses mixed Modified_Jacobian-affine coordinates. Assumes input is
    + * already field-encoded using field_enc, and returns output that is still
    + * field-encoded. */
    +mp_err
    +ec_GFp_pt_add_jm_aff(const mp_int *px, const mp_int *py, const mp_int *pz,
    +                                         const mp_int *paz4, const mp_int *qx,
    +                                         const mp_int *qy, mp_int *rx, mp_int *ry, mp_int *rz,
    +                                         mp_int *raz4, mp_int scratch[], const ECGroup *group)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_int *A, *B, *C, *D, *C2, *C3;
    +
    +        A = &scratch[0];
    +        B = &scratch[1];
    +        C = &scratch[2];
    +        D = &scratch[3];
    +        C2 = &scratch[4];
    +        C3 = &scratch[5];
    +
    +#if MAX_SCRATCH < 6
    +#error "Scratch array defined too small "
    +#endif
    +
    +        /* If either P or Q is the point at infinity, then return the other
    +         * point */
    +        if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES) {
    +                MP_CHECKOK(ec_GFp_pt_aff2jac(qx, qy, rx, ry, rz, group));
    +                MP_CHECKOK(group->meth->field_sqr(rz, raz4, group->meth));
    +                MP_CHECKOK(group->meth->field_sqr(raz4, raz4, group->meth));
    +                MP_CHECKOK(group->meth->
    +                                   field_mul(raz4, &group->curvea, raz4, group->meth));
    +                goto CLEANUP;
    +        }
    +        if (ec_GFp_pt_is_inf_aff(qx, qy) == MP_YES) {
    +                MP_CHECKOK(mp_copy(px, rx));
    +                MP_CHECKOK(mp_copy(py, ry));
    +                MP_CHECKOK(mp_copy(pz, rz));
    +                MP_CHECKOK(mp_copy(paz4, raz4));
    +                goto CLEANUP;
    +        }
    +
    +        /* A = qx * pz^2, B = qy * pz^3 */
    +        MP_CHECKOK(group->meth->field_sqr(pz, A, group->meth));
    +        MP_CHECKOK(group->meth->field_mul(A, pz, B, group->meth));
    +        MP_CHECKOK(group->meth->field_mul(A, qx, A, group->meth));
    +        MP_CHECKOK(group->meth->field_mul(B, qy, B, group->meth));
    +
    +        /* C = A - px, D = B - py */
    +        MP_CHECKOK(group->meth->field_sub(A, px, C, group->meth));
    +        MP_CHECKOK(group->meth->field_sub(B, py, D, group->meth));
    +
    +        /* C2 = C^2, C3 = C^3 */
    +        MP_CHECKOK(group->meth->field_sqr(C, C2, group->meth));
    +        MP_CHECKOK(group->meth->field_mul(C, C2, C3, group->meth));
    +
    +        /* rz = pz * C */
    +        MP_CHECKOK(group->meth->field_mul(pz, C, rz, group->meth));
    +
    +        /* C = px * C^2 */
    +        MP_CHECKOK(group->meth->field_mul(px, C2, C, group->meth));
    +        /* A = D^2 */
    +        MP_CHECKOK(group->meth->field_sqr(D, A, group->meth));
    +
    +        /* rx = D^2 - (C^3 + 2 * (px * C^2)) */
    +        MP_CHECKOK(group->meth->field_add(C, C, rx, group->meth));
    +        MP_CHECKOK(group->meth->field_add(C3, rx, rx, group->meth));
    +        MP_CHECKOK(group->meth->field_sub(A, rx, rx, group->meth));
    +
    +        /* C3 = py * C^3 */
    +        MP_CHECKOK(group->meth->field_mul(py, C3, C3, group->meth));
    +
    +        /* ry = D * (px * C^2 - rx) - py * C^3 */
    +        MP_CHECKOK(group->meth->field_sub(C, rx, ry, group->meth));
    +        MP_CHECKOK(group->meth->field_mul(D, ry, ry, group->meth));
    +        MP_CHECKOK(group->meth->field_sub(ry, C3, ry, group->meth));
    +
    +        /* raz4 = a * rz^4 */
    +        MP_CHECKOK(group->meth->field_sqr(rz, raz4, group->meth));
    +        MP_CHECKOK(group->meth->field_sqr(raz4, raz4, group->meth));
    +        MP_CHECKOK(group->meth->
    +                           field_mul(raz4, &group->curvea, raz4, group->meth));
    +CLEANUP:
    +        return res;
    +}
    +
    +/* Computes R = nP where R is (rx, ry) and P is the base point. Elliptic
    + * curve points P and R can be identical. Uses mixed Modified-Jacobian
    + * co-ordinates for doubling and Chudnovsky Jacobian coordinates for
    + * additions. Assumes input is already field-encoded using field_enc, and
    + * returns output that is still field-encoded. Uses 5-bit window NAF
    + * method (algorithm 11) for scalar-point multiplication from Brown,
    + * Hankerson, Lopez, Menezes. Software Implementation of the NIST Elliptic
    + * Curves Over Prime Fields. */
    +mp_err
    +ec_GFp_pt_mul_jm_wNAF(const mp_int *n, const mp_int *px, const mp_int *py,
    +                                          mp_int *rx, mp_int *ry, const ECGroup *group)
    +{
    +        mp_err res = MP_OKAY;
    +        mp_int precomp[16][2], rz, tpx, tpy;
    +        mp_int raz4;
    +        mp_int scratch[MAX_SCRATCH];
    +        signed char *naf = NULL;
    +        int i, orderBitSize;
    +
    +        MP_DIGITS(&rz) = 0;
    +        MP_DIGITS(&raz4) = 0;
    +        MP_DIGITS(&tpx) = 0;
    +        MP_DIGITS(&tpy) = 0;
    +        for (i = 0; i < 16; i++) {
    +                MP_DIGITS(&precomp[i][0]) = 0;
    +                MP_DIGITS(&precomp[i][1]) = 0;
    +        }
    +        for (i = 0; i < MAX_SCRATCH; i++) {
    +                MP_DIGITS(&scratch[i]) = 0;
    +        }
    +
    +        ARGCHK(group != NULL, MP_BADARG);
    +        ARGCHK((n != NULL) && (px != NULL) && (py != NULL), MP_BADARG);
    +
    +        /* initialize precomputation table */
    +        MP_CHECKOK(mp_init(&tpx, FLAG(n)));
    +        MP_CHECKOK(mp_init(&tpy, FLAG(n)));;
    +        MP_CHECKOK(mp_init(&rz, FLAG(n)));
    +        MP_CHECKOK(mp_init(&raz4, FLAG(n)));
    +
    +        for (i = 0; i < 16; i++) {
    +                MP_CHECKOK(mp_init(&precomp[i][0], FLAG(n)));
    +                MP_CHECKOK(mp_init(&precomp[i][1], FLAG(n)));
    +        }
    +        for (i = 0; i < MAX_SCRATCH; i++) {
    +                MP_CHECKOK(mp_init(&scratch[i], FLAG(n)));
    +        }
    +
    +        /* Set out[8] = P */
    +        MP_CHECKOK(mp_copy(px, &precomp[8][0]));
    +        MP_CHECKOK(mp_copy(py, &precomp[8][1]));
    +
    +        /* Set (tpx, tpy) = 2P */
    +        MP_CHECKOK(group->
    +                           point_dbl(&precomp[8][0], &precomp[8][1], &tpx, &tpy,
    +                                                 group));
    +
    +        /* Set 3P, 5P, ..., 15P */
    +        for (i = 8; i < 15; i++) {
    +                MP_CHECKOK(group->
    +                                   point_add(&precomp[i][0], &precomp[i][1], &tpx, &tpy,
    +                                                         &precomp[i + 1][0], &precomp[i + 1][1],
    +                                                         group));
    +        }
    +
    +        /* Set -15P, -13P, ..., -P */
    +        for (i = 0; i < 8; i++) {
    +                MP_CHECKOK(mp_copy(&precomp[15 - i][0], &precomp[i][0]));
    +                MP_CHECKOK(group->meth->
    +                                   field_neg(&precomp[15 - i][1], &precomp[i][1],
    +                                                         group->meth));
    +        }
    +
    +        /* R = inf */
    +        MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, &rz));
    +
    +        orderBitSize = mpl_significant_bits(&group->order);
    +
    +        /* Allocate memory for NAF */
    +#ifdef _KERNEL
    +        naf = (signed char *) kmem_alloc((orderBitSize + 1), FLAG(n));
    +#else
    +        naf = (signed char *) malloc(sizeof(signed char) * (orderBitSize + 1));
    +        if (naf == NULL) {
    +                res = MP_MEM;
    +                goto CLEANUP;
    +        }
    +#endif
    +
    +        /* Compute 5NAF */
    +        ec_compute_wNAF(naf, orderBitSize, n, 5);
    +
    +        /* wNAF method */
    +        for (i = orderBitSize; i >= 0; i--) {
    +                /* R = 2R */
    +                ec_GFp_pt_dbl_jm(rx, ry, &rz, &raz4, rx, ry, &rz,
    +                                             &raz4, scratch, group);
    +                if (naf[i] != 0) {
    +                        ec_GFp_pt_add_jm_aff(rx, ry, &rz, &raz4,
    +                                                                 &precomp[(naf[i] + 15) / 2][0],
    +                                                                 &precomp[(naf[i] + 15) / 2][1], rx, ry,
    +                                                                 &rz, &raz4, scratch, group);
    +                }
    +        }
    +
    +        /* convert result S to affine coordinates */
    +        MP_CHECKOK(ec_GFp_pt_jac2aff(rx, ry, &rz, rx, ry, group));
    +
    +  CLEANUP:
    +        for (i = 0; i < MAX_SCRATCH; i++) {
    +                mp_clear(&scratch[i]);
    +        }
    +        for (i = 0; i < 16; i++) {
    +                mp_clear(&precomp[i][0]);
    +                mp_clear(&precomp[i][1]);
    +        }
    +        mp_clear(&tpx);
    +        mp_clear(&tpy);
    +        mp_clear(&rz);
    +        mp_clear(&raz4);
    +#ifdef _KERNEL
    +        kmem_free(naf, (orderBitSize + 1));
    +#else
    +        free(naf);
    +#endif
    +        return res;
    +}
    diff --git a/jdk/src/share/native/sun/security/ec/ecp_mont.c b/jdk/src/share/native/sun/security/ec/ecp_mont.c
    new file mode 100644
    index 00000000000..6b4dbb29e25
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/ecp_mont.c
    @@ -0,0 +1,223 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the elliptic curve math library.
    + *
    + * The Initial Developer of the Original Code is
    + * Sun Microsystems, Inc.
    + * Portions created by the Initial Developer are Copyright (C) 2003
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Douglas Stebila , Sun Microsystems Laboratories
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +/* Uses Montgomery reduction for field arithmetic.  See mpi/mpmontg.c for
    + * code implementation. */
    +
    +#include "mpi.h"
    +#include "mplogic.h"
    +#include "mpi-priv.h"
    +#include "ecl-priv.h"
    +#include "ecp.h"
    +#ifndef _KERNEL
    +#include 
    +#include 
    +#endif
    +
    +/* Construct a generic GFMethod for arithmetic over prime fields with
    + * irreducible irr. */
    +GFMethod *
    +GFMethod_consGFp_mont(const mp_int *irr)
    +{
    +        mp_err res = MP_OKAY;
    +        int i;
    +        GFMethod *meth = NULL;
    +        mp_mont_modulus *mmm;
    +
    +        meth = GFMethod_consGFp(irr);
    +        if (meth == NULL)
    +                return NULL;
    +
    +#ifdef _KERNEL
    +        mmm = (mp_mont_modulus *) kmem_alloc(sizeof(mp_mont_modulus),
    +            FLAG(irr));
    +#else
    +        mmm = (mp_mont_modulus *) malloc(sizeof(mp_mont_modulus));
    +#endif
    +        if (mmm == NULL) {
    +                res = MP_MEM;
    +                goto CLEANUP;
    +        }
    +
    +        meth->field_mul = &ec_GFp_mul_mont;
    +        meth->field_sqr = &ec_GFp_sqr_mont;
    +        meth->field_div = &ec_GFp_div_mont;
    +        meth->field_enc = &ec_GFp_enc_mont;
    +        meth->field_dec = &ec_GFp_dec_mont;
    +        meth->extra1 = mmm;
    +        meth->extra2 = NULL;
    +        meth->extra_free = &ec_GFp_extra_free_mont;
    +
    +        mmm->N = meth->irr;
    +        i = mpl_significant_bits(&meth->irr);
    +        i += MP_DIGIT_BIT - 1;
    +        mmm->b = i - i % MP_DIGIT_BIT;
    +        mmm->n0prime = 0 - s_mp_invmod_radix(MP_DIGIT(&meth->irr, 0));
    +
    +  CLEANUP:
    +        if (res != MP_OKAY) {
    +                GFMethod_free(meth);
    +                return NULL;
    +        }
    +        return meth;
    +}
    +
    +/* Wrapper functions for generic prime field arithmetic. */
    +
    +/* Field multiplication using Montgomery reduction. */
    +mp_err
    +ec_GFp_mul_mont(const mp_int *a, const mp_int *b, mp_int *r,
    +                                const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +
    +#ifdef MP_MONT_USE_MP_MUL
    +        /* if MP_MONT_USE_MP_MUL is defined, then the function s_mp_mul_mont
    +         * is not implemented and we have to use mp_mul and s_mp_redc directly
    +         */
    +        MP_CHECKOK(mp_mul(a, b, r));
    +        MP_CHECKOK(s_mp_redc(r, (mp_mont_modulus *) meth->extra1));
    +#else
    +        mp_int s;
    +
    +        MP_DIGITS(&s) = 0;
    +        /* s_mp_mul_mont doesn't allow source and destination to be the same */
    +        if ((a == r) || (b == r)) {
    +                MP_CHECKOK(mp_init(&s, FLAG(a)));
    +                MP_CHECKOK(s_mp_mul_mont
    +                                   (a, b, &s, (mp_mont_modulus *) meth->extra1));
    +                MP_CHECKOK(mp_copy(&s, r));
    +                mp_clear(&s);
    +        } else {
    +                return s_mp_mul_mont(a, b, r, (mp_mont_modulus *) meth->extra1);
    +        }
    +#endif
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* Field squaring using Montgomery reduction. */
    +mp_err
    +ec_GFp_sqr_mont(const mp_int *a, mp_int *r, const GFMethod *meth)
    +{
    +        return ec_GFp_mul_mont(a, a, r, meth);
    +}
    +
    +/* Field division using Montgomery reduction. */
    +mp_err
    +ec_GFp_div_mont(const mp_int *a, const mp_int *b, mp_int *r,
    +                                const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +
    +        /* if A=aZ represents a encoded in montgomery coordinates with Z and #
    +         * and \ respectively represent multiplication and division in
    +         * montgomery coordinates, then A\B = (a/b)Z = (A/B)Z and Binv =
    +         * (1/b)Z = (1/B)(Z^2) where B # Binv = Z */
    +        MP_CHECKOK(ec_GFp_div(a, b, r, meth));
    +        MP_CHECKOK(ec_GFp_enc_mont(r, r, meth));
    +        if (a == NULL) {
    +                MP_CHECKOK(ec_GFp_enc_mont(r, r, meth));
    +        }
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* Encode a field element in Montgomery form. See s_mp_to_mont in
    + * mpi/mpmontg.c */
    +mp_err
    +ec_GFp_enc_mont(const mp_int *a, mp_int *r, const GFMethod *meth)
    +{
    +        mp_mont_modulus *mmm;
    +        mp_err res = MP_OKAY;
    +
    +        mmm = (mp_mont_modulus *) meth->extra1;
    +        MP_CHECKOK(mpl_lsh(a, r, mmm->b));
    +        MP_CHECKOK(mp_mod(r, &mmm->N, r));
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* Decode a field element from Montgomery form. */
    +mp_err
    +ec_GFp_dec_mont(const mp_int *a, mp_int *r, const GFMethod *meth)
    +{
    +        mp_err res = MP_OKAY;
    +
    +        if (a != r) {
    +                MP_CHECKOK(mp_copy(a, r));
    +        }
    +        MP_CHECKOK(s_mp_redc(r, (mp_mont_modulus *) meth->extra1));
    +  CLEANUP:
    +        return res;
    +}
    +
    +/* Free the memory allocated to the extra fields of Montgomery GFMethod
    + * object. */
    +void
    +ec_GFp_extra_free_mont(GFMethod *meth)
    +{
    +        if (meth->extra1 != NULL) {
    +#ifdef _KERNEL
    +                kmem_free(meth->extra1, sizeof(mp_mont_modulus));
    +#else
    +                free(meth->extra1);
    +#endif
    +                meth->extra1 = NULL;
    +        }
    +}
    diff --git a/jdk/src/share/native/sun/security/ec/logtab.h b/jdk/src/share/native/sun/security/ec/logtab.h
    new file mode 100644
    index 00000000000..6efa0199560
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/logtab.h
    @@ -0,0 +1,82 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the Netscape security libraries.
    + *
    + * The Initial Developer of the Original Code is
    + * Netscape Communications Corporation.
    + * Portions created by the Initial Developer are Copyright (C) 1994-2000
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Dr Vipul Gupta , Sun Microsystems Laboratories
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#ifndef _LOGTAB_H
    +#define _LOGTAB_H
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +const float s_logv_2[] = {
    +   0.000000000f, 0.000000000f, 1.000000000f, 0.630929754f,  /*  0  1  2  3 */
    +   0.500000000f, 0.430676558f, 0.386852807f, 0.356207187f,  /*  4  5  6  7 */
    +   0.333333333f, 0.315464877f, 0.301029996f, 0.289064826f,  /*  8  9 10 11 */
    +   0.278942946f, 0.270238154f, 0.262649535f, 0.255958025f,  /* 12 13 14 15 */
    +   0.250000000f, 0.244650542f, 0.239812467f, 0.235408913f,  /* 16 17 18 19 */
    +   0.231378213f, 0.227670249f, 0.224243824f, 0.221064729f,  /* 20 21 22 23 */
    +   0.218104292f, 0.215338279f, 0.212746054f, 0.210309918f,  /* 24 25 26 27 */
    +   0.208014598f, 0.205846832f, 0.203795047f, 0.201849087f,  /* 28 29 30 31 */
    +   0.200000000f, 0.198239863f, 0.196561632f, 0.194959022f,  /* 32 33 34 35 */
    +   0.193426404f, 0.191958720f, 0.190551412f, 0.189200360f,  /* 36 37 38 39 */
    +   0.187901825f, 0.186652411f, 0.185449023f, 0.184288833f,  /* 40 41 42 43 */
    +   0.183169251f, 0.182087900f, 0.181042597f, 0.180031327f,  /* 44 45 46 47 */
    +   0.179052232f, 0.178103594f, 0.177183820f, 0.176291434f,  /* 48 49 50 51 */
    +   0.175425064f, 0.174583430f, 0.173765343f, 0.172969690f,  /* 52 53 54 55 */
    +   0.172195434f, 0.171441601f, 0.170707280f, 0.169991616f,  /* 56 57 58 59 */
    +   0.169293808f, 0.168613099f, 0.167948779f, 0.167300179f,  /* 60 61 62 63 */
    +   0.166666667f
    +};
    +
    +#endif /* _LOGTAB_H */
    diff --git a/jdk/src/share/native/sun/security/ec/mp_gf2m-priv.h b/jdk/src/share/native/sun/security/ec/mp_gf2m-priv.h
    new file mode 100644
    index 00000000000..7a4505807fc
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/mp_gf2m-priv.h
    @@ -0,0 +1,122 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the Multi-precision Binary Polynomial Arithmetic Library.
    + *
    + * The Initial Developer of the Original Code is
    + * Sun Microsystems, Inc.
    + * Portions created by the Initial Developer are Copyright (C) 2003
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Sheueling Chang Shantz  and
    + *   Douglas Stebila  of Sun Laboratories.
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#ifndef _MP_GF2M_PRIV_H_
    +#define _MP_GF2M_PRIV_H_
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +#include "mpi-priv.h"
    +
    +extern const mp_digit mp_gf2m_sqr_tb[16];
    +
    +#if defined(MP_USE_UINT_DIGIT)
    +#define MP_DIGIT_BITS 32
    +#else
    +#define MP_DIGIT_BITS 64
    +#endif
    +
    +/* Platform-specific macros for fast binary polynomial squaring. */
    +#if MP_DIGIT_BITS == 32
    +#define gf2m_SQR1(w) \
    +    mp_gf2m_sqr_tb[(w) >> 28 & 0xF] << 24 | mp_gf2m_sqr_tb[(w) >> 24 & 0xF] << 16 | \
    +    mp_gf2m_sqr_tb[(w) >> 20 & 0xF] <<  8 | mp_gf2m_sqr_tb[(w) >> 16 & 0xF]
    +#define gf2m_SQR0(w) \
    +    mp_gf2m_sqr_tb[(w) >> 12 & 0xF] << 24 | mp_gf2m_sqr_tb[(w) >>  8 & 0xF] << 16 | \
    +    mp_gf2m_sqr_tb[(w) >>  4 & 0xF] <<  8 | mp_gf2m_sqr_tb[(w)       & 0xF]
    +#else
    +#define gf2m_SQR1(w) \
    +    mp_gf2m_sqr_tb[(w) >> 60 & 0xF] << 56 | mp_gf2m_sqr_tb[(w) >> 56 & 0xF] << 48 | \
    +    mp_gf2m_sqr_tb[(w) >> 52 & 0xF] << 40 | mp_gf2m_sqr_tb[(w) >> 48 & 0xF] << 32 | \
    +    mp_gf2m_sqr_tb[(w) >> 44 & 0xF] << 24 | mp_gf2m_sqr_tb[(w) >> 40 & 0xF] << 16 | \
    +    mp_gf2m_sqr_tb[(w) >> 36 & 0xF] <<  8 | mp_gf2m_sqr_tb[(w) >> 32 & 0xF]
    +#define gf2m_SQR0(w) \
    +    mp_gf2m_sqr_tb[(w) >> 28 & 0xF] << 56 | mp_gf2m_sqr_tb[(w) >> 24 & 0xF] << 48 | \
    +    mp_gf2m_sqr_tb[(w) >> 20 & 0xF] << 40 | mp_gf2m_sqr_tb[(w) >> 16 & 0xF] << 32 | \
    +    mp_gf2m_sqr_tb[(w) >> 12 & 0xF] << 24 | mp_gf2m_sqr_tb[(w) >>  8 & 0xF] << 16 | \
    +    mp_gf2m_sqr_tb[(w) >>  4 & 0xF] <<  8 | mp_gf2m_sqr_tb[(w)       & 0xF]
    +#endif
    +
    +/* Multiply two binary polynomials mp_digits a, b.
    + * Result is a polynomial with degree < 2 * MP_DIGIT_BITS - 1.
    + * Output in two mp_digits rh, rl.
    + */
    +void s_bmul_1x1(mp_digit *rh, mp_digit *rl, const mp_digit a, const mp_digit b);
    +
    +/* Compute xor-multiply of two binary polynomials  (a1, a0) x (b1, b0)
    + * result is a binary polynomial in 4 mp_digits r[4].
    + * The caller MUST ensure that r has the right amount of space allocated.
    + */
    +void s_bmul_2x2(mp_digit *r, const mp_digit a1, const mp_digit a0, const mp_digit b1,
    +        const mp_digit b0);
    +
    +/* Compute xor-multiply of two binary polynomials  (a2, a1, a0) x (b2, b1, b0)
    + * result is a binary polynomial in 6 mp_digits r[6].
    + * The caller MUST ensure that r has the right amount of space allocated.
    + */
    +void s_bmul_3x3(mp_digit *r, const mp_digit a2, const mp_digit a1, const mp_digit a0,
    +        const mp_digit b2, const mp_digit b1, const mp_digit b0);
    +
    +/* Compute xor-multiply of two binary polynomials  (a3, a2, a1, a0) x (b3, b2, b1, b0)
    + * result is a binary polynomial in 8 mp_digits r[8].
    + * The caller MUST ensure that r has the right amount of space allocated.
    + */
    +void s_bmul_4x4(mp_digit *r, const mp_digit a3, const mp_digit a2, const mp_digit a1,
    +        const mp_digit a0, const mp_digit b3, const mp_digit b2, const mp_digit b1,
    +        const mp_digit b0);
    +
    +#endif /* _MP_GF2M_PRIV_H_ */
    diff --git a/jdk/src/share/native/sun/security/ec/mp_gf2m.c b/jdk/src/share/native/sun/security/ec/mp_gf2m.c
    new file mode 100644
    index 00000000000..74b64789c96
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/mp_gf2m.c
    @@ -0,0 +1,624 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the Multi-precision Binary Polynomial Arithmetic Library.
    + *
    + * The Initial Developer of the Original Code is
    + * Sun Microsystems, Inc.
    + * Portions created by the Initial Developer are Copyright (C) 2003
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Sheueling Chang Shantz  and
    + *   Douglas Stebila  of Sun Laboratories.
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +#include "mp_gf2m.h"
    +#include "mp_gf2m-priv.h"
    +#include "mplogic.h"
    +#include "mpi-priv.h"
    +
    +const mp_digit mp_gf2m_sqr_tb[16] =
    +{
    +      0,     1,     4,     5,    16,    17,    20,    21,
    +     64,    65,    68,    69,    80,    81,    84,    85
    +};
    +
    +/* Multiply two binary polynomials mp_digits a, b.
    + * Result is a polynomial with degree < 2 * MP_DIGIT_BITS - 1.
    + * Output in two mp_digits rh, rl.
    + */
    +#if MP_DIGIT_BITS == 32
    +void
    +s_bmul_1x1(mp_digit *rh, mp_digit *rl, const mp_digit a, const mp_digit b)
    +{
    +    register mp_digit h, l, s;
    +    mp_digit tab[8], top2b = a >> 30;
    +    register mp_digit a1, a2, a4;
    +
    +    a1 = a & (0x3FFFFFFF); a2 = a1 << 1; a4 = a2 << 1;
    +
    +    tab[0] =  0; tab[1] = a1;    tab[2] = a2;    tab[3] = a1^a2;
    +    tab[4] = a4; tab[5] = a1^a4; tab[6] = a2^a4; tab[7] = a1^a2^a4;
    +
    +    s = tab[b       & 0x7]; l  = s;
    +    s = tab[b >>  3 & 0x7]; l ^= s <<  3; h  = s >> 29;
    +    s = tab[b >>  6 & 0x7]; l ^= s <<  6; h ^= s >> 26;
    +    s = tab[b >>  9 & 0x7]; l ^= s <<  9; h ^= s >> 23;
    +    s = tab[b >> 12 & 0x7]; l ^= s << 12; h ^= s >> 20;
    +    s = tab[b >> 15 & 0x7]; l ^= s << 15; h ^= s >> 17;
    +    s = tab[b >> 18 & 0x7]; l ^= s << 18; h ^= s >> 14;
    +    s = tab[b >> 21 & 0x7]; l ^= s << 21; h ^= s >> 11;
    +    s = tab[b >> 24 & 0x7]; l ^= s << 24; h ^= s >>  8;
    +    s = tab[b >> 27 & 0x7]; l ^= s << 27; h ^= s >>  5;
    +    s = tab[b >> 30      ]; l ^= s << 30; h ^= s >>  2;
    +
    +    /* compensate for the top two bits of a */
    +
    +    if (top2b & 01) { l ^= b << 30; h ^= b >> 2; }
    +    if (top2b & 02) { l ^= b << 31; h ^= b >> 1; }
    +
    +    *rh = h; *rl = l;
    +}
    +#else
    +void
    +s_bmul_1x1(mp_digit *rh, mp_digit *rl, const mp_digit a, const mp_digit b)
    +{
    +    register mp_digit h, l, s;
    +    mp_digit tab[16], top3b = a >> 61;
    +    register mp_digit a1, a2, a4, a8;
    +
    +    a1 = a & (0x1FFFFFFFFFFFFFFFULL); a2 = a1 << 1;
    +    a4 = a2 << 1; a8 = a4 << 1;
    +    tab[ 0] = 0;     tab[ 1] = a1;       tab[ 2] = a2;       tab[ 3] = a1^a2;
    +    tab[ 4] = a4;    tab[ 5] = a1^a4;    tab[ 6] = a2^a4;    tab[ 7] = a1^a2^a4;
    +    tab[ 8] = a8;    tab[ 9] = a1^a8;    tab[10] = a2^a8;    tab[11] = a1^a2^a8;
    +    tab[12] = a4^a8; tab[13] = a1^a4^a8; tab[14] = a2^a4^a8; tab[15] = a1^a2^a4^a8;
    +
    +    s = tab[b       & 0xF]; l  = s;
    +    s = tab[b >>  4 & 0xF]; l ^= s <<  4; h  = s >> 60;
    +    s = tab[b >>  8 & 0xF]; l ^= s <<  8; h ^= s >> 56;
    +    s = tab[b >> 12 & 0xF]; l ^= s << 12; h ^= s >> 52;
    +    s = tab[b >> 16 & 0xF]; l ^= s << 16; h ^= s >> 48;
    +    s = tab[b >> 20 & 0xF]; l ^= s << 20; h ^= s >> 44;
    +    s = tab[b >> 24 & 0xF]; l ^= s << 24; h ^= s >> 40;
    +    s = tab[b >> 28 & 0xF]; l ^= s << 28; h ^= s >> 36;
    +    s = tab[b >> 32 & 0xF]; l ^= s << 32; h ^= s >> 32;
    +    s = tab[b >> 36 & 0xF]; l ^= s << 36; h ^= s >> 28;
    +    s = tab[b >> 40 & 0xF]; l ^= s << 40; h ^= s >> 24;
    +    s = tab[b >> 44 & 0xF]; l ^= s << 44; h ^= s >> 20;
    +    s = tab[b >> 48 & 0xF]; l ^= s << 48; h ^= s >> 16;
    +    s = tab[b >> 52 & 0xF]; l ^= s << 52; h ^= s >> 12;
    +    s = tab[b >> 56 & 0xF]; l ^= s << 56; h ^= s >>  8;
    +    s = tab[b >> 60      ]; l ^= s << 60; h ^= s >>  4;
    +
    +    /* compensate for the top three bits of a */
    +
    +    if (top3b & 01) { l ^= b << 61; h ^= b >> 3; }
    +    if (top3b & 02) { l ^= b << 62; h ^= b >> 2; }
    +    if (top3b & 04) { l ^= b << 63; h ^= b >> 1; }
    +
    +    *rh = h; *rl = l;
    +}
    +#endif
    +
    +/* Compute xor-multiply of two binary polynomials  (a1, a0) x (b1, b0)
    + * result is a binary polynomial in 4 mp_digits r[4].
    + * The caller MUST ensure that r has the right amount of space allocated.
    + */
    +void
    +s_bmul_2x2(mp_digit *r, const mp_digit a1, const mp_digit a0, const mp_digit b1,
    +           const mp_digit b0)
    +{
    +    mp_digit m1, m0;
    +    /* r[3] = h1, r[2] = h0; r[1] = l1; r[0] = l0 */
    +    s_bmul_1x1(r+3, r+2, a1, b1);
    +    s_bmul_1x1(r+1, r, a0, b0);
    +    s_bmul_1x1(&m1, &m0, a0 ^ a1, b0 ^ b1);
    +    /* Correction on m1 ^= l1 ^ h1; m0 ^= l0 ^ h0; */
    +    r[2] ^= m1 ^ r[1] ^ r[3];  /* h0 ^= m1 ^ l1 ^ h1; */
    +    r[1]  = r[3] ^ r[2] ^ r[0] ^ m1 ^ m0;  /* l1 ^= l0 ^ h0 ^ m0; */
    +}
    +
    +/* Compute xor-multiply of two binary polynomials  (a2, a1, a0) x (b2, b1, b0)
    + * result is a binary polynomial in 6 mp_digits r[6].
    + * The caller MUST ensure that r has the right amount of space allocated.
    + */
    +void
    +s_bmul_3x3(mp_digit *r, const mp_digit a2, const mp_digit a1, const mp_digit a0,
    +        const mp_digit b2, const mp_digit b1, const mp_digit b0)
    +{
    +        mp_digit zm[4];
    +
    +        s_bmul_1x1(r+5, r+4, a2, b2);         /* fill top 2 words */
    +        s_bmul_2x2(zm, a1, a2^a0, b1, b2^b0); /* fill middle 4 words */
    +        s_bmul_2x2(r, a1, a0, b1, b0);        /* fill bottom 4 words */
    +
    +        zm[3] ^= r[3];
    +        zm[2] ^= r[2];
    +        zm[1] ^= r[1] ^ r[5];
    +        zm[0] ^= r[0] ^ r[4];
    +
    +        r[5]  ^= zm[3];
    +        r[4]  ^= zm[2];
    +        r[3]  ^= zm[1];
    +        r[2]  ^= zm[0];
    +}
    +
    +/* Compute xor-multiply of two binary polynomials  (a3, a2, a1, a0) x (b3, b2, b1, b0)
    + * result is a binary polynomial in 8 mp_digits r[8].
    + * The caller MUST ensure that r has the right amount of space allocated.
    + */
    +void s_bmul_4x4(mp_digit *r, const mp_digit a3, const mp_digit a2, const mp_digit a1,
    +        const mp_digit a0, const mp_digit b3, const mp_digit b2, const mp_digit b1,
    +        const mp_digit b0)
    +{
    +        mp_digit zm[4];
    +
    +        s_bmul_2x2(r+4, a3, a2, b3, b2);            /* fill top 4 words */
    +        s_bmul_2x2(zm, a3^a1, a2^a0, b3^b1, b2^b0); /* fill middle 4 words */
    +        s_bmul_2x2(r, a1, a0, b1, b0);              /* fill bottom 4 words */
    +
    +        zm[3] ^= r[3] ^ r[7];
    +        zm[2] ^= r[2] ^ r[6];
    +        zm[1] ^= r[1] ^ r[5];
    +        zm[0] ^= r[0] ^ r[4];
    +
    +        r[5]  ^= zm[3];
    +        r[4]  ^= zm[2];
    +        r[3]  ^= zm[1];
    +        r[2]  ^= zm[0];
    +}
    +
    +/* Compute addition of two binary polynomials a and b,
    + * store result in c; c could be a or b, a and b could be equal;
    + * c is the bitwise XOR of a and b.
    + */
    +mp_err
    +mp_badd(const mp_int *a, const mp_int *b, mp_int *c)
    +{
    +    mp_digit *pa, *pb, *pc;
    +    mp_size ix;
    +    mp_size used_pa, used_pb;
    +    mp_err res = MP_OKAY;
    +
    +    /* Add all digits up to the precision of b.  If b had more
    +     * precision than a initially, swap a, b first
    +     */
    +    if (MP_USED(a) >= MP_USED(b)) {
    +        pa = MP_DIGITS(a);
    +        pb = MP_DIGITS(b);
    +        used_pa = MP_USED(a);
    +        used_pb = MP_USED(b);
    +    } else {
    +        pa = MP_DIGITS(b);
    +        pb = MP_DIGITS(a);
    +        used_pa = MP_USED(b);
    +        used_pb = MP_USED(a);
    +    }
    +
    +    /* Make sure c has enough precision for the output value */
    +    MP_CHECKOK( s_mp_pad(c, used_pa) );
    +
    +    /* Do word-by-word xor */
    +    pc = MP_DIGITS(c);
    +    for (ix = 0; ix < used_pb; ix++) {
    +        (*pc++) = (*pa++) ^ (*pb++);
    +    }
    +
    +    /* Finish the rest of digits until we're actually done */
    +    for (; ix < used_pa; ++ix) {
    +        *pc++ = *pa++;
    +    }
    +
    +    MP_USED(c) = used_pa;
    +    MP_SIGN(c) = ZPOS;
    +    s_mp_clamp(c);
    +
    +CLEANUP:
    +    return res;
    +}
    +
    +#define s_mp_div2(a) MP_CHECKOK( mpl_rsh((a), (a), 1) );
    +
    +/* Compute binary polynomial multiply d = a * b */
    +static void
    +s_bmul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *d)
    +{
    +    mp_digit a_i, a0b0, a1b1, carry = 0;
    +    while (a_len--) {
    +        a_i = *a++;
    +        s_bmul_1x1(&a1b1, &a0b0, a_i, b);
    +        *d++ = a0b0 ^ carry;
    +        carry = a1b1;
    +    }
    +    *d = carry;
    +}
    +
    +/* Compute binary polynomial xor multiply accumulate d ^= a * b */
    +static void
    +s_bmul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *d)
    +{
    +    mp_digit a_i, a0b0, a1b1, carry = 0;
    +    while (a_len--) {
    +        a_i = *a++;
    +        s_bmul_1x1(&a1b1, &a0b0, a_i, b);
    +        *d++ ^= a0b0 ^ carry;
    +        carry = a1b1;
    +    }
    +    *d ^= carry;
    +}
    +
    +/* Compute binary polynomial xor multiply c = a * b.
    + * All parameters may be identical.
    + */
    +mp_err
    +mp_bmul(const mp_int *a, const mp_int *b, mp_int *c)
    +{
    +    mp_digit *pb, b_i;
    +    mp_int tmp;
    +    mp_size ib, a_used, b_used;
    +    mp_err res = MP_OKAY;
    +
    +    MP_DIGITS(&tmp) = 0;
    +
    +    ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
    +
    +    if (a == c) {
    +        MP_CHECKOK( mp_init_copy(&tmp, a) );
    +        if (a == b)
    +            b = &tmp;
    +        a = &tmp;
    +    } else if (b == c) {
    +        MP_CHECKOK( mp_init_copy(&tmp, b) );
    +        b = &tmp;
    +    }
    +
    +    if (MP_USED(a) < MP_USED(b)) {
    +        const mp_int *xch = b;      /* switch a and b if b longer */
    +        b = a;
    +        a = xch;
    +    }
    +
    +    MP_USED(c) = 1; MP_DIGIT(c, 0) = 0;
    +    MP_CHECKOK( s_mp_pad(c, USED(a) + USED(b)) );
    +
    +    pb = MP_DIGITS(b);
    +    s_bmul_d(MP_DIGITS(a), MP_USED(a), *pb++, MP_DIGITS(c));
    +
    +    /* Outer loop:  Digits of b */
    +    a_used = MP_USED(a);
    +    b_used = MP_USED(b);
    +        MP_USED(c) = a_used + b_used;
    +    for (ib = 1; ib < b_used; ib++) {
    +        b_i = *pb++;
    +
    +        /* Inner product:  Digits of a */
    +        if (b_i)
    +            s_bmul_d_add(MP_DIGITS(a), a_used, b_i, MP_DIGITS(c) + ib);
    +        else
    +            MP_DIGIT(c, ib + a_used) = b_i;
    +    }
    +
    +    s_mp_clamp(c);
    +
    +    SIGN(c) = ZPOS;
    +
    +CLEANUP:
    +    mp_clear(&tmp);
    +    return res;
    +}
    +
    +
    +/* Compute modular reduction of a and store result in r.
    + * r could be a.
    + * For modular arithmetic, the irreducible polynomial f(t) is represented
    + * as an array of int[], where f(t) is of the form:
    + *     f(t) = t^p[0] + t^p[1] + ... + t^p[k]
    + * where m = p[0] > p[1] > ... > p[k] = 0.
    + */
    +mp_err
    +mp_bmod(const mp_int *a, const unsigned int p[], mp_int *r)
    +{
    +    int j, k;
    +    int n, dN, d0, d1;
    +    mp_digit zz, *z, tmp;
    +    mp_size used;
    +    mp_err res = MP_OKAY;
    +
    +    /* The algorithm does the reduction in place in r,
    +     * if a != r, copy a into r first so reduction can be done in r
    +     */
    +    if (a != r) {
    +        MP_CHECKOK( mp_copy(a, r) );
    +    }
    +    z = MP_DIGITS(r);
    +
    +    /* start reduction */
    +    dN = p[0] / MP_DIGIT_BITS;
    +    used = MP_USED(r);
    +
    +    for (j = used - 1; j > dN;) {
    +
    +        zz = z[j];
    +        if (zz == 0) {
    +            j--; continue;
    +        }
    +        z[j] = 0;
    +
    +        for (k = 1; p[k] > 0; k++) {
    +            /* reducing component t^p[k] */
    +            n = p[0] - p[k];
    +            d0 = n % MP_DIGIT_BITS;
    +            d1 = MP_DIGIT_BITS - d0;
    +            n /= MP_DIGIT_BITS;
    +            z[j-n] ^= (zz>>d0);
    +            if (d0)
    +                z[j-n-1] ^= (zz<> d0);
    +        if (d0)
    +            z[j-n-1] ^= (zz << d1);
    +
    +    }
    +
    +    /* final round of reduction */
    +    while (j == dN) {
    +
    +        d0 = p[0] % MP_DIGIT_BITS;
    +        zz = z[dN] >> d0;
    +        if (zz == 0) break;
    +        d1 = MP_DIGIT_BITS - d0;
    +
    +        /* clear up the top d1 bits */
    +        if (d0) z[dN] = (z[dN] << d1) >> d1;
    +        *z ^= zz; /* reduction t^0 component */
    +
    +        for (k = 1; p[k] > 0; k++) {
    +            /* reducing component t^p[k]*/
    +            n = p[k] / MP_DIGIT_BITS;
    +            d0 = p[k] % MP_DIGIT_BITS;
    +            d1 = MP_DIGIT_BITS - d0;
    +            z[n] ^= (zz << d0);
    +            tmp = zz >> d1;
    +            if (d0 && tmp)
    +                z[n+1] ^= tmp;
    +        }
    +    }
    +
    +    s_mp_clamp(r);
    +CLEANUP:
    +    return res;
    +}
    +
    +/* Compute the product of two polynomials a and b, reduce modulo p,
    + * Store the result in r.  r could be a or b; a could be b.
    + */
    +mp_err
    +mp_bmulmod(const mp_int *a, const mp_int *b, const unsigned int p[], mp_int *r)
    +{
    +    mp_err res;
    +
    +    if (a == b) return mp_bsqrmod(a, p, r);
    +    if ((res = mp_bmul(a, b, r) ) != MP_OKAY)
    +        return res;
    +    return mp_bmod(r, p, r);
    +}
    +
    +/* Compute binary polynomial squaring c = a*a mod p .
    + * Parameter r and a can be identical.
    + */
    +
    +mp_err
    +mp_bsqrmod(const mp_int *a, const unsigned int p[], mp_int *r)
    +{
    +    mp_digit *pa, *pr, a_i;
    +    mp_int tmp;
    +    mp_size ia, a_used;
    +    mp_err res;
    +
    +    ARGCHK(a != NULL && r != NULL, MP_BADARG);
    +    MP_DIGITS(&tmp) = 0;
    +
    +    if (a == r) {
    +        MP_CHECKOK( mp_init_copy(&tmp, a) );
    +        a = &tmp;
    +    }
    +
    +    MP_USED(r) = 1; MP_DIGIT(r, 0) = 0;
    +    MP_CHECKOK( s_mp_pad(r, 2*USED(a)) );
    +
    +    pa = MP_DIGITS(a);
    +    pr = MP_DIGITS(r);
    +    a_used = MP_USED(a);
    +        MP_USED(r) = 2 * a_used;
    +
    +    for (ia = 0; ia < a_used; ia++) {
    +        a_i = *pa++;
    +        *pr++ = gf2m_SQR0(a_i);
    +        *pr++ = gf2m_SQR1(a_i);
    +    }
    +
    +    MP_CHECKOK( mp_bmod(r, p, r) );
    +    s_mp_clamp(r);
    +    SIGN(r) = ZPOS;
    +
    +CLEANUP:
    +    mp_clear(&tmp);
    +    return res;
    +}
    +
    +/* Compute binary polynomial y/x mod p, y divided by x, reduce modulo p.
    + * Store the result in r. r could be x or y, and x could equal y.
    + * Uses algorithm Modular_Division_GF(2^m) from
    + *     Chang-Shantz, S.  "From Euclid's GCD to Montgomery Multiplication to
    + *     the Great Divide".
    + */
    +int
    +mp_bdivmod(const mp_int *y, const mp_int *x, const mp_int *pp,
    +    const unsigned int p[], mp_int *r)
    +{
    +    mp_int aa, bb, uu;
    +    mp_int *a, *b, *u, *v;
    +    mp_err res = MP_OKAY;
    +
    +    MP_DIGITS(&aa) = 0;
    +    MP_DIGITS(&bb) = 0;
    +    MP_DIGITS(&uu) = 0;
    +
    +    MP_CHECKOK( mp_init_copy(&aa, x) );
    +    MP_CHECKOK( mp_init_copy(&uu, y) );
    +    MP_CHECKOK( mp_init_copy(&bb, pp) );
    +    MP_CHECKOK( s_mp_pad(r, USED(pp)) );
    +    MP_USED(r) = 1; MP_DIGIT(r, 0) = 0;
    +
    +    a = &aa; b= &bb; u=&uu; v=r;
    +    /* reduce x and y mod p */
    +    MP_CHECKOK( mp_bmod(a, p, a) );
    +    MP_CHECKOK( mp_bmod(u, p, u) );
    +
    +    while (!mp_isodd(a)) {
    +        s_mp_div2(a);
    +        if (mp_isodd(u)) {
    +            MP_CHECKOK( mp_badd(u, pp, u) );
    +        }
    +        s_mp_div2(u);
    +    }
    +
    +    do {
    +        if (mp_cmp_mag(b, a) > 0) {
    +            MP_CHECKOK( mp_badd(b, a, b) );
    +            MP_CHECKOK( mp_badd(v, u, v) );
    +            do {
    +                s_mp_div2(b);
    +                if (mp_isodd(v)) {
    +                    MP_CHECKOK( mp_badd(v, pp, v) );
    +                }
    +                s_mp_div2(v);
    +            } while (!mp_isodd(b));
    +        }
    +        else if ((MP_DIGIT(a,0) == 1) && (MP_USED(a) == 1))
    +            break;
    +        else {
    +            MP_CHECKOK( mp_badd(a, b, a) );
    +            MP_CHECKOK( mp_badd(u, v, u) );
    +            do {
    +                s_mp_div2(a);
    +                if (mp_isodd(u)) {
    +                    MP_CHECKOK( mp_badd(u, pp, u) );
    +                }
    +                s_mp_div2(u);
    +            } while (!mp_isodd(a));
    +        }
    +    } while (1);
    +
    +    MP_CHECKOK( mp_copy(u, r) );
    +
    +CLEANUP:
    +    /* XXX this appears to be a memory leak in the NSS code */
    +    mp_clear(&aa);
    +    mp_clear(&bb);
    +    mp_clear(&uu);
    +    return res;
    +
    +}
    +
    +/* Convert the bit-string representation of a polynomial a into an array
    + * of integers corresponding to the bits with non-zero coefficient.
    + * Up to max elements of the array will be filled.  Return value is total
    + * number of coefficients that would be extracted if array was large enough.
    + */
    +int
    +mp_bpoly2arr(const mp_int *a, unsigned int p[], int max)
    +{
    +    int i, j, k;
    +    mp_digit top_bit, mask;
    +
    +    top_bit = 1;
    +    top_bit <<= MP_DIGIT_BIT - 1;
    +
    +    for (k = 0; k < max; k++) p[k] = 0;
    +    k = 0;
    +
    +    for (i = MP_USED(a) - 1; i >= 0; i--) {
    +        mask = top_bit;
    +        for (j = MP_DIGIT_BIT - 1; j >= 0; j--) {
    +            if (MP_DIGITS(a)[i] & mask) {
    +                if (k < max) p[k] = MP_DIGIT_BIT * i + j;
    +                k++;
    +            }
    +            mask >>= 1;
    +        }
    +    }
    +
    +    return k;
    +}
    +
    +/* Convert the coefficient array representation of a polynomial to a
    + * bit-string.  The array must be terminated by 0.
    + */
    +mp_err
    +mp_barr2poly(const unsigned int p[], mp_int *a)
    +{
    +
    +    mp_err res = MP_OKAY;
    +    int i;
    +
    +    mp_zero(a);
    +    for (i = 0; p[i] > 0; i++) {
    +        MP_CHECKOK( mpl_set_bit(a, p[i], 1) );
    +    }
    +    MP_CHECKOK( mpl_set_bit(a, 0, 1) );
    +
    +CLEANUP:
    +    return res;
    +}
    diff --git a/jdk/src/share/native/sun/security/ec/mp_gf2m.h b/jdk/src/share/native/sun/security/ec/mp_gf2m.h
    new file mode 100644
    index 00000000000..b09f3d34377
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/mp_gf2m.h
    @@ -0,0 +1,83 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the Multi-precision Binary Polynomial Arithmetic Library.
    + *
    + * The Initial Developer of the Original Code is
    + * Sun Microsystems, Inc.
    + * Portions created by the Initial Developer are Copyright (C) 2003
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Sheueling Chang Shantz  and
    + *   Douglas Stebila  of Sun Laboratories.
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#ifndef _MP_GF2M_H_
    +#define _MP_GF2M_H_
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +#include "mpi.h"
    +
    +mp_err mp_badd(const mp_int *a, const mp_int *b, mp_int *c);
    +mp_err mp_bmul(const mp_int *a, const mp_int *b, mp_int *c);
    +
    +/* For modular arithmetic, the irreducible polynomial f(t) is represented
    + * as an array of int[], where f(t) is of the form:
    + *     f(t) = t^p[0] + t^p[1] + ... + t^p[k]
    + * where m = p[0] > p[1] > ... > p[k] = 0.
    + */
    +mp_err mp_bmod(const mp_int *a, const unsigned int p[], mp_int *r);
    +mp_err mp_bmulmod(const mp_int *a, const mp_int *b, const unsigned int p[],
    +    mp_int *r);
    +mp_err mp_bsqrmod(const mp_int *a, const unsigned int p[], mp_int *r);
    +mp_err mp_bdivmod(const mp_int *y, const mp_int *x, const mp_int *pp,
    +    const unsigned int p[], mp_int *r);
    +
    +int mp_bpoly2arr(const mp_int *a, unsigned int p[], int max);
    +mp_err mp_barr2poly(const unsigned int p[], mp_int *a);
    +
    +#endif /* _MP_GF2M_H_ */
    diff --git a/jdk/src/share/native/sun/security/ec/mpi-config.h b/jdk/src/share/native/sun/security/ec/mpi-config.h
    new file mode 100644
    index 00000000000..3618677a90a
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/mpi-config.h
    @@ -0,0 +1,130 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
    + *
    + * The Initial Developer of the Original Code is
    + * Michael J. Fromberger.
    + * Portions created by the Initial Developer are Copyright (C) 1997
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Netscape Communications Corporation
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#ifndef _MPI_CONFIG_H
    +#define _MPI_CONFIG_H
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +/* $Id: mpi-config.h,v 1.5 2004/04/25 15:03:10 gerv%gerv.net Exp $ */
    +
    +/*
    +  For boolean options,
    +  0 = no
    +  1 = yes
    +
    +  Other options are documented individually.
    +
    + */
    +
    +#ifndef MP_IOFUNC
    +#define MP_IOFUNC     0  /* include mp_print() ?                */
    +#endif
    +
    +#ifndef MP_MODARITH
    +#define MP_MODARITH   1  /* include modular arithmetic ?        */
    +#endif
    +
    +#ifndef MP_NUMTH
    +#define MP_NUMTH      1  /* include number theoretic functions? */
    +#endif
    +
    +#ifndef MP_LOGTAB
    +#define MP_LOGTAB     1  /* use table of logs instead of log()? */
    +#endif
    +
    +#ifndef MP_MEMSET
    +#define MP_MEMSET     1  /* use memset() to zero buffers?       */
    +#endif
    +
    +#ifndef MP_MEMCPY
    +#define MP_MEMCPY     1  /* use memcpy() to copy buffers?       */
    +#endif
    +
    +#ifndef MP_CRYPTO
    +#define MP_CRYPTO     1  /* erase memory on free?               */
    +#endif
    +
    +#ifndef MP_ARGCHK
    +/*
    +  0 = no parameter checks
    +  1 = runtime checks, continue execution and return an error to caller
    +  2 = assertions; dump core on parameter errors
    + */
    +#ifdef DEBUG
    +#define MP_ARGCHK     2  /* how to check input arguments        */
    +#else
    +#define MP_ARGCHK     1  /* how to check input arguments        */
    +#endif
    +#endif
    +
    +#ifndef MP_DEBUG
    +#define MP_DEBUG      0  /* print diagnostic output?            */
    +#endif
    +
    +#ifndef MP_DEFPREC
    +#define MP_DEFPREC    64 /* default precision, in digits        */
    +#endif
    +
    +#ifndef MP_MACRO
    +#define MP_MACRO      0  /* use macros for frequent calls?      */
    +#endif
    +
    +#ifndef MP_SQUARE
    +#define MP_SQUARE     1  /* use separate squaring code?         */
    +#endif
    +
    +#endif /* _MPI_CONFIG_H */
    diff --git a/jdk/src/share/native/sun/security/ec/mpi-priv.h b/jdk/src/share/native/sun/security/ec/mpi-priv.h
    new file mode 100644
    index 00000000000..b2b07ec3210
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/mpi-priv.h
    @@ -0,0 +1,340 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + *  Arbitrary precision integer arithmetic library
    + *
    + *  NOTE WELL: the content of this header file is NOT part of the "public"
    + *  API for the MPI library, and may change at any time.
    + *  Application programs that use libmpi should NOT include this header file.
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
    + *
    + * The Initial Developer of the Original Code is
    + * Michael J. Fromberger.
    + * Portions created by the Initial Developer are Copyright (C) 1998
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Netscape Communications Corporation
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#ifndef _MPI_PRIV_H
    +#define _MPI_PRIV_H
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +/* $Id: mpi-priv.h,v 1.20 2005/11/22 07:16:43 relyea%netscape.com Exp $ */
    +
    +#include "mpi.h"
    +#ifndef _KERNEL
    +#include 
    +#include 
    +#include 
    +#endif /* _KERNEL */
    +
    +#if MP_DEBUG
    +#include 
    +
    +#define DIAG(T,V) {fprintf(stderr,T);mp_print(V,stderr);fputc('\n',stderr);}
    +#else
    +#define DIAG(T,V)
    +#endif
    +
    +/* If we aren't using a wired-in logarithm table, we need to include
    +   the math library to get the log() function
    + */
    +
    +/* {{{ s_logv_2[] - log table for 2 in various bases */
    +
    +#if MP_LOGTAB
    +/*
    +  A table of the logs of 2 for various bases (the 0 and 1 entries of
    +  this table are meaningless and should not be referenced).
    +
    +  This table is used to compute output lengths for the mp_toradix()
    +  function.  Since a number n in radix r takes up about log_r(n)
    +  digits, we estimate the output size by taking the least integer
    +  greater than log_r(n), where:
    +
    +  log_r(n) = log_2(n) * log_r(2)
    +
    +  This table, therefore, is a table of log_r(2) for 2 <= r <= 36,
    +  which are the output bases supported.
    + */
    +
    +extern const float s_logv_2[];
    +#define LOG_V_2(R)  s_logv_2[(R)]
    +
    +#else
    +
    +/*
    +   If MP_LOGTAB is not defined, use the math library to compute the
    +   logarithms on the fly.  Otherwise, use the table.
    +   Pick which works best for your system.
    + */
    +
    +#include 
    +#define LOG_V_2(R)  (log(2.0)/log(R))
    +
    +#endif /* if MP_LOGTAB */
    +
    +/* }}} */
    +
    +/* {{{ Digit arithmetic macros */
    +
    +/*
    +  When adding and multiplying digits, the results can be larger than
    +  can be contained in an mp_digit.  Thus, an mp_word is used.  These
    +  macros mask off the upper and lower digits of the mp_word (the
    +  mp_word may be more than 2 mp_digits wide, but we only concern
    +  ourselves with the low-order 2 mp_digits)
    + */
    +
    +#define  CARRYOUT(W)  (mp_digit)((W)>>DIGIT_BIT)
    +#define  ACCUM(W)     (mp_digit)(W)
    +
    +#define MP_MIN(a,b)   (((a) < (b)) ? (a) : (b))
    +#define MP_MAX(a,b)   (((a) > (b)) ? (a) : (b))
    +#define MP_HOWMANY(a,b) (((a) + (b) - 1)/(b))
    +#define MP_ROUNDUP(a,b) (MP_HOWMANY(a,b) * (b))
    +
    +/* }}} */
    +
    +/* {{{ Comparison constants */
    +
    +#define  MP_LT       -1
    +#define  MP_EQ        0
    +#define  MP_GT        1
    +
    +/* }}} */
    +
    +/* {{{ private function declarations */
    +
    +/*
    +   If MP_MACRO is false, these will be defined as actual functions;
    +   otherwise, suitable macro definitions will be used.  This works
    +   around the fact that ANSI C89 doesn't support an 'inline' keyword
    +   (although I hear C9x will ... about bloody time).  At present, the
    +   macro definitions are identical to the function bodies, but they'll
    +   expand in place, instead of generating a function call.
    +
    +   I chose these particular functions to be made into macros because
    +   some profiling showed they are called a lot on a typical workload,
    +   and yet they are primarily housekeeping.
    + */
    +#if MP_MACRO == 0
    + void     s_mp_setz(mp_digit *dp, mp_size count); /* zero digits           */
    + void     s_mp_copy(const mp_digit *sp, mp_digit *dp, mp_size count); /* copy */
    + void    *s_mp_alloc(size_t nb, size_t ni, int flag); /* general allocator    */
    + void     s_mp_free(void *ptr, mp_size);          /* general free function */
    +extern unsigned long mp_allocs;
    +extern unsigned long mp_frees;
    +extern unsigned long mp_copies;
    +#else
    +
    + /* Even if these are defined as macros, we need to respect the settings
    +    of the MP_MEMSET and MP_MEMCPY configuration options...
    +  */
    + #if MP_MEMSET == 0
    +  #define  s_mp_setz(dp, count) \
    +       {int ix;for(ix=0;ix<(count);ix++)(dp)[ix]=0;}
    + #else
    +  #define  s_mp_setz(dp, count) memset(dp, 0, (count) * sizeof(mp_digit))
    + #endif /* MP_MEMSET */
    +
    + #if MP_MEMCPY == 0
    +  #define  s_mp_copy(sp, dp, count) \
    +       {int ix;for(ix=0;ix<(count);ix++)(dp)[ix]=(sp)[ix];}
    + #else
    +  #define  s_mp_copy(sp, dp, count) memcpy(dp, sp, (count) * sizeof(mp_digit))
    + #endif /* MP_MEMCPY */
    +
    + #define  s_mp_alloc(nb, ni)  calloc(nb, ni)
    + #define  s_mp_free(ptr) {if(ptr) free(ptr);}
    +#endif /* MP_MACRO */
    +
    +mp_err   s_mp_grow(mp_int *mp, mp_size min);   /* increase allocated size */
    +mp_err   s_mp_pad(mp_int *mp, mp_size min);    /* left pad with zeroes    */
    +
    +#if MP_MACRO == 0
    + void     s_mp_clamp(mp_int *mp);               /* clip leading zeroes     */
    +#else
    + #define  s_mp_clamp(mp)\
    +  { mp_size used = MP_USED(mp); \
    +    while (used > 1 && DIGIT(mp, used - 1) == 0) --used; \
    +    MP_USED(mp) = used; \
    +  }
    +#endif /* MP_MACRO */
    +
    +void     s_mp_exch(mp_int *a, mp_int *b);      /* swap a and b in place   */
    +
    +mp_err   s_mp_lshd(mp_int *mp, mp_size p);     /* left-shift by p digits  */
    +void     s_mp_rshd(mp_int *mp, mp_size p);     /* right-shift by p digits */
    +mp_err   s_mp_mul_2d(mp_int *mp, mp_digit d);  /* multiply by 2^d in place */
    +void     s_mp_div_2d(mp_int *mp, mp_digit d);  /* divide by 2^d in place  */
    +void     s_mp_mod_2d(mp_int *mp, mp_digit d);  /* modulo 2^d in place     */
    +void     s_mp_div_2(mp_int *mp);               /* divide by 2 in place    */
    +mp_err   s_mp_mul_2(mp_int *mp);               /* multiply by 2 in place  */
    +mp_err   s_mp_norm(mp_int *a, mp_int *b, mp_digit *pd);
    +                                               /* normalize for division  */
    +mp_err   s_mp_add_d(mp_int *mp, mp_digit d);   /* unsigned digit addition */
    +mp_err   s_mp_sub_d(mp_int *mp, mp_digit d);   /* unsigned digit subtract */
    +mp_err   s_mp_mul_d(mp_int *mp, mp_digit d);   /* unsigned digit multiply */
    +mp_err   s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r);
    +                                               /* unsigned digit divide   */
    +mp_err   s_mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu);
    +                                               /* Barrett reduction       */
    +mp_err   s_mp_add(mp_int *a, const mp_int *b); /* magnitude addition      */
    +mp_err   s_mp_add_3arg(const mp_int *a, const mp_int *b, mp_int *c);
    +mp_err   s_mp_sub(mp_int *a, const mp_int *b); /* magnitude subtract      */
    +mp_err   s_mp_sub_3arg(const mp_int *a, const mp_int *b, mp_int *c);
    +mp_err   s_mp_add_offset(mp_int *a, mp_int *b, mp_size offset);
    +                                               /* a += b * RADIX^offset   */
    +mp_err   s_mp_mul(mp_int *a, const mp_int *b); /* magnitude multiply      */
    +#if MP_SQUARE
    +mp_err   s_mp_sqr(mp_int *a);                  /* magnitude square        */
    +#else
    +#define  s_mp_sqr(a) s_mp_mul(a, a)
    +#endif
    +mp_err   s_mp_div(mp_int *rem, mp_int *div, mp_int *quot); /* magnitude div */
    +mp_err   s_mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c);
    +mp_err   s_mp_2expt(mp_int *a, mp_digit k);    /* a = 2^k                 */
    +int      s_mp_cmp(const mp_int *a, const mp_int *b); /* magnitude comparison */
    +int      s_mp_cmp_d(const mp_int *a, mp_digit d); /* magnitude digit compare */
    +int      s_mp_ispow2(const mp_int *v);         /* is v a power of 2?      */
    +int      s_mp_ispow2d(mp_digit d);             /* is d a power of 2?      */
    +
    +int      s_mp_tovalue(char ch, int r);          /* convert ch to value    */
    +char     s_mp_todigit(mp_digit val, int r, int low); /* convert val to digit */
    +int      s_mp_outlen(int bits, int r);          /* output length in bytes */
    +mp_digit s_mp_invmod_radix(mp_digit P);   /* returns (P ** -1) mod RADIX */
    +mp_err   s_mp_invmod_odd_m( const mp_int *a, const mp_int *m, mp_int *c);
    +mp_err   s_mp_invmod_2d(    const mp_int *a, mp_size k,       mp_int *c);
    +mp_err   s_mp_invmod_even_m(const mp_int *a, const mp_int *m, mp_int *c);
    +
    +#ifdef NSS_USE_COMBA
    +
    +#define IS_POWER_OF_2(a) ((a) && !((a) & ((a)-1)))
    +
    +void s_mp_mul_comba_4(const mp_int *A, const mp_int *B, mp_int *C);
    +void s_mp_mul_comba_8(const mp_int *A, const mp_int *B, mp_int *C);
    +void s_mp_mul_comba_16(const mp_int *A, const mp_int *B, mp_int *C);
    +void s_mp_mul_comba_32(const mp_int *A, const mp_int *B, mp_int *C);
    +
    +void s_mp_sqr_comba_4(const mp_int *A, mp_int *B);
    +void s_mp_sqr_comba_8(const mp_int *A, mp_int *B);
    +void s_mp_sqr_comba_16(const mp_int *A, mp_int *B);
    +void s_mp_sqr_comba_32(const mp_int *A, mp_int *B);
    +
    +#endif /* end NSS_USE_COMBA */
    +
    +/* ------ mpv functions, operate on arrays of digits, not on mp_int's ------ */
    +#if defined (__OS2__) && defined (__IBMC__)
    +#define MPI_ASM_DECL __cdecl
    +#else
    +#define MPI_ASM_DECL
    +#endif
    +
    +#ifdef MPI_AMD64
    +
    +mp_digit MPI_ASM_DECL s_mpv_mul_set_vec64(mp_digit*, mp_digit *, mp_size, mp_digit);
    +mp_digit MPI_ASM_DECL s_mpv_mul_add_vec64(mp_digit*, const mp_digit*, mp_size, mp_digit);
    +
    +/* c = a * b */
    +#define s_mpv_mul_d(a, a_len, b, c) \
    +        ((unsigned long*)c)[a_len] = s_mpv_mul_set_vec64(c, a, a_len, b)
    +
    +/* c += a * b */
    +#define s_mpv_mul_d_add(a, a_len, b, c) \
    +        ((unsigned long*)c)[a_len] = s_mpv_mul_add_vec64(c, a, a_len, b)
    +
    +#else
    +
    +void     MPI_ASM_DECL s_mpv_mul_d(const mp_digit *a, mp_size a_len,
    +                                        mp_digit b, mp_digit *c);
    +void     MPI_ASM_DECL s_mpv_mul_d_add(const mp_digit *a, mp_size a_len,
    +                                            mp_digit b, mp_digit *c);
    +
    +#endif
    +
    +void     MPI_ASM_DECL s_mpv_mul_d_add_prop(const mp_digit *a,
    +                                                mp_size a_len, mp_digit b,
    +                                                mp_digit *c);
    +void     MPI_ASM_DECL s_mpv_sqr_add_prop(const mp_digit *a,
    +                                                mp_size a_len,
    +                                                mp_digit *sqrs);
    +
    +mp_err   MPI_ASM_DECL s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo,
    +                            mp_digit divisor, mp_digit *quot, mp_digit *rem);
    +
    +/* c += a * b * (MP_RADIX ** offset);  */
    +#define s_mp_mul_d_add_offset(a, b, c, off) \
    +(s_mpv_mul_d_add_prop(MP_DIGITS(a), MP_USED(a), b, MP_DIGITS(c) + off), MP_OKAY)
    +
    +typedef struct {
    +  mp_int       N;       /* modulus N */
    +  mp_digit     n0prime; /* n0' = - (n0 ** -1) mod MP_RADIX */
    +  mp_size      b;       /* R == 2 ** b,  also b = # significant bits in N */
    +} mp_mont_modulus;
    +
    +mp_err s_mp_mul_mont(const mp_int *a, const mp_int *b, mp_int *c,
    +                       mp_mont_modulus *mmm);
    +mp_err s_mp_redc(mp_int *T, mp_mont_modulus *mmm);
    +
    +/*
    + * s_mpi_getProcessorLineSize() returns the size in bytes of the cache line
    + * if a cache exists, or zero if there is no cache. If more than one
    + * cache line exists, it should return the smallest line size (which is
    + * usually the L1 cache).
    + *
    + * mp_modexp uses this information to make sure that private key information
    + * isn't being leaked through the cache.
    + *
    + * see mpcpucache.c for the implementation.
    + */
    +unsigned long s_mpi_getProcessorLineSize();
    +
    +/* }}} */
    +#endif /* _MPI_PRIV_H */
    diff --git a/jdk/src/share/native/sun/security/ec/mpi.c b/jdk/src/share/native/sun/security/ec/mpi.c
    new file mode 100644
    index 00000000000..9f771882b01
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/mpi.c
    @@ -0,0 +1,4886 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + *
    + *  Arbitrary precision integer arithmetic library
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
    + *
    + * The Initial Developer of the Original Code is
    + * Michael J. Fromberger.
    + * Portions created by the Initial Developer are Copyright (C) 1998
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Netscape Communications Corporation
    + *   Douglas Stebila  of Sun Laboratories.
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +/* $Id: mpi.c,v 1.45 2006/09/29 20:12:21 alexei.volkov.bugs%sun.com Exp $ */
    +
    +#include "mpi-priv.h"
    +#if defined(OSF1)
    +#include 
    +#endif
    +
    +#if MP_LOGTAB
    +/*
    +  A table of the logs of 2 for various bases (the 0 and 1 entries of
    +  this table are meaningless and should not be referenced).
    +
    +  This table is used to compute output lengths for the mp_toradix()
    +  function.  Since a number n in radix r takes up about log_r(n)
    +  digits, we estimate the output size by taking the least integer
    +  greater than log_r(n), where:
    +
    +  log_r(n) = log_2(n) * log_r(2)
    +
    +  This table, therefore, is a table of log_r(2) for 2 <= r <= 36,
    +  which are the output bases supported.
    + */
    +#include "logtab.h"
    +#endif
    +
    +/* {{{ Constant strings */
    +
    +/* Constant strings returned by mp_strerror() */
    +static const char *mp_err_string[] = {
    +  "unknown result code",     /* say what?            */
    +  "boolean true",            /* MP_OKAY, MP_YES      */
    +  "boolean false",           /* MP_NO                */
    +  "out of memory",           /* MP_MEM               */
    +  "argument out of range",   /* MP_RANGE             */
    +  "invalid input parameter", /* MP_BADARG            */
    +  "result is undefined"      /* MP_UNDEF             */
    +};
    +
    +/* Value to digit maps for radix conversion   */
    +
    +/* s_dmap_1 - standard digits and letters */
    +static const char *s_dmap_1 =
    +  "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
    +
    +/* }}} */
    +
    +unsigned long mp_allocs;
    +unsigned long mp_frees;
    +unsigned long mp_copies;
    +
    +/* {{{ Default precision manipulation */
    +
    +/* Default precision for newly created mp_int's      */
    +static mp_size s_mp_defprec = MP_DEFPREC;
    +
    +mp_size mp_get_prec(void)
    +{
    +  return s_mp_defprec;
    +
    +} /* end mp_get_prec() */
    +
    +void         mp_set_prec(mp_size prec)
    +{
    +  if(prec == 0)
    +    s_mp_defprec = MP_DEFPREC;
    +  else
    +    s_mp_defprec = prec;
    +
    +} /* end mp_set_prec() */
    +
    +/* }}} */
    +
    +/*------------------------------------------------------------------------*/
    +/* {{{ mp_init(mp, kmflag) */
    +
    +/*
    +  mp_init(mp, kmflag)
    +
    +  Initialize a new zero-valued mp_int.  Returns MP_OKAY if successful,
    +  MP_MEM if memory could not be allocated for the structure.
    + */
    +
    +mp_err mp_init(mp_int *mp, int kmflag)
    +{
    +  return mp_init_size(mp, s_mp_defprec, kmflag);
    +
    +} /* end mp_init() */
    +
    +/* }}} */
    +
    +/* {{{ mp_init_size(mp, prec, kmflag) */
    +
    +/*
    +  mp_init_size(mp, prec, kmflag)
    +
    +  Initialize a new zero-valued mp_int with at least the given
    +  precision; returns MP_OKAY if successful, or MP_MEM if memory could
    +  not be allocated for the structure.
    + */
    +
    +mp_err mp_init_size(mp_int *mp, mp_size prec, int kmflag)
    +{
    +  ARGCHK(mp != NULL && prec > 0, MP_BADARG);
    +
    +  prec = MP_ROUNDUP(prec, s_mp_defprec);
    +  if((DIGITS(mp) = s_mp_alloc(prec, sizeof(mp_digit), kmflag)) == NULL)
    +    return MP_MEM;
    +
    +  SIGN(mp) = ZPOS;
    +  USED(mp) = 1;
    +  ALLOC(mp) = prec;
    +
    +  return MP_OKAY;
    +
    +} /* end mp_init_size() */
    +
    +/* }}} */
    +
    +/* {{{ mp_init_copy(mp, from) */
    +
    +/*
    +  mp_init_copy(mp, from)
    +
    +  Initialize mp as an exact copy of from.  Returns MP_OKAY if
    +  successful, MP_MEM if memory could not be allocated for the new
    +  structure.
    + */
    +
    +mp_err mp_init_copy(mp_int *mp, const mp_int *from)
    +{
    +  ARGCHK(mp != NULL && from != NULL, MP_BADARG);
    +
    +  if(mp == from)
    +    return MP_OKAY;
    +
    +  if((DIGITS(mp) = s_mp_alloc(ALLOC(from), sizeof(mp_digit), FLAG(from))) == NULL)
    +    return MP_MEM;
    +
    +  s_mp_copy(DIGITS(from), DIGITS(mp), USED(from));
    +  USED(mp) = USED(from);
    +  ALLOC(mp) = ALLOC(from);
    +  SIGN(mp) = SIGN(from);
    +
    +#ifndef _WIN32
    +  FLAG(mp) = FLAG(from);
    +#endif /* _WIN32 */
    +
    +  return MP_OKAY;
    +
    +} /* end mp_init_copy() */
    +
    +/* }}} */
    +
    +/* {{{ mp_copy(from, to) */
    +
    +/*
    +  mp_copy(from, to)
    +
    +  Copies the mp_int 'from' to the mp_int 'to'.  It is presumed that
    +  'to' has already been initialized (if not, use mp_init_copy()
    +  instead). If 'from' and 'to' are identical, nothing happens.
    + */
    +
    +mp_err mp_copy(const mp_int *from, mp_int *to)
    +{
    +  ARGCHK(from != NULL && to != NULL, MP_BADARG);
    +
    +  if(from == to)
    +    return MP_OKAY;
    +
    +  ++mp_copies;
    +  { /* copy */
    +    mp_digit   *tmp;
    +
    +    /*
    +      If the allocated buffer in 'to' already has enough space to hold
    +      all the used digits of 'from', we'll re-use it to avoid hitting
    +      the memory allocater more than necessary; otherwise, we'd have
    +      to grow anyway, so we just allocate a hunk and make the copy as
    +      usual
    +     */
    +    if(ALLOC(to) >= USED(from)) {
    +      s_mp_setz(DIGITS(to) + USED(from), ALLOC(to) - USED(from));
    +      s_mp_copy(DIGITS(from), DIGITS(to), USED(from));
    +
    +    } else {
    +      if((tmp = s_mp_alloc(ALLOC(from), sizeof(mp_digit), FLAG(from))) == NULL)
    +        return MP_MEM;
    +
    +      s_mp_copy(DIGITS(from), tmp, USED(from));
    +
    +      if(DIGITS(to) != NULL) {
    +#if MP_CRYPTO
    +        s_mp_setz(DIGITS(to), ALLOC(to));
    +#endif
    +        s_mp_free(DIGITS(to), ALLOC(to));
    +      }
    +
    +      DIGITS(to) = tmp;
    +      ALLOC(to) = ALLOC(from);
    +    }
    +
    +    /* Copy the precision and sign from the original */
    +    USED(to) = USED(from);
    +    SIGN(to) = SIGN(from);
    +  } /* end copy */
    +
    +  return MP_OKAY;
    +
    +} /* end mp_copy() */
    +
    +/* }}} */
    +
    +/* {{{ mp_exch(mp1, mp2) */
    +
    +/*
    +  mp_exch(mp1, mp2)
    +
    +  Exchange mp1 and mp2 without allocating any intermediate memory
    +  (well, unless you count the stack space needed for this call and the
    +  locals it creates...).  This cannot fail.
    + */
    +
    +void mp_exch(mp_int *mp1, mp_int *mp2)
    +{
    +#if MP_ARGCHK == 2
    +  assert(mp1 != NULL && mp2 != NULL);
    +#else
    +  if(mp1 == NULL || mp2 == NULL)
    +    return;
    +#endif
    +
    +  s_mp_exch(mp1, mp2);
    +
    +} /* end mp_exch() */
    +
    +/* }}} */
    +
    +/* {{{ mp_clear(mp) */
    +
    +/*
    +  mp_clear(mp)
    +
    +  Release the storage used by an mp_int, and void its fields so that
    +  if someone calls mp_clear() again for the same int later, we won't
    +  get tollchocked.
    + */
    +
    +void   mp_clear(mp_int *mp)
    +{
    +  if(mp == NULL)
    +    return;
    +
    +  if(DIGITS(mp) != NULL) {
    +#if MP_CRYPTO
    +    s_mp_setz(DIGITS(mp), ALLOC(mp));
    +#endif
    +    s_mp_free(DIGITS(mp), ALLOC(mp));
    +    DIGITS(mp) = NULL;
    +  }
    +
    +  USED(mp) = 0;
    +  ALLOC(mp) = 0;
    +
    +} /* end mp_clear() */
    +
    +/* }}} */
    +
    +/* {{{ mp_zero(mp) */
    +
    +/*
    +  mp_zero(mp)
    +
    +  Set mp to zero.  Does not change the allocated size of the structure,
    +  and therefore cannot fail (except on a bad argument, which we ignore)
    + */
    +void   mp_zero(mp_int *mp)
    +{
    +  if(mp == NULL)
    +    return;
    +
    +  s_mp_setz(DIGITS(mp), ALLOC(mp));
    +  USED(mp) = 1;
    +  SIGN(mp) = ZPOS;
    +
    +} /* end mp_zero() */
    +
    +/* }}} */
    +
    +/* {{{ mp_set(mp, d) */
    +
    +void   mp_set(mp_int *mp, mp_digit d)
    +{
    +  if(mp == NULL)
    +    return;
    +
    +  mp_zero(mp);
    +  DIGIT(mp, 0) = d;
    +
    +} /* end mp_set() */
    +
    +/* }}} */
    +
    +/* {{{ mp_set_int(mp, z) */
    +
    +mp_err mp_set_int(mp_int *mp, long z)
    +{
    +  int            ix;
    +  unsigned long  v = labs(z);
    +  mp_err         res;
    +
    +  ARGCHK(mp != NULL, MP_BADARG);
    +
    +  mp_zero(mp);
    +  if(z == 0)
    +    return MP_OKAY;  /* shortcut for zero */
    +
    +  if (sizeof v <= sizeof(mp_digit)) {
    +    DIGIT(mp,0) = v;
    +  } else {
    +    for (ix = sizeof(long) - 1; ix >= 0; ix--) {
    +      if ((res = s_mp_mul_d(mp, (UCHAR_MAX + 1))) != MP_OKAY)
    +        return res;
    +
    +      res = s_mp_add_d(mp, (mp_digit)((v >> (ix * CHAR_BIT)) & UCHAR_MAX));
    +      if (res != MP_OKAY)
    +        return res;
    +    }
    +  }
    +  if(z < 0)
    +    SIGN(mp) = NEG;
    +
    +  return MP_OKAY;
    +
    +} /* end mp_set_int() */
    +
    +/* }}} */
    +
    +/* {{{ mp_set_ulong(mp, z) */
    +
    +mp_err mp_set_ulong(mp_int *mp, unsigned long z)
    +{
    +  int            ix;
    +  mp_err         res;
    +
    +  ARGCHK(mp != NULL, MP_BADARG);
    +
    +  mp_zero(mp);
    +  if(z == 0)
    +    return MP_OKAY;  /* shortcut for zero */
    +
    +  if (sizeof z <= sizeof(mp_digit)) {
    +    DIGIT(mp,0) = z;
    +  } else {
    +    for (ix = sizeof(long) - 1; ix >= 0; ix--) {
    +      if ((res = s_mp_mul_d(mp, (UCHAR_MAX + 1))) != MP_OKAY)
    +        return res;
    +
    +      res = s_mp_add_d(mp, (mp_digit)((z >> (ix * CHAR_BIT)) & UCHAR_MAX));
    +      if (res != MP_OKAY)
    +        return res;
    +    }
    +  }
    +  return MP_OKAY;
    +} /* end mp_set_ulong() */
    +
    +/* }}} */
    +
    +/*------------------------------------------------------------------------*/
    +/* {{{ Digit arithmetic */
    +
    +/* {{{ mp_add_d(a, d, b) */
    +
    +/*
    +  mp_add_d(a, d, b)
    +
    +  Compute the sum b = a + d, for a single digit d.  Respects the sign of
    +  its primary addend (single digits are unsigned anyway).
    + */
    +
    +mp_err mp_add_d(const mp_int *a, mp_digit d, mp_int *b)
    +{
    +  mp_int   tmp;
    +  mp_err   res;
    +
    +  ARGCHK(a != NULL && b != NULL, MP_BADARG);
    +
    +  if((res = mp_init_copy(&tmp, a)) != MP_OKAY)
    +    return res;
    +
    +  if(SIGN(&tmp) == ZPOS) {
    +    if((res = s_mp_add_d(&tmp, d)) != MP_OKAY)
    +      goto CLEANUP;
    +  } else if(s_mp_cmp_d(&tmp, d) >= 0) {
    +    if((res = s_mp_sub_d(&tmp, d)) != MP_OKAY)
    +      goto CLEANUP;
    +  } else {
    +    mp_neg(&tmp, &tmp);
    +
    +    DIGIT(&tmp, 0) = d - DIGIT(&tmp, 0);
    +  }
    +
    +  if(s_mp_cmp_d(&tmp, 0) == 0)
    +    SIGN(&tmp) = ZPOS;
    +
    +  s_mp_exch(&tmp, b);
    +
    +CLEANUP:
    +  mp_clear(&tmp);
    +  return res;
    +
    +} /* end mp_add_d() */
    +
    +/* }}} */
    +
    +/* {{{ mp_sub_d(a, d, b) */
    +
    +/*
    +  mp_sub_d(a, d, b)
    +
    +  Compute the difference b = a - d, for a single digit d.  Respects the
    +  sign of its subtrahend (single digits are unsigned anyway).
    + */
    +
    +mp_err mp_sub_d(const mp_int *a, mp_digit d, mp_int *b)
    +{
    +  mp_int   tmp;
    +  mp_err   res;
    +
    +  ARGCHK(a != NULL && b != NULL, MP_BADARG);
    +
    +  if((res = mp_init_copy(&tmp, a)) != MP_OKAY)
    +    return res;
    +
    +  if(SIGN(&tmp) == NEG) {
    +    if((res = s_mp_add_d(&tmp, d)) != MP_OKAY)
    +      goto CLEANUP;
    +  } else if(s_mp_cmp_d(&tmp, d) >= 0) {
    +    if((res = s_mp_sub_d(&tmp, d)) != MP_OKAY)
    +      goto CLEANUP;
    +  } else {
    +    mp_neg(&tmp, &tmp);
    +
    +    DIGIT(&tmp, 0) = d - DIGIT(&tmp, 0);
    +    SIGN(&tmp) = NEG;
    +  }
    +
    +  if(s_mp_cmp_d(&tmp, 0) == 0)
    +    SIGN(&tmp) = ZPOS;
    +
    +  s_mp_exch(&tmp, b);
    +
    +CLEANUP:
    +  mp_clear(&tmp);
    +  return res;
    +
    +} /* end mp_sub_d() */
    +
    +/* }}} */
    +
    +/* {{{ mp_mul_d(a, d, b) */
    +
    +/*
    +  mp_mul_d(a, d, b)
    +
    +  Compute the product b = a * d, for a single digit d.  Respects the sign
    +  of its multiplicand (single digits are unsigned anyway)
    + */
    +
    +mp_err mp_mul_d(const mp_int *a, mp_digit d, mp_int *b)
    +{
    +  mp_err  res;
    +
    +  ARGCHK(a != NULL && b != NULL, MP_BADARG);
    +
    +  if(d == 0) {
    +    mp_zero(b);
    +    return MP_OKAY;
    +  }
    +
    +  if((res = mp_copy(a, b)) != MP_OKAY)
    +    return res;
    +
    +  res = s_mp_mul_d(b, d);
    +
    +  return res;
    +
    +} /* end mp_mul_d() */
    +
    +/* }}} */
    +
    +/* {{{ mp_mul_2(a, c) */
    +
    +mp_err mp_mul_2(const mp_int *a, mp_int *c)
    +{
    +  mp_err  res;
    +
    +  ARGCHK(a != NULL && c != NULL, MP_BADARG);
    +
    +  if((res = mp_copy(a, c)) != MP_OKAY)
    +    return res;
    +
    +  return s_mp_mul_2(c);
    +
    +} /* end mp_mul_2() */
    +
    +/* }}} */
    +
    +/* {{{ mp_div_d(a, d, q, r) */
    +
    +/*
    +  mp_div_d(a, d, q, r)
    +
    +  Compute the quotient q = a / d and remainder r = a mod d, for a
    +  single digit d.  Respects the sign of its divisor (single digits are
    +  unsigned anyway).
    + */
    +
    +mp_err mp_div_d(const mp_int *a, mp_digit d, mp_int *q, mp_digit *r)
    +{
    +  mp_err   res;
    +  mp_int   qp;
    +  mp_digit rem;
    +  int      pow;
    +
    +  ARGCHK(a != NULL, MP_BADARG);
    +
    +  if(d == 0)
    +    return MP_RANGE;
    +
    +  /* Shortcut for powers of two ... */
    +  if((pow = s_mp_ispow2d(d)) >= 0) {
    +    mp_digit  mask;
    +
    +    mask = ((mp_digit)1 << pow) - 1;
    +    rem = DIGIT(a, 0) & mask;
    +
    +    if(q) {
    +      mp_copy(a, q);
    +      s_mp_div_2d(q, pow);
    +    }
    +
    +    if(r)
    +      *r = rem;
    +
    +    return MP_OKAY;
    +  }
    +
    +  if((res = mp_init_copy(&qp, a)) != MP_OKAY)
    +    return res;
    +
    +  res = s_mp_div_d(&qp, d, &rem);
    +
    +  if(s_mp_cmp_d(&qp, 0) == 0)
    +    SIGN(q) = ZPOS;
    +
    +  if(r)
    +    *r = rem;
    +
    +  if(q)
    +    s_mp_exch(&qp, q);
    +
    +  mp_clear(&qp);
    +  return res;
    +
    +} /* end mp_div_d() */
    +
    +/* }}} */
    +
    +/* {{{ mp_div_2(a, c) */
    +
    +/*
    +  mp_div_2(a, c)
    +
    +  Compute c = a / 2, disregarding the remainder.
    + */
    +
    +mp_err mp_div_2(const mp_int *a, mp_int *c)
    +{
    +  mp_err  res;
    +
    +  ARGCHK(a != NULL && c != NULL, MP_BADARG);
    +
    +  if((res = mp_copy(a, c)) != MP_OKAY)
    +    return res;
    +
    +  s_mp_div_2(c);
    +
    +  return MP_OKAY;
    +
    +} /* end mp_div_2() */
    +
    +/* }}} */
    +
    +/* {{{ mp_expt_d(a, d, b) */
    +
    +mp_err mp_expt_d(const mp_int *a, mp_digit d, mp_int *c)
    +{
    +  mp_int   s, x;
    +  mp_err   res;
    +
    +  ARGCHK(a != NULL && c != NULL, MP_BADARG);
    +
    +  if((res = mp_init(&s, FLAG(a))) != MP_OKAY)
    +    return res;
    +  if((res = mp_init_copy(&x, a)) != MP_OKAY)
    +    goto X;
    +
    +  DIGIT(&s, 0) = 1;
    +
    +  while(d != 0) {
    +    if(d & 1) {
    +      if((res = s_mp_mul(&s, &x)) != MP_OKAY)
    +        goto CLEANUP;
    +    }
    +
    +    d /= 2;
    +
    +    if((res = s_mp_sqr(&x)) != MP_OKAY)
    +      goto CLEANUP;
    +  }
    +
    +  s_mp_exch(&s, c);
    +
    +CLEANUP:
    +  mp_clear(&x);
    +X:
    +  mp_clear(&s);
    +
    +  return res;
    +
    +} /* end mp_expt_d() */
    +
    +/* }}} */
    +
    +/* }}} */
    +
    +/*------------------------------------------------------------------------*/
    +/* {{{ Full arithmetic */
    +
    +/* {{{ mp_abs(a, b) */
    +
    +/*
    +  mp_abs(a, b)
    +
    +  Compute b = |a|.  'a' and 'b' may be identical.
    + */
    +
    +mp_err mp_abs(const mp_int *a, mp_int *b)
    +{
    +  mp_err   res;
    +
    +  ARGCHK(a != NULL && b != NULL, MP_BADARG);
    +
    +  if((res = mp_copy(a, b)) != MP_OKAY)
    +    return res;
    +
    +  SIGN(b) = ZPOS;
    +
    +  return MP_OKAY;
    +
    +} /* end mp_abs() */
    +
    +/* }}} */
    +
    +/* {{{ mp_neg(a, b) */
    +
    +/*
    +  mp_neg(a, b)
    +
    +  Compute b = -a.  'a' and 'b' may be identical.
    + */
    +
    +mp_err mp_neg(const mp_int *a, mp_int *b)
    +{
    +  mp_err   res;
    +
    +  ARGCHK(a != NULL && b != NULL, MP_BADARG);
    +
    +  if((res = mp_copy(a, b)) != MP_OKAY)
    +    return res;
    +
    +  if(s_mp_cmp_d(b, 0) == MP_EQ)
    +    SIGN(b) = ZPOS;
    +  else
    +    SIGN(b) = (SIGN(b) == NEG) ? ZPOS : NEG;
    +
    +  return MP_OKAY;
    +
    +} /* end mp_neg() */
    +
    +/* }}} */
    +
    +/* {{{ mp_add(a, b, c) */
    +
    +/*
    +  mp_add(a, b, c)
    +
    +  Compute c = a + b.  All parameters may be identical.
    + */
    +
    +mp_err mp_add(const mp_int *a, const mp_int *b, mp_int *c)
    +{
    +  mp_err  res;
    +
    +  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
    +
    +  if(SIGN(a) == SIGN(b)) { /* same sign:  add values, keep sign */
    +    MP_CHECKOK( s_mp_add_3arg(a, b, c) );
    +  } else if(s_mp_cmp(a, b) >= 0) {  /* different sign: |a| >= |b|   */
    +    MP_CHECKOK( s_mp_sub_3arg(a, b, c) );
    +  } else {                          /* different sign: |a|  < |b|   */
    +    MP_CHECKOK( s_mp_sub_3arg(b, a, c) );
    +  }
    +
    +  if (s_mp_cmp_d(c, 0) == MP_EQ)
    +    SIGN(c) = ZPOS;
    +
    +CLEANUP:
    +  return res;
    +
    +} /* end mp_add() */
    +
    +/* }}} */
    +
    +/* {{{ mp_sub(a, b, c) */
    +
    +/*
    +  mp_sub(a, b, c)
    +
    +  Compute c = a - b.  All parameters may be identical.
    + */
    +
    +mp_err mp_sub(const mp_int *a, const mp_int *b, mp_int *c)
    +{
    +  mp_err  res;
    +  int     magDiff;
    +
    +  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
    +
    +  if (a == b) {
    +    mp_zero(c);
    +    return MP_OKAY;
    +  }
    +
    +  if (MP_SIGN(a) != MP_SIGN(b)) {
    +    MP_CHECKOK( s_mp_add_3arg(a, b, c) );
    +  } else if (!(magDiff = s_mp_cmp(a, b))) {
    +    mp_zero(c);
    +    res = MP_OKAY;
    +  } else if (magDiff > 0) {
    +    MP_CHECKOK( s_mp_sub_3arg(a, b, c) );
    +  } else {
    +    MP_CHECKOK( s_mp_sub_3arg(b, a, c) );
    +    MP_SIGN(c) = !MP_SIGN(a);
    +  }
    +
    +  if (s_mp_cmp_d(c, 0) == MP_EQ)
    +    MP_SIGN(c) = MP_ZPOS;
    +
    +CLEANUP:
    +  return res;
    +
    +} /* end mp_sub() */
    +
    +/* }}} */
    +
    +/* {{{ mp_mul(a, b, c) */
    +
    +/*
    +  mp_mul(a, b, c)
    +
    +  Compute c = a * b.  All parameters may be identical.
    + */
    +mp_err   mp_mul(const mp_int *a, const mp_int *b, mp_int * c)
    +{
    +  mp_digit *pb;
    +  mp_int   tmp;
    +  mp_err   res;
    +  mp_size  ib;
    +  mp_size  useda, usedb;
    +
    +  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
    +
    +  if (a == c) {
    +    if ((res = mp_init_copy(&tmp, a)) != MP_OKAY)
    +      return res;
    +    if (a == b)
    +      b = &tmp;
    +    a = &tmp;
    +  } else if (b == c) {
    +    if ((res = mp_init_copy(&tmp, b)) != MP_OKAY)
    +      return res;
    +    b = &tmp;
    +  } else {
    +    MP_DIGITS(&tmp) = 0;
    +  }
    +
    +  if (MP_USED(a) < MP_USED(b)) {
    +    const mp_int *xch = b;      /* switch a and b, to do fewer outer loops */
    +    b = a;
    +    a = xch;
    +  }
    +
    +  MP_USED(c) = 1; MP_DIGIT(c, 0) = 0;
    +  if((res = s_mp_pad(c, USED(a) + USED(b))) != MP_OKAY)
    +    goto CLEANUP;
    +
    +#ifdef NSS_USE_COMBA
    +  if ((MP_USED(a) == MP_USED(b)) && IS_POWER_OF_2(MP_USED(b))) {
    +      if (MP_USED(a) == 4) {
    +          s_mp_mul_comba_4(a, b, c);
    +          goto CLEANUP;
    +      }
    +      if (MP_USED(a) == 8) {
    +          s_mp_mul_comba_8(a, b, c);
    +          goto CLEANUP;
    +      }
    +      if (MP_USED(a) == 16) {
    +          s_mp_mul_comba_16(a, b, c);
    +          goto CLEANUP;
    +      }
    +      if (MP_USED(a) == 32) {
    +          s_mp_mul_comba_32(a, b, c);
    +          goto CLEANUP;
    +      }
    +  }
    +#endif
    +
    +  pb = MP_DIGITS(b);
    +  s_mpv_mul_d(MP_DIGITS(a), MP_USED(a), *pb++, MP_DIGITS(c));
    +
    +  /* Outer loop:  Digits of b */
    +  useda = MP_USED(a);
    +  usedb = MP_USED(b);
    +  for (ib = 1; ib < usedb; ib++) {
    +    mp_digit b_i    = *pb++;
    +
    +    /* Inner product:  Digits of a */
    +    if (b_i)
    +      s_mpv_mul_d_add(MP_DIGITS(a), useda, b_i, MP_DIGITS(c) + ib);
    +    else
    +      MP_DIGIT(c, ib + useda) = b_i;
    +  }
    +
    +  s_mp_clamp(c);
    +
    +  if(SIGN(a) == SIGN(b) || s_mp_cmp_d(c, 0) == MP_EQ)
    +    SIGN(c) = ZPOS;
    +  else
    +    SIGN(c) = NEG;
    +
    +CLEANUP:
    +  mp_clear(&tmp);
    +  return res;
    +} /* end mp_mul() */
    +
    +/* }}} */
    +
    +/* {{{ mp_sqr(a, sqr) */
    +
    +#if MP_SQUARE
    +/*
    +  Computes the square of a.  This can be done more
    +  efficiently than a general multiplication, because many of the
    +  computation steps are redundant when squaring.  The inner product
    +  step is a bit more complicated, but we save a fair number of
    +  iterations of the multiplication loop.
    + */
    +
    +/* sqr = a^2;   Caller provides both a and tmp; */
    +mp_err   mp_sqr(const mp_int *a, mp_int *sqr)
    +{
    +  mp_digit *pa;
    +  mp_digit d;
    +  mp_err   res;
    +  mp_size  ix;
    +  mp_int   tmp;
    +  int      count;
    +
    +  ARGCHK(a != NULL && sqr != NULL, MP_BADARG);
    +
    +  if (a == sqr) {
    +    if((res = mp_init_copy(&tmp, a)) != MP_OKAY)
    +      return res;
    +    a = &tmp;
    +  } else {
    +    DIGITS(&tmp) = 0;
    +    res = MP_OKAY;
    +  }
    +
    +  ix = 2 * MP_USED(a);
    +  if (ix > MP_ALLOC(sqr)) {
    +    MP_USED(sqr) = 1;
    +    MP_CHECKOK( s_mp_grow(sqr, ix) );
    +  }
    +  MP_USED(sqr) = ix;
    +  MP_DIGIT(sqr, 0) = 0;
    +
    +#ifdef NSS_USE_COMBA
    +  if (IS_POWER_OF_2(MP_USED(a))) {
    +      if (MP_USED(a) == 4) {
    +          s_mp_sqr_comba_4(a, sqr);
    +          goto CLEANUP;
    +      }
    +      if (MP_USED(a) == 8) {
    +          s_mp_sqr_comba_8(a, sqr);
    +          goto CLEANUP;
    +      }
    +      if (MP_USED(a) == 16) {
    +          s_mp_sqr_comba_16(a, sqr);
    +          goto CLEANUP;
    +      }
    +      if (MP_USED(a) == 32) {
    +          s_mp_sqr_comba_32(a, sqr);
    +          goto CLEANUP;
    +      }
    +  }
    +#endif
    +
    +  pa = MP_DIGITS(a);
    +  count = MP_USED(a) - 1;
    +  if (count > 0) {
    +    d = *pa++;
    +    s_mpv_mul_d(pa, count, d, MP_DIGITS(sqr) + 1);
    +    for (ix = 3; --count > 0; ix += 2) {
    +      d = *pa++;
    +      s_mpv_mul_d_add(pa, count, d, MP_DIGITS(sqr) + ix);
    +    } /* for(ix ...) */
    +    MP_DIGIT(sqr, MP_USED(sqr)-1) = 0; /* above loop stopped short of this. */
    +
    +    /* now sqr *= 2 */
    +    s_mp_mul_2(sqr);
    +  } else {
    +    MP_DIGIT(sqr, 1) = 0;
    +  }
    +
    +  /* now add the squares of the digits of a to sqr. */
    +  s_mpv_sqr_add_prop(MP_DIGITS(a), MP_USED(a), MP_DIGITS(sqr));
    +
    +  SIGN(sqr) = ZPOS;
    +  s_mp_clamp(sqr);
    +
    +CLEANUP:
    +  mp_clear(&tmp);
    +  return res;
    +
    +} /* end mp_sqr() */
    +#endif
    +
    +/* }}} */
    +
    +/* {{{ mp_div(a, b, q, r) */
    +
    +/*
    +  mp_div(a, b, q, r)
    +
    +  Compute q = a / b and r = a mod b.  Input parameters may be re-used
    +  as output parameters.  If q or r is NULL, that portion of the
    +  computation will be discarded (although it will still be computed)
    + */
    +mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *q, mp_int *r)
    +{
    +  mp_err   res;
    +  mp_int   *pQ, *pR;
    +  mp_int   qtmp, rtmp, btmp;
    +  int      cmp;
    +  mp_sign  signA;
    +  mp_sign  signB;
    +
    +  ARGCHK(a != NULL && b != NULL, MP_BADARG);
    +
    +  signA = MP_SIGN(a);
    +  signB = MP_SIGN(b);
    +
    +  if(mp_cmp_z(b) == MP_EQ)
    +    return MP_RANGE;
    +
    +  DIGITS(&qtmp) = 0;
    +  DIGITS(&rtmp) = 0;
    +  DIGITS(&btmp) = 0;
    +
    +  /* Set up some temporaries... */
    +  if (!r || r == a || r == b) {
    +    MP_CHECKOK( mp_init_copy(&rtmp, a) );
    +    pR = &rtmp;
    +  } else {
    +    MP_CHECKOK( mp_copy(a, r) );
    +    pR = r;
    +  }
    +
    +  if (!q || q == a || q == b) {
    +    MP_CHECKOK( mp_init_size(&qtmp, MP_USED(a), FLAG(a)) );
    +    pQ = &qtmp;
    +  } else {
    +    MP_CHECKOK( s_mp_pad(q, MP_USED(a)) );
    +    pQ = q;
    +    mp_zero(pQ);
    +  }
    +
    +  /*
    +    If |a| <= |b|, we can compute the solution without division;
    +    otherwise, we actually do the work required.
    +   */
    +  if ((cmp = s_mp_cmp(a, b)) <= 0) {
    +    if (cmp) {
    +      /* r was set to a above. */
    +      mp_zero(pQ);
    +    } else {
    +      mp_set(pQ, 1);
    +      mp_zero(pR);
    +    }
    +  } else {
    +    MP_CHECKOK( mp_init_copy(&btmp, b) );
    +    MP_CHECKOK( s_mp_div(pR, &btmp, pQ) );
    +  }
    +
    +  /* Compute the signs for the output  */
    +  MP_SIGN(pR) = signA;   /* Sr = Sa              */
    +  /* Sq = ZPOS if Sa == Sb */ /* Sq = NEG if Sa != Sb */
    +  MP_SIGN(pQ) = (signA == signB) ? ZPOS : NEG;
    +
    +  if(s_mp_cmp_d(pQ, 0) == MP_EQ)
    +    SIGN(pQ) = ZPOS;
    +  if(s_mp_cmp_d(pR, 0) == MP_EQ)
    +    SIGN(pR) = ZPOS;
    +
    +  /* Copy output, if it is needed      */
    +  if(q && q != pQ)
    +    s_mp_exch(pQ, q);
    +
    +  if(r && r != pR)
    +    s_mp_exch(pR, r);
    +
    +CLEANUP:
    +  mp_clear(&btmp);
    +  mp_clear(&rtmp);
    +  mp_clear(&qtmp);
    +
    +  return res;
    +
    +} /* end mp_div() */
    +
    +/* }}} */
    +
    +/* {{{ mp_div_2d(a, d, q, r) */
    +
    +mp_err mp_div_2d(const mp_int *a, mp_digit d, mp_int *q, mp_int *r)
    +{
    +  mp_err  res;
    +
    +  ARGCHK(a != NULL, MP_BADARG);
    +
    +  if(q) {
    +    if((res = mp_copy(a, q)) != MP_OKAY)
    +      return res;
    +  }
    +  if(r) {
    +    if((res = mp_copy(a, r)) != MP_OKAY)
    +      return res;
    +  }
    +  if(q) {
    +    s_mp_div_2d(q, d);
    +  }
    +  if(r) {
    +    s_mp_mod_2d(r, d);
    +  }
    +
    +  return MP_OKAY;
    +
    +} /* end mp_div_2d() */
    +
    +/* }}} */
    +
    +/* {{{ mp_expt(a, b, c) */
    +
    +/*
    +  mp_expt(a, b, c)
    +
    +  Compute c = a ** b, that is, raise a to the b power.  Uses a
    +  standard iterative square-and-multiply technique.
    + */
    +
    +mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c)
    +{
    +  mp_int   s, x;
    +  mp_err   res;
    +  mp_digit d;
    +  int      dig, bit;
    +
    +  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
    +
    +  if(mp_cmp_z(b) < 0)
    +    return MP_RANGE;
    +
    +  if((res = mp_init(&s, FLAG(a))) != MP_OKAY)
    +    return res;
    +
    +  mp_set(&s, 1);
    +
    +  if((res = mp_init_copy(&x, a)) != MP_OKAY)
    +    goto X;
    +
    +  /* Loop over low-order digits in ascending order */
    +  for(dig = 0; dig < (USED(b) - 1); dig++) {
    +    d = DIGIT(b, dig);
    +
    +    /* Loop over bits of each non-maximal digit */
    +    for(bit = 0; bit < DIGIT_BIT; bit++) {
    +      if(d & 1) {
    +        if((res = s_mp_mul(&s, &x)) != MP_OKAY)
    +          goto CLEANUP;
    +      }
    +
    +      d >>= 1;
    +
    +      if((res = s_mp_sqr(&x)) != MP_OKAY)
    +        goto CLEANUP;
    +    }
    +  }
    +
    +  /* Consider now the last digit... */
    +  d = DIGIT(b, dig);
    +
    +  while(d) {
    +    if(d & 1) {
    +      if((res = s_mp_mul(&s, &x)) != MP_OKAY)
    +        goto CLEANUP;
    +    }
    +
    +    d >>= 1;
    +
    +    if((res = s_mp_sqr(&x)) != MP_OKAY)
    +      goto CLEANUP;
    +  }
    +
    +  if(mp_iseven(b))
    +    SIGN(&s) = SIGN(a);
    +
    +  res = mp_copy(&s, c);
    +
    +CLEANUP:
    +  mp_clear(&x);
    +X:
    +  mp_clear(&s);
    +
    +  return res;
    +
    +} /* end mp_expt() */
    +
    +/* }}} */
    +
    +/* {{{ mp_2expt(a, k) */
    +
    +/* Compute a = 2^k */
    +
    +mp_err mp_2expt(mp_int *a, mp_digit k)
    +{
    +  ARGCHK(a != NULL, MP_BADARG);
    +
    +  return s_mp_2expt(a, k);
    +
    +} /* end mp_2expt() */
    +
    +/* }}} */
    +
    +/* {{{ mp_mod(a, m, c) */
    +
    +/*
    +  mp_mod(a, m, c)
    +
    +  Compute c = a (mod m).  Result will always be 0 <= c < m.
    + */
    +
    +mp_err mp_mod(const mp_int *a, const mp_int *m, mp_int *c)
    +{
    +  mp_err  res;
    +  int     mag;
    +
    +  ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG);
    +
    +  if(SIGN(m) == NEG)
    +    return MP_RANGE;
    +
    +  /*
    +     If |a| > m, we need to divide to get the remainder and take the
    +     absolute value.
    +
    +     If |a| < m, we don't need to do any division, just copy and adjust
    +     the sign (if a is negative).
    +
    +     If |a| == m, we can simply set the result to zero.
    +
    +     This order is intended to minimize the average path length of the
    +     comparison chain on common workloads -- the most frequent cases are
    +     that |a| != m, so we do those first.
    +   */
    +  if((mag = s_mp_cmp(a, m)) > 0) {
    +    if((res = mp_div(a, m, NULL, c)) != MP_OKAY)
    +      return res;
    +
    +    if(SIGN(c) == NEG) {
    +      if((res = mp_add(c, m, c)) != MP_OKAY)
    +        return res;
    +    }
    +
    +  } else if(mag < 0) {
    +    if((res = mp_copy(a, c)) != MP_OKAY)
    +      return res;
    +
    +    if(mp_cmp_z(a) < 0) {
    +      if((res = mp_add(c, m, c)) != MP_OKAY)
    +        return res;
    +
    +    }
    +
    +  } else {
    +    mp_zero(c);
    +
    +  }
    +
    +  return MP_OKAY;
    +
    +} /* end mp_mod() */
    +
    +/* }}} */
    +
    +/* {{{ mp_mod_d(a, d, c) */
    +
    +/*
    +  mp_mod_d(a, d, c)
    +
    +  Compute c = a (mod d).  Result will always be 0 <= c < d
    + */
    +mp_err mp_mod_d(const mp_int *a, mp_digit d, mp_digit *c)
    +{
    +  mp_err   res;
    +  mp_digit rem;
    +
    +  ARGCHK(a != NULL && c != NULL, MP_BADARG);
    +
    +  if(s_mp_cmp_d(a, d) > 0) {
    +    if((res = mp_div_d(a, d, NULL, &rem)) != MP_OKAY)
    +      return res;
    +
    +  } else {
    +    if(SIGN(a) == NEG)
    +      rem = d - DIGIT(a, 0);
    +    else
    +      rem = DIGIT(a, 0);
    +  }
    +
    +  if(c)
    +    *c = rem;
    +
    +  return MP_OKAY;
    +
    +} /* end mp_mod_d() */
    +
    +/* }}} */
    +
    +/* {{{ mp_sqrt(a, b) */
    +
    +/*
    +  mp_sqrt(a, b)
    +
    +  Compute the integer square root of a, and store the result in b.
    +  Uses an integer-arithmetic version of Newton's iterative linear
    +  approximation technique to determine this value; the result has the
    +  following two properties:
    +
    +     b^2 <= a
    +     (b+1)^2 >= a
    +
    +  It is a range error to pass a negative value.
    + */
    +mp_err mp_sqrt(const mp_int *a, mp_int *b)
    +{
    +  mp_int   x, t;
    +  mp_err   res;
    +  mp_size  used;
    +
    +  ARGCHK(a != NULL && b != NULL, MP_BADARG);
    +
    +  /* Cannot take square root of a negative value */
    +  if(SIGN(a) == NEG)
    +    return MP_RANGE;
    +
    +  /* Special cases for zero and one, trivial     */
    +  if(mp_cmp_d(a, 1) <= 0)
    +    return mp_copy(a, b);
    +
    +  /* Initialize the temporaries we'll use below  */
    +  if((res = mp_init_size(&t, USED(a), FLAG(a))) != MP_OKAY)
    +    return res;
    +
    +  /* Compute an initial guess for the iteration as a itself */
    +  if((res = mp_init_copy(&x, a)) != MP_OKAY)
    +    goto X;
    +
    +  used = MP_USED(&x);
    +  if (used > 1) {
    +    s_mp_rshd(&x, used / 2);
    +  }
    +
    +  for(;;) {
    +    /* t = (x * x) - a */
    +    mp_copy(&x, &t);      /* can't fail, t is big enough for original x */
    +    if((res = mp_sqr(&t, &t)) != MP_OKAY ||
    +       (res = mp_sub(&t, a, &t)) != MP_OKAY)
    +      goto CLEANUP;
    +
    +    /* t = t / 2x       */
    +    s_mp_mul_2(&x);
    +    if((res = mp_div(&t, &x, &t, NULL)) != MP_OKAY)
    +      goto CLEANUP;
    +    s_mp_div_2(&x);
    +
    +    /* Terminate the loop, if the quotient is zero */
    +    if(mp_cmp_z(&t) == MP_EQ)
    +      break;
    +
    +    /* x = x - t       */
    +    if((res = mp_sub(&x, &t, &x)) != MP_OKAY)
    +      goto CLEANUP;
    +
    +  }
    +
    +  /* Copy result to output parameter */
    +  mp_sub_d(&x, 1, &x);
    +  s_mp_exch(&x, b);
    +
    + CLEANUP:
    +  mp_clear(&x);
    + X:
    +  mp_clear(&t);
    +
    +  return res;
    +
    +} /* end mp_sqrt() */
    +
    +/* }}} */
    +
    +/* }}} */
    +
    +/*------------------------------------------------------------------------*/
    +/* {{{ Modular arithmetic */
    +
    +#if MP_MODARITH
    +/* {{{ mp_addmod(a, b, m, c) */
    +
    +/*
    +  mp_addmod(a, b, m, c)
    +
    +  Compute c = (a + b) mod m
    + */
    +
    +mp_err mp_addmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)
    +{
    +  mp_err  res;
    +
    +  ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
    +
    +  if((res = mp_add(a, b, c)) != MP_OKAY)
    +    return res;
    +  if((res = mp_mod(c, m, c)) != MP_OKAY)
    +    return res;
    +
    +  return MP_OKAY;
    +
    +}
    +
    +/* }}} */
    +
    +/* {{{ mp_submod(a, b, m, c) */
    +
    +/*
    +  mp_submod(a, b, m, c)
    +
    +  Compute c = (a - b) mod m
    + */
    +
    +mp_err mp_submod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)
    +{
    +  mp_err  res;
    +
    +  ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
    +
    +  if((res = mp_sub(a, b, c)) != MP_OKAY)
    +    return res;
    +  if((res = mp_mod(c, m, c)) != MP_OKAY)
    +    return res;
    +
    +  return MP_OKAY;
    +
    +}
    +
    +/* }}} */
    +
    +/* {{{ mp_mulmod(a, b, m, c) */
    +
    +/*
    +  mp_mulmod(a, b, m, c)
    +
    +  Compute c = (a * b) mod m
    + */
    +
    +mp_err mp_mulmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)
    +{
    +  mp_err  res;
    +
    +  ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
    +
    +  if((res = mp_mul(a, b, c)) != MP_OKAY)
    +    return res;
    +  if((res = mp_mod(c, m, c)) != MP_OKAY)
    +    return res;
    +
    +  return MP_OKAY;
    +
    +}
    +
    +/* }}} */
    +
    +/* {{{ mp_sqrmod(a, m, c) */
    +
    +#if MP_SQUARE
    +mp_err mp_sqrmod(const mp_int *a, const mp_int *m, mp_int *c)
    +{
    +  mp_err  res;
    +
    +  ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG);
    +
    +  if((res = mp_sqr(a, c)) != MP_OKAY)
    +    return res;
    +  if((res = mp_mod(c, m, c)) != MP_OKAY)
    +    return res;
    +
    +  return MP_OKAY;
    +
    +} /* end mp_sqrmod() */
    +#endif
    +
    +/* }}} */
    +
    +/* {{{ s_mp_exptmod(a, b, m, c) */
    +
    +/*
    +  s_mp_exptmod(a, b, m, c)
    +
    +  Compute c = (a ** b) mod m.  Uses a standard square-and-multiply
    +  method with modular reductions at each step. (This is basically the
    +  same code as mp_expt(), except for the addition of the reductions)
    +
    +  The modular reductions are done using Barrett's algorithm (see
    +  s_mp_reduce() below for details)
    + */
    +
    +mp_err s_mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)
    +{
    +  mp_int   s, x, mu;
    +  mp_err   res;
    +  mp_digit d;
    +  int      dig, bit;
    +
    +  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
    +
    +  if(mp_cmp_z(b) < 0 || mp_cmp_z(m) <= 0)
    +    return MP_RANGE;
    +
    +  if((res = mp_init(&s, FLAG(a))) != MP_OKAY)
    +    return res;
    +  if((res = mp_init_copy(&x, a)) != MP_OKAY ||
    +     (res = mp_mod(&x, m, &x)) != MP_OKAY)
    +    goto X;
    +  if((res = mp_init(&mu, FLAG(a))) != MP_OKAY)
    +    goto MU;
    +
    +  mp_set(&s, 1);
    +
    +  /* mu = b^2k / m */
    +  s_mp_add_d(&mu, 1);
    +  s_mp_lshd(&mu, 2 * USED(m));
    +  if((res = mp_div(&mu, m, &mu, NULL)) != MP_OKAY)
    +    goto CLEANUP;
    +
    +  /* Loop over digits of b in ascending order, except highest order */
    +  for(dig = 0; dig < (USED(b) - 1); dig++) {
    +    d = DIGIT(b, dig);
    +
    +    /* Loop over the bits of the lower-order digits */
    +    for(bit = 0; bit < DIGIT_BIT; bit++) {
    +      if(d & 1) {
    +        if((res = s_mp_mul(&s, &x)) != MP_OKAY)
    +          goto CLEANUP;
    +        if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY)
    +          goto CLEANUP;
    +      }
    +
    +      d >>= 1;
    +
    +      if((res = s_mp_sqr(&x)) != MP_OKAY)
    +        goto CLEANUP;
    +      if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY)
    +        goto CLEANUP;
    +    }
    +  }
    +
    +  /* Now do the last digit... */
    +  d = DIGIT(b, dig);
    +
    +  while(d) {
    +    if(d & 1) {
    +      if((res = s_mp_mul(&s, &x)) != MP_OKAY)
    +        goto CLEANUP;
    +      if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY)
    +        goto CLEANUP;
    +    }
    +
    +    d >>= 1;
    +
    +    if((res = s_mp_sqr(&x)) != MP_OKAY)
    +      goto CLEANUP;
    +    if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY)
    +      goto CLEANUP;
    +  }
    +
    +  s_mp_exch(&s, c);
    +
    + CLEANUP:
    +  mp_clear(&mu);
    + MU:
    +  mp_clear(&x);
    + X:
    +  mp_clear(&s);
    +
    +  return res;
    +
    +} /* end s_mp_exptmod() */
    +
    +/* }}} */
    +
    +/* {{{ mp_exptmod_d(a, d, m, c) */
    +
    +mp_err mp_exptmod_d(const mp_int *a, mp_digit d, const mp_int *m, mp_int *c)
    +{
    +  mp_int   s, x;
    +  mp_err   res;
    +
    +  ARGCHK(a != NULL && c != NULL, MP_BADARG);
    +
    +  if((res = mp_init(&s, FLAG(a))) != MP_OKAY)
    +    return res;
    +  if((res = mp_init_copy(&x, a)) != MP_OKAY)
    +    goto X;
    +
    +  mp_set(&s, 1);
    +
    +  while(d != 0) {
    +    if(d & 1) {
    +      if((res = s_mp_mul(&s, &x)) != MP_OKAY ||
    +         (res = mp_mod(&s, m, &s)) != MP_OKAY)
    +        goto CLEANUP;
    +    }
    +
    +    d /= 2;
    +
    +    if((res = s_mp_sqr(&x)) != MP_OKAY ||
    +       (res = mp_mod(&x, m, &x)) != MP_OKAY)
    +      goto CLEANUP;
    +  }
    +
    +  s_mp_exch(&s, c);
    +
    +CLEANUP:
    +  mp_clear(&x);
    +X:
    +  mp_clear(&s);
    +
    +  return res;
    +
    +} /* end mp_exptmod_d() */
    +
    +/* }}} */
    +#endif /* if MP_MODARITH */
    +
    +/* }}} */
    +
    +/*------------------------------------------------------------------------*/
    +/* {{{ Comparison functions */
    +
    +/* {{{ mp_cmp_z(a) */
    +
    +/*
    +  mp_cmp_z(a)
    +
    +  Compare a <=> 0.  Returns <0 if a<0, 0 if a=0, >0 if a>0.
    + */
    +
    +int    mp_cmp_z(const mp_int *a)
    +{
    +  if(SIGN(a) == NEG)
    +    return MP_LT;
    +  else if(USED(a) == 1 && DIGIT(a, 0) == 0)
    +    return MP_EQ;
    +  else
    +    return MP_GT;
    +
    +} /* end mp_cmp_z() */
    +
    +/* }}} */
    +
    +/* {{{ mp_cmp_d(a, d) */
    +
    +/*
    +  mp_cmp_d(a, d)
    +
    +  Compare a <=> d.  Returns <0 if a0 if a>d
    + */
    +
    +int    mp_cmp_d(const mp_int *a, mp_digit d)
    +{
    +  ARGCHK(a != NULL, MP_EQ);
    +
    +  if(SIGN(a) == NEG)
    +    return MP_LT;
    +
    +  return s_mp_cmp_d(a, d);
    +
    +} /* end mp_cmp_d() */
    +
    +/* }}} */
    +
    +/* {{{ mp_cmp(a, b) */
    +
    +int    mp_cmp(const mp_int *a, const mp_int *b)
    +{
    +  ARGCHK(a != NULL && b != NULL, MP_EQ);
    +
    +  if(SIGN(a) == SIGN(b)) {
    +    int  mag;
    +
    +    if((mag = s_mp_cmp(a, b)) == MP_EQ)
    +      return MP_EQ;
    +
    +    if(SIGN(a) == ZPOS)
    +      return mag;
    +    else
    +      return -mag;
    +
    +  } else if(SIGN(a) == ZPOS) {
    +    return MP_GT;
    +  } else {
    +    return MP_LT;
    +  }
    +
    +} /* end mp_cmp() */
    +
    +/* }}} */
    +
    +/* {{{ mp_cmp_mag(a, b) */
    +
    +/*
    +  mp_cmp_mag(a, b)
    +
    +  Compares |a| <=> |b|, and returns an appropriate comparison result
    + */
    +
    +int    mp_cmp_mag(mp_int *a, mp_int *b)
    +{
    +  ARGCHK(a != NULL && b != NULL, MP_EQ);
    +
    +  return s_mp_cmp(a, b);
    +
    +} /* end mp_cmp_mag() */
    +
    +/* }}} */
    +
    +/* {{{ mp_cmp_int(a, z, kmflag) */
    +
    +/*
    +  This just converts z to an mp_int, and uses the existing comparison
    +  routines.  This is sort of inefficient, but it's not clear to me how
    +  frequently this wil get used anyway.  For small positive constants,
    +  you can always use mp_cmp_d(), and for zero, there is mp_cmp_z().
    + */
    +int    mp_cmp_int(const mp_int *a, long z, int kmflag)
    +{
    +  mp_int  tmp;
    +  int     out;
    +
    +  ARGCHK(a != NULL, MP_EQ);
    +
    +  mp_init(&tmp, kmflag); mp_set_int(&tmp, z);
    +  out = mp_cmp(a, &tmp);
    +  mp_clear(&tmp);
    +
    +  return out;
    +
    +} /* end mp_cmp_int() */
    +
    +/* }}} */
    +
    +/* {{{ mp_isodd(a) */
    +
    +/*
    +  mp_isodd(a)
    +
    +  Returns a true (non-zero) value if a is odd, false (zero) otherwise.
    + */
    +int    mp_isodd(const mp_int *a)
    +{
    +  ARGCHK(a != NULL, 0);
    +
    +  return (int)(DIGIT(a, 0) & 1);
    +
    +} /* end mp_isodd() */
    +
    +/* }}} */
    +
    +/* {{{ mp_iseven(a) */
    +
    +int    mp_iseven(const mp_int *a)
    +{
    +  return !mp_isodd(a);
    +
    +} /* end mp_iseven() */
    +
    +/* }}} */
    +
    +/* }}} */
    +
    +/*------------------------------------------------------------------------*/
    +/* {{{ Number theoretic functions */
    +
    +#if MP_NUMTH
    +/* {{{ mp_gcd(a, b, c) */
    +
    +/*
    +  Like the old mp_gcd() function, except computes the GCD using the
    +  binary algorithm due to Josef Stein in 1961 (via Knuth).
    + */
    +mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c)
    +{
    +  mp_err   res;
    +  mp_int   u, v, t;
    +  mp_size  k = 0;
    +
    +  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
    +
    +  if(mp_cmp_z(a) == MP_EQ && mp_cmp_z(b) == MP_EQ)
    +      return MP_RANGE;
    +  if(mp_cmp_z(a) == MP_EQ) {
    +    return mp_copy(b, c);
    +  } else if(mp_cmp_z(b) == MP_EQ) {
    +    return mp_copy(a, c);
    +  }
    +
    +  if((res = mp_init(&t, FLAG(a))) != MP_OKAY)
    +    return res;
    +  if((res = mp_init_copy(&u, a)) != MP_OKAY)
    +    goto U;
    +  if((res = mp_init_copy(&v, b)) != MP_OKAY)
    +    goto V;
    +
    +  SIGN(&u) = ZPOS;
    +  SIGN(&v) = ZPOS;
    +
    +  /* Divide out common factors of 2 until at least 1 of a, b is even */
    +  while(mp_iseven(&u) && mp_iseven(&v)) {
    +    s_mp_div_2(&u);
    +    s_mp_div_2(&v);
    +    ++k;
    +  }
    +
    +  /* Initialize t */
    +  if(mp_isodd(&u)) {
    +    if((res = mp_copy(&v, &t)) != MP_OKAY)
    +      goto CLEANUP;
    +
    +    /* t = -v */
    +    if(SIGN(&v) == ZPOS)
    +      SIGN(&t) = NEG;
    +    else
    +      SIGN(&t) = ZPOS;
    +
    +  } else {
    +    if((res = mp_copy(&u, &t)) != MP_OKAY)
    +      goto CLEANUP;
    +
    +  }
    +
    +  for(;;) {
    +    while(mp_iseven(&t)) {
    +      s_mp_div_2(&t);
    +    }
    +
    +    if(mp_cmp_z(&t) == MP_GT) {
    +      if((res = mp_copy(&t, &u)) != MP_OKAY)
    +        goto CLEANUP;
    +
    +    } else {
    +      if((res = mp_copy(&t, &v)) != MP_OKAY)
    +        goto CLEANUP;
    +
    +      /* v = -t */
    +      if(SIGN(&t) == ZPOS)
    +        SIGN(&v) = NEG;
    +      else
    +        SIGN(&v) = ZPOS;
    +    }
    +
    +    if((res = mp_sub(&u, &v, &t)) != MP_OKAY)
    +      goto CLEANUP;
    +
    +    if(s_mp_cmp_d(&t, 0) == MP_EQ)
    +      break;
    +  }
    +
    +  s_mp_2expt(&v, k);       /* v = 2^k   */
    +  res = mp_mul(&u, &v, c); /* c = u * v */
    +
    + CLEANUP:
    +  mp_clear(&v);
    + V:
    +  mp_clear(&u);
    + U:
    +  mp_clear(&t);
    +
    +  return res;
    +
    +} /* end mp_gcd() */
    +
    +/* }}} */
    +
    +/* {{{ mp_lcm(a, b, c) */
    +
    +/* We compute the least common multiple using the rule:
    +
    +   ab = [a, b](a, b)
    +
    +   ... by computing the product, and dividing out the gcd.
    + */
    +
    +mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c)
    +{
    +  mp_int  gcd, prod;
    +  mp_err  res;
    +
    +  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
    +
    +  /* Set up temporaries */
    +  if((res = mp_init(&gcd, FLAG(a))) != MP_OKAY)
    +    return res;
    +  if((res = mp_init(&prod, FLAG(a))) != MP_OKAY)
    +    goto GCD;
    +
    +  if((res = mp_mul(a, b, &prod)) != MP_OKAY)
    +    goto CLEANUP;
    +  if((res = mp_gcd(a, b, &gcd)) != MP_OKAY)
    +    goto CLEANUP;
    +
    +  res = mp_div(&prod, &gcd, c, NULL);
    +
    + CLEANUP:
    +  mp_clear(&prod);
    + GCD:
    +  mp_clear(&gcd);
    +
    +  return res;
    +
    +} /* end mp_lcm() */
    +
    +/* }}} */
    +
    +/* {{{ mp_xgcd(a, b, g, x, y) */
    +
    +/*
    +  mp_xgcd(a, b, g, x, y)
    +
    +  Compute g = (a, b) and values x and y satisfying Bezout's identity
    +  (that is, ax + by = g).  This uses the binary extended GCD algorithm
    +  based on the Stein algorithm used for mp_gcd()
    +  See algorithm 14.61 in Handbook of Applied Cryptogrpahy.
    + */
    +
    +mp_err mp_xgcd(const mp_int *a, const mp_int *b, mp_int *g, mp_int *x, mp_int *y)
    +{
    +  mp_int   gx, xc, yc, u, v, A, B, C, D;
    +  mp_int  *clean[9];
    +  mp_err   res;
    +  int      last = -1;
    +
    +  if(mp_cmp_z(b) == 0)
    +    return MP_RANGE;
    +
    +  /* Initialize all these variables we need */
    +  MP_CHECKOK( mp_init(&u, FLAG(a)) );
    +  clean[++last] = &u;
    +  MP_CHECKOK( mp_init(&v, FLAG(a)) );
    +  clean[++last] = &v;
    +  MP_CHECKOK( mp_init(&gx, FLAG(a)) );
    +  clean[++last] = &gx;
    +  MP_CHECKOK( mp_init(&A, FLAG(a)) );
    +  clean[++last] = &A;
    +  MP_CHECKOK( mp_init(&B, FLAG(a)) );
    +  clean[++last] = &B;
    +  MP_CHECKOK( mp_init(&C, FLAG(a)) );
    +  clean[++last] = &C;
    +  MP_CHECKOK( mp_init(&D, FLAG(a)) );
    +  clean[++last] = &D;
    +  MP_CHECKOK( mp_init_copy(&xc, a) );
    +  clean[++last] = &xc;
    +  mp_abs(&xc, &xc);
    +  MP_CHECKOK( mp_init_copy(&yc, b) );
    +  clean[++last] = &yc;
    +  mp_abs(&yc, &yc);
    +
    +  mp_set(&gx, 1);
    +
    +  /* Divide by two until at least one of them is odd */
    +  while(mp_iseven(&xc) && mp_iseven(&yc)) {
    +    mp_size nx = mp_trailing_zeros(&xc);
    +    mp_size ny = mp_trailing_zeros(&yc);
    +    mp_size n  = MP_MIN(nx, ny);
    +    s_mp_div_2d(&xc,n);
    +    s_mp_div_2d(&yc,n);
    +    MP_CHECKOK( s_mp_mul_2d(&gx,n) );
    +  }
    +
    +  mp_copy(&xc, &u);
    +  mp_copy(&yc, &v);
    +  mp_set(&A, 1); mp_set(&D, 1);
    +
    +  /* Loop through binary GCD algorithm */
    +  do {
    +    while(mp_iseven(&u)) {
    +      s_mp_div_2(&u);
    +
    +      if(mp_iseven(&A) && mp_iseven(&B)) {
    +        s_mp_div_2(&A); s_mp_div_2(&B);
    +      } else {
    +        MP_CHECKOK( mp_add(&A, &yc, &A) );
    +        s_mp_div_2(&A);
    +        MP_CHECKOK( mp_sub(&B, &xc, &B) );
    +        s_mp_div_2(&B);
    +      }
    +    }
    +
    +    while(mp_iseven(&v)) {
    +      s_mp_div_2(&v);
    +
    +      if(mp_iseven(&C) && mp_iseven(&D)) {
    +        s_mp_div_2(&C); s_mp_div_2(&D);
    +      } else {
    +        MP_CHECKOK( mp_add(&C, &yc, &C) );
    +        s_mp_div_2(&C);
    +        MP_CHECKOK( mp_sub(&D, &xc, &D) );
    +        s_mp_div_2(&D);
    +      }
    +    }
    +
    +    if(mp_cmp(&u, &v) >= 0) {
    +      MP_CHECKOK( mp_sub(&u, &v, &u) );
    +      MP_CHECKOK( mp_sub(&A, &C, &A) );
    +      MP_CHECKOK( mp_sub(&B, &D, &B) );
    +    } else {
    +      MP_CHECKOK( mp_sub(&v, &u, &v) );
    +      MP_CHECKOK( mp_sub(&C, &A, &C) );
    +      MP_CHECKOK( mp_sub(&D, &B, &D) );
    +    }
    +  } while (mp_cmp_z(&u) != 0);
    +
    +  /* copy results to output */
    +  if(x)
    +    MP_CHECKOK( mp_copy(&C, x) );
    +
    +  if(y)
    +    MP_CHECKOK( mp_copy(&D, y) );
    +
    +  if(g)
    +    MP_CHECKOK( mp_mul(&gx, &v, g) );
    +
    + CLEANUP:
    +  while(last >= 0)
    +    mp_clear(clean[last--]);
    +
    +  return res;
    +
    +} /* end mp_xgcd() */
    +
    +/* }}} */
    +
    +mp_size mp_trailing_zeros(const mp_int *mp)
    +{
    +  mp_digit d;
    +  mp_size  n = 0;
    +  int      ix;
    +
    +  if (!mp || !MP_DIGITS(mp) || !mp_cmp_z(mp))
    +    return n;
    +
    +  for (ix = 0; !(d = MP_DIGIT(mp,ix)) && (ix < MP_USED(mp)); ++ix)
    +    n += MP_DIGIT_BIT;
    +  if (!d)
    +    return 0;   /* shouldn't happen, but ... */
    +#if !defined(MP_USE_UINT_DIGIT)
    +  if (!(d & 0xffffffffU)) {
    +    d >>= 32;
    +    n  += 32;
    +  }
    +#endif
    +  if (!(d & 0xffffU)) {
    +    d >>= 16;
    +    n  += 16;
    +  }
    +  if (!(d & 0xffU)) {
    +    d >>= 8;
    +    n  += 8;
    +  }
    +  if (!(d & 0xfU)) {
    +    d >>= 4;
    +    n  += 4;
    +  }
    +  if (!(d & 0x3U)) {
    +    d >>= 2;
    +    n  += 2;
    +  }
    +  if (!(d & 0x1U)) {
    +    d >>= 1;
    +    n  += 1;
    +  }
    +#if MP_ARGCHK == 2
    +  assert(0 != (d & 1));
    +#endif
    +  return n;
    +}
    +
    +/* Given a and prime p, computes c and k such that a*c == 2**k (mod p).
    +** Returns k (positive) or error (negative).
    +** This technique from the paper "Fast Modular Reciprocals" (unpublished)
    +** by Richard Schroeppel (a.k.a. Captain Nemo).
    +*/
    +mp_err s_mp_almost_inverse(const mp_int *a, const mp_int *p, mp_int *c)
    +{
    +  mp_err res;
    +  mp_err k    = 0;
    +  mp_int d, f, g;
    +
    +  ARGCHK(a && p && c, MP_BADARG);
    +
    +  MP_DIGITS(&d) = 0;
    +  MP_DIGITS(&f) = 0;
    +  MP_DIGITS(&g) = 0;
    +  MP_CHECKOK( mp_init(&d, FLAG(a)) );
    +  MP_CHECKOK( mp_init_copy(&f, a) );    /* f = a */
    +  MP_CHECKOK( mp_init_copy(&g, p) );    /* g = p */
    +
    +  mp_set(c, 1);
    +  mp_zero(&d);
    +
    +  if (mp_cmp_z(&f) == 0) {
    +    res = MP_UNDEF;
    +  } else
    +  for (;;) {
    +    int diff_sign;
    +    while (mp_iseven(&f)) {
    +      mp_size n = mp_trailing_zeros(&f);
    +      if (!n) {
    +        res = MP_UNDEF;
    +        goto CLEANUP;
    +      }
    +      s_mp_div_2d(&f, n);
    +      MP_CHECKOK( s_mp_mul_2d(&d, n) );
    +      k += n;
    +    }
    +    if (mp_cmp_d(&f, 1) == MP_EQ) {     /* f == 1 */
    +      res = k;
    +      break;
    +    }
    +    diff_sign = mp_cmp(&f, &g);
    +    if (diff_sign < 0) {                /* f < g */
    +      s_mp_exch(&f, &g);
    +      s_mp_exch(c, &d);
    +    } else if (diff_sign == 0) {                /* f == g */
    +      res = MP_UNDEF;           /* a and p are not relatively prime */
    +      break;
    +    }
    +    if ((MP_DIGIT(&f,0) % 4) == (MP_DIGIT(&g,0) % 4)) {
    +      MP_CHECKOK( mp_sub(&f, &g, &f) ); /* f = f - g */
    +      MP_CHECKOK( mp_sub(c,  &d,  c) ); /* c = c - d */
    +    } else {
    +      MP_CHECKOK( mp_add(&f, &g, &f) ); /* f = f + g */
    +      MP_CHECKOK( mp_add(c,  &d,  c) ); /* c = c + d */
    +    }
    +  }
    +  if (res >= 0) {
    +    while (MP_SIGN(c) != MP_ZPOS) {
    +      MP_CHECKOK( mp_add(c, p, c) );
    +    }
    +    res = k;
    +  }
    +
    +CLEANUP:
    +  mp_clear(&d);
    +  mp_clear(&f);
    +  mp_clear(&g);
    +  return res;
    +}
    +
    +/* Compute T = (P ** -1) mod MP_RADIX.  Also works for 16-bit mp_digits.
    +** This technique from the paper "Fast Modular Reciprocals" (unpublished)
    +** by Richard Schroeppel (a.k.a. Captain Nemo).
    +*/
    +mp_digit  s_mp_invmod_radix(mp_digit P)
    +{
    +  mp_digit T = P;
    +  T *= 2 - (P * T);
    +  T *= 2 - (P * T);
    +  T *= 2 - (P * T);
    +  T *= 2 - (P * T);
    +#if !defined(MP_USE_UINT_DIGIT)
    +  T *= 2 - (P * T);
    +  T *= 2 - (P * T);
    +#endif
    +  return T;
    +}
    +
    +/* Given c, k, and prime p, where a*c == 2**k (mod p),
    +** Compute x = (a ** -1) mod p.  This is similar to Montgomery reduction.
    +** This technique from the paper "Fast Modular Reciprocals" (unpublished)
    +** by Richard Schroeppel (a.k.a. Captain Nemo).
    +*/
    +mp_err  s_mp_fixup_reciprocal(const mp_int *c, const mp_int *p, int k, mp_int *x)
    +{
    +  int      k_orig = k;
    +  mp_digit r;
    +  mp_size  ix;
    +  mp_err   res;
    +
    +  if (mp_cmp_z(c) < 0) {                /* c < 0 */
    +    MP_CHECKOK( mp_add(c, p, x) );      /* x = c + p */
    +  } else {
    +    MP_CHECKOK( mp_copy(c, x) );        /* x = c */
    +  }
    +
    +  /* make sure x is large enough */
    +  ix = MP_HOWMANY(k, MP_DIGIT_BIT) + MP_USED(p) + 1;
    +  ix = MP_MAX(ix, MP_USED(x));
    +  MP_CHECKOK( s_mp_pad(x, ix) );
    +
    +  r = 0 - s_mp_invmod_radix(MP_DIGIT(p,0));
    +
    +  for (ix = 0; k > 0; ix++) {
    +    int      j = MP_MIN(k, MP_DIGIT_BIT);
    +    mp_digit v = r * MP_DIGIT(x, ix);
    +    if (j < MP_DIGIT_BIT) {
    +      v &= ((mp_digit)1 << j) - 1;      /* v = v mod (2 ** j) */
    +    }
    +    s_mp_mul_d_add_offset(p, v, x, ix); /* x += p * v * (RADIX ** ix) */
    +    k -= j;
    +  }
    +  s_mp_clamp(x);
    +  s_mp_div_2d(x, k_orig);
    +  res = MP_OKAY;
    +
    +CLEANUP:
    +  return res;
    +}
    +
    +/* compute mod inverse using Schroeppel's method, only if m is odd */
    +mp_err s_mp_invmod_odd_m(const mp_int *a, const mp_int *m, mp_int *c)
    +{
    +  int k;
    +  mp_err  res;
    +  mp_int  x;
    +
    +  ARGCHK(a && m && c, MP_BADARG);
    +
    +  if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
    +    return MP_RANGE;
    +  if (mp_iseven(m))
    +    return MP_UNDEF;
    +
    +  MP_DIGITS(&x) = 0;
    +
    +  if (a == c) {
    +    if ((res = mp_init_copy(&x, a)) != MP_OKAY)
    +      return res;
    +    if (a == m)
    +      m = &x;
    +    a = &x;
    +  } else if (m == c) {
    +    if ((res = mp_init_copy(&x, m)) != MP_OKAY)
    +      return res;
    +    m = &x;
    +  } else {
    +    MP_DIGITS(&x) = 0;
    +  }
    +
    +  MP_CHECKOK( s_mp_almost_inverse(a, m, c) );
    +  k = res;
    +  MP_CHECKOK( s_mp_fixup_reciprocal(c, m, k, c) );
    +CLEANUP:
    +  mp_clear(&x);
    +  return res;
    +}
    +
    +/* Known good algorithm for computing modular inverse.  But slow. */
    +mp_err mp_invmod_xgcd(const mp_int *a, const mp_int *m, mp_int *c)
    +{
    +  mp_int  g, x;
    +  mp_err  res;
    +
    +  ARGCHK(a && m && c, MP_BADARG);
    +
    +  if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
    +    return MP_RANGE;
    +
    +  MP_DIGITS(&g) = 0;
    +  MP_DIGITS(&x) = 0;
    +  MP_CHECKOK( mp_init(&x, FLAG(a)) );
    +  MP_CHECKOK( mp_init(&g, FLAG(a)) );
    +
    +  MP_CHECKOK( mp_xgcd(a, m, &g, &x, NULL) );
    +
    +  if (mp_cmp_d(&g, 1) != MP_EQ) {
    +    res = MP_UNDEF;
    +    goto CLEANUP;
    +  }
    +
    +  res = mp_mod(&x, m, c);
    +  SIGN(c) = SIGN(a);
    +
    +CLEANUP:
    +  mp_clear(&x);
    +  mp_clear(&g);
    +
    +  return res;
    +}
    +
    +/* modular inverse where modulus is 2**k. */
    +/* c = a**-1 mod 2**k */
    +mp_err s_mp_invmod_2d(const mp_int *a, mp_size k, mp_int *c)
    +{
    +  mp_err res;
    +  mp_size ix = k + 4;
    +  mp_int t0, t1, val, tmp, two2k;
    +
    +  static const mp_digit d2 = 2;
    +  static const mp_int two = { 0, MP_ZPOS, 1, 1, (mp_digit *)&d2 };
    +
    +  if (mp_iseven(a))
    +    return MP_UNDEF;
    +  if (k <= MP_DIGIT_BIT) {
    +    mp_digit i = s_mp_invmod_radix(MP_DIGIT(a,0));
    +    if (k < MP_DIGIT_BIT)
    +      i &= ((mp_digit)1 << k) - (mp_digit)1;
    +    mp_set(c, i);
    +    return MP_OKAY;
    +  }
    +  MP_DIGITS(&t0) = 0;
    +  MP_DIGITS(&t1) = 0;
    +  MP_DIGITS(&val) = 0;
    +  MP_DIGITS(&tmp) = 0;
    +  MP_DIGITS(&two2k) = 0;
    +  MP_CHECKOK( mp_init_copy(&val, a) );
    +  s_mp_mod_2d(&val, k);
    +  MP_CHECKOK( mp_init_copy(&t0, &val) );
    +  MP_CHECKOK( mp_init_copy(&t1, &t0)  );
    +  MP_CHECKOK( mp_init(&tmp, FLAG(a)) );
    +  MP_CHECKOK( mp_init(&two2k, FLAG(a)) );
    +  MP_CHECKOK( s_mp_2expt(&two2k, k) );
    +  do {
    +    MP_CHECKOK( mp_mul(&val, &t1, &tmp)  );
    +    MP_CHECKOK( mp_sub(&two, &tmp, &tmp) );
    +    MP_CHECKOK( mp_mul(&t1, &tmp, &t1)   );
    +    s_mp_mod_2d(&t1, k);
    +    while (MP_SIGN(&t1) != MP_ZPOS) {
    +      MP_CHECKOK( mp_add(&t1, &two2k, &t1) );
    +    }
    +    if (mp_cmp(&t1, &t0) == MP_EQ)
    +      break;
    +    MP_CHECKOK( mp_copy(&t1, &t0) );
    +  } while (--ix > 0);
    +  if (!ix) {
    +    res = MP_UNDEF;
    +  } else {
    +    mp_exch(c, &t1);
    +  }
    +
    +CLEANUP:
    +  mp_clear(&t0);
    +  mp_clear(&t1);
    +  mp_clear(&val);
    +  mp_clear(&tmp);
    +  mp_clear(&two2k);
    +  return res;
    +}
    +
    +mp_err s_mp_invmod_even_m(const mp_int *a, const mp_int *m, mp_int *c)
    +{
    +  mp_err res;
    +  mp_size k;
    +  mp_int oddFactor, evenFactor; /* factors of the modulus */
    +  mp_int oddPart, evenPart;     /* parts to combine via CRT. */
    +  mp_int C2, tmp1, tmp2;
    +
    +  /*static const mp_digit d1 = 1; */
    +  /*static const mp_int one = { MP_ZPOS, 1, 1, (mp_digit *)&d1 }; */
    +
    +  if ((res = s_mp_ispow2(m)) >= 0) {
    +    k = res;
    +    return s_mp_invmod_2d(a, k, c);
    +  }
    +  MP_DIGITS(&oddFactor) = 0;
    +  MP_DIGITS(&evenFactor) = 0;
    +  MP_DIGITS(&oddPart) = 0;
    +  MP_DIGITS(&evenPart) = 0;
    +  MP_DIGITS(&C2)     = 0;
    +  MP_DIGITS(&tmp1)   = 0;
    +  MP_DIGITS(&tmp2)   = 0;
    +
    +  MP_CHECKOK( mp_init_copy(&oddFactor, m) );    /* oddFactor = m */
    +  MP_CHECKOK( mp_init(&evenFactor, FLAG(m)) );
    +  MP_CHECKOK( mp_init(&oddPart, FLAG(m)) );
    +  MP_CHECKOK( mp_init(&evenPart, FLAG(m)) );
    +  MP_CHECKOK( mp_init(&C2, FLAG(m))     );
    +  MP_CHECKOK( mp_init(&tmp1, FLAG(m))   );
    +  MP_CHECKOK( mp_init(&tmp2, FLAG(m))   );
    +
    +  k = mp_trailing_zeros(m);
    +  s_mp_div_2d(&oddFactor, k);
    +  MP_CHECKOK( s_mp_2expt(&evenFactor, k) );
    +
    +  /* compute a**-1 mod oddFactor. */
    +  MP_CHECKOK( s_mp_invmod_odd_m(a, &oddFactor, &oddPart) );
    +  /* compute a**-1 mod evenFactor, where evenFactor == 2**k. */
    +  MP_CHECKOK( s_mp_invmod_2d(   a,       k,    &evenPart) );
    +
    +  /* Use Chinese Remainer theorem to compute a**-1 mod m. */
    +  /* let m1 = oddFactor,  v1 = oddPart,
    +   * let m2 = evenFactor, v2 = evenPart.
    +   */
    +
    +  /* Compute C2 = m1**-1 mod m2. */
    +  MP_CHECKOK( s_mp_invmod_2d(&oddFactor, k,    &C2) );
    +
    +  /* compute u = (v2 - v1)*C2 mod m2 */
    +  MP_CHECKOK( mp_sub(&evenPart, &oddPart,   &tmp1) );
    +  MP_CHECKOK( mp_mul(&tmp1,     &C2,        &tmp2) );
    +  s_mp_mod_2d(&tmp2, k);
    +  while (MP_SIGN(&tmp2) != MP_ZPOS) {
    +    MP_CHECKOK( mp_add(&tmp2, &evenFactor, &tmp2) );
    +  }
    +
    +  /* compute answer = v1 + u*m1 */
    +  MP_CHECKOK( mp_mul(&tmp2,     &oddFactor, c) );
    +  MP_CHECKOK( mp_add(&oddPart,  c,          c) );
    +  /* not sure this is necessary, but it's low cost if not. */
    +  MP_CHECKOK( mp_mod(c,         m,          c) );
    +
    +CLEANUP:
    +  mp_clear(&oddFactor);
    +  mp_clear(&evenFactor);
    +  mp_clear(&oddPart);
    +  mp_clear(&evenPart);
    +  mp_clear(&C2);
    +  mp_clear(&tmp1);
    +  mp_clear(&tmp2);
    +  return res;
    +}
    +
    +
    +/* {{{ mp_invmod(a, m, c) */
    +
    +/*
    +  mp_invmod(a, m, c)
    +
    +  Compute c = a^-1 (mod m), if there is an inverse for a (mod m).
    +  This is equivalent to the question of whether (a, m) = 1.  If not,
    +  MP_UNDEF is returned, and there is no inverse.
    + */
    +
    +mp_err mp_invmod(const mp_int *a, const mp_int *m, mp_int *c)
    +{
    +
    +  ARGCHK(a && m && c, MP_BADARG);
    +
    +  if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
    +    return MP_RANGE;
    +
    +  if (mp_isodd(m)) {
    +    return s_mp_invmod_odd_m(a, m, c);
    +  }
    +  if (mp_iseven(a))
    +    return MP_UNDEF;    /* not invertable */
    +
    +  return s_mp_invmod_even_m(a, m, c);
    +
    +} /* end mp_invmod() */
    +
    +/* }}} */
    +#endif /* if MP_NUMTH */
    +
    +/* }}} */
    +
    +/*------------------------------------------------------------------------*/
    +/* {{{ mp_print(mp, ofp) */
    +
    +#if MP_IOFUNC
    +/*
    +  mp_print(mp, ofp)
    +
    +  Print a textual representation of the given mp_int on the output
    +  stream 'ofp'.  Output is generated using the internal radix.
    + */
    +
    +void   mp_print(mp_int *mp, FILE *ofp)
    +{
    +  int   ix;
    +
    +  if(mp == NULL || ofp == NULL)
    +    return;
    +
    +  fputc((SIGN(mp) == NEG) ? '-' : '+', ofp);
    +
    +  for(ix = USED(mp) - 1; ix >= 0; ix--) {
    +    fprintf(ofp, DIGIT_FMT, DIGIT(mp, ix));
    +  }
    +
    +} /* end mp_print() */
    +
    +#endif /* if MP_IOFUNC */
    +
    +/* }}} */
    +
    +/*------------------------------------------------------------------------*/
    +/* {{{ More I/O Functions */
    +
    +/* {{{ mp_read_raw(mp, str, len) */
    +
    +/*
    +   mp_read_raw(mp, str, len)
    +
    +   Read in a raw value (base 256) into the given mp_int
    + */
    +
    +mp_err  mp_read_raw(mp_int *mp, char *str, int len)
    +{
    +  int            ix;
    +  mp_err         res;
    +  unsigned char *ustr = (unsigned char *)str;
    +
    +  ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG);
    +
    +  mp_zero(mp);
    +
    +  /* Get sign from first byte */
    +  if(ustr[0])
    +    SIGN(mp) = NEG;
    +  else
    +    SIGN(mp) = ZPOS;
    +
    +  /* Read the rest of the digits */
    +  for(ix = 1; ix < len; ix++) {
    +    if((res = mp_mul_d(mp, 256, mp)) != MP_OKAY)
    +      return res;
    +    if((res = mp_add_d(mp, ustr[ix], mp)) != MP_OKAY)
    +      return res;
    +  }
    +
    +  return MP_OKAY;
    +
    +} /* end mp_read_raw() */
    +
    +/* }}} */
    +
    +/* {{{ mp_raw_size(mp) */
    +
    +int    mp_raw_size(mp_int *mp)
    +{
    +  ARGCHK(mp != NULL, 0);
    +
    +  return (USED(mp) * sizeof(mp_digit)) + 1;
    +
    +} /* end mp_raw_size() */
    +
    +/* }}} */
    +
    +/* {{{ mp_toraw(mp, str) */
    +
    +mp_err mp_toraw(mp_int *mp, char *str)
    +{
    +  int  ix, jx, pos = 1;
    +
    +  ARGCHK(mp != NULL && str != NULL, MP_BADARG);
    +
    +  str[0] = (char)SIGN(mp);
    +
    +  /* Iterate over each digit... */
    +  for(ix = USED(mp) - 1; ix >= 0; ix--) {
    +    mp_digit  d = DIGIT(mp, ix);
    +
    +    /* Unpack digit bytes, high order first */
    +    for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {
    +      str[pos++] = (char)(d >> (jx * CHAR_BIT));
    +    }
    +  }
    +
    +  return MP_OKAY;
    +
    +} /* end mp_toraw() */
    +
    +/* }}} */
    +
    +/* {{{ mp_read_radix(mp, str, radix) */
    +
    +/*
    +  mp_read_radix(mp, str, radix)
    +
    +  Read an integer from the given string, and set mp to the resulting
    +  value.  The input is presumed to be in base 10.  Leading non-digit
    +  characters are ignored, and the function reads until a non-digit
    +  character or the end of the string.
    + */
    +
    +mp_err  mp_read_radix(mp_int *mp, const char *str, int radix)
    +{
    +  int     ix = 0, val = 0;
    +  mp_err  res;
    +  mp_sign sig = ZPOS;
    +
    +  ARGCHK(mp != NULL && str != NULL && radix >= 2 && radix <= MAX_RADIX,
    +         MP_BADARG);
    +
    +  mp_zero(mp);
    +
    +  /* Skip leading non-digit characters until a digit or '-' or '+' */
    +  while(str[ix] &&
    +        (s_mp_tovalue(str[ix], radix) < 0) &&
    +        str[ix] != '-' &&
    +        str[ix] != '+') {
    +    ++ix;
    +  }
    +
    +  if(str[ix] == '-') {
    +    sig = NEG;
    +    ++ix;
    +  } else if(str[ix] == '+') {
    +    sig = ZPOS; /* this is the default anyway... */
    +    ++ix;
    +  }
    +
    +  while((val = s_mp_tovalue(str[ix], radix)) >= 0) {
    +    if((res = s_mp_mul_d(mp, radix)) != MP_OKAY)
    +      return res;
    +    if((res = s_mp_add_d(mp, val)) != MP_OKAY)
    +      return res;
    +    ++ix;
    +  }
    +
    +  if(s_mp_cmp_d(mp, 0) == MP_EQ)
    +    SIGN(mp) = ZPOS;
    +  else
    +    SIGN(mp) = sig;
    +
    +  return MP_OKAY;
    +
    +} /* end mp_read_radix() */
    +
    +mp_err mp_read_variable_radix(mp_int *a, const char * str, int default_radix)
    +{
    +  int     radix = default_radix;
    +  int     cx;
    +  mp_sign sig   = ZPOS;
    +  mp_err  res;
    +
    +  /* Skip leading non-digit characters until a digit or '-' or '+' */
    +  while ((cx = *str) != 0 &&
    +        (s_mp_tovalue(cx, radix) < 0) &&
    +        cx != '-' &&
    +        cx != '+') {
    +    ++str;
    +  }
    +
    +  if (cx == '-') {
    +    sig = NEG;
    +    ++str;
    +  } else if (cx == '+') {
    +    sig = ZPOS; /* this is the default anyway... */
    +    ++str;
    +  }
    +
    +  if (str[0] == '0') {
    +    if ((str[1] | 0x20) == 'x') {
    +      radix = 16;
    +      str += 2;
    +    } else {
    +      radix = 8;
    +      str++;
    +    }
    +  }
    +  res = mp_read_radix(a, str, radix);
    +  if (res == MP_OKAY) {
    +    MP_SIGN(a) = (s_mp_cmp_d(a, 0) == MP_EQ) ? ZPOS : sig;
    +  }
    +  return res;
    +}
    +
    +/* }}} */
    +
    +/* {{{ mp_radix_size(mp, radix) */
    +
    +int    mp_radix_size(mp_int *mp, int radix)
    +{
    +  int  bits;
    +
    +  if(!mp || radix < 2 || radix > MAX_RADIX)
    +    return 0;
    +
    +  bits = USED(mp) * DIGIT_BIT - 1;
    +
    +  return s_mp_outlen(bits, radix);
    +
    +} /* end mp_radix_size() */
    +
    +/* }}} */
    +
    +/* {{{ mp_toradix(mp, str, radix) */
    +
    +mp_err mp_toradix(mp_int *mp, char *str, int radix)
    +{
    +  int  ix, pos = 0;
    +
    +  ARGCHK(mp != NULL && str != NULL, MP_BADARG);
    +  ARGCHK(radix > 1 && radix <= MAX_RADIX, MP_RANGE);
    +
    +  if(mp_cmp_z(mp) == MP_EQ) {
    +    str[0] = '0';
    +    str[1] = '\0';
    +  } else {
    +    mp_err   res;
    +    mp_int   tmp;
    +    mp_sign  sgn;
    +    mp_digit rem, rdx = (mp_digit)radix;
    +    char     ch;
    +
    +    if((res = mp_init_copy(&tmp, mp)) != MP_OKAY)
    +      return res;
    +
    +    /* Save sign for later, and take absolute value */
    +    sgn = SIGN(&tmp); SIGN(&tmp) = ZPOS;
    +
    +    /* Generate output digits in reverse order      */
    +    while(mp_cmp_z(&tmp) != 0) {
    +      if((res = mp_div_d(&tmp, rdx, &tmp, &rem)) != MP_OKAY) {
    +        mp_clear(&tmp);
    +        return res;
    +      }
    +
    +      /* Generate digits, use capital letters */
    +      ch = s_mp_todigit(rem, radix, 0);
    +
    +      str[pos++] = ch;
    +    }
    +
    +    /* Add - sign if original value was negative */
    +    if(sgn == NEG)
    +      str[pos++] = '-';
    +
    +    /* Add trailing NUL to end the string        */
    +    str[pos--] = '\0';
    +
    +    /* Reverse the digits and sign indicator     */
    +    ix = 0;
    +    while(ix < pos) {
    +      char tmp = str[ix];
    +
    +      str[ix] = str[pos];
    +      str[pos] = tmp;
    +      ++ix;
    +      --pos;
    +    }
    +
    +    mp_clear(&tmp);
    +  }
    +
    +  return MP_OKAY;
    +
    +} /* end mp_toradix() */
    +
    +/* }}} */
    +
    +/* {{{ mp_tovalue(ch, r) */
    +
    +int    mp_tovalue(char ch, int r)
    +{
    +  return s_mp_tovalue(ch, r);
    +
    +} /* end mp_tovalue() */
    +
    +/* }}} */
    +
    +/* }}} */
    +
    +/* {{{ mp_strerror(ec) */
    +
    +/*
    +  mp_strerror(ec)
    +
    +  Return a string describing the meaning of error code 'ec'.  The
    +  string returned is allocated in static memory, so the caller should
    +  not attempt to modify or free the memory associated with this
    +  string.
    + */
    +const char  *mp_strerror(mp_err ec)
    +{
    +  int   aec = (ec < 0) ? -ec : ec;
    +
    +  /* Code values are negative, so the senses of these comparisons
    +     are accurate */
    +  if(ec < MP_LAST_CODE || ec > MP_OKAY) {
    +    return mp_err_string[0];  /* unknown error code */
    +  } else {
    +    return mp_err_string[aec + 1];
    +  }
    +
    +} /* end mp_strerror() */
    +
    +/* }}} */
    +
    +/*========================================================================*/
    +/*------------------------------------------------------------------------*/
    +/* Static function definitions (internal use only)                        */
    +
    +/* {{{ Memory management */
    +
    +/* {{{ s_mp_grow(mp, min) */
    +
    +/* Make sure there are at least 'min' digits allocated to mp              */
    +mp_err   s_mp_grow(mp_int *mp, mp_size min)
    +{
    +  if(min > ALLOC(mp)) {
    +    mp_digit   *tmp;
    +
    +    /* Set min to next nearest default precision block size */
    +    min = MP_ROUNDUP(min, s_mp_defprec);
    +
    +    if((tmp = s_mp_alloc(min, sizeof(mp_digit), FLAG(mp))) == NULL)
    +      return MP_MEM;
    +
    +    s_mp_copy(DIGITS(mp), tmp, USED(mp));
    +
    +#if MP_CRYPTO
    +    s_mp_setz(DIGITS(mp), ALLOC(mp));
    +#endif
    +    s_mp_free(DIGITS(mp), ALLOC(mp));
    +    DIGITS(mp) = tmp;
    +    ALLOC(mp) = min;
    +  }
    +
    +  return MP_OKAY;
    +
    +} /* end s_mp_grow() */
    +
    +/* }}} */
    +
    +/* {{{ s_mp_pad(mp, min) */
    +
    +/* Make sure the used size of mp is at least 'min', growing if needed     */
    +mp_err   s_mp_pad(mp_int *mp, mp_size min)
    +{
    +  if(min > USED(mp)) {
    +    mp_err  res;
    +
    +    /* Make sure there is room to increase precision  */
    +    if (min > ALLOC(mp)) {
    +      if ((res = s_mp_grow(mp, min)) != MP_OKAY)
    +        return res;
    +    } else {
    +      s_mp_setz(DIGITS(mp) + USED(mp), min - USED(mp));
    +    }
    +
    +    /* Increase precision; should already be 0-filled */
    +    USED(mp) = min;
    +  }
    +
    +  return MP_OKAY;
    +
    +} /* end s_mp_pad() */
    +
    +/* }}} */
    +
    +/* {{{ s_mp_setz(dp, count) */
    +
    +#if MP_MACRO == 0
    +/* Set 'count' digits pointed to by dp to be zeroes                       */
    +void s_mp_setz(mp_digit *dp, mp_size count)
    +{
    +#if MP_MEMSET == 0
    +  int  ix;
    +
    +  for(ix = 0; ix < count; ix++)
    +    dp[ix] = 0;
    +#else
    +  memset(dp, 0, count * sizeof(mp_digit));
    +#endif
    +
    +} /* end s_mp_setz() */
    +#endif
    +
    +/* }}} */
    +
    +/* {{{ s_mp_copy(sp, dp, count) */
    +
    +#if MP_MACRO == 0
    +/* Copy 'count' digits from sp to dp                                      */
    +void s_mp_copy(const mp_digit *sp, mp_digit *dp, mp_size count)
    +{
    +#if MP_MEMCPY == 0
    +  int  ix;
    +
    +  for(ix = 0; ix < count; ix++)
    +    dp[ix] = sp[ix];
    +#else
    +  memcpy(dp, sp, count * sizeof(mp_digit));
    +#endif
    +
    +} /* end s_mp_copy() */
    +#endif
    +
    +/* }}} */
    +
    +/* {{{ s_mp_alloc(nb, ni, kmflag) */
    +
    +#if MP_MACRO == 0
    +/* Allocate ni records of nb bytes each, and return a pointer to that     */
    +void    *s_mp_alloc(size_t nb, size_t ni, int kmflag)
    +{
    +  mp_int *mp;
    +  ++mp_allocs;
    +#ifdef _KERNEL
    +  mp = kmem_zalloc(nb * ni, kmflag);
    +  if (mp != NULL)
    +    FLAG(mp) = kmflag;
    +  return (mp);
    +#else
    +  return calloc(nb, ni);
    +#endif
    +
    +} /* end s_mp_alloc() */
    +#endif
    +
    +/* }}} */
    +
    +/* {{{ s_mp_free(ptr) */
    +
    +#if MP_MACRO == 0
    +/* Free the memory pointed to by ptr                                      */
    +void     s_mp_free(void *ptr, mp_size alloc)
    +{
    +  if(ptr) {
    +    ++mp_frees;
    +#ifdef _KERNEL
    +    kmem_free(ptr, alloc * sizeof (mp_digit));
    +#else
    +    free(ptr);
    +#endif
    +  }
    +} /* end s_mp_free() */
    +#endif
    +
    +/* }}} */
    +
    +/* {{{ s_mp_clamp(mp) */
    +
    +#if MP_MACRO == 0
    +/* Remove leading zeroes from the given value                             */
    +void     s_mp_clamp(mp_int *mp)
    +{
    +  mp_size used = MP_USED(mp);
    +  while (used > 1 && DIGIT(mp, used - 1) == 0)
    +    --used;
    +  MP_USED(mp) = used;
    +} /* end s_mp_clamp() */
    +#endif
    +
    +/* }}} */
    +
    +/* {{{ s_mp_exch(a, b) */
    +
    +/* Exchange the data for a and b; (b, a) = (a, b)                         */
    +void     s_mp_exch(mp_int *a, mp_int *b)
    +{
    +  mp_int   tmp;
    +
    +  tmp = *a;
    +  *a = *b;
    +  *b = tmp;
    +
    +} /* end s_mp_exch() */
    +
    +/* }}} */
    +
    +/* }}} */
    +
    +/* {{{ Arithmetic helpers */
    +
    +/* {{{ s_mp_lshd(mp, p) */
    +
    +/*
    +   Shift mp leftward by p digits, growing if needed, and zero-filling
    +   the in-shifted digits at the right end.  This is a convenient
    +   alternative to multiplication by powers of the radix
    +   The value of USED(mp) must already have been set to the value for
    +   the shifted result.
    + */
    +
    +mp_err   s_mp_lshd(mp_int *mp, mp_size p)
    +{
    +  mp_err  res;
    +  mp_size pos;
    +  int     ix;
    +
    +  if(p == 0)
    +    return MP_OKAY;
    +
    +  if (MP_USED(mp) == 1 && MP_DIGIT(mp, 0) == 0)
    +    return MP_OKAY;
    +
    +  if((res = s_mp_pad(mp, USED(mp) + p)) != MP_OKAY)
    +    return res;
    +
    +  pos = USED(mp) - 1;
    +
    +  /* Shift all the significant figures over as needed */
    +  for(ix = pos - p; ix >= 0; ix--)
    +    DIGIT(mp, ix + p) = DIGIT(mp, ix);
    +
    +  /* Fill the bottom digits with zeroes */
    +  for(ix = 0; ix < p; ix++)
    +    DIGIT(mp, ix) = 0;
    +
    +  return MP_OKAY;
    +
    +} /* end s_mp_lshd() */
    +
    +/* }}} */
    +
    +/* {{{ s_mp_mul_2d(mp, d) */
    +
    +/*
    +  Multiply the integer by 2^d, where d is a number of bits.  This
    +  amounts to a bitwise shift of the value.
    + */
    +mp_err   s_mp_mul_2d(mp_int *mp, mp_digit d)
    +{
    +  mp_err   res;
    +  mp_digit dshift, bshift;
    +  mp_digit mask;
    +
    +  ARGCHK(mp != NULL,  MP_BADARG);
    +
    +  dshift = d / MP_DIGIT_BIT;
    +  bshift = d % MP_DIGIT_BIT;
    +  /* bits to be shifted out of the top word */
    +  mask   = ((mp_digit)~0 << (MP_DIGIT_BIT - bshift));
    +  mask  &= MP_DIGIT(mp, MP_USED(mp) - 1);
    +
    +  if (MP_OKAY != (res = s_mp_pad(mp, MP_USED(mp) + dshift + (mask != 0) )))
    +    return res;
    +
    +  if (dshift && MP_OKAY != (res = s_mp_lshd(mp, dshift)))
    +    return res;
    +
    +  if (bshift) {
    +    mp_digit *pa = MP_DIGITS(mp);
    +    mp_digit *alim = pa + MP_USED(mp);
    +    mp_digit  prev = 0;
    +
    +    for (pa += dshift; pa < alim; ) {
    +      mp_digit x = *pa;
    +      *pa++ = (x << bshift) | prev;
    +      prev = x >> (DIGIT_BIT - bshift);
    +    }
    +  }
    +
    +  s_mp_clamp(mp);
    +  return MP_OKAY;
    +} /* end s_mp_mul_2d() */
    +
    +/* {{{ s_mp_rshd(mp, p) */
    +
    +/*
    +   Shift mp rightward by p digits.  Maintains the invariant that
    +   digits above the precision are all zero.  Digits shifted off the
    +   end are lost.  Cannot fail.
    + */
    +
    +void     s_mp_rshd(mp_int *mp, mp_size p)
    +{
    +  mp_size  ix;
    +  mp_digit *src, *dst;
    +
    +  if(p == 0)
    +    return;
    +
    +  /* Shortcut when all digits are to be shifted off */
    +  if(p >= USED(mp)) {
    +    s_mp_setz(DIGITS(mp), ALLOC(mp));
    +    USED(mp) = 1;
    +    SIGN(mp) = ZPOS;
    +    return;
    +  }
    +
    +  /* Shift all the significant figures over as needed */
    +  dst = MP_DIGITS(mp);
    +  src = dst + p;
    +  for (ix = USED(mp) - p; ix > 0; ix--)
    +    *dst++ = *src++;
    +
    +  MP_USED(mp) -= p;
    +  /* Fill the top digits with zeroes */
    +  while (p-- > 0)
    +    *dst++ = 0;
    +
    +#if 0
    +  /* Strip off any leading zeroes    */
    +  s_mp_clamp(mp);
    +#endif
    +
    +} /* end s_mp_rshd() */
    +
    +/* }}} */
    +
    +/* {{{ s_mp_div_2(mp) */
    +
    +/* Divide by two -- take advantage of radix properties to do it fast      */
    +void     s_mp_div_2(mp_int *mp)
    +{
    +  s_mp_div_2d(mp, 1);
    +
    +} /* end s_mp_div_2() */
    +
    +/* }}} */
    +
    +/* {{{ s_mp_mul_2(mp) */
    +
    +mp_err s_mp_mul_2(mp_int *mp)
    +{
    +  mp_digit *pd;
    +  int      ix, used;
    +  mp_digit kin = 0;
    +
    +  /* Shift digits leftward by 1 bit */
    +  used = MP_USED(mp);
    +  pd = MP_DIGITS(mp);
    +  for (ix = 0; ix < used; ix++) {
    +    mp_digit d = *pd;
    +    *pd++ = (d << 1) | kin;
    +    kin = (d >> (DIGIT_BIT - 1));
    +  }
    +
    +  /* Deal with rollover from last digit */
    +  if (kin) {
    +    if (ix >= ALLOC(mp)) {
    +      mp_err res;
    +      if((res = s_mp_grow(mp, ALLOC(mp) + 1)) != MP_OKAY)
    +        return res;
    +    }
    +
    +    DIGIT(mp, ix) = kin;
    +    USED(mp) += 1;
    +  }
    +
    +  return MP_OKAY;
    +
    +} /* end s_mp_mul_2() */
    +
    +/* }}} */
    +
    +/* {{{ s_mp_mod_2d(mp, d) */
    +
    +/*
    +  Remainder the integer by 2^d, where d is a number of bits.  This
    +  amounts to a bitwise AND of the value, and does not require the full
    +  division code
    + */
    +void     s_mp_mod_2d(mp_int *mp, mp_digit d)
    +{
    +  mp_size  ndig = (d / DIGIT_BIT), nbit = (d % DIGIT_BIT);
    +  mp_size  ix;
    +  mp_digit dmask;
    +
    +  if(ndig >= USED(mp))
    +    return;
    +
    +  /* Flush all the bits above 2^d in its digit */
    +  dmask = ((mp_digit)1 << nbit) - 1;
    +  DIGIT(mp, ndig) &= dmask;
    +
    +  /* Flush all digits above the one with 2^d in it */
    +  for(ix = ndig + 1; ix < USED(mp); ix++)
    +    DIGIT(mp, ix) = 0;
    +
    +  s_mp_clamp(mp);
    +
    +} /* end s_mp_mod_2d() */
    +
    +/* }}} */
    +
    +/* {{{ s_mp_div_2d(mp, d) */
    +
    +/*
    +  Divide the integer by 2^d, where d is a number of bits.  This
    +  amounts to a bitwise shift of the value, and does not require the
    +  full division code (used in Barrett reduction, see below)
    + */
    +void     s_mp_div_2d(mp_int *mp, mp_digit d)
    +{
    +  int       ix;
    +  mp_digit  save, next, mask;
    +
    +  s_mp_rshd(mp, d / DIGIT_BIT);
    +  d %= DIGIT_BIT;
    +  if (d) {
    +    mask = ((mp_digit)1 << d) - 1;
    +    save = 0;
    +    for(ix = USED(mp) - 1; ix >= 0; ix--) {
    +      next = DIGIT(mp, ix) & mask;
    +      DIGIT(mp, ix) = (DIGIT(mp, ix) >> d) | (save << (DIGIT_BIT - d));
    +      save = next;
    +    }
    +  }
    +  s_mp_clamp(mp);
    +
    +} /* end s_mp_div_2d() */
    +
    +/* }}} */
    +
    +/* {{{ s_mp_norm(a, b, *d) */
    +
    +/*
    +  s_mp_norm(a, b, *d)
    +
    +  Normalize a and b for division, where b is the divisor.  In order
    +  that we might make good guesses for quotient digits, we want the
    +  leading digit of b to be at least half the radix, which we
    +  accomplish by multiplying a and b by a power of 2.  The exponent
    +  (shift count) is placed in *pd, so that the remainder can be shifted
    +  back at the end of the division process.
    + */
    +
    +mp_err   s_mp_norm(mp_int *a, mp_int *b, mp_digit *pd)
    +{
    +  mp_digit  d;
    +  mp_digit  mask;
    +  mp_digit  b_msd;
    +  mp_err    res    = MP_OKAY;
    +
    +  d = 0;
    +  mask  = DIGIT_MAX & ~(DIGIT_MAX >> 1);        /* mask is msb of digit */
    +  b_msd = DIGIT(b, USED(b) - 1);
    +  while (!(b_msd & mask)) {
    +    b_msd <<= 1;
    +    ++d;
    +  }
    +
    +  if (d) {
    +    MP_CHECKOK( s_mp_mul_2d(a, d) );
    +    MP_CHECKOK( s_mp_mul_2d(b, d) );
    +  }
    +
    +  *pd = d;
    +CLEANUP:
    +  return res;
    +
    +} /* end s_mp_norm() */
    +
    +/* }}} */
    +
    +/* }}} */
    +
    +/* {{{ Primitive digit arithmetic */
    +
    +/* {{{ s_mp_add_d(mp, d) */
    +
    +/* Add d to |mp| in place                                                 */
    +mp_err   s_mp_add_d(mp_int *mp, mp_digit d)    /* unsigned digit addition */
    +{
    +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
    +  mp_word   w, k = 0;
    +  mp_size   ix = 1;
    +
    +  w = (mp_word)DIGIT(mp, 0) + d;
    +  DIGIT(mp, 0) = ACCUM(w);
    +  k = CARRYOUT(w);
    +
    +  while(ix < USED(mp) && k) {
    +    w = (mp_word)DIGIT(mp, ix) + k;
    +    DIGIT(mp, ix) = ACCUM(w);
    +    k = CARRYOUT(w);
    +    ++ix;
    +  }
    +
    +  if(k != 0) {
    +    mp_err  res;
    +
    +    if((res = s_mp_pad(mp, USED(mp) + 1)) != MP_OKAY)
    +      return res;
    +
    +    DIGIT(mp, ix) = (mp_digit)k;
    +  }
    +
    +  return MP_OKAY;
    +#else
    +  mp_digit * pmp = MP_DIGITS(mp);
    +  mp_digit sum, mp_i, carry = 0;
    +  mp_err   res = MP_OKAY;
    +  int used = (int)MP_USED(mp);
    +
    +  mp_i = *pmp;
    +  *pmp++ = sum = d + mp_i;
    +  carry = (sum < d);
    +  while (carry && --used > 0) {
    +    mp_i = *pmp;
    +    *pmp++ = sum = carry + mp_i;
    +    carry = !sum;
    +  }
    +  if (carry && !used) {
    +    /* mp is growing */
    +    used = MP_USED(mp);
    +    MP_CHECKOK( s_mp_pad(mp, used + 1) );
    +    MP_DIGIT(mp, used) = carry;
    +  }
    +CLEANUP:
    +  return res;
    +#endif
    +} /* end s_mp_add_d() */
    +
    +/* }}} */
    +
    +/* {{{ s_mp_sub_d(mp, d) */
    +
    +/* Subtract d from |mp| in place, assumes |mp| > d                        */
    +mp_err   s_mp_sub_d(mp_int *mp, mp_digit d)    /* unsigned digit subtract */
    +{
    +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
    +  mp_word   w, b = 0;
    +  mp_size   ix = 1;
    +
    +  /* Compute initial subtraction    */
    +  w = (RADIX + (mp_word)DIGIT(mp, 0)) - d;
    +  b = CARRYOUT(w) ? 0 : 1;
    +  DIGIT(mp, 0) = ACCUM(w);
    +
    +  /* Propagate borrows leftward     */
    +  while(b && ix < USED(mp)) {
    +    w = (RADIX + (mp_word)DIGIT(mp, ix)) - b;
    +    b = CARRYOUT(w) ? 0 : 1;
    +    DIGIT(mp, ix) = ACCUM(w);
    +    ++ix;
    +  }
    +
    +  /* Remove leading zeroes          */
    +  s_mp_clamp(mp);
    +
    +  /* If we have a borrow out, it's a violation of the input invariant */
    +  if(b)
    +    return MP_RANGE;
    +  else
    +    return MP_OKAY;
    +#else
    +  mp_digit *pmp = MP_DIGITS(mp);
    +  mp_digit mp_i, diff, borrow;
    +  mp_size  used = MP_USED(mp);
    +
    +  mp_i = *pmp;
    +  *pmp++ = diff = mp_i - d;
    +  borrow = (diff > mp_i);
    +  while (borrow && --used) {
    +    mp_i = *pmp;
    +    *pmp++ = diff = mp_i - borrow;
    +    borrow = (diff > mp_i);
    +  }
    +  s_mp_clamp(mp);
    +  return (borrow && !used) ? MP_RANGE : MP_OKAY;
    +#endif
    +} /* end s_mp_sub_d() */
    +
    +/* }}} */
    +
    +/* {{{ s_mp_mul_d(a, d) */
    +
    +/* Compute a = a * d, single digit multiplication                         */
    +mp_err   s_mp_mul_d(mp_int *a, mp_digit d)
    +{
    +  mp_err  res;
    +  mp_size used;
    +  int     pow;
    +
    +  if (!d) {
    +    mp_zero(a);
    +    return MP_OKAY;
    +  }
    +  if (d == 1)
    +    return MP_OKAY;
    +  if (0 <= (pow = s_mp_ispow2d(d))) {
    +    return s_mp_mul_2d(a, (mp_digit)pow);
    +  }
    +
    +  used = MP_USED(a);
    +  MP_CHECKOK( s_mp_pad(a, used + 1) );
    +
    +  s_mpv_mul_d(MP_DIGITS(a), used, d, MP_DIGITS(a));
    +
    +  s_mp_clamp(a);
    +
    +CLEANUP:
    +  return res;
    +
    +} /* end s_mp_mul_d() */
    +
    +/* }}} */
    +
    +/* {{{ s_mp_div_d(mp, d, r) */
    +
    +/*
    +  s_mp_div_d(mp, d, r)
    +
    +  Compute the quotient mp = mp / d and remainder r = mp mod d, for a
    +  single digit d.  If r is null, the remainder will be discarded.
    + */
    +
    +mp_err   s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r)
    +{
    +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
    +  mp_word   w = 0, q;
    +#else
    +  mp_digit  w, q;
    +#endif
    +  int       ix;
    +  mp_err    res;
    +  mp_int    quot;
    +  mp_int    rem;
    +
    +  if(d == 0)
    +    return MP_RANGE;
    +  if (d == 1) {
    +    if (r)
    +      *r = 0;
    +    return MP_OKAY;
    +  }
    +  /* could check for power of 2 here, but mp_div_d does that. */
    +  if (MP_USED(mp) == 1) {
    +    mp_digit n   = MP_DIGIT(mp,0);
    +    mp_digit rem;
    +
    +    q   = n / d;
    +    rem = n % d;
    +    MP_DIGIT(mp,0) = q;
    +    if (r)
    +      *r = rem;
    +    return MP_OKAY;
    +  }
    +
    +  MP_DIGITS(&rem)  = 0;
    +  MP_DIGITS(") = 0;
    +  /* Make room for the quotient */
    +  MP_CHECKOK( mp_init_size(", USED(mp), FLAG(mp)) );
    +
    +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
    +  for(ix = USED(mp) - 1; ix >= 0; ix--) {
    +    w = (w << DIGIT_BIT) | DIGIT(mp, ix);
    +
    +    if(w >= d) {
    +      q = w / d;
    +      w = w % d;
    +    } else {
    +      q = 0;
    +    }
    +
    +    s_mp_lshd(", 1);
    +    DIGIT(", 0) = (mp_digit)q;
    +  }
    +#else
    +  {
    +    mp_digit p;
    +#if !defined(MP_ASSEMBLY_DIV_2DX1D)
    +    mp_digit norm;
    +#endif
    +
    +    MP_CHECKOK( mp_init_copy(&rem, mp) );
    +
    +#if !defined(MP_ASSEMBLY_DIV_2DX1D)
    +    MP_DIGIT(", 0) = d;
    +    MP_CHECKOK( s_mp_norm(&rem, ", &norm) );
    +    if (norm)
    +      d <<= norm;
    +    MP_DIGIT(", 0) = 0;
    +#endif
    +
    +    p = 0;
    +    for (ix = USED(&rem) - 1; ix >= 0; ix--) {
    +      w = DIGIT(&rem, ix);
    +
    +      if (p) {
    +        MP_CHECKOK( s_mpv_div_2dx1d(p, w, d, &q, &w) );
    +      } else if (w >= d) {
    +        q = w / d;
    +        w = w % d;
    +      } else {
    +        q = 0;
    +      }
    +
    +      MP_CHECKOK( s_mp_lshd(", 1) );
    +      DIGIT(", 0) = q;
    +      p = w;
    +    }
    +#if !defined(MP_ASSEMBLY_DIV_2DX1D)
    +    if (norm)
    +      w >>= norm;
    +#endif
    +  }
    +#endif
    +
    +  /* Deliver the remainder, if desired */
    +  if(r)
    +    *r = (mp_digit)w;
    +
    +  s_mp_clamp(");
    +  mp_exch(", mp);
    +CLEANUP:
    +  mp_clear(");
    +  mp_clear(&rem);
    +
    +  return res;
    +} /* end s_mp_div_d() */
    +
    +/* }}} */
    +
    +
    +/* }}} */
    +
    +/* {{{ Primitive full arithmetic */
    +
    +/* {{{ s_mp_add(a, b) */
    +
    +/* Compute a = |a| + |b|                                                  */
    +mp_err   s_mp_add(mp_int *a, const mp_int *b)  /* magnitude addition      */
    +{
    +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
    +  mp_word   w = 0;
    +#else
    +  mp_digit  d, sum, carry = 0;
    +#endif
    +  mp_digit *pa, *pb;
    +  mp_size   ix;
    +  mp_size   used;
    +  mp_err    res;
    +
    +  /* Make sure a has enough precision for the output value */
    +  if((USED(b) > USED(a)) && (res = s_mp_pad(a, USED(b))) != MP_OKAY)
    +    return res;
    +
    +  /*
    +    Add up all digits up to the precision of b.  If b had initially
    +    the same precision as a, or greater, we took care of it by the
    +    padding step above, so there is no problem.  If b had initially
    +    less precision, we'll have to make sure the carry out is duly
    +    propagated upward among the higher-order digits of the sum.
    +   */
    +  pa = MP_DIGITS(a);
    +  pb = MP_DIGITS(b);
    +  used = MP_USED(b);
    +  for(ix = 0; ix < used; ix++) {
    +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
    +    w = w + *pa + *pb++;
    +    *pa++ = ACCUM(w);
    +    w = CARRYOUT(w);
    +#else
    +    d = *pa;
    +    sum = d + *pb++;
    +    d = (sum < d);                      /* detect overflow */
    +    *pa++ = sum += carry;
    +    carry = d + (sum < carry);          /* detect overflow */
    +#endif
    +  }
    +
    +  /* If we run out of 'b' digits before we're actually done, make
    +     sure the carries get propagated upward...
    +   */
    +  used = MP_USED(a);
    +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
    +  while (w && ix < used) {
    +    w = w + *pa;
    +    *pa++ = ACCUM(w);
    +    w = CARRYOUT(w);
    +    ++ix;
    +  }
    +#else
    +  while (carry && ix < used) {
    +    sum = carry + *pa;
    +    *pa++ = sum;
    +    carry = !sum;
    +    ++ix;
    +  }
    +#endif
    +
    +  /* If there's an overall carry out, increase precision and include
    +     it.  We could have done this initially, but why touch the memory
    +     allocator unless we're sure we have to?
    +   */
    +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
    +  if (w) {
    +    if((res = s_mp_pad(a, used + 1)) != MP_OKAY)
    +      return res;
    +
    +    DIGIT(a, ix) = (mp_digit)w;
    +  }
    +#else
    +  if (carry) {
    +    if((res = s_mp_pad(a, used + 1)) != MP_OKAY)
    +      return res;
    +
    +    DIGIT(a, used) = carry;
    +  }
    +#endif
    +
    +  return MP_OKAY;
    +} /* end s_mp_add() */
    +
    +/* }}} */
    +
    +/* Compute c = |a| + |b|         */ /* magnitude addition      */
    +mp_err   s_mp_add_3arg(const mp_int *a, const mp_int *b, mp_int *c)
    +{
    +  mp_digit *pa, *pb, *pc;
    +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
    +  mp_word   w = 0;
    +#else
    +  mp_digit  sum, carry = 0, d;
    +#endif
    +  mp_size   ix;
    +  mp_size   used;
    +  mp_err    res;
    +
    +  MP_SIGN(c) = MP_SIGN(a);
    +  if (MP_USED(a) < MP_USED(b)) {
    +    const mp_int *xch = a;
    +    a = b;
    +    b = xch;
    +  }
    +
    +  /* Make sure a has enough precision for the output value */
    +  if (MP_OKAY != (res = s_mp_pad(c, MP_USED(a))))
    +    return res;
    +
    +  /*
    +    Add up all digits up to the precision of b.  If b had initially
    +    the same precision as a, or greater, we took care of it by the
    +    exchange step above, so there is no problem.  If b had initially
    +    less precision, we'll have to make sure the carry out is duly
    +    propagated upward among the higher-order digits of the sum.
    +   */
    +  pa = MP_DIGITS(a);
    +  pb = MP_DIGITS(b);
    +  pc = MP_DIGITS(c);
    +  used = MP_USED(b);
    +  for (ix = 0; ix < used; ix++) {
    +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
    +    w = w + *pa++ + *pb++;
    +    *pc++ = ACCUM(w);
    +    w = CARRYOUT(w);
    +#else
    +    d = *pa++;
    +    sum = d + *pb++;
    +    d = (sum < d);                      /* detect overflow */
    +    *pc++ = sum += carry;
    +    carry = d + (sum < carry);          /* detect overflow */
    +#endif
    +  }
    +
    +  /* If we run out of 'b' digits before we're actually done, make
    +     sure the carries get propagated upward...
    +   */
    +  for (used = MP_USED(a); ix < used; ++ix) {
    +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
    +    w = w + *pa++;
    +    *pc++ = ACCUM(w);
    +    w = CARRYOUT(w);
    +#else
    +    *pc++ = sum = carry + *pa++;
    +    carry = (sum < carry);
    +#endif
    +  }
    +
    +  /* If there's an overall carry out, increase precision and include
    +     it.  We could have done this initially, but why touch the memory
    +     allocator unless we're sure we have to?
    +   */
    +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
    +  if (w) {
    +    if((res = s_mp_pad(c, used + 1)) != MP_OKAY)
    +      return res;
    +
    +    DIGIT(c, used) = (mp_digit)w;
    +    ++used;
    +  }
    +#else
    +  if (carry) {
    +    if((res = s_mp_pad(c, used + 1)) != MP_OKAY)
    +      return res;
    +
    +    DIGIT(c, used) = carry;
    +    ++used;
    +  }
    +#endif
    +  MP_USED(c) = used;
    +  return MP_OKAY;
    +}
    +/* {{{ s_mp_add_offset(a, b, offset) */
    +
    +/* Compute a = |a| + ( |b| * (RADIX ** offset) )             */
    +mp_err   s_mp_add_offset(mp_int *a, mp_int *b, mp_size offset)
    +{
    +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
    +  mp_word   w, k = 0;
    +#else
    +  mp_digit  d, sum, carry = 0;
    +#endif
    +  mp_size   ib;
    +  mp_size   ia;
    +  mp_size   lim;
    +  mp_err    res;
    +
    +  /* Make sure a has enough precision for the output value */
    +  lim = MP_USED(b) + offset;
    +  if((lim > USED(a)) && (res = s_mp_pad(a, lim)) != MP_OKAY)
    +    return res;
    +
    +  /*
    +    Add up all digits up to the precision of b.  If b had initially
    +    the same precision as a, or greater, we took care of it by the
    +    padding step above, so there is no problem.  If b had initially
    +    less precision, we'll have to make sure the carry out is duly
    +    propagated upward among the higher-order digits of the sum.
    +   */
    +  lim = USED(b);
    +  for(ib = 0, ia = offset; ib < lim; ib++, ia++) {
    +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
    +    w = (mp_word)DIGIT(a, ia) + DIGIT(b, ib) + k;
    +    DIGIT(a, ia) = ACCUM(w);
    +    k = CARRYOUT(w);
    +#else
    +    d = MP_DIGIT(a, ia);
    +    sum = d + MP_DIGIT(b, ib);
    +    d = (sum < d);
    +    MP_DIGIT(a,ia) = sum += carry;
    +    carry = d + (sum < carry);
    +#endif
    +  }
    +
    +  /* If we run out of 'b' digits before we're actually done, make
    +     sure the carries get propagated upward...
    +   */
    +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
    +  for (lim = MP_USED(a); k && (ia < lim); ++ia) {
    +    w = (mp_word)DIGIT(a, ia) + k;
    +    DIGIT(a, ia) = ACCUM(w);
    +    k = CARRYOUT(w);
    +  }
    +#else
    +  for (lim = MP_USED(a); carry && (ia < lim); ++ia) {
    +    d = MP_DIGIT(a, ia);
    +    MP_DIGIT(a,ia) = sum = d + carry;
    +    carry = (sum < d);
    +  }
    +#endif
    +
    +  /* If there's an overall carry out, increase precision and include
    +     it.  We could have done this initially, but why touch the memory
    +     allocator unless we're sure we have to?
    +   */
    +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
    +  if(k) {
    +    if((res = s_mp_pad(a, USED(a) + 1)) != MP_OKAY)
    +      return res;
    +
    +    DIGIT(a, ia) = (mp_digit)k;
    +  }
    +#else
    +  if (carry) {
    +    if((res = s_mp_pad(a, lim + 1)) != MP_OKAY)
    +      return res;
    +
    +    DIGIT(a, lim) = carry;
    +  }
    +#endif
    +  s_mp_clamp(a);
    +
    +  return MP_OKAY;
    +
    +} /* end s_mp_add_offset() */
    +
    +/* }}} */
    +
    +/* {{{ s_mp_sub(a, b) */
    +
    +/* Compute a = |a| - |b|, assumes |a| >= |b|                              */
    +mp_err   s_mp_sub(mp_int *a, const mp_int *b)  /* magnitude subtract      */
    +{
    +  mp_digit *pa, *pb, *limit;
    +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
    +  mp_sword  w = 0;
    +#else
    +  mp_digit  d, diff, borrow = 0;
    +#endif
    +
    +  /*
    +    Subtract and propagate borrow.  Up to the precision of b, this
    +    accounts for the digits of b; after that, we just make sure the
    +    carries get to the right place.  This saves having to pad b out to
    +    the precision of a just to make the loops work right...
    +   */
    +  pa = MP_DIGITS(a);
    +  pb = MP_DIGITS(b);
    +  limit = pb + MP_USED(b);
    +  while (pb < limit) {
    +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
    +    w = w + *pa - *pb++;
    +    *pa++ = ACCUM(w);
    +    w >>= MP_DIGIT_BIT;
    +#else
    +    d = *pa;
    +    diff = d - *pb++;
    +    d = (diff > d);                             /* detect borrow */
    +    if (borrow && --diff == MP_DIGIT_MAX)
    +      ++d;
    +    *pa++ = diff;
    +    borrow = d;
    +#endif
    +  }
    +  limit = MP_DIGITS(a) + MP_USED(a);
    +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
    +  while (w && pa < limit) {
    +    w = w + *pa;
    +    *pa++ = ACCUM(w);
    +    w >>= MP_DIGIT_BIT;
    +  }
    +#else
    +  while (borrow && pa < limit) {
    +    d = *pa;
    +    *pa++ = diff = d - borrow;
    +    borrow = (diff > d);
    +  }
    +#endif
    +
    +  /* Clobber any leading zeroes we created    */
    +  s_mp_clamp(a);
    +
    +  /*
    +     If there was a borrow out, then |b| > |a| in violation
    +     of our input invariant.  We've already done the work,
    +     but we'll at least complain about it...
    +   */
    +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
    +  return w ? MP_RANGE : MP_OKAY;
    +#else
    +  return borrow ? MP_RANGE : MP_OKAY;
    +#endif
    +} /* end s_mp_sub() */
    +
    +/* }}} */
    +
    +/* Compute c = |a| - |b|, assumes |a| >= |b| */ /* magnitude subtract      */
    +mp_err   s_mp_sub_3arg(const mp_int *a, const mp_int *b, mp_int *c)
    +{
    +  mp_digit *pa, *pb, *pc;
    +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
    +  mp_sword  w = 0;
    +#else
    +  mp_digit  d, diff, borrow = 0;
    +#endif
    +  int       ix, limit;
    +  mp_err    res;
    +
    +  MP_SIGN(c) = MP_SIGN(a);
    +
    +  /* Make sure a has enough precision for the output value */
    +  if (MP_OKAY != (res = s_mp_pad(c, MP_USED(a))))
    +    return res;
    +
    +  /*
    +    Subtract and propagate borrow.  Up to the precision of b, this
    +    accounts for the digits of b; after that, we just make sure the
    +    carries get to the right place.  This saves having to pad b out to
    +    the precision of a just to make the loops work right...
    +   */
    +  pa = MP_DIGITS(a);
    +  pb = MP_DIGITS(b);
    +  pc = MP_DIGITS(c);
    +  limit = MP_USED(b);
    +  for (ix = 0; ix < limit; ++ix) {
    +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
    +    w = w + *pa++ - *pb++;
    +    *pc++ = ACCUM(w);
    +    w >>= MP_DIGIT_BIT;
    +#else
    +    d = *pa++;
    +    diff = d - *pb++;
    +    d = (diff > d);
    +    if (borrow && --diff == MP_DIGIT_MAX)
    +      ++d;
    +    *pc++ = diff;
    +    borrow = d;
    +#endif
    +  }
    +  for (limit = MP_USED(a); ix < limit; ++ix) {
    +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
    +    w = w + *pa++;
    +    *pc++ = ACCUM(w);
    +    w >>= MP_DIGIT_BIT;
    +#else
    +    d = *pa++;
    +    *pc++ = diff = d - borrow;
    +    borrow = (diff > d);
    +#endif
    +  }
    +
    +  /* Clobber any leading zeroes we created    */
    +  MP_USED(c) = ix;
    +  s_mp_clamp(c);
    +
    +  /*
    +     If there was a borrow out, then |b| > |a| in violation
    +     of our input invariant.  We've already done the work,
    +     but we'll at least complain about it...
    +   */
    +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
    +  return w ? MP_RANGE : MP_OKAY;
    +#else
    +  return borrow ? MP_RANGE : MP_OKAY;
    +#endif
    +}
    +/* {{{ s_mp_mul(a, b) */
    +
    +/* Compute a = |a| * |b|                                                  */
    +mp_err   s_mp_mul(mp_int *a, const mp_int *b)
    +{
    +  return mp_mul(a, b, a);
    +} /* end s_mp_mul() */
    +
    +/* }}} */
    +
    +#if defined(MP_USE_UINT_DIGIT) && defined(MP_USE_LONG_LONG_MULTIPLY)
    +/* This trick works on Sparc V8 CPUs with the Workshop compilers. */
    +#define MP_MUL_DxD(a, b, Phi, Plo) \
    +  { unsigned long long product = (unsigned long long)a * b; \
    +    Plo = (mp_digit)product; \
    +    Phi = (mp_digit)(product >> MP_DIGIT_BIT); }
    +#elif defined(OSF1)
    +#define MP_MUL_DxD(a, b, Phi, Plo) \
    +  { Plo = asm ("mulq %a0, %a1, %v0", a, b);\
    +    Phi = asm ("umulh %a0, %a1, %v0", a, b); }
    +#else
    +#define MP_MUL_DxD(a, b, Phi, Plo) \
    +  { mp_digit a0b1, a1b0; \
    +    Plo = (a & MP_HALF_DIGIT_MAX) * (b & MP_HALF_DIGIT_MAX); \
    +    Phi = (a >> MP_HALF_DIGIT_BIT) * (b >> MP_HALF_DIGIT_BIT); \
    +    a0b1 = (a & MP_HALF_DIGIT_MAX) * (b >> MP_HALF_DIGIT_BIT); \
    +    a1b0 = (a >> MP_HALF_DIGIT_BIT) * (b & MP_HALF_DIGIT_MAX); \
    +    a1b0 += a0b1; \
    +    Phi += a1b0 >> MP_HALF_DIGIT_BIT; \
    +    if (a1b0 < a0b1)  \
    +      Phi += MP_HALF_RADIX; \
    +    a1b0 <<= MP_HALF_DIGIT_BIT; \
    +    Plo += a1b0; \
    +    if (Plo < a1b0) \
    +      ++Phi; \
    +  }
    +#endif
    +
    +#if !defined(MP_ASSEMBLY_MULTIPLY)
    +/* c = a * b */
    +void s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
    +{
    +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD)
    +  mp_digit   d = 0;
    +
    +  /* Inner product:  Digits of a */
    +  while (a_len--) {
    +    mp_word w = ((mp_word)b * *a++) + d;
    +    *c++ = ACCUM(w);
    +    d = CARRYOUT(w);
    +  }
    +  *c = d;
    +#else
    +  mp_digit carry = 0;
    +  while (a_len--) {
    +    mp_digit a_i = *a++;
    +    mp_digit a0b0, a1b1;
    +
    +    MP_MUL_DxD(a_i, b, a1b1, a0b0);
    +
    +    a0b0 += carry;
    +    if (a0b0 < carry)
    +      ++a1b1;
    +    *c++ = a0b0;
    +    carry = a1b1;
    +  }
    +  *c = carry;
    +#endif
    +}
    +
    +/* c += a * b */
    +void s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b,
    +                              mp_digit *c)
    +{
    +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD)
    +  mp_digit   d = 0;
    +
    +  /* Inner product:  Digits of a */
    +  while (a_len--) {
    +    mp_word w = ((mp_word)b * *a++) + *c + d;
    +    *c++ = ACCUM(w);
    +    d = CARRYOUT(w);
    +  }
    +  *c = d;
    +#else
    +  mp_digit carry = 0;
    +  while (a_len--) {
    +    mp_digit a_i = *a++;
    +    mp_digit a0b0, a1b1;
    +
    +    MP_MUL_DxD(a_i, b, a1b1, a0b0);
    +
    +    a0b0 += carry;
    +    if (a0b0 < carry)
    +      ++a1b1;
    +    a0b0 += a_i = *c;
    +    if (a0b0 < a_i)
    +      ++a1b1;
    +    *c++ = a0b0;
    +    carry = a1b1;
    +  }
    +  *c = carry;
    +#endif
    +}
    +
    +/* Presently, this is only used by the Montgomery arithmetic code. */
    +/* c += a * b */
    +void s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
    +{
    +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD)
    +  mp_digit   d = 0;
    +
    +  /* Inner product:  Digits of a */
    +  while (a_len--) {
    +    mp_word w = ((mp_word)b * *a++) + *c + d;
    +    *c++ = ACCUM(w);
    +    d = CARRYOUT(w);
    +  }
    +
    +  while (d) {
    +    mp_word w = (mp_word)*c + d;
    +    *c++ = ACCUM(w);
    +    d = CARRYOUT(w);
    +  }
    +#else
    +  mp_digit carry = 0;
    +  while (a_len--) {
    +    mp_digit a_i = *a++;
    +    mp_digit a0b0, a1b1;
    +
    +    MP_MUL_DxD(a_i, b, a1b1, a0b0);
    +
    +    a0b0 += carry;
    +    if (a0b0 < carry)
    +      ++a1b1;
    +
    +    a0b0 += a_i = *c;
    +    if (a0b0 < a_i)
    +      ++a1b1;
    +
    +    *c++ = a0b0;
    +    carry = a1b1;
    +  }
    +  while (carry) {
    +    mp_digit c_i = *c;
    +    carry += c_i;
    +    *c++ = carry;
    +    carry = carry < c_i;
    +  }
    +#endif
    +}
    +#endif
    +
    +#if defined(MP_USE_UINT_DIGIT) && defined(MP_USE_LONG_LONG_MULTIPLY)
    +/* This trick works on Sparc V8 CPUs with the Workshop compilers. */
    +#define MP_SQR_D(a, Phi, Plo) \
    +  { unsigned long long square = (unsigned long long)a * a; \
    +    Plo = (mp_digit)square; \
    +    Phi = (mp_digit)(square >> MP_DIGIT_BIT); }
    +#elif defined(OSF1)
    +#define MP_SQR_D(a, Phi, Plo) \
    +  { Plo = asm ("mulq  %a0, %a0, %v0", a);\
    +    Phi = asm ("umulh %a0, %a0, %v0", a); }
    +#else
    +#define MP_SQR_D(a, Phi, Plo) \
    +  { mp_digit Pmid; \
    +    Plo  = (a  & MP_HALF_DIGIT_MAX) * (a  & MP_HALF_DIGIT_MAX); \
    +    Phi  = (a >> MP_HALF_DIGIT_BIT) * (a >> MP_HALF_DIGIT_BIT); \
    +    Pmid = (a  & MP_HALF_DIGIT_MAX) * (a >> MP_HALF_DIGIT_BIT); \
    +    Phi += Pmid >> (MP_HALF_DIGIT_BIT - 1);  \
    +    Pmid <<= (MP_HALF_DIGIT_BIT + 1);  \
    +    Plo += Pmid;  \
    +    if (Plo < Pmid)  \
    +      ++Phi;  \
    +  }
    +#endif
    +
    +#if !defined(MP_ASSEMBLY_SQUARE)
    +/* Add the squares of the digits of a to the digits of b. */
    +void s_mpv_sqr_add_prop(const mp_digit *pa, mp_size a_len, mp_digit *ps)
    +{
    +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD)
    +  mp_word  w;
    +  mp_digit d;
    +  mp_size  ix;
    +
    +  w  = 0;
    +#define ADD_SQUARE(n) \
    +    d = pa[n]; \
    +    w += (d * (mp_word)d) + ps[2*n]; \
    +    ps[2*n] = ACCUM(w); \
    +    w = (w >> DIGIT_BIT) + ps[2*n+1]; \
    +    ps[2*n+1] = ACCUM(w); \
    +    w = (w >> DIGIT_BIT)
    +
    +  for (ix = a_len; ix >= 4; ix -= 4) {
    +    ADD_SQUARE(0);
    +    ADD_SQUARE(1);
    +    ADD_SQUARE(2);
    +    ADD_SQUARE(3);
    +    pa += 4;
    +    ps += 8;
    +  }
    +  if (ix) {
    +    ps += 2*ix;
    +    pa += ix;
    +    switch (ix) {
    +    case 3: ADD_SQUARE(-3); /* FALLTHRU */
    +    case 2: ADD_SQUARE(-2); /* FALLTHRU */
    +    case 1: ADD_SQUARE(-1); /* FALLTHRU */
    +    case 0: break;
    +    }
    +  }
    +  while (w) {
    +    w += *ps;
    +    *ps++ = ACCUM(w);
    +    w = (w >> DIGIT_BIT);
    +  }
    +#else
    +  mp_digit carry = 0;
    +  while (a_len--) {
    +    mp_digit a_i = *pa++;
    +    mp_digit a0a0, a1a1;
    +
    +    MP_SQR_D(a_i, a1a1, a0a0);
    +
    +    /* here a1a1 and a0a0 constitute a_i ** 2 */
    +    a0a0 += carry;
    +    if (a0a0 < carry)
    +      ++a1a1;
    +
    +    /* now add to ps */
    +    a0a0 += a_i = *ps;
    +    if (a0a0 < a_i)
    +      ++a1a1;
    +    *ps++ = a0a0;
    +    a1a1 += a_i = *ps;
    +    carry = (a1a1 < a_i);
    +    *ps++ = a1a1;
    +  }
    +  while (carry) {
    +    mp_digit s_i = *ps;
    +    carry += s_i;
    +    *ps++ = carry;
    +    carry = carry < s_i;
    +  }
    +#endif
    +}
    +#endif
    +
    +#if (defined(MP_NO_MP_WORD) || defined(MP_NO_DIV_WORD)) \
    +&& !defined(MP_ASSEMBLY_DIV_2DX1D)
    +/*
    +** Divide 64-bit (Nhi,Nlo) by 32-bit divisor, which must be normalized
    +** so its high bit is 1.   This code is from NSPR.
    +*/
    +mp_err s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor,
    +                       mp_digit *qp, mp_digit *rp)
    +{
    +    mp_digit d1, d0, q1, q0;
    +    mp_digit r1, r0, m;
    +
    +    d1 = divisor >> MP_HALF_DIGIT_BIT;
    +    d0 = divisor & MP_HALF_DIGIT_MAX;
    +    r1 = Nhi % d1;
    +    q1 = Nhi / d1;
    +    m = q1 * d0;
    +    r1 = (r1 << MP_HALF_DIGIT_BIT) | (Nlo >> MP_HALF_DIGIT_BIT);
    +    if (r1 < m) {
    +        q1--, r1 += divisor;
    +        if (r1 >= divisor && r1 < m) {
    +            q1--, r1 += divisor;
    +        }
    +    }
    +    r1 -= m;
    +    r0 = r1 % d1;
    +    q0 = r1 / d1;
    +    m = q0 * d0;
    +    r0 = (r0 << MP_HALF_DIGIT_BIT) | (Nlo & MP_HALF_DIGIT_MAX);
    +    if (r0 < m) {
    +        q0--, r0 += divisor;
    +        if (r0 >= divisor && r0 < m) {
    +            q0--, r0 += divisor;
    +        }
    +    }
    +    if (qp)
    +        *qp = (q1 << MP_HALF_DIGIT_BIT) | q0;
    +    if (rp)
    +        *rp = r0 - m;
    +    return MP_OKAY;
    +}
    +#endif
    +
    +#if MP_SQUARE
    +/* {{{ s_mp_sqr(a) */
    +
    +mp_err   s_mp_sqr(mp_int *a)
    +{
    +  mp_err   res;
    +  mp_int   tmp;
    +
    +  if((res = mp_init_size(&tmp, 2 * USED(a), FLAG(a))) != MP_OKAY)
    +    return res;
    +  res = mp_sqr(a, &tmp);
    +  if (res == MP_OKAY) {
    +    s_mp_exch(&tmp, a);
    +  }
    +  mp_clear(&tmp);
    +  return res;
    +}
    +
    +/* }}} */
    +#endif
    +
    +/* {{{ s_mp_div(a, b) */
    +
    +/*
    +  s_mp_div(a, b)
    +
    +  Compute a = a / b and b = a mod b.  Assumes b > a.
    + */
    +
    +mp_err   s_mp_div(mp_int *rem,  /* i: dividend, o: remainder */
    +                  mp_int *div,  /* i: divisor                */
    +                  mp_int *quot) /* i: 0;        o: quotient  */
    +{
    +  mp_int   part, t;
    +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
    +  mp_word  q_msd;
    +#else
    +  mp_digit q_msd;
    +#endif
    +  mp_err   res;
    +  mp_digit d;
    +  mp_digit div_msd;
    +  int      ix;
    +
    +  if(mp_cmp_z(div) == 0)
    +    return MP_RANGE;
    +
    +  /* Shortcut if divisor is power of two */
    +  if((ix = s_mp_ispow2(div)) >= 0) {
    +    MP_CHECKOK( mp_copy(rem, quot) );
    +    s_mp_div_2d(quot, (mp_digit)ix);
    +    s_mp_mod_2d(rem,  (mp_digit)ix);
    +
    +    return MP_OKAY;
    +  }
    +
    +  DIGITS(&t) = 0;
    +  MP_SIGN(rem) = ZPOS;
    +  MP_SIGN(div) = ZPOS;
    +
    +  /* A working temporary for division     */
    +  MP_CHECKOK( mp_init_size(&t, MP_ALLOC(rem), FLAG(rem)));
    +
    +  /* Normalize to optimize guessing       */
    +  MP_CHECKOK( s_mp_norm(rem, div, &d) );
    +
    +  part = *rem;
    +
    +  /* Perform the division itself...woo!   */
    +  MP_USED(quot) = MP_ALLOC(quot);
    +
    +  /* Find a partial substring of rem which is at least div */
    +  /* If we didn't find one, we're finished dividing    */
    +  while (MP_USED(rem) > MP_USED(div) || s_mp_cmp(rem, div) >= 0) {
    +    int i;
    +    int unusedRem;
    +
    +    unusedRem = MP_USED(rem) - MP_USED(div);
    +    MP_DIGITS(&part) = MP_DIGITS(rem) + unusedRem;
    +    MP_ALLOC(&part)  = MP_ALLOC(rem)  - unusedRem;
    +    MP_USED(&part)   = MP_USED(div);
    +    if (s_mp_cmp(&part, div) < 0) {
    +      -- unusedRem;
    +#if MP_ARGCHK == 2
    +      assert(unusedRem >= 0);
    +#endif
    +      -- MP_DIGITS(&part);
    +      ++ MP_USED(&part);
    +      ++ MP_ALLOC(&part);
    +    }
    +
    +    /* Compute a guess for the next quotient digit       */
    +    q_msd = MP_DIGIT(&part, MP_USED(&part) - 1);
    +    div_msd = MP_DIGIT(div, MP_USED(div) - 1);
    +    if (q_msd >= div_msd) {
    +      q_msd = 1;
    +    } else if (MP_USED(&part) > 1) {
    +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
    +      q_msd = (q_msd << MP_DIGIT_BIT) | MP_DIGIT(&part, MP_USED(&part) - 2);
    +      q_msd /= div_msd;
    +      if (q_msd == RADIX)
    +        --q_msd;
    +#else
    +      mp_digit r;
    +      MP_CHECKOK( s_mpv_div_2dx1d(q_msd, MP_DIGIT(&part, MP_USED(&part) - 2),
    +                                  div_msd, &q_msd, &r) );
    +#endif
    +    } else {
    +      q_msd = 0;
    +    }
    +#if MP_ARGCHK == 2
    +    assert(q_msd > 0); /* This case should never occur any more. */
    +#endif
    +    if (q_msd <= 0)
    +      break;
    +
    +    /* See what that multiplies out to                   */
    +    mp_copy(div, &t);
    +    MP_CHECKOK( s_mp_mul_d(&t, (mp_digit)q_msd) );
    +
    +    /*
    +       If it's too big, back it off.  We should not have to do this
    +       more than once, or, in rare cases, twice.  Knuth describes a
    +       method by which this could be reduced to a maximum of once, but
    +       I didn't implement that here.
    +     * When using s_mpv_div_2dx1d, we may have to do this 3 times.
    +     */
    +    for (i = 4; s_mp_cmp(&t, &part) > 0 && i > 0; --i) {
    +      --q_msd;
    +      s_mp_sub(&t, div);        /* t -= div */
    +    }
    +    if (i < 0) {
    +      res = MP_RANGE;
    +      goto CLEANUP;
    +    }
    +
    +    /* At this point, q_msd should be the right next digit   */
    +    MP_CHECKOK( s_mp_sub(&part, &t) );  /* part -= t */
    +    s_mp_clamp(rem);
    +
    +    /*
    +      Include the digit in the quotient.  We allocated enough memory
    +      for any quotient we could ever possibly get, so we should not
    +      have to check for failures here
    +     */
    +    MP_DIGIT(quot, unusedRem) = (mp_digit)q_msd;
    +  }
    +
    +  /* Denormalize remainder                */
    +  if (d) {
    +    s_mp_div_2d(rem, d);
    +  }
    +
    +  s_mp_clamp(quot);
    +
    +CLEANUP:
    +  mp_clear(&t);
    +
    +  return res;
    +
    +} /* end s_mp_div() */
    +
    +
    +/* }}} */
    +
    +/* {{{ s_mp_2expt(a, k) */
    +
    +mp_err   s_mp_2expt(mp_int *a, mp_digit k)
    +{
    +  mp_err    res;
    +  mp_size   dig, bit;
    +
    +  dig = k / DIGIT_BIT;
    +  bit = k % DIGIT_BIT;
    +
    +  mp_zero(a);
    +  if((res = s_mp_pad(a, dig + 1)) != MP_OKAY)
    +    return res;
    +
    +  DIGIT(a, dig) |= ((mp_digit)1 << bit);
    +
    +  return MP_OKAY;
    +
    +} /* end s_mp_2expt() */
    +
    +/* }}} */
    +
    +/* {{{ s_mp_reduce(x, m, mu) */
    +
    +/*
    +  Compute Barrett reduction, x (mod m), given a precomputed value for
    +  mu = b^2k / m, where b = RADIX and k = #digits(m).  This should be
    +  faster than straight division, when many reductions by the same
    +  value of m are required (such as in modular exponentiation).  This
    +  can nearly halve the time required to do modular exponentiation,
    +  as compared to using the full integer divide to reduce.
    +
    +  This algorithm was derived from the _Handbook of Applied
    +  Cryptography_ by Menezes, Oorschot and VanStone, Ch. 14,
    +  pp. 603-604.
    + */
    +
    +mp_err   s_mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu)
    +{
    +  mp_int   q;
    +  mp_err   res;
    +
    +  if((res = mp_init_copy(&q, x)) != MP_OKAY)
    +    return res;
    +
    +  s_mp_rshd(&q, USED(m) - 1);  /* q1 = x / b^(k-1)  */
    +  s_mp_mul(&q, mu);            /* q2 = q1 * mu      */
    +  s_mp_rshd(&q, USED(m) + 1);  /* q3 = q2 / b^(k+1) */
    +
    +  /* x = x mod b^(k+1), quick (no division) */
    +  s_mp_mod_2d(x, DIGIT_BIT * (USED(m) + 1));
    +
    +  /* q = q * m mod b^(k+1), quick (no division) */
    +  s_mp_mul(&q, m);
    +  s_mp_mod_2d(&q, DIGIT_BIT * (USED(m) + 1));
    +
    +  /* x = x - q */
    +  if((res = mp_sub(x, &q, x)) != MP_OKAY)
    +    goto CLEANUP;
    +
    +  /* If x < 0, add b^(k+1) to it */
    +  if(mp_cmp_z(x) < 0) {
    +    mp_set(&q, 1);
    +    if((res = s_mp_lshd(&q, USED(m) + 1)) != MP_OKAY)
    +      goto CLEANUP;
    +    if((res = mp_add(x, &q, x)) != MP_OKAY)
    +      goto CLEANUP;
    +  }
    +
    +  /* Back off if it's too big */
    +  while(mp_cmp(x, m) >= 0) {
    +    if((res = s_mp_sub(x, m)) != MP_OKAY)
    +      break;
    +  }
    +
    + CLEANUP:
    +  mp_clear(&q);
    +
    +  return res;
    +
    +} /* end s_mp_reduce() */
    +
    +/* }}} */
    +
    +/* }}} */
    +
    +/* {{{ Primitive comparisons */
    +
    +/* {{{ s_mp_cmp(a, b) */
    +
    +/* Compare |a| <=> |b|, return 0 if equal, <0 if a0 if a>b           */
    +int      s_mp_cmp(const mp_int *a, const mp_int *b)
    +{
    +  mp_size used_a = MP_USED(a);
    +  {
    +    mp_size used_b = MP_USED(b);
    +
    +    if (used_a > used_b)
    +      goto IS_GT;
    +    if (used_a < used_b)
    +      goto IS_LT;
    +  }
    +  {
    +    mp_digit *pa, *pb;
    +    mp_digit da = 0, db = 0;
    +
    +#define CMP_AB(n) if ((da = pa[n]) != (db = pb[n])) goto done
    +
    +    pa = MP_DIGITS(a) + used_a;
    +    pb = MP_DIGITS(b) + used_a;
    +    while (used_a >= 4) {
    +      pa     -= 4;
    +      pb     -= 4;
    +      used_a -= 4;
    +      CMP_AB(3);
    +      CMP_AB(2);
    +      CMP_AB(1);
    +      CMP_AB(0);
    +    }
    +    while (used_a-- > 0 && ((da = *--pa) == (db = *--pb)))
    +      /* do nothing */;
    +done:
    +    if (da > db)
    +      goto IS_GT;
    +    if (da < db)
    +      goto IS_LT;
    +  }
    +  return MP_EQ;
    +IS_LT:
    +  return MP_LT;
    +IS_GT:
    +  return MP_GT;
    +} /* end s_mp_cmp() */
    +
    +/* }}} */
    +
    +/* {{{ s_mp_cmp_d(a, d) */
    +
    +/* Compare |a| <=> d, return 0 if equal, <0 if a0 if a>d             */
    +int      s_mp_cmp_d(const mp_int *a, mp_digit d)
    +{
    +  if(USED(a) > 1)
    +    return MP_GT;
    +
    +  if(DIGIT(a, 0) < d)
    +    return MP_LT;
    +  else if(DIGIT(a, 0) > d)
    +    return MP_GT;
    +  else
    +    return MP_EQ;
    +
    +} /* end s_mp_cmp_d() */
    +
    +/* }}} */
    +
    +/* {{{ s_mp_ispow2(v) */
    +
    +/*
    +  Returns -1 if the value is not a power of two; otherwise, it returns
    +  k such that v = 2^k, i.e. lg(v).
    + */
    +int      s_mp_ispow2(const mp_int *v)
    +{
    +  mp_digit d;
    +  int      extra = 0, ix;
    +
    +  ix = MP_USED(v) - 1;
    +  d = MP_DIGIT(v, ix); /* most significant digit of v */
    +
    +  extra = s_mp_ispow2d(d);
    +  if (extra < 0 || ix == 0)
    +    return extra;
    +
    +  while (--ix >= 0) {
    +    if (DIGIT(v, ix) != 0)
    +      return -1; /* not a power of two */
    +    extra += MP_DIGIT_BIT;
    +  }
    +
    +  return extra;
    +
    +} /* end s_mp_ispow2() */
    +
    +/* }}} */
    +
    +/* {{{ s_mp_ispow2d(d) */
    +
    +int      s_mp_ispow2d(mp_digit d)
    +{
    +  if ((d != 0) && ((d & (d-1)) == 0)) { /* d is a power of 2 */
    +    int pow = 0;
    +#if defined (MP_USE_UINT_DIGIT)
    +    if (d & 0xffff0000U)
    +      pow += 16;
    +    if (d & 0xff00ff00U)
    +      pow += 8;
    +    if (d & 0xf0f0f0f0U)
    +      pow += 4;
    +    if (d & 0xccccccccU)
    +      pow += 2;
    +    if (d & 0xaaaaaaaaU)
    +      pow += 1;
    +#elif defined(MP_USE_LONG_LONG_DIGIT)
    +    if (d & 0xffffffff00000000ULL)
    +      pow += 32;
    +    if (d & 0xffff0000ffff0000ULL)
    +      pow += 16;
    +    if (d & 0xff00ff00ff00ff00ULL)
    +      pow += 8;
    +    if (d & 0xf0f0f0f0f0f0f0f0ULL)
    +      pow += 4;
    +    if (d & 0xccccccccccccccccULL)
    +      pow += 2;
    +    if (d & 0xaaaaaaaaaaaaaaaaULL)
    +      pow += 1;
    +#elif defined(MP_USE_LONG_DIGIT)
    +    if (d & 0xffffffff00000000UL)
    +      pow += 32;
    +    if (d & 0xffff0000ffff0000UL)
    +      pow += 16;
    +    if (d & 0xff00ff00ff00ff00UL)
    +      pow += 8;
    +    if (d & 0xf0f0f0f0f0f0f0f0UL)
    +      pow += 4;
    +    if (d & 0xccccccccccccccccUL)
    +      pow += 2;
    +    if (d & 0xaaaaaaaaaaaaaaaaUL)
    +      pow += 1;
    +#else
    +#error "unknown type for mp_digit"
    +#endif
    +    return pow;
    +  }
    +  return -1;
    +
    +} /* end s_mp_ispow2d() */
    +
    +/* }}} */
    +
    +/* }}} */
    +
    +/* {{{ Primitive I/O helpers */
    +
    +/* {{{ s_mp_tovalue(ch, r) */
    +
    +/*
    +  Convert the given character to its digit value, in the given radix.
    +  If the given character is not understood in the given radix, -1 is
    +  returned.  Otherwise the digit's numeric value is returned.
    +
    +  The results will be odd if you use a radix < 2 or > 62, you are
    +  expected to know what you're up to.
    + */
    +int      s_mp_tovalue(char ch, int r)
    +{
    +  int    val, xch;
    +
    +  if(r > 36)
    +    xch = ch;
    +  else
    +    xch = toupper(ch);
    +
    +  if(isdigit(xch))
    +    val = xch - '0';
    +  else if(isupper(xch))
    +    val = xch - 'A' + 10;
    +  else if(islower(xch))
    +    val = xch - 'a' + 36;
    +  else if(xch == '+')
    +    val = 62;
    +  else if(xch == '/')
    +    val = 63;
    +  else
    +    return -1;
    +
    +  if(val < 0 || val >= r)
    +    return -1;
    +
    +  return val;
    +
    +} /* end s_mp_tovalue() */
    +
    +/* }}} */
    +
    +/* {{{ s_mp_todigit(val, r, low) */
    +
    +/*
    +  Convert val to a radix-r digit, if possible.  If val is out of range
    +  for r, returns zero.  Otherwise, returns an ASCII character denoting
    +  the value in the given radix.
    +
    +  The results may be odd if you use a radix < 2 or > 64, you are
    +  expected to know what you're doing.
    + */
    +
    +char     s_mp_todigit(mp_digit val, int r, int low)
    +{
    +  char   ch;
    +
    +  if(val >= r)
    +    return 0;
    +
    +  ch = s_dmap_1[val];
    +
    +  if(r <= 36 && low)
    +    ch = tolower(ch);
    +
    +  return ch;
    +
    +} /* end s_mp_todigit() */
    +
    +/* }}} */
    +
    +/* {{{ s_mp_outlen(bits, radix) */
    +
    +/*
    +   Return an estimate for how long a string is needed to hold a radix
    +   r representation of a number with 'bits' significant bits, plus an
    +   extra for a zero terminator (assuming C style strings here)
    + */
    +int      s_mp_outlen(int bits, int r)
    +{
    +  return (int)((double)bits * LOG_V_2(r) + 1.5) + 1;
    +
    +} /* end s_mp_outlen() */
    +
    +/* }}} */
    +
    +/* }}} */
    +
    +/* {{{ mp_read_unsigned_octets(mp, str, len) */
    +/* mp_read_unsigned_octets(mp, str, len)
    +   Read in a raw value (base 256) into the given mp_int
    +   No sign bit, number is positive.  Leading zeros ignored.
    + */
    +
    +mp_err
    +mp_read_unsigned_octets(mp_int *mp, const unsigned char *str, mp_size len)
    +{
    +  int            count;
    +  mp_err         res;
    +  mp_digit       d;
    +
    +  ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG);
    +
    +  mp_zero(mp);
    +
    +  count = len % sizeof(mp_digit);
    +  if (count) {
    +    for (d = 0; count-- > 0; --len) {
    +      d = (d << 8) | *str++;
    +    }
    +    MP_DIGIT(mp, 0) = d;
    +  }
    +
    +  /* Read the rest of the digits */
    +  for(; len > 0; len -= sizeof(mp_digit)) {
    +    for (d = 0, count = sizeof(mp_digit); count > 0; --count) {
    +      d = (d << 8) | *str++;
    +    }
    +    if (MP_EQ == mp_cmp_z(mp)) {
    +      if (!d)
    +        continue;
    +    } else {
    +      if((res = s_mp_lshd(mp, 1)) != MP_OKAY)
    +        return res;
    +    }
    +    MP_DIGIT(mp, 0) = d;
    +  }
    +  return MP_OKAY;
    +} /* end mp_read_unsigned_octets() */
    +/* }}} */
    +
    +/* {{{ mp_unsigned_octet_size(mp) */
    +int
    +mp_unsigned_octet_size(const mp_int *mp)
    +{
    +  int  bytes;
    +  int  ix;
    +  mp_digit  d = 0;
    +
    +  ARGCHK(mp != NULL, MP_BADARG);
    +  ARGCHK(MP_ZPOS == SIGN(mp), MP_BADARG);
    +
    +  bytes = (USED(mp) * sizeof(mp_digit));
    +
    +  /* subtract leading zeros. */
    +  /* Iterate over each digit... */
    +  for(ix = USED(mp) - 1; ix >= 0; ix--) {
    +    d = DIGIT(mp, ix);
    +    if (d)
    +        break;
    +    bytes -= sizeof(d);
    +  }
    +  if (!bytes)
    +    return 1;
    +
    +  /* Have MSD, check digit bytes, high order first */
    +  for(ix = sizeof(mp_digit) - 1; ix >= 0; ix--) {
    +    unsigned char x = (unsigned char)(d >> (ix * CHAR_BIT));
    +    if (x)
    +        break;
    +    --bytes;
    +  }
    +  return bytes;
    +} /* end mp_unsigned_octet_size() */
    +/* }}} */
    +
    +/* {{{ mp_to_unsigned_octets(mp, str) */
    +/* output a buffer of big endian octets no longer than specified. */
    +mp_err
    +mp_to_unsigned_octets(const mp_int *mp, unsigned char *str, mp_size maxlen)
    +{
    +  int  ix, pos = 0;
    +  int  bytes;
    +
    +  ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
    +
    +  bytes = mp_unsigned_octet_size(mp);
    +  ARGCHK(bytes <= maxlen, MP_BADARG);
    +
    +  /* Iterate over each digit... */
    +  for(ix = USED(mp) - 1; ix >= 0; ix--) {
    +    mp_digit  d = DIGIT(mp, ix);
    +    int       jx;
    +
    +    /* Unpack digit bytes, high order first */
    +    for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {
    +      unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT));
    +      if (!pos && !x)   /* suppress leading zeros */
    +        continue;
    +      str[pos++] = x;
    +    }
    +  }
    +  if (!pos)
    +    str[pos++] = 0;
    +  return pos;
    +} /* end mp_to_unsigned_octets() */
    +/* }}} */
    +
    +/* {{{ mp_to_signed_octets(mp, str) */
    +/* output a buffer of big endian octets no longer than specified. */
    +mp_err
    +mp_to_signed_octets(const mp_int *mp, unsigned char *str, mp_size maxlen)
    +{
    +  int  ix, pos = 0;
    +  int  bytes;
    +
    +  ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
    +
    +  bytes = mp_unsigned_octet_size(mp);
    +  ARGCHK(bytes <= maxlen, MP_BADARG);
    +
    +  /* Iterate over each digit... */
    +  for(ix = USED(mp) - 1; ix >= 0; ix--) {
    +    mp_digit  d = DIGIT(mp, ix);
    +    int       jx;
    +
    +    /* Unpack digit bytes, high order first */
    +    for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {
    +      unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT));
    +      if (!pos) {
    +        if (!x)         /* suppress leading zeros */
    +          continue;
    +        if (x & 0x80) { /* add one leading zero to make output positive.  */
    +          ARGCHK(bytes + 1 <= maxlen, MP_BADARG);
    +          if (bytes + 1 > maxlen)
    +            return MP_BADARG;
    +          str[pos++] = 0;
    +        }
    +      }
    +      str[pos++] = x;
    +    }
    +  }
    +  if (!pos)
    +    str[pos++] = 0;
    +  return pos;
    +} /* end mp_to_signed_octets() */
    +/* }}} */
    +
    +/* {{{ mp_to_fixlen_octets(mp, str) */
    +/* output a buffer of big endian octets exactly as long as requested. */
    +mp_err
    +mp_to_fixlen_octets(const mp_int *mp, unsigned char *str, mp_size length)
    +{
    +  int  ix, pos = 0;
    +  int  bytes;
    +
    +  ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
    +
    +  bytes = mp_unsigned_octet_size(mp);
    +  ARGCHK(bytes <= length, MP_BADARG);
    +
    +  /* place any needed leading zeros */
    +  for (;length > bytes; --length) {
    +        *str++ = 0;
    +  }
    +
    +  /* Iterate over each digit... */
    +  for(ix = USED(mp) - 1; ix >= 0; ix--) {
    +    mp_digit  d = DIGIT(mp, ix);
    +    int       jx;
    +
    +    /* Unpack digit bytes, high order first */
    +    for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {
    +      unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT));
    +      if (!pos && !x)   /* suppress leading zeros */
    +        continue;
    +      str[pos++] = x;
    +    }
    +  }
    +  if (!pos)
    +    str[pos++] = 0;
    +  return MP_OKAY;
    +} /* end mp_to_fixlen_octets() */
    +/* }}} */
    +
    +
    +/*------------------------------------------------------------------------*/
    +/* HERE THERE BE DRAGONS                                                  */
    diff --git a/jdk/src/share/native/sun/security/ec/mpi.h b/jdk/src/share/native/sun/security/ec/mpi.h
    new file mode 100644
    index 00000000000..5f70b763209
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/mpi.h
    @@ -0,0 +1,409 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + *
    + *  Arbitrary precision integer arithmetic library
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
    + *
    + * The Initial Developer of the Original Code is
    + * Michael J. Fromberger.
    + * Portions created by the Initial Developer are Copyright (C) 1998
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Netscape Communications Corporation
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#ifndef _MPI_H
    +#define _MPI_H
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +/* $Id: mpi.h,v 1.22 2004/04/27 23:04:36 gerv%gerv.net Exp $ */
    +
    +#include "mpi-config.h"
    +
    +#ifndef _WIN32
    +#include 
    +#endif /* _WIN32 */
    +
    +#ifdef _KERNEL
    +#include 
    +#include 
    +#define assert ASSERT
    +#define labs(a) (a >= 0 ? a : -a)
    +#define UCHAR_MAX 255
    +#define memset(s, c, n) bzero(s, n)
    +#define memcpy(a,b,c) bcopy((caddr_t)b, (caddr_t)a, c)
    +/*
    + * Generic #define's to cover missing things in the kernel
    + */
    +#ifndef isdigit
    +#define isdigit(x)      ((x) >= '0' && (x) <= '9')
    +#endif
    +#ifndef isupper
    +#define isupper(x)      (((unsigned)(x) >= 'A') && ((unsigned)(x) <= 'Z'))
    +#endif
    +#ifndef islower
    +#define islower(x)      (((unsigned)(x) >= 'a') && ((unsigned)(x) <= 'z'))
    +#endif
    +#ifndef isalpha
    +#define isalpha(x)      (isupper(x) || islower(x))
    +#endif
    +#ifndef toupper
    +#define toupper(x)      (islower(x) ? (x) - 'a' + 'A' : (x))
    +#endif
    +#ifndef tolower
    +#define tolower(x)      (isupper(x) ? (x) + 'a' - 'A' : (x))
    +#endif
    +#ifndef isspace
    +#define isspace(x)      (((x) == ' ') || ((x) == '\r') || ((x) == '\n') || \
    +                         ((x) == '\t') || ((x) == '\b'))
    +#endif
    +#endif /* _KERNEL */
    +
    +#if MP_DEBUG
    +#undef MP_IOFUNC
    +#define MP_IOFUNC 1
    +#endif
    +
    +#if MP_IOFUNC
    +#include 
    +#include 
    +#endif
    +
    +#ifndef _KERNEL
    +#include 
    +#endif
    +
    +#if defined(BSDI)
    +#undef ULLONG_MAX
    +#endif
    +
    +#if defined( macintosh )
    +#include 
    +#elif defined( _WIN32_WCE)
    +/* #include  What do we need here ?? */
    +#else
    +#include 
    +#endif
    +
    +#define  MP_NEG    1
    +#define  MP_ZPOS   0
    +
    +#define  MP_OKAY          0 /* no error, all is well */
    +#define  MP_YES           0 /* yes (boolean result)  */
    +#define  MP_NO           -1 /* no (boolean result)   */
    +#define  MP_MEM          -2 /* out of memory         */
    +#define  MP_RANGE        -3 /* argument out of range */
    +#define  MP_BADARG       -4 /* invalid parameter     */
    +#define  MP_UNDEF        -5 /* answer is undefined   */
    +#define  MP_LAST_CODE    MP_UNDEF
    +
    +typedef unsigned int      mp_sign;
    +typedef unsigned int      mp_size;
    +typedef int               mp_err;
    +typedef int               mp_flag;
    +
    +#define MP_32BIT_MAX 4294967295U
    +
    +#if !defined(ULONG_MAX)
    +#error "ULONG_MAX not defined"
    +#elif !defined(UINT_MAX)
    +#error "UINT_MAX not defined"
    +#elif !defined(USHRT_MAX)
    +#error "USHRT_MAX not defined"
    +#endif
    +
    +#if defined(ULONG_LONG_MAX)                     /* GCC, HPUX */
    +#define MP_ULONG_LONG_MAX ULONG_LONG_MAX
    +#elif defined(ULLONG_MAX)                       /* Solaris */
    +#define MP_ULONG_LONG_MAX ULLONG_MAX
    +/* MP_ULONG_LONG_MAX was defined to be ULLONG_MAX */
    +#elif defined(ULONGLONG_MAX)                    /* IRIX, AIX */
    +#define MP_ULONG_LONG_MAX ULONGLONG_MAX
    +#endif
    +
    +/* We only use unsigned long for mp_digit iff long is more than 32 bits. */
    +#if !defined(MP_USE_UINT_DIGIT) && ULONG_MAX > MP_32BIT_MAX
    +typedef unsigned long     mp_digit;
    +#define MP_DIGIT_MAX      ULONG_MAX
    +#define MP_DIGIT_FMT      "%016lX"   /* printf() format for 1 digit */
    +#define MP_HALF_DIGIT_MAX UINT_MAX
    +#undef  MP_NO_MP_WORD
    +#define MP_NO_MP_WORD 1
    +#undef  MP_USE_LONG_DIGIT
    +#define MP_USE_LONG_DIGIT 1
    +#undef  MP_USE_LONG_LONG_DIGIT
    +
    +#elif !defined(MP_USE_UINT_DIGIT) && defined(MP_ULONG_LONG_MAX)
    +typedef unsigned long long mp_digit;
    +#define MP_DIGIT_MAX       MP_ULONG_LONG_MAX
    +#define MP_DIGIT_FMT      "%016llX"  /* printf() format for 1 digit */
    +#define MP_HALF_DIGIT_MAX  UINT_MAX
    +#undef  MP_NO_MP_WORD
    +#define MP_NO_MP_WORD 1
    +#undef  MP_USE_LONG_LONG_DIGIT
    +#define MP_USE_LONG_LONG_DIGIT 1
    +#undef  MP_USE_LONG_DIGIT
    +
    +#else
    +typedef unsigned int      mp_digit;
    +#define MP_DIGIT_MAX      UINT_MAX
    +#define MP_DIGIT_FMT      "%08X"     /* printf() format for 1 digit */
    +#define MP_HALF_DIGIT_MAX USHRT_MAX
    +#undef  MP_USE_UINT_DIGIT
    +#define MP_USE_UINT_DIGIT 1
    +#undef  MP_USE_LONG_LONG_DIGIT
    +#undef  MP_USE_LONG_DIGIT
    +#endif
    +
    +#if !defined(MP_NO_MP_WORD)
    +#if  defined(MP_USE_UINT_DIGIT) && \
    +    (defined(MP_ULONG_LONG_MAX) || (ULONG_MAX > UINT_MAX))
    +
    +#if (ULONG_MAX > UINT_MAX)
    +typedef unsigned long     mp_word;
    +typedef          long     mp_sword;
    +#define MP_WORD_MAX       ULONG_MAX
    +
    +#else
    +typedef unsigned long long mp_word;
    +typedef          long long mp_sword;
    +#define MP_WORD_MAX       MP_ULONG_LONG_MAX
    +#endif
    +
    +#else
    +#define MP_NO_MP_WORD 1
    +#endif
    +#endif /* !defined(MP_NO_MP_WORD) */
    +
    +#if !defined(MP_WORD_MAX) && defined(MP_DEFINE_SMALL_WORD)
    +typedef unsigned int      mp_word;
    +typedef          int      mp_sword;
    +#define MP_WORD_MAX       UINT_MAX
    +#endif
    +
    +#ifndef CHAR_BIT
    +#define CHAR_BIT 8
    +#endif
    +
    +#define MP_DIGIT_BIT      (CHAR_BIT*sizeof(mp_digit))
    +#define MP_WORD_BIT       (CHAR_BIT*sizeof(mp_word))
    +#define MP_RADIX          (1+(mp_word)MP_DIGIT_MAX)
    +
    +#define MP_HALF_DIGIT_BIT (MP_DIGIT_BIT/2)
    +#define MP_HALF_RADIX     (1+(mp_digit)MP_HALF_DIGIT_MAX)
    +/* MP_HALF_RADIX really ought to be called MP_SQRT_RADIX, but it's named
    +** MP_HALF_RADIX because it's the radix for MP_HALF_DIGITs, and it's
    +** consistent with the other _HALF_ names.
    +*/
    +
    +
    +/* Macros for accessing the mp_int internals           */
    +#define  MP_FLAG(MP)     ((MP)->flag)
    +#define  MP_SIGN(MP)     ((MP)->sign)
    +#define  MP_USED(MP)     ((MP)->used)
    +#define  MP_ALLOC(MP)    ((MP)->alloc)
    +#define  MP_DIGITS(MP)   ((MP)->dp)
    +#define  MP_DIGIT(MP,N)  (MP)->dp[(N)]
    +
    +/* This defines the maximum I/O base (minimum is 2)   */
    +#define MP_MAX_RADIX         64
    +
    +typedef struct {
    +  mp_sign       flag;    /* KM_SLEEP/KM_NOSLEEP        */
    +  mp_sign       sign;    /* sign of this quantity      */
    +  mp_size       alloc;   /* how many digits allocated  */
    +  mp_size       used;    /* how many digits used       */
    +  mp_digit     *dp;      /* the digits themselves      */
    +} mp_int;
    +
    +/* Default precision       */
    +mp_size mp_get_prec(void);
    +void    mp_set_prec(mp_size prec);
    +
    +/* Memory management       */
    +mp_err mp_init(mp_int *mp, int kmflag);
    +mp_err mp_init_size(mp_int *mp, mp_size prec, int kmflag);
    +mp_err mp_init_copy(mp_int *mp, const mp_int *from);
    +mp_err mp_copy(const mp_int *from, mp_int *to);
    +void   mp_exch(mp_int *mp1, mp_int *mp2);
    +void   mp_clear(mp_int *mp);
    +void   mp_zero(mp_int *mp);
    +void   mp_set(mp_int *mp, mp_digit d);
    +mp_err mp_set_int(mp_int *mp, long z);
    +#define mp_set_long(mp,z) mp_set_int(mp,z)
    +mp_err mp_set_ulong(mp_int *mp, unsigned long z);
    +
    +/* Single digit arithmetic */
    +mp_err mp_add_d(const mp_int *a, mp_digit d, mp_int *b);
    +mp_err mp_sub_d(const mp_int *a, mp_digit d, mp_int *b);
    +mp_err mp_mul_d(const mp_int *a, mp_digit d, mp_int *b);
    +mp_err mp_mul_2(const mp_int *a, mp_int *c);
    +mp_err mp_div_d(const mp_int *a, mp_digit d, mp_int *q, mp_digit *r);
    +mp_err mp_div_2(const mp_int *a, mp_int *c);
    +mp_err mp_expt_d(const mp_int *a, mp_digit d, mp_int *c);
    +
    +/* Sign manipulations      */
    +mp_err mp_abs(const mp_int *a, mp_int *b);
    +mp_err mp_neg(const mp_int *a, mp_int *b);
    +
    +/* Full arithmetic         */
    +mp_err mp_add(const mp_int *a, const mp_int *b, mp_int *c);
    +mp_err mp_sub(const mp_int *a, const mp_int *b, mp_int *c);
    +mp_err mp_mul(const mp_int *a, const mp_int *b, mp_int *c);
    +#if MP_SQUARE
    +mp_err mp_sqr(const mp_int *a, mp_int *b);
    +#else
    +#define mp_sqr(a, b) mp_mul(a, a, b)
    +#endif
    +mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *q, mp_int *r);
    +mp_err mp_div_2d(const mp_int *a, mp_digit d, mp_int *q, mp_int *r);
    +mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c);
    +mp_err mp_2expt(mp_int *a, mp_digit k);
    +mp_err mp_sqrt(const mp_int *a, mp_int *b);
    +
    +/* Modular arithmetic      */
    +#if MP_MODARITH
    +mp_err mp_mod(const mp_int *a, const mp_int *m, mp_int *c);
    +mp_err mp_mod_d(const mp_int *a, mp_digit d, mp_digit *c);
    +mp_err mp_addmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c);
    +mp_err mp_submod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c);
    +mp_err mp_mulmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c);
    +#if MP_SQUARE
    +mp_err mp_sqrmod(const mp_int *a, const mp_int *m, mp_int *c);
    +#else
    +#define mp_sqrmod(a, m, c) mp_mulmod(a, a, m, c)
    +#endif
    +mp_err mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c);
    +mp_err mp_exptmod_d(const mp_int *a, mp_digit d, const mp_int *m, mp_int *c);
    +#endif /* MP_MODARITH */
    +
    +/* Comparisons             */
    +int    mp_cmp_z(const mp_int *a);
    +int    mp_cmp_d(const mp_int *a, mp_digit d);
    +int    mp_cmp(const mp_int *a, const mp_int *b);
    +int    mp_cmp_mag(mp_int *a, mp_int *b);
    +int    mp_cmp_int(const mp_int *a, long z, int kmflag);
    +int    mp_isodd(const mp_int *a);
    +int    mp_iseven(const mp_int *a);
    +
    +/* Number theoretic        */
    +#if MP_NUMTH
    +mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c);
    +mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c);
    +mp_err mp_xgcd(const mp_int *a, const mp_int *b, mp_int *g, mp_int *x, mp_int *y);
    +mp_err mp_invmod(const mp_int *a, const mp_int *m, mp_int *c);
    +mp_err mp_invmod_xgcd(const mp_int *a, const mp_int *m, mp_int *c);
    +#endif /* end MP_NUMTH */
    +
    +/* Input and output        */
    +#if MP_IOFUNC
    +void   mp_print(mp_int *mp, FILE *ofp);
    +#endif /* end MP_IOFUNC */
    +
    +/* Base conversion         */
    +mp_err mp_read_raw(mp_int *mp, char *str, int len);
    +int    mp_raw_size(mp_int *mp);
    +mp_err mp_toraw(mp_int *mp, char *str);
    +mp_err mp_read_radix(mp_int *mp, const char *str, int radix);
    +mp_err mp_read_variable_radix(mp_int *a, const char * str, int default_radix);
    +int    mp_radix_size(mp_int *mp, int radix);
    +mp_err mp_toradix(mp_int *mp, char *str, int radix);
    +int    mp_tovalue(char ch, int r);
    +
    +#define mp_tobinary(M, S)  mp_toradix((M), (S), 2)
    +#define mp_tooctal(M, S)   mp_toradix((M), (S), 8)
    +#define mp_todecimal(M, S) mp_toradix((M), (S), 10)
    +#define mp_tohex(M, S)     mp_toradix((M), (S), 16)
    +
    +/* Error strings           */
    +const  char  *mp_strerror(mp_err ec);
    +
    +/* Octet string conversion functions */
    +mp_err mp_read_unsigned_octets(mp_int *mp, const unsigned char *str, mp_size len);
    +int    mp_unsigned_octet_size(const mp_int *mp);
    +mp_err mp_to_unsigned_octets(const mp_int *mp, unsigned char *str, mp_size maxlen);
    +mp_err mp_to_signed_octets(const mp_int *mp, unsigned char *str, mp_size maxlen);
    +mp_err mp_to_fixlen_octets(const mp_int *mp, unsigned char *str, mp_size len);
    +
    +/* Miscellaneous */
    +mp_size mp_trailing_zeros(const mp_int *mp);
    +
    +#define MP_CHECKOK(x)  if (MP_OKAY > (res = (x))) goto CLEANUP
    +#define MP_CHECKERR(x) if (MP_OKAY > (res = (x))) goto CLEANUP
    +
    +#if defined(MP_API_COMPATIBLE)
    +#define NEG             MP_NEG
    +#define ZPOS            MP_ZPOS
    +#define DIGIT_MAX       MP_DIGIT_MAX
    +#define DIGIT_BIT       MP_DIGIT_BIT
    +#define DIGIT_FMT       MP_DIGIT_FMT
    +#define RADIX           MP_RADIX
    +#define MAX_RADIX       MP_MAX_RADIX
    +#define FLAG(MP)        MP_FLAG(MP)
    +#define SIGN(MP)        MP_SIGN(MP)
    +#define USED(MP)        MP_USED(MP)
    +#define ALLOC(MP)       MP_ALLOC(MP)
    +#define DIGITS(MP)      MP_DIGITS(MP)
    +#define DIGIT(MP,N)     MP_DIGIT(MP,N)
    +
    +#if MP_ARGCHK == 1
    +#define  ARGCHK(X,Y)  {if(!(X)){return (Y);}}
    +#elif MP_ARGCHK == 2
    +#ifdef _KERNEL
    +#define  ARGCHK(X,Y)  ASSERT(X)
    +#else
    +#include 
    +#define  ARGCHK(X,Y)  assert(X)
    +#endif
    +#else
    +#define  ARGCHK(X,Y)  /*  */
    +#endif
    +#endif /* defined MP_API_COMPATIBLE */
    +
    +#endif /* _MPI_H */
    diff --git a/jdk/src/share/native/sun/security/ec/mplogic.c b/jdk/src/share/native/sun/security/ec/mplogic.c
    new file mode 100644
    index 00000000000..6a5f00a1c36
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/mplogic.c
    @@ -0,0 +1,242 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + *
    + *  Bitwise logical operations on MPI values
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
    + *
    + * The Initial Developer of the Original Code is
    + * Michael J. Fromberger.
    + * Portions created by the Initial Developer are Copyright (C) 1998
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +/* $Id: mplogic.c,v 1.15 2004/04/27 23:04:36 gerv%gerv.net Exp $ */
    +
    +#include "mpi-priv.h"
    +#include "mplogic.h"
    +
    +/* {{{ Lookup table for population count */
    +
    +static unsigned char bitc[] = {
    +   0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
    +   1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
    +   1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
    +   2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
    +   1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
    +   2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
    +   2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
    +   3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
    +   1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
    +   2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
    +   2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
    +   3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
    +   2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
    +   3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
    +   3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
    +   4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
    +};
    +
    +/* }}} */
    +
    +/*
    +  mpl_rsh(a, b, d)     - b = a >> d
    +  mpl_lsh(a, b, d)     - b = a << d
    + */
    +
    +/* {{{ mpl_rsh(a, b, d) */
    +
    +mp_err mpl_rsh(const mp_int *a, mp_int *b, mp_digit d)
    +{
    +  mp_err   res;
    +
    +  ARGCHK(a != NULL && b != NULL, MP_BADARG);
    +
    +  if((res = mp_copy(a, b)) != MP_OKAY)
    +    return res;
    +
    +  s_mp_div_2d(b, d);
    +
    +  return MP_OKAY;
    +
    +} /* end mpl_rsh() */
    +
    +/* }}} */
    +
    +/* {{{ mpl_lsh(a, b, d) */
    +
    +mp_err mpl_lsh(const mp_int *a, mp_int *b, mp_digit d)
    +{
    +  mp_err   res;
    +
    +  ARGCHK(a != NULL && b != NULL, MP_BADARG);
    +
    +  if((res = mp_copy(a, b)) != MP_OKAY)
    +    return res;
    +
    +  return s_mp_mul_2d(b, d);
    +
    +} /* end mpl_lsh() */
    +
    +/* }}} */
    +
    +/*------------------------------------------------------------------------*/
    +/*
    +  mpl_set_bit
    +
    +  Returns MP_OKAY or some error code.
    +  Grows a if needed to set a bit to 1.
    + */
    +mp_err mpl_set_bit(mp_int *a, mp_size bitNum, mp_size value)
    +{
    +  mp_size      ix;
    +  mp_err       rv;
    +  mp_digit     mask;
    +
    +  ARGCHK(a != NULL, MP_BADARG);
    +
    +  ix = bitNum / MP_DIGIT_BIT;
    +  if (ix + 1 > MP_USED(a)) {
    +    rv = s_mp_pad(a, ix + 1);
    +    if (rv != MP_OKAY)
    +      return rv;
    +  }
    +
    +  bitNum = bitNum % MP_DIGIT_BIT;
    +  mask = (mp_digit)1 << bitNum;
    +  if (value)
    +    MP_DIGIT(a,ix) |= mask;
    +  else
    +    MP_DIGIT(a,ix) &= ~mask;
    +  s_mp_clamp(a);
    +  return MP_OKAY;
    +}
    +
    +/*
    +  mpl_get_bit
    +
    +  returns 0 or 1 or some (negative) error code.
    + */
    +mp_err mpl_get_bit(const mp_int *a, mp_size bitNum)
    +{
    +  mp_size      bit, ix;
    +  mp_err       rv;
    +
    +  ARGCHK(a != NULL, MP_BADARG);
    +
    +  ix = bitNum / MP_DIGIT_BIT;
    +  ARGCHK(ix <= MP_USED(a) - 1, MP_RANGE);
    +
    +  bit   = bitNum % MP_DIGIT_BIT;
    +  rv = (mp_err)(MP_DIGIT(a, ix) >> bit) & 1;
    +  return rv;
    +}
    +
    +/*
    +  mpl_get_bits
    +  - Extracts numBits bits from a, where the least significant extracted bit
    +  is bit lsbNum.  Returns a negative value if error occurs.
    +  - Because sign bit is used to indicate error, maximum number of bits to
    +  be returned is the lesser of (a) the number of bits in an mp_digit, or
    +  (b) one less than the number of bits in an mp_err.
    +  - lsbNum + numbits can be greater than the number of significant bits in
    +  integer a, as long as bit lsbNum is in the high order digit of a.
    + */
    +mp_err mpl_get_bits(const mp_int *a, mp_size lsbNum, mp_size numBits)
    +{
    +  mp_size    rshift = (lsbNum % MP_DIGIT_BIT);
    +  mp_size    lsWndx = (lsbNum / MP_DIGIT_BIT);
    +  mp_digit * digit  = MP_DIGITS(a) + lsWndx;
    +  mp_digit   mask   = ((1 << numBits) - 1);
    +
    +  ARGCHK(numBits < CHAR_BIT * sizeof mask, MP_BADARG);
    +  ARGCHK(MP_HOWMANY(lsbNum, MP_DIGIT_BIT) <= MP_USED(a), MP_RANGE);
    +
    +  if ((numBits + lsbNum % MP_DIGIT_BIT <= MP_DIGIT_BIT) ||
    +      (lsWndx + 1 >= MP_USED(a))) {
    +    mask &= (digit[0] >> rshift);
    +  } else {
    +    mask &= ((digit[0] >> rshift) | (digit[1] << (MP_DIGIT_BIT - rshift)));
    +  }
    +  return (mp_err)mask;
    +}
    +
    +/*
    +  mpl_significant_bits
    +  returns number of significnant bits in abs(a).
    +  returns 1 if value is zero.
    + */
    +mp_err mpl_significant_bits(const mp_int *a)
    +{
    +  mp_err bits   = 0;
    +  int    ix;
    +
    +  ARGCHK(a != NULL, MP_BADARG);
    +
    +  ix = MP_USED(a);
    +  for (ix = MP_USED(a); ix > 0; ) {
    +    mp_digit d;
    +    d = MP_DIGIT(a, --ix);
    +    if (d) {
    +      while (d) {
    +        ++bits;
    +        d >>= 1;
    +      }
    +      break;
    +    }
    +  }
    +  bits += ix * MP_DIGIT_BIT;
    +  if (!bits)
    +    bits = 1;
    +  return bits;
    +}
    +
    +/*------------------------------------------------------------------------*/
    +/* HERE THERE BE DRAGONS                                                  */
    diff --git a/jdk/src/share/native/sun/security/ec/mplogic.h b/jdk/src/share/native/sun/security/ec/mplogic.h
    new file mode 100644
    index 00000000000..97ddb49c7ea
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/mplogic.h
    @@ -0,0 +1,105 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + *
    + *  Bitwise logical operations on MPI values
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
    + *
    + * The Initial Developer of the Original Code is
    + * Michael J. Fromberger.
    + * Portions created by the Initial Developer are Copyright (C) 1998
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#ifndef _MPLOGIC_H
    +#define _MPLOGIC_H
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +/* $Id: mplogic.h,v 1.7 2004/04/27 23:04:36 gerv%gerv.net Exp $ */
    +
    +#include "mpi.h"
    +
    +/*
    +  The logical operations treat an mp_int as if it were a bit vector,
    +  without regard to its sign (an mp_int is represented in a signed
    +  magnitude format).  Values are treated as if they had an infinite
    +  string of zeros left of the most-significant bit.
    + */
    +
    +/* Parity results                    */
    +
    +#define MP_EVEN       MP_YES
    +#define MP_ODD        MP_NO
    +
    +/* Bitwise functions                 */
    +
    +mp_err mpl_not(mp_int *a, mp_int *b);            /* one's complement  */
    +mp_err mpl_and(mp_int *a, mp_int *b, mp_int *c); /* bitwise AND       */
    +mp_err mpl_or(mp_int *a, mp_int *b, mp_int *c);  /* bitwise OR        */
    +mp_err mpl_xor(mp_int *a, mp_int *b, mp_int *c); /* bitwise XOR       */
    +
    +/* Shift functions                   */
    +
    +mp_err mpl_rsh(const mp_int *a, mp_int *b, mp_digit d);   /* right shift    */
    +mp_err mpl_lsh(const mp_int *a, mp_int *b, mp_digit d);   /* left shift     */
    +
    +/* Bit count and parity              */
    +
    +mp_err mpl_num_set(mp_int *a, int *num);         /* count set bits    */
    +mp_err mpl_num_clear(mp_int *a, int *num);       /* count clear bits  */
    +mp_err mpl_parity(mp_int *a);                    /* determine parity  */
    +
    +/* Get & Set the value of a bit */
    +
    +mp_err mpl_set_bit(mp_int *a, mp_size bitNum, mp_size value);
    +mp_err mpl_get_bit(const mp_int *a, mp_size bitNum);
    +mp_err mpl_get_bits(const mp_int *a, mp_size lsbNum, mp_size numBits);
    +mp_err mpl_significant_bits(const mp_int *a);
    +
    +#endif /* _MPLOGIC_H */
    diff --git a/jdk/src/share/native/sun/security/ec/mpmontg.c b/jdk/src/share/native/sun/security/ec/mpmontg.c
    new file mode 100644
    index 00000000000..df17f427321
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/mpmontg.c
    @@ -0,0 +1,199 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the Netscape security libraries.
    + *
    + * The Initial Developer of the Original Code is
    + * Netscape Communications Corporation.
    + * Portions created by the Initial Developer are Copyright (C) 2000
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Sheueling Chang Shantz ,
    + *   Stephen Fung , and
    + *   Douglas Stebila  of Sun Laboratories.
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +/* $Id: mpmontg.c,v 1.20 2006/08/29 02:41:38 nelson%bolyard.com Exp $ */
    +
    +/* This file implements moduluar exponentiation using Montgomery's
    + * method for modular reduction.  This file implements the method
    + * described as "Improvement 1" in the paper "A Cryptogrpahic Library for
    + * the Motorola DSP56000" by Stephen R. Dusse' and Burton S. Kaliski Jr.
    + * published in "Advances in Cryptology: Proceedings of EUROCRYPT '90"
    + * "Lecture Notes in Computer Science" volume 473, 1991, pg 230-244,
    + * published by Springer Verlag.
    + */
    +
    +#define MP_USING_CACHE_SAFE_MOD_EXP 1
    +#ifndef _KERNEL
    +#include 
    +#include  /* ptrdiff_t */
    +#endif
    +#include "mpi-priv.h"
    +#include "mplogic.h"
    +#include "mpprime.h"
    +#ifdef MP_USING_MONT_MULF
    +#include "montmulf.h"
    +#endif
    +
    +/* if MP_CHAR_STORE_SLOW is defined, we  */
    +/* need to know endianness of this platform. */
    +#ifdef MP_CHAR_STORE_SLOW
    +#if !defined(MP_IS_BIG_ENDIAN) && !defined(MP_IS_LITTLE_ENDIAN)
    +#error "You must define MP_IS_BIG_ENDIAN or MP_IS_LITTLE_ENDIAN\n" \
    +       "  if you define MP_CHAR_STORE_SLOW."
    +#endif
    +#endif
    +
    +#ifndef STATIC
    +#define STATIC
    +#endif
    +
    +#define MAX_ODD_INTS    32   /* 2 ** (WINDOW_BITS - 1) */
    +
    +#ifndef _KERNEL
    +#if defined(_WIN32_WCE)
    +#define ABORT  res = MP_UNDEF; goto CLEANUP
    +#else
    +#define ABORT abort()
    +#endif
    +#else
    +#define ABORT  res = MP_UNDEF; goto CLEANUP
    +#endif /* _KERNEL */
    +
    +/* computes T = REDC(T), 2^b == R */
    +mp_err s_mp_redc(mp_int *T, mp_mont_modulus *mmm)
    +{
    +  mp_err res;
    +  mp_size i;
    +
    +  i = MP_USED(T) + MP_USED(&mmm->N) + 2;
    +  MP_CHECKOK( s_mp_pad(T, i) );
    +  for (i = 0; i < MP_USED(&mmm->N); ++i ) {
    +    mp_digit m_i = MP_DIGIT(T, i) * mmm->n0prime;
    +    /* T += N * m_i * (MP_RADIX ** i); */
    +    MP_CHECKOK( s_mp_mul_d_add_offset(&mmm->N, m_i, T, i) );
    +  }
    +  s_mp_clamp(T);
    +
    +  /* T /= R */
    +  s_mp_div_2d(T, mmm->b);
    +
    +  if ((res = s_mp_cmp(T, &mmm->N)) >= 0) {
    +    /* T = T - N */
    +    MP_CHECKOK( s_mp_sub(T, &mmm->N) );
    +#ifdef DEBUG
    +    if ((res = mp_cmp(T, &mmm->N)) >= 0) {
    +      res = MP_UNDEF;
    +      goto CLEANUP;
    +    }
    +#endif
    +  }
    +  res = MP_OKAY;
    +CLEANUP:
    +  return res;
    +}
    +
    +#if !defined(MP_ASSEMBLY_MUL_MONT) && !defined(MP_MONT_USE_MP_MUL)
    +mp_err s_mp_mul_mont(const mp_int *a, const mp_int *b, mp_int *c,
    +                   mp_mont_modulus *mmm)
    +{
    +  mp_digit *pb;
    +  mp_digit m_i;
    +  mp_err   res;
    +  mp_size  ib;
    +  mp_size  useda, usedb;
    +
    +  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
    +
    +  if (MP_USED(a) < MP_USED(b)) {
    +    const mp_int *xch = b;      /* switch a and b, to do fewer outer loops */
    +    b = a;
    +    a = xch;
    +  }
    +
    +  MP_USED(c) = 1; MP_DIGIT(c, 0) = 0;
    +  ib = MP_USED(a) + MP_MAX(MP_USED(b), MP_USED(&mmm->N)) + 2;
    +  if((res = s_mp_pad(c, ib)) != MP_OKAY)
    +    goto CLEANUP;
    +
    +  useda = MP_USED(a);
    +  pb = MP_DIGITS(b);
    +  s_mpv_mul_d(MP_DIGITS(a), useda, *pb++, MP_DIGITS(c));
    +  s_mp_setz(MP_DIGITS(c) + useda + 1, ib - (useda + 1));
    +  m_i = MP_DIGIT(c, 0) * mmm->n0prime;
    +  s_mp_mul_d_add_offset(&mmm->N, m_i, c, 0);
    +
    +  /* Outer loop:  Digits of b */
    +  usedb = MP_USED(b);
    +  for (ib = 1; ib < usedb; ib++) {
    +    mp_digit b_i    = *pb++;
    +
    +    /* Inner product:  Digits of a */
    +    if (b_i)
    +      s_mpv_mul_d_add_prop(MP_DIGITS(a), useda, b_i, MP_DIGITS(c) + ib);
    +    m_i = MP_DIGIT(c, ib) * mmm->n0prime;
    +    s_mp_mul_d_add_offset(&mmm->N, m_i, c, ib);
    +  }
    +  if (usedb < MP_USED(&mmm->N)) {
    +    for (usedb = MP_USED(&mmm->N); ib < usedb; ++ib ) {
    +      m_i = MP_DIGIT(c, ib) * mmm->n0prime;
    +      s_mp_mul_d_add_offset(&mmm->N, m_i, c, ib);
    +    }
    +  }
    +  s_mp_clamp(c);
    +  s_mp_div_2d(c, mmm->b);
    +  if (s_mp_cmp(c, &mmm->N) >= 0) {
    +    MP_CHECKOK( s_mp_sub(c, &mmm->N) );
    +  }
    +  res = MP_OKAY;
    +
    +CLEANUP:
    +  return res;
    +}
    +#endif
    diff --git a/jdk/src/share/native/sun/security/ec/mpprime.h b/jdk/src/share/native/sun/security/ec/mpprime.h
    new file mode 100644
    index 00000000000..78bcb18352a
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/mpprime.h
    @@ -0,0 +1,89 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + *
    + *  Utilities for finding and working with prime and pseudo-prime
    + *  integers
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
    + *
    + * The Initial Developer of the Original Code is
    + * Michael J. Fromberger.
    + * Portions created by the Initial Developer are Copyright (C) 1997
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#ifndef _MP_PRIME_H
    +#define _MP_PRIME_H
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +#include "mpi.h"
    +
    +extern const int prime_tab_size;   /* number of primes available */
    +extern const mp_digit prime_tab[];
    +
    +/* Tests for divisibility    */
    +mp_err  mpp_divis(mp_int *a, mp_int *b);
    +mp_err  mpp_divis_d(mp_int *a, mp_digit d);
    +
    +/* Random selection          */
    +mp_err  mpp_random(mp_int *a);
    +mp_err  mpp_random_size(mp_int *a, mp_size prec);
    +
    +/* Pseudo-primality testing  */
    +mp_err  mpp_divis_vector(mp_int *a, const mp_digit *vec, int size, int *which);
    +mp_err  mpp_divis_primes(mp_int *a, mp_digit *np);
    +mp_err  mpp_fermat(mp_int *a, mp_digit w);
    +mp_err mpp_fermat_list(mp_int *a, const mp_digit *primes, mp_size nPrimes);
    +mp_err  mpp_pprime(mp_int *a, int nt);
    +mp_err mpp_sieve(mp_int *trial, const mp_digit *primes, mp_size nPrimes,
    +                 unsigned char *sieve, mp_size nSieve);
    +mp_err mpp_make_prime(mp_int *start, mp_size nBits, mp_size strong,
    +                      unsigned long * nTries);
    +
    +#endif /* _MP_PRIME_H */
    diff --git a/jdk/src/share/native/sun/security/ec/oid.c b/jdk/src/share/native/sun/security/ec/oid.c
    new file mode 100644
    index 00000000000..f3ced99bcb5
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/oid.c
    @@ -0,0 +1,473 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the Netscape security libraries.
    + *
    + * The Initial Developer of the Original Code is
    + * Netscape Communications Corporation.
    + * Portions created by the Initial Developer are Copyright (C) 1994-2000
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Dr Vipul Gupta , Sun Microsystems Laboratories
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +#include 
    +
    +#ifndef _WIN32
    +#ifndef __linux__
    +#include 
    +#endif /* __linux__ */
    +#include 
    +#endif /* _WIN32 */
    +
    +#ifdef _KERNEL
    +#include 
    +#else
    +#include 
    +#endif
    +#include "ec.h"
    +#include "ecl-curve.h"
    +#include "ecc_impl.h"
    +#include "secoidt.h"
    +
    +#define CERTICOM_OID            0x2b, 0x81, 0x04
    +#define SECG_OID                CERTICOM_OID, 0x00
    +
    +#define ANSI_X962_OID           0x2a, 0x86, 0x48, 0xce, 0x3d
    +#define ANSI_X962_CURVE_OID     ANSI_X962_OID, 0x03
    +#define ANSI_X962_GF2m_OID      ANSI_X962_CURVE_OID, 0x00
    +#define ANSI_X962_GFp_OID       ANSI_X962_CURVE_OID, 0x01
    +
    +#define CONST_OID static const unsigned char
    +
    +/* ANSI X9.62 prime curve OIDs */
    +/* NOTE: prime192v1 is the same as secp192r1, prime256v1 is the
    + * same as secp256r1
    + */
    +CONST_OID ansiX962prime192v1[] = { ANSI_X962_GFp_OID, 0x01 };
    +CONST_OID ansiX962prime192v2[] = { ANSI_X962_GFp_OID, 0x02 };
    +CONST_OID ansiX962prime192v3[] = { ANSI_X962_GFp_OID, 0x03 };
    +CONST_OID ansiX962prime239v1[] = { ANSI_X962_GFp_OID, 0x04 };
    +CONST_OID ansiX962prime239v2[] = { ANSI_X962_GFp_OID, 0x05 };
    +CONST_OID ansiX962prime239v3[] = { ANSI_X962_GFp_OID, 0x06 };
    +CONST_OID ansiX962prime256v1[] = { ANSI_X962_GFp_OID, 0x07 };
    +
    +/* SECG prime curve OIDs */
    +CONST_OID secgECsecp112r1[] = { SECG_OID, 0x06 };
    +CONST_OID secgECsecp112r2[] = { SECG_OID, 0x07 };
    +CONST_OID secgECsecp128r1[] = { SECG_OID, 0x1c };
    +CONST_OID secgECsecp128r2[] = { SECG_OID, 0x1d };
    +CONST_OID secgECsecp160k1[] = { SECG_OID, 0x09 };
    +CONST_OID secgECsecp160r1[] = { SECG_OID, 0x08 };
    +CONST_OID secgECsecp160r2[] = { SECG_OID, 0x1e };
    +CONST_OID secgECsecp192k1[] = { SECG_OID, 0x1f };
    +CONST_OID secgECsecp224k1[] = { SECG_OID, 0x20 };
    +CONST_OID secgECsecp224r1[] = { SECG_OID, 0x21 };
    +CONST_OID secgECsecp256k1[] = { SECG_OID, 0x0a };
    +CONST_OID secgECsecp384r1[] = { SECG_OID, 0x22 };
    +CONST_OID secgECsecp521r1[] = { SECG_OID, 0x23 };
    +
    +/* SECG characterisitic two curve OIDs */
    +CONST_OID secgECsect113r1[] = {SECG_OID, 0x04 };
    +CONST_OID secgECsect113r2[] = {SECG_OID, 0x05 };
    +CONST_OID secgECsect131r1[] = {SECG_OID, 0x16 };
    +CONST_OID secgECsect131r2[] = {SECG_OID, 0x17 };
    +CONST_OID secgECsect163k1[] = {SECG_OID, 0x01 };
    +CONST_OID secgECsect163r1[] = {SECG_OID, 0x02 };
    +CONST_OID secgECsect163r2[] = {SECG_OID, 0x0f };
    +CONST_OID secgECsect193r1[] = {SECG_OID, 0x18 };
    +CONST_OID secgECsect193r2[] = {SECG_OID, 0x19 };
    +CONST_OID secgECsect233k1[] = {SECG_OID, 0x1a };
    +CONST_OID secgECsect233r1[] = {SECG_OID, 0x1b };
    +CONST_OID secgECsect239k1[] = {SECG_OID, 0x03 };
    +CONST_OID secgECsect283k1[] = {SECG_OID, 0x10 };
    +CONST_OID secgECsect283r1[] = {SECG_OID, 0x11 };
    +CONST_OID secgECsect409k1[] = {SECG_OID, 0x24 };
    +CONST_OID secgECsect409r1[] = {SECG_OID, 0x25 };
    +CONST_OID secgECsect571k1[] = {SECG_OID, 0x26 };
    +CONST_OID secgECsect571r1[] = {SECG_OID, 0x27 };
    +
    +/* ANSI X9.62 characteristic two curve OIDs */
    +CONST_OID ansiX962c2pnb163v1[] = { ANSI_X962_GF2m_OID, 0x01 };
    +CONST_OID ansiX962c2pnb163v2[] = { ANSI_X962_GF2m_OID, 0x02 };
    +CONST_OID ansiX962c2pnb163v3[] = { ANSI_X962_GF2m_OID, 0x03 };
    +CONST_OID ansiX962c2pnb176v1[] = { ANSI_X962_GF2m_OID, 0x04 };
    +CONST_OID ansiX962c2tnb191v1[] = { ANSI_X962_GF2m_OID, 0x05 };
    +CONST_OID ansiX962c2tnb191v2[] = { ANSI_X962_GF2m_OID, 0x06 };
    +CONST_OID ansiX962c2tnb191v3[] = { ANSI_X962_GF2m_OID, 0x07 };
    +CONST_OID ansiX962c2onb191v4[] = { ANSI_X962_GF2m_OID, 0x08 };
    +CONST_OID ansiX962c2onb191v5[] = { ANSI_X962_GF2m_OID, 0x09 };
    +CONST_OID ansiX962c2pnb208w1[] = { ANSI_X962_GF2m_OID, 0x0a };
    +CONST_OID ansiX962c2tnb239v1[] = { ANSI_X962_GF2m_OID, 0x0b };
    +CONST_OID ansiX962c2tnb239v2[] = { ANSI_X962_GF2m_OID, 0x0c };
    +CONST_OID ansiX962c2tnb239v3[] = { ANSI_X962_GF2m_OID, 0x0d };
    +CONST_OID ansiX962c2onb239v4[] = { ANSI_X962_GF2m_OID, 0x0e };
    +CONST_OID ansiX962c2onb239v5[] = { ANSI_X962_GF2m_OID, 0x0f };
    +CONST_OID ansiX962c2pnb272w1[] = { ANSI_X962_GF2m_OID, 0x10 };
    +CONST_OID ansiX962c2pnb304w1[] = { ANSI_X962_GF2m_OID, 0x11 };
    +CONST_OID ansiX962c2tnb359v1[] = { ANSI_X962_GF2m_OID, 0x12 };
    +CONST_OID ansiX962c2pnb368w1[] = { ANSI_X962_GF2m_OID, 0x13 };
    +CONST_OID ansiX962c2tnb431r1[] = { ANSI_X962_GF2m_OID, 0x14 };
    +
    +#define OI(x) { siDEROID, (unsigned char *)x, sizeof x }
    +#ifndef SECOID_NO_STRINGS
    +#define OD(oid,tag,desc,mech,ext) { OI(oid), tag, desc, mech, ext }
    +#else
    +#define OD(oid,tag,desc,mech,ext) { OI(oid), tag, 0, mech, ext }
    +#endif
    +
    +#define CKM_INVALID_MECHANISM 0xffffffffUL
    +
    +/* XXX this is incorrect */
    +#define INVALID_CERT_EXTENSION 1
    +
    +#define CKM_ECDSA                      0x00001041
    +#define CKM_ECDSA_SHA1                 0x00001042
    +#define CKM_ECDH1_DERIVE               0x00001050
    +
    +static SECOidData ANSI_prime_oids[] = {
    +    { { siDEROID, NULL, 0 }, ECCurve_noName,
    +        "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
    +
    +    OD( ansiX962prime192v1, ECCurve_NIST_P192,
    +        "ANSI X9.62 elliptic curve prime192v1 (aka secp192r1, NIST P-192)",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( ansiX962prime192v2, ECCurve_X9_62_PRIME_192V2,
    +        "ANSI X9.62 elliptic curve prime192v2",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( ansiX962prime192v3, ECCurve_X9_62_PRIME_192V3,
    +        "ANSI X9.62 elliptic curve prime192v3",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( ansiX962prime239v1, ECCurve_X9_62_PRIME_239V1,
    +        "ANSI X9.62 elliptic curve prime239v1",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( ansiX962prime239v2, ECCurve_X9_62_PRIME_239V2,
    +        "ANSI X9.62 elliptic curve prime239v2",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( ansiX962prime239v3, ECCurve_X9_62_PRIME_239V3,
    +        "ANSI X9.62 elliptic curve prime239v3",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( ansiX962prime256v1, ECCurve_NIST_P256,
    +        "ANSI X9.62 elliptic curve prime256v1 (aka secp256r1, NIST P-256)",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION )
    +};
    +
    +static SECOidData SECG_oids[] = {
    +    { { siDEROID, NULL, 0 }, ECCurve_noName,
    +        "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
    +
    +    OD( secgECsect163k1, ECCurve_NIST_K163,
    +        "SECG elliptic curve sect163k1 (aka NIST K-163)",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( secgECsect163r1, ECCurve_SECG_CHAR2_163R1,
    +        "SECG elliptic curve sect163r1",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( secgECsect239k1, ECCurve_SECG_CHAR2_239K1,
    +        "SECG elliptic curve sect239k1",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( secgECsect113r1, ECCurve_SECG_CHAR2_113R1,
    +        "SECG elliptic curve sect113r1",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( secgECsect113r2, ECCurve_SECG_CHAR2_113R2,
    +        "SECG elliptic curve sect113r2",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( secgECsecp112r1, ECCurve_SECG_PRIME_112R1,
    +        "SECG elliptic curve secp112r1",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( secgECsecp112r2, ECCurve_SECG_PRIME_112R2,
    +        "SECG elliptic curve secp112r2",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( secgECsecp160r1, ECCurve_SECG_PRIME_160R1,
    +        "SECG elliptic curve secp160r1",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( secgECsecp160k1, ECCurve_SECG_PRIME_160K1,
    +        "SECG elliptic curve secp160k1",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( secgECsecp256k1, ECCurve_SECG_PRIME_256K1,
    +        "SECG elliptic curve secp256k1",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    { { siDEROID, NULL, 0 }, ECCurve_noName,
    +        "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
    +    { { siDEROID, NULL, 0 }, ECCurve_noName,
    +        "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
    +    { { siDEROID, NULL, 0 }, ECCurve_noName,
    +        "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
    +    { { siDEROID, NULL, 0 }, ECCurve_noName,
    +        "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
    +    OD( secgECsect163r2, ECCurve_NIST_B163,
    +        "SECG elliptic curve sect163r2 (aka NIST B-163)",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( secgECsect283k1, ECCurve_NIST_K283,
    +        "SECG elliptic curve sect283k1 (aka NIST K-283)",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( secgECsect283r1, ECCurve_NIST_B283,
    +        "SECG elliptic curve sect283r1 (aka NIST B-283)",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    { { siDEROID, NULL, 0 }, ECCurve_noName,
    +        "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
    +    { { siDEROID, NULL, 0 }, ECCurve_noName,
    +        "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
    +    { { siDEROID, NULL, 0 }, ECCurve_noName,
    +        "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
    +    { { siDEROID, NULL, 0 }, ECCurve_noName,
    +        "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
    +    OD( secgECsect131r1, ECCurve_SECG_CHAR2_131R1,
    +        "SECG elliptic curve sect131r1",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( secgECsect131r2, ECCurve_SECG_CHAR2_131R2,
    +        "SECG elliptic curve sect131r2",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( secgECsect193r1, ECCurve_SECG_CHAR2_193R1,
    +        "SECG elliptic curve sect193r1",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( secgECsect193r2, ECCurve_SECG_CHAR2_193R2,
    +        "SECG elliptic curve sect193r2",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( secgECsect233k1, ECCurve_NIST_K233,
    +        "SECG elliptic curve sect233k1 (aka NIST K-233)",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( secgECsect233r1, ECCurve_NIST_B233,
    +        "SECG elliptic curve sect233r1 (aka NIST B-233)",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( secgECsecp128r1, ECCurve_SECG_PRIME_128R1,
    +        "SECG elliptic curve secp128r1",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( secgECsecp128r2, ECCurve_SECG_PRIME_128R2,
    +        "SECG elliptic curve secp128r2",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( secgECsecp160r2, ECCurve_SECG_PRIME_160R2,
    +        "SECG elliptic curve secp160r2",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( secgECsecp192k1, ECCurve_SECG_PRIME_192K1,
    +        "SECG elliptic curve secp192k1",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( secgECsecp224k1, ECCurve_SECG_PRIME_224K1,
    +        "SECG elliptic curve secp224k1",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( secgECsecp224r1, ECCurve_NIST_P224,
    +        "SECG elliptic curve secp224r1 (aka NIST P-224)",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( secgECsecp384r1, ECCurve_NIST_P384,
    +        "SECG elliptic curve secp384r1 (aka NIST P-384)",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( secgECsecp521r1, ECCurve_NIST_P521,
    +        "SECG elliptic curve secp521r1 (aka NIST P-521)",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( secgECsect409k1, ECCurve_NIST_K409,
    +        "SECG elliptic curve sect409k1 (aka NIST K-409)",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( secgECsect409r1, ECCurve_NIST_B409,
    +        "SECG elliptic curve sect409r1 (aka NIST B-409)",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( secgECsect571k1, ECCurve_NIST_K571,
    +        "SECG elliptic curve sect571k1 (aka NIST K-571)",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( secgECsect571r1, ECCurve_NIST_B571,
    +        "SECG elliptic curve sect571r1 (aka NIST B-571)",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION )
    +};
    +
    +static SECOidData ANSI_oids[] = {
    +    { { siDEROID, NULL, 0 }, ECCurve_noName,
    +        "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
    +
    +    /* ANSI X9.62 named elliptic curves (characteristic two field) */
    +    OD( ansiX962c2pnb163v1, ECCurve_X9_62_CHAR2_PNB163V1,
    +        "ANSI X9.62 elliptic curve c2pnb163v1",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( ansiX962c2pnb163v2, ECCurve_X9_62_CHAR2_PNB163V2,
    +        "ANSI X9.62 elliptic curve c2pnb163v2",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( ansiX962c2pnb163v3, ECCurve_X9_62_CHAR2_PNB163V3,
    +        "ANSI X9.62 elliptic curve c2pnb163v3",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( ansiX962c2pnb176v1, ECCurve_X9_62_CHAR2_PNB176V1,
    +        "ANSI X9.62 elliptic curve c2pnb176v1",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( ansiX962c2tnb191v1, ECCurve_X9_62_CHAR2_TNB191V1,
    +        "ANSI X9.62 elliptic curve c2tnb191v1",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( ansiX962c2tnb191v2, ECCurve_X9_62_CHAR2_TNB191V2,
    +        "ANSI X9.62 elliptic curve c2tnb191v2",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( ansiX962c2tnb191v3, ECCurve_X9_62_CHAR2_TNB191V3,
    +        "ANSI X9.62 elliptic curve c2tnb191v3",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    { { siDEROID, NULL, 0 }, ECCurve_noName,
    +        "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
    +    { { siDEROID, NULL, 0 }, ECCurve_noName,
    +        "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
    +    OD( ansiX962c2pnb208w1, ECCurve_X9_62_CHAR2_PNB208W1,
    +        "ANSI X9.62 elliptic curve c2pnb208w1",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( ansiX962c2tnb239v1, ECCurve_X9_62_CHAR2_TNB239V1,
    +        "ANSI X9.62 elliptic curve c2tnb239v1",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( ansiX962c2tnb239v2, ECCurve_X9_62_CHAR2_TNB239V2,
    +        "ANSI X9.62 elliptic curve c2tnb239v2",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( ansiX962c2tnb239v3, ECCurve_X9_62_CHAR2_TNB239V3,
    +        "ANSI X9.62 elliptic curve c2tnb239v3",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    { { siDEROID, NULL, 0 }, ECCurve_noName,
    +        "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
    +    { { siDEROID, NULL, 0 }, ECCurve_noName,
    +        "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
    +    OD( ansiX962c2pnb272w1, ECCurve_X9_62_CHAR2_PNB272W1,
    +        "ANSI X9.62 elliptic curve c2pnb272w1",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( ansiX962c2pnb304w1, ECCurve_X9_62_CHAR2_PNB304W1,
    +        "ANSI X9.62 elliptic curve c2pnb304w1",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( ansiX962c2tnb359v1, ECCurve_X9_62_CHAR2_TNB359V1,
    +        "ANSI X9.62 elliptic curve c2tnb359v1",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( ansiX962c2pnb368w1, ECCurve_X9_62_CHAR2_PNB368W1,
    +        "ANSI X9.62 elliptic curve c2pnb368w1",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION ),
    +    OD( ansiX962c2tnb431r1, ECCurve_X9_62_CHAR2_TNB431R1,
    +        "ANSI X9.62 elliptic curve c2tnb431r1",
    +        CKM_INVALID_MECHANISM,
    +        INVALID_CERT_EXTENSION )
    +};
    +
    +SECOidData *
    +SECOID_FindOID(const SECItem *oid)
    +{
    +    SECOidData *po;
    +    SECOidData *ret;
    +    int i;
    +
    +    if (oid->len == 8) {
    +        if (oid->data[6] == 0x00) {
    +                /* XXX bounds check */
    +                po = &ANSI_oids[oid->data[7]];
    +                if (memcmp(oid->data, po->oid.data, 8) == 0)
    +                        ret = po;
    +        }
    +        if (oid->data[6] == 0x01) {
    +                /* XXX bounds check */
    +                po = &ANSI_prime_oids[oid->data[7]];
    +                if (memcmp(oid->data, po->oid.data, 8) == 0)
    +                        ret = po;
    +        }
    +    } else if (oid->len == 5) {
    +        /* XXX bounds check */
    +        po = &SECG_oids[oid->data[4]];
    +        if (memcmp(oid->data, po->oid.data, 5) == 0)
    +                ret = po;
    +    } else {
    +        ret = NULL;
    +    }
    +    return(ret);
    +}
    +
    +ECCurveName
    +SECOID_FindOIDTag(const SECItem *oid)
    +{
    +    SECOidData *oiddata;
    +
    +    oiddata = SECOID_FindOID (oid);
    +    if (oiddata == NULL)
    +        return ECCurve_noName;
    +
    +    return oiddata->offset;
    +}
    diff --git a/jdk/src/share/native/sun/security/ec/secitem.c b/jdk/src/share/native/sun/security/ec/secitem.c
    new file mode 100644
    index 00000000000..d9daacc8bc4
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/secitem.c
    @@ -0,0 +1,199 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the Netscape security libraries.
    + *
    + * The Initial Developer of the Original Code is
    + * Netscape Communications Corporation.
    + * Portions created by the Initial Developer are Copyright (C) 1994-2000
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +/*
    + * Support routines for SECItem data structure.
    + *
    + * $Id: secitem.c,v 1.14 2006/05/22 22:24:34 wtchang%redhat.com Exp $
    + */
    +
    +#include 
    +
    +#ifndef _WIN32
    +#ifndef __linux__
    +#include 
    +#endif /* __linux__ */
    +#include 
    +#endif /* _WIN32 */
    +
    +#ifdef _KERNEL
    +#include 
    +#else
    +#include 
    +
    +#ifndef _WIN32
    +#include 
    +#endif /* _WIN32 */
    +
    +#include 
    +#endif
    +#include "ec.h"
    +#include "ecl-curve.h"
    +#include "ecc_impl.h"
    +
    +void SECITEM_FreeItem(SECItem *, PRBool);
    +
    +SECItem *
    +SECITEM_AllocItem(PRArenaPool *arena, SECItem *item, unsigned int len,
    +    int kmflag)
    +{
    +    SECItem *result = NULL;
    +    void *mark = NULL;
    +
    +    if (arena != NULL) {
    +        mark = PORT_ArenaMark(arena);
    +    }
    +
    +    if (item == NULL) {
    +        if (arena != NULL) {
    +            result = PORT_ArenaZAlloc(arena, sizeof(SECItem), kmflag);
    +        } else {
    +            result = PORT_ZAlloc(sizeof(SECItem), kmflag);
    +        }
    +        if (result == NULL) {
    +            goto loser;
    +        }
    +    } else {
    +        PORT_Assert(item->data == NULL);
    +        result = item;
    +    }
    +
    +    result->len = len;
    +    if (len) {
    +        if (arena != NULL) {
    +            result->data = PORT_ArenaAlloc(arena, len, kmflag);
    +        } else {
    +            result->data = PORT_Alloc(len, kmflag);
    +        }
    +        if (result->data == NULL) {
    +            goto loser;
    +        }
    +    } else {
    +        result->data = NULL;
    +    }
    +
    +    if (mark) {
    +        PORT_ArenaUnmark(arena, mark);
    +    }
    +    return(result);
    +
    +loser:
    +    if ( arena != NULL ) {
    +        if (mark) {
    +            PORT_ArenaRelease(arena, mark);
    +        }
    +        if (item != NULL) {
    +            item->data = NULL;
    +            item->len = 0;
    +        }
    +    } else {
    +        if (result != NULL) {
    +            SECITEM_FreeItem(result, (item == NULL) ? PR_TRUE : PR_FALSE);
    +        }
    +        /*
    +         * If item is not NULL, the above has set item->data and
    +         * item->len to 0.
    +         */
    +    }
    +    return(NULL);
    +}
    +
    +SECStatus
    +SECITEM_CopyItem(PRArenaPool *arena, SECItem *to, const SECItem *from,
    +   int kmflag)
    +{
    +    to->type = from->type;
    +    if (from->data && from->len) {
    +        if ( arena ) {
    +            to->data = (unsigned char*) PORT_ArenaAlloc(arena, from->len,
    +                kmflag);
    +        } else {
    +            to->data = (unsigned char*) PORT_Alloc(from->len, kmflag);
    +        }
    +
    +        if (!to->data) {
    +            return SECFailure;
    +        }
    +        PORT_Memcpy(to->data, from->data, from->len);
    +        to->len = from->len;
    +    } else {
    +        to->data = 0;
    +        to->len = 0;
    +    }
    +    return SECSuccess;
    +}
    +
    +void
    +SECITEM_FreeItem(SECItem *zap, PRBool freeit)
    +{
    +    if (zap) {
    +#ifdef _KERNEL
    +        kmem_free(zap->data, zap->len);
    +#else
    +        free(zap->data);
    +#endif
    +        zap->data = 0;
    +        zap->len = 0;
    +        if (freeit) {
    +#ifdef _KERNEL
    +            kmem_free(zap, sizeof (SECItem));
    +#else
    +            free(zap);
    +#endif
    +        }
    +    }
    +}
    diff --git a/jdk/src/share/native/sun/security/ec/secoidt.h b/jdk/src/share/native/sun/security/ec/secoidt.h
    new file mode 100644
    index 00000000000..0935388cdb8
    --- /dev/null
    +++ b/jdk/src/share/native/sun/security/ec/secoidt.h
    @@ -0,0 +1,103 @@
    +/* *********************************************************************
    + *
    + * Sun elects to have this file available under and governed by the
    + * Mozilla Public License Version 1.1 ("MPL") (see
    + * http://www.mozilla.org/MPL/ for full license text). For the avoidance
    + * of doubt and subject to the following, Sun also elects to allow
    + * licensees to use this file under the MPL, the GNU General Public
    + * License version 2 only or the Lesser General Public License version
    + * 2.1 only. Any references to the "GNU General Public License version 2
    + * or later" or "GPL" in the following shall be construed to mean the
    + * GNU General Public License version 2 only. Any references to the "GNU
    + * Lesser General Public License version 2.1 or later" or "LGPL" in the
    + * following shall be construed to mean the GNU Lesser General Public
    + * License version 2.1 only. However, the following notice accompanied
    + * the original version of this file:
    + *
    + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    + *
    + * The contents of this file are subject to the Mozilla Public License Version
    + * 1.1 (the "License"); you may not use this file except in compliance with
    + * the License. You may obtain a copy of the License at
    + * http://www.mozilla.org/MPL/
    + *
    + * Software distributed under the License is distributed on an "AS IS" basis,
    + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    + * for the specific language governing rights and limitations under the
    + * License.
    + *
    + * The Original Code is the Netscape security libraries.
    + *
    + * The Initial Developer of the Original Code is
    + * Netscape Communications Corporation.
    + * Portions created by the Initial Developer are Copyright (C) 1994-2000
    + * the Initial Developer. All Rights Reserved.
    + *
    + * Contributor(s):
    + *   Dr Vipul Gupta , Sun Microsystems Laboratories
    + *
    + * Alternatively, the contents of this file may be used under the terms of
    + * either the GNU General Public License Version 2 or later (the "GPL"), or
    + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    + * in which case the provisions of the GPL or the LGPL are applicable instead
    + * of those above. If you wish to allow use of your version of this file only
    + * under the terms of either the GPL or the LGPL, and not to allow others to
    + * use your version of this file under the terms of the MPL, indicate your
    + * decision by deleting the provisions above and replace them with the notice
    + * and other provisions required by the GPL or the LGPL. If you do not delete
    + * the provisions above, a recipient may use your version of this file under
    + * the terms of any one of the MPL, the GPL or the LGPL.
    + *
    + *********************************************************************** */
    +/*
    + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    + * Use is subject to license terms.
    + */
    +
    +#ifndef _SECOIDT_H_
    +#define _SECOIDT_H_
    +
    +#pragma ident   "%Z%%M% %I%     %E% SMI"
    +
    +/*
    + * secoidt.h - public data structures for ASN.1 OID functions
    + *
    + * $Id: secoidt.h,v 1.23 2007/05/05 22:45:16 nelson%bolyard.com Exp $
    + */
    +
    +typedef struct SECOidDataStr SECOidData;
    +typedef struct SECAlgorithmIDStr SECAlgorithmID;
    +
    +/*
    +** An X.500 algorithm identifier
    +*/
    +struct SECAlgorithmIDStr {
    +    SECItem algorithm;
    +    SECItem parameters;
    +};
    +
    +#define SEC_OID_SECG_EC_SECP192R1 SEC_OID_ANSIX962_EC_PRIME192V1
    +#define SEC_OID_SECG_EC_SECP256R1 SEC_OID_ANSIX962_EC_PRIME256V1
    +#define SEC_OID_PKCS12_KEY_USAGE  SEC_OID_X509_KEY_USAGE
    +
    +/* fake OID for DSS sign/verify */
    +#define SEC_OID_SHA SEC_OID_MISS_DSS
    +
    +typedef enum {
    +    INVALID_CERT_EXTENSION = 0,
    +    UNSUPPORTED_CERT_EXTENSION = 1,
    +    SUPPORTED_CERT_EXTENSION = 2
    +} SECSupportExtenTag;
    +
    +struct SECOidDataStr {
    +    SECItem            oid;
    +    ECCurveName        offset;
    +    const char *       desc;
    +    unsigned long      mechanism;
    +    SECSupportExtenTag supportedExtension;
    +                                /* only used for x.509 v3 extensions, so
    +                                   that we can print the names of those
    +                                   extensions that we don't even support */
    +};
    +
    +#endif /* _SECOIDT_H_ */
    diff --git a/jdk/test/sun/security/ec/TestEC.java b/jdk/test/sun/security/ec/TestEC.java
    new file mode 100644
    index 00000000000..0f87692a01a
    --- /dev/null
    +++ b/jdk/test/sun/security/ec/TestEC.java
    @@ -0,0 +1,66 @@
    +/*
    + * Copyright 2009 Sun Microsystems, Inc.  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.
    + *
    + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    + * CA 95054 USA or visit www.sun.com if you need additional information or
    + * have any questions.
    + */
    +
    +/**
    + * @test
    + * @bug 6840752
    + * @summary  Provide out-of-the-box support for ECC algorithms
    + * @library ../pkcs11
    + * @library ../pkcs11/ec
    + * @run main TestEC
    + */
    +
    +import java.security.Provider;
    +
    +/*
    + * Leverage the collection of EC tests used by PKCS11
    + *
    + * NOTE: the following files were copied here from the PKCS11 EC Test area
    + *       and must be kept in sync with the originals:
    + *
    + *           ../pkcs11/ec/p12passwords.txt
    + *           ../pkcs11/ec/pkcs12/secp256r1server-secp384r1ca.p12
    + *           ../pkcs11/ec/pkcs12/sect193r1server-rsa1024ca.p12
    + */
    +
    +public class TestEC {
    +
    +    public static void main(String[] args) throws Exception {
    +        Provider p = new sun.security.ec.SunEC();
    +        System.out.println("Running tests with " + p.getName() +
    +            " provider...\n");
    +
    +        long start = System.currentTimeMillis();
    +        new TestECDH().main(p);
    +        new TestECDSA().main(p);
    +        //new TestCurves().main(p);
    +        new TestKeyFactory().main(p);
    +        new TestECGenSpec().main(p);
    +        new ReadPKCS12().main(p);
    +        //new ReadCertificates().main(p);
    +        long stop = System.currentTimeMillis();
    +
    +        System.out.println("\nCompleted tests with " + p.getName() +
    +            " provider (" + (stop - start) + " ms).");
    +    }
    +}
    diff --git a/jdk/test/sun/security/ec/p12passwords.txt b/jdk/test/sun/security/ec/p12passwords.txt
    new file mode 100644
    index 00000000000..62f620cbdba
    --- /dev/null
    +++ b/jdk/test/sun/security/ec/p12passwords.txt
    @@ -0,0 +1,18 @@
    +# MS_ECC_Samples.zip
    +256-ecc.pfx ecc
    +256_2-ecc.pfx ecc
    +384-ecc.pfx ecc
    +521-ecc.pfx ecc
    +# MS_Client_certs.zip
    +eccclicert256.pfx 1
    +eccclicert384.pfx 1
    +eccclicert521.pfx 1
    +# NSS_ECC_PKCS12.zip
    +ECCp160.p12 ecc
    +ECCp192.p12 ecc
    +ECCp224.p12 ecc
    +ECCp256.p12 ecc
    +ECCp384.p12 ecc
    +ECCp521.p12 ecc
    +# All other files
    +* password
    diff --git a/jdk/test/sun/security/ec/pkcs12/secp256r1server-secp384r1ca.p12 b/jdk/test/sun/security/ec/pkcs12/secp256r1server-secp384r1ca.p12
    new file mode 100644
    index 0000000000000000000000000000000000000000..1a23788103d6806f2e5e95ca871e4a2426ae705f
    GIT binary patch
    literal 1273
    zcmXqLV)@F%$ZXKWvYU-ltIebBJ1-+Uf{wF9++VsK}*HWcjpIJkd*1GF{u|gMH~)tC_D|V;eW>
    zTF(}r6(=*}uZz9)r;-EGbKfgy>+&b>the!xvRqd#ck{j1haJIN;$NTERobaG@l(F2
    zXyYw;zhjH0v)`zDpD6K$TSBnERW|SSuO&>~;?qz3PCi;%BV^LOd+Ux>th|?QetcHF
    zWufw#l1&`fAABnR$|n|_lCG4Ybw4N}aBtH74?HfxjS|u`rB_*H2JL;=ByDS7df?x_
    zYq5P(^3@zIb)H>y*dw{wX2#A_8T%6X{uvs)_gWWh^5Dd>zD<(_3xi5tY1WyVgz3o6
    zSRBF>C~{^_*<6|Qx7@j}{TbGLaIzCJdGyD+?Rxav`x_VD)c&npM1Jy-GJ%
    zlHq)xEBqd{{};R8Gs^Z@P;8jBm8Ho^ZXOAp8V5Df1J~j4nRI!8q%qvHm_Z+%uZ=q*%e2>+Enfx!j
    z8>RK9t2UpN`%&83w#X{;mF=VK$>(3aNXfDml(JUZ%6cj5_}^>KK7T*GBw4xL=jrXa
    zy^|kL)BmJ)^WkJS?+MQ|R(El>6n+w4;(Xrc-y+*w_BFFpkEpLwOZ_{cG^zRL;+o|l+ILSr<#7r?6f$=Dxx4@WPREzN(!{n%CG-!1=))_--p
    zw`9ASiLtILpU|tDx;AYy`W}B@49rrDzDOBoK@+1LOB16NP}mHJjo7$h*@%mgX+h%_
    zgT{?0d5am8w{~kvMYFf^2!iq!OXGy_Wk&j;ec9%B#aSo(yqXi2di|u)T<5LlU&lB5
    zrWJ%QHIO@=qUZ9+hPmoxf2PIar-#f}ZB_I*kQ09Thw|r79?@re4@T$an(R7xIY?)^
    z!>xNo#o?C|x%%H!NxpC9zU5o-VzP2mo;=_7ht4&|J;EvXEvGfSsN3CJ!y(@}Ni5#w
    zZhy-YQK>CQdO5^byqRIC?QfW4pbYmSr>LPAi-^%JmF-6sCoZx1bdi5?Ip_R)51zj?
    za78E*F|?2~V<=`wWk_ZyU@&4ZWiVqXVlV`Y6fu+m#funp;qt}|77Qj}`DBJf149Ev
    z15P$pZ9ZluDOLs+kzKq=j(h#x7T(U<#Gp6nHSa3r`A1kd?%s0uuesQ21qw3&G^`!C
    
    literal 0
    HcmV?d00001
    
    diff --git a/jdk/test/sun/security/ec/pkcs12/sect193r1server-rsa1024ca.p12 b/jdk/test/sun/security/ec/pkcs12/sect193r1server-rsa1024ca.p12
    new file mode 100644
    index 0000000000000000000000000000000000000000..ed4d861e4ca49cf3a574a67f52b8848306f69fe2
    GIT binary patch
    literal 1252
    zcmXqLVtK&C$ZXKWvW$&WtIebBJ1-+U
    zf*B7y*8H!PHP@--pWdg159{8oE>R6m)wk>WC-#}!CAi~)#Qe3%t3G7RHLhB6G3VBr
    zsam~pr$b~JoqaD@f3ww-*_7&(^@0CU%AUK9TNozJy;J
    zA7PNCc`xB|X#PBgLcL|dihD|5Imy2b+;5xJy86Q6Ko{;bcGD>-0XH9O>^{9?%CyrFNPi9h6tIuZC|cW?f$#JkV`Pc@HGT<*c7BJ*hBjd$%U
    zuH^Zo$i-^BSK(NAO@8O=yXTmHy%#FlW4PiRXYwm9MN98S+wG|)qOvB8J=a3}51jQ&
    zdUff@_AO$SR*pM;H~#v!$nV&rFUJk9HyUkYn3NqEIYl{LncUU=DVDG7Y{OL+$*Mz)HLGI&igYeIp}a+FUfw3f%!@%El>e5}w$GFM?9bMJwFcw4$72LN&vV>2*wAd==+ruV(-DRqiv#?1DNU!NVr)y=ohx{-$o~4PX}e
    z!=!n5PJPnx@ch@^k#p2SrY_I=mVbxMhx<|28nKOTF-A#q?_9f(v7lt;iR%Ji|4rQ3
    z_w>;R!wdsuxKB7m4aHbQ%(i78Tos*n{`+?GnHwY2G7II;tuSyzC=xL=kuzc_W=Lg7
    zW+-7WWUyo~W+(#EAdw=5GBBwNWEC?c0!0lNj2KLSDiaM14HOMH*;uvtn3<$l8CXPw
    m=X>2;aJj?&kK>Uw>3dZEw|#JxVBv_JE&b=r+-3_
    Date: Tue, 11 Aug 2009 20:02:43 -0600
    Subject: [PATCH 78/96] 6870298: 4/4 fix minor typos in
     java/lang/instrument/Instrumentation.java
    
    Fix typos in the JavaDoc.
    
    Reviewed-by: tbell
    ---
     .../java/lang/instrument/Instrumentation.java        | 12 ++++++------
     1 file changed, 6 insertions(+), 6 deletions(-)
    
    diff --git a/jdk/src/share/classes/java/lang/instrument/Instrumentation.java b/jdk/src/share/classes/java/lang/instrument/Instrumentation.java
    index e2b58b54872..4c2dc1ae976 100644
    --- a/jdk/src/share/classes/java/lang/instrument/Instrumentation.java
    +++ b/jdk/src/share/classes/java/lang/instrument/Instrumentation.java
    @@ -81,7 +81,7 @@ public interface Instrumentation {
          * an exception during execution, the JVM will still call the other registered
          * transformers in order. The same transformer may be added more than once,
          * but it is strongly discouraged -- avoid this by creating a new instance of
    -     * tranformer class.
    +     * transformer class.
          * 

    * This method is intended for use in instrumentation, as described in the * {@linkplain Instrumentation class specification}. @@ -183,7 +183,7 @@ public interface Instrumentation { *

    * * The order of transformation is described in the - * ({@link java.lang.instrument.ClassFileTransformer#transform transform} method. + * {@link java.lang.instrument.ClassFileTransformer#transform transform} method. * This same order is used in the automatic reapplication of retransformation * incapable transforms. *

    @@ -424,7 +424,7 @@ public interface Instrumentation { * classes or resources other than those to be defined by the bootstrap * class loader for the purpose of instrumentation. * Failure to observe this warning could result in unexpected - * behaviour that is difficult to diagnose. For example, suppose there is a + * behavior that is difficult to diagnose. For example, suppose there is a * loader L, and L's parent for delegation is the bootstrap class loader. * Furthermore, a method in class C, a class defined by L, makes reference to * a non-public accessor class C$1. If the JAR file contains a class C$1 then @@ -475,9 +475,9 @@ public interface Instrumentation { * classes or resources other than those to be defined by the system class * loader for the purpose of instrumentation. * Failure to observe this warning could result in unexpected - * behaviour that is difficult to diagnose (see + * behavior that is difficult to diagnose (see * {@link #appendToBootstrapClassLoaderSearch - * appendToBootstrapClassLoaderSearch}. + * appendToBootstrapClassLoaderSearch}). * *

    The system class loader supports adding a JAR file to be searched if * it implements a method named appendToClassPathForInstrumentation @@ -485,7 +485,7 @@ public interface Instrumentation { * method is not required to have public access. The name of * the JAR file is obtained by invoking the {@link java.util.zip.ZipFile#getName * getName()} method on the jarfile and this is provided as the - * parameter to the appendtoClassPathForInstrumentation method. + * parameter to the appendToClassPathForInstrumentation method. * *

    The Java Virtual Machine * Specification specifies that a subsequent attempt to resolve a symbolic From dfa68f9504c4ef8a9014b09f08d0984db5b11b20 Mon Sep 17 00:00:00 2001 From: Xueming Shen Date: Thu, 13 Aug 2009 10:50:23 -0700 Subject: [PATCH 79/96] 6840246: Lightweight implementation of String.split for simple use case Added a fastpath for simple use case Reviewed-by: alanb, martin --- jdk/src/share/classes/java/lang/String.java | 48 +++++++++++++++++++++ jdk/test/java/lang/String/Split.java | 47 ++++++++++++++++++++ 2 files changed, 95 insertions(+) diff --git a/jdk/src/share/classes/java/lang/String.java b/jdk/src/share/classes/java/lang/String.java index 316da645f3c..e4327434c38 100644 --- a/jdk/src/share/classes/java/lang/String.java +++ b/jdk/src/share/classes/java/lang/String.java @@ -2301,6 +2301,54 @@ public final class String * @spec JSR-51 */ public String[] split(String regex, int limit) { + /* fastpath if the regex is a + (1)one-char String and this character is not one of the + RegEx's meta characters ".$|()[{^?*+\\", or + (2)two-char String and the first char is the backslash and + the second is not the ascii digit or ascii letter. + */ + char ch = 0; + if (((regex.count == 1 && + ".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) || + (regex.length() == 2 && + regex.charAt(0) == '\\' && + (((ch = regex.charAt(1))-'0')|('9'-ch)) < 0 && + ((ch-'a')|('z'-ch)) < 0 && + ((ch-'A')|('Z'-ch)) < 0)) && + (ch < Character.MIN_HIGH_SURROGATE || + ch > Character.MAX_LOW_SURROGATE)) + { + int off = 0; + int next = 0; + boolean limited = limit > 0; + ArrayList list = new ArrayList(); + while ((next = indexOf(ch, off)) != -1) { + if (!limited || list.size() < limit - 1) { + list.add(substring(off, next)); + off = next + 1; + } else { // last one + //assert (list.size() == limit - 1); + list.add(substring(off, count)); + off = count; + break; + } + } + // If no match was found, return this + if (off == 0) + return new String[] { this }; + + // Add remaining segment + if (!limited || list.size() < limit) + list.add(substring(off, count)); + + // Construct result + int resultSize = list.size(); + if (limit == 0) + while (resultSize > 0 && list.get(resultSize-1).length() == 0) + resultSize--; + String[] result = new String[resultSize]; + return list.subList(0, resultSize).toArray(result); + } return Pattern.compile(regex).split(this, limit); } diff --git a/jdk/test/java/lang/String/Split.java b/jdk/test/java/lang/String/Split.java index b4ab5fb4c54..fa03eb397b9 100644 --- a/jdk/test/java/lang/String/Split.java +++ b/jdk/test/java/lang/String/Split.java @@ -23,14 +23,18 @@ /** * @test + * @bug 6840246 * @summary test String.split() */ +import java.util.Arrays; +import java.util.Random; import java.util.regex.*; public class Split { public static void main(String[] args) throws Exception { String source = "0123456789"; + for (int limit=-2; limit<3; limit++) { for (int x=0; x<10; x++) { String[] result = source.split(Integer.toString(x), limit); @@ -80,5 +84,48 @@ public class Split { throw new RuntimeException("String.split failure 8"); if (!result[0].equals(source)) throw new RuntimeException("String.split failure 9"); + + // check fastpath of String.split() + source = "0123456789abcdefgABCDEFG"; + Random r = new Random(); + + for (boolean doEscape: new boolean[] {false, true}) { + for (int cp = 0; cp < 0x11000; cp++) { + Pattern p = null; + String regex = new String(Character.toChars(cp)); + if (doEscape) + regex = "\\" + regex; + try { + p = Pattern.compile(regex); + } catch (PatternSyntaxException pse) { + // illegal syntax + try { + "abc".split(regex); + } catch (PatternSyntaxException pse0) { + continue; + } + throw new RuntimeException("String.split failure 11"); + } + int off = r.nextInt(source.length()); + String[] srcStrs = new String[] { + "", + source, + regex + source, + source + regex, + source.substring(0, 3) + + regex + source.substring(3, 9) + + regex + source.substring(9, 15) + + regex + source.substring(15), + source.substring(0, off) + regex + source.substring(off) + }; + for (String src: srcStrs) { + for (int limit=-2; limit<3; limit++) { + if (!Arrays.equals(src.split(regex, limit), + p.split(src, limit))) + throw new RuntimeException("String.split failure 12"); + } + } + } + } } } From 7dd13af2ed380c8afef9061eb8a0d76fd81476a9 Mon Sep 17 00:00:00 2001 From: "J. Duke" Date: Wed, 5 Jul 2017 16:57:28 +0200 Subject: [PATCH 80/96] Added tag jdk7-b67 for changeset eb24af1404ae --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 26a83d0a666..6e9c2f2985d 100644 --- a/.hgtags +++ b/.hgtags @@ -41,3 +41,4 @@ dfd8506f74c3731bb169ce93c72612d78ee0413b jdk7-b63 d22867c5f1b295a0a2b3b4bc8999a2676f6e20c3 jdk7-b64 7d3bf00f3cc4f8125de1842521e7567f37dc84b8 jdk7-b65 62109d1b9e7310f29ab51ca6f1d71b899c0ce6b0 jdk7-b66 +eb24af1404aec8aa140c4cd4d13d2839b150dd41 jdk7-b67 From 75f841a96e65cd5e83a56d727aab663f7b3622a3 Mon Sep 17 00:00:00 2001 From: "J. Duke" Date: Wed, 5 Jul 2017 16:58:00 +0200 Subject: [PATCH 81/96] Added tag jdk7-b68 for changeset bca2225b66d7 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 6e9c2f2985d..a6b203eeee6 100644 --- a/.hgtags +++ b/.hgtags @@ -42,3 +42,4 @@ d22867c5f1b295a0a2b3b4bc8999a2676f6e20c3 jdk7-b64 7d3bf00f3cc4f8125de1842521e7567f37dc84b8 jdk7-b65 62109d1b9e7310f29ab51ca6f1d71b899c0ce6b0 jdk7-b66 eb24af1404aec8aa140c4cd4d13d2839b150dd41 jdk7-b67 +bca2225b66d78c4bf4d9801f54cac7715a598650 jdk7-b68 From 5fcd7752868a2b4b113a144a11a2039386670a19 Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 13 Aug 2009 12:11:21 -0700 Subject: [PATCH 82/96] Added tag jdk7-b69 for changeset e0b23259a484 --- jdk/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/.hgtags b/jdk/.hgtags index 1d2a3d286ba..a198de438f1 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -43,3 +43,4 @@ a50217eb3ee10b9f9547e0708e5c9625405083ef jdk7-b64 bd31b30a5b21f20e42965b1633f18a5c7946d398 jdk7-b66 a952aafd5181af953b0ef3010dbd2fcc28460e8a jdk7-b67 b23d905cb5d3b382295240d28ab0bfb266b4503c jdk7-b68 +226b20019b1f020c09ea97d137d98e011ce65d76 jdk7-b69 From e35a79a5184199f3a0a16b3627f416b2e9eb0c3a Mon Sep 17 00:00:00 2001 From: Bradford Wetmore Date: Thu, 13 Aug 2009 12:36:10 -0700 Subject: [PATCH 83/96] 6870335: Provider numbers need to be bumped to 1.7 Reviewed-by: mullan --- jdk/src/share/classes/com/sun/security/sasl/Provider.java | 2 +- jdk/src/share/classes/sun/security/jgss/SunProvider.java | 2 +- jdk/src/share/classes/sun/security/provider/Sun.java | 2 +- jdk/src/share/classes/sun/security/smartcardio/SunPCSC.java | 2 +- jdk/src/share/classes/sun/security/ssl/SunJSSE.java | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/jdk/src/share/classes/com/sun/security/sasl/Provider.java b/jdk/src/share/classes/com/sun/security/sasl/Provider.java index c1900e582fb..effc5b7bbc3 100644 --- a/jdk/src/share/classes/com/sun/security/sasl/Provider.java +++ b/jdk/src/share/classes/com/sun/security/sasl/Provider.java @@ -51,7 +51,7 @@ public final class Provider extends java.security.Provider { " server mechanisms for: DIGEST-MD5, GSSAPI, CRAM-MD5)"; public Provider() { - super("SunSASL", 1.5, info); + super("SunSASL", 1.7d, info); AccessController.doPrivileged(new PrivilegedAction() { public Void run() { diff --git a/jdk/src/share/classes/sun/security/jgss/SunProvider.java b/jdk/src/share/classes/sun/security/jgss/SunProvider.java index 362bec5936d..26039b9db1d 100644 --- a/jdk/src/share/classes/sun/security/jgss/SunProvider.java +++ b/jdk/src/share/classes/sun/security/jgss/SunProvider.java @@ -62,7 +62,7 @@ public final class SunProvider extends Provider { public SunProvider() { /* We are the Sun JGSS provider */ - super("SunJGSS", 1.0, INFO); + super("SunJGSS", 1.7d, INFO); AccessController.doPrivileged( new java.security.PrivilegedAction() { diff --git a/jdk/src/share/classes/sun/security/provider/Sun.java b/jdk/src/share/classes/sun/security/provider/Sun.java index 1cbf37c35ec..ec2687da99e 100644 --- a/jdk/src/share/classes/sun/security/provider/Sun.java +++ b/jdk/src/share/classes/sun/security/provider/Sun.java @@ -46,7 +46,7 @@ public final class Sun extends Provider { public Sun() { /* We are the SUN provider */ - super("SUN", 1.6, INFO); + super("SUN", 1.7, INFO); // if there is no security manager installed, put directly into // the provider. Otherwise, create a temporary map and use a diff --git a/jdk/src/share/classes/sun/security/smartcardio/SunPCSC.java b/jdk/src/share/classes/sun/security/smartcardio/SunPCSC.java index 938614e54f9..fc76ce8118a 100644 --- a/jdk/src/share/classes/sun/security/smartcardio/SunPCSC.java +++ b/jdk/src/share/classes/sun/security/smartcardio/SunPCSC.java @@ -40,7 +40,7 @@ public final class SunPCSC extends Provider { private static final long serialVersionUID = 6168388284028876579L; public SunPCSC() { - super("SunPCSC", 1.6d, "Sun PC/SC provider"); + super("SunPCSC", 1.7d, "Sun PC/SC provider"); AccessController.doPrivileged(new PrivilegedAction() { public Void run() { put("TerminalFactory.PC/SC", "sun.security.smartcardio.SunPCSC$Factory"); diff --git a/jdk/src/share/classes/sun/security/ssl/SunJSSE.java b/jdk/src/share/classes/sun/security/ssl/SunJSSE.java index a097ebb428b..0811fc0d83b 100644 --- a/jdk/src/share/classes/sun/security/ssl/SunJSSE.java +++ b/jdk/src/share/classes/sun/security/ssl/SunJSSE.java @@ -103,7 +103,7 @@ public abstract class SunJSSE extends java.security.Provider { // standard constructor protected SunJSSE() { - super("SunJSSE", 1.6d, info); + super("SunJSSE", 1.7d, info); subclassCheck(); if (Boolean.TRUE.equals(fips)) { throw new ProviderException From fcfe031b58d3b732f366dc43042f64dfc9f57e6d Mon Sep 17 00:00:00 2001 From: Xueming Shen Date: Thu, 13 Aug 2009 15:01:18 -0700 Subject: [PATCH 84/96] 6676423: (prefs) Opensource unit/regression tests for java.util.prefs Moved the existing test cases for prefs to open area Reviewed-by: martin, alanb --- jdk/test/java/util/prefs/CommentsInXml.java | 60 +++++++++++ jdk/test/java/util/prefs/ConflictInFlush.java | 49 +++++++++ jdk/test/java/util/prefs/ExportNode.java | 53 ++++++++++ jdk/test/java/util/prefs/ExportSubtree.java | 95 +++++++++++++++++ jdk/test/java/util/prefs/PrefsSpi.java | 44 ++++++++ jdk/test/java/util/prefs/PrefsSpi.sh | 100 ++++++++++++++++++ .../java/util/prefs/RemoveReadOnlyNode.java | 63 +++++++++++ .../util/prefs/RemoveUnregedListener.java | 63 +++++++++++ .../java/util/prefs/SerializeExceptions.java | 48 +++++++++ 9 files changed, 575 insertions(+) create mode 100644 jdk/test/java/util/prefs/CommentsInXml.java create mode 100644 jdk/test/java/util/prefs/ConflictInFlush.java create mode 100644 jdk/test/java/util/prefs/ExportNode.java create mode 100644 jdk/test/java/util/prefs/ExportSubtree.java create mode 100644 jdk/test/java/util/prefs/PrefsSpi.java create mode 100644 jdk/test/java/util/prefs/PrefsSpi.sh create mode 100644 jdk/test/java/util/prefs/RemoveReadOnlyNode.java create mode 100644 jdk/test/java/util/prefs/RemoveUnregedListener.java create mode 100644 jdk/test/java/util/prefs/SerializeExceptions.java diff --git a/jdk/test/java/util/prefs/CommentsInXml.java b/jdk/test/java/util/prefs/CommentsInXml.java new file mode 100644 index 00000000000..b65cfa29e7d --- /dev/null +++ b/jdk/test/java/util/prefs/CommentsInXml.java @@ -0,0 +1,60 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 4619564 + * @summary XMl Comments in Preferences File lead to ClassCastException + * @author kladko + */ + +import java.io.*; +import java.util.prefs.*; + +public class CommentsInXml { + + public static void main(String[] argv) throws Exception { + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + + bos.write(new String( + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + ).getBytes()); + + Preferences ur = Preferences.userRoot(); + ur.importPreferences(new ByteArrayInputStream(bos.toByteArray())); + ur.node("hlrAgent").removeNode(); // clean + } +} diff --git a/jdk/test/java/util/prefs/ConflictInFlush.java b/jdk/test/java/util/prefs/ConflictInFlush.java new file mode 100644 index 00000000000..598b909d345 --- /dev/null +++ b/jdk/test/java/util/prefs/ConflictInFlush.java @@ -0,0 +1,49 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 4703132 + * @summary flush() throws an IllegalStateException on a removed node + * @author Sucheta Dambalkar + */ + +import java.util.prefs.*; + +public final class ConflictInFlush{ + + public static void main(String args[]) { + Preferences root = Preferences.userRoot(); + try { + Preferences node = root.node("1/2/3"); + node.flush(); + System.out.println("Node "+node+" has been created"); + System.out.println("Removing node "+node); + node.removeNode(); + node.flush(); + }catch (BackingStoreException bse){ + bse.printStackTrace(); + } + + } +} diff --git a/jdk/test/java/util/prefs/ExportNode.java b/jdk/test/java/util/prefs/ExportNode.java new file mode 100644 index 00000000000..5ab802efb59 --- /dev/null +++ b/jdk/test/java/util/prefs/ExportNode.java @@ -0,0 +1,53 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + + +/* + * @test + * @bug 4387136 4947349 + * @summary Due to a bug in XMLSupport.putPreferencesInXml(...), + * node's keys would not get exported. + * @author Konstantin Kladko + */ +import java.util.prefs.*; +import java.io.*; + +public class ExportNode { + public static void main(String[] args) throws + BackingStoreException, IOException { + Preferences N1 = Preferences.userRoot().node("ExportNodeTest1"); + N1.put("ExportNodeTestName1","ExportNodeTestValue1"); + Preferences N2 = N1.node("ExportNodeTest2"); + N2.put("ExportNodeTestName2","ExportNodeTestValue2"); + ByteArrayOutputStream exportStream = new ByteArrayOutputStream(); + N2.exportNode(exportStream); + + // Removal of preference node should always succeed on Solaris/Linux + // by successfully acquiring the appropriate file lock (4947349) + N1.removeNode(); + + if (((exportStream.toString()).lastIndexOf("ExportNodeTestName2")== -1) || + ((exportStream.toString()).lastIndexOf("ExportNodeTestName1")!= -1)) { + } + } +} diff --git a/jdk/test/java/util/prefs/ExportSubtree.java b/jdk/test/java/util/prefs/ExportSubtree.java new file mode 100644 index 00000000000..c3d4cd7e936 --- /dev/null +++ b/jdk/test/java/util/prefs/ExportSubtree.java @@ -0,0 +1,95 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + + +/* @test + @bug 6203576 4700020 + @summary checks if the output of exportSubtree() is identical to + the output from previous release. + */ + +import java.io.*; +import java.util.prefs.*; + +public class ExportSubtree { + public static void main(String[] args) throws Exception { + try + { + //File f = new File(System.getProperty("test.src", "."), "TestPrefs.xml"); + ByteArrayInputStream bais = new ByteArrayInputStream(importPrefs.getBytes("utf-8")); + Preferences.importPreferences(bais); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + Preferences.userRoot().node("testExportSubtree").exportSubtree(baos); + Preferences.userRoot().node("testExportSubtree").removeNode(); + if (!expectedResult.equals(baos.toString())) { + //System.out.print(baos.toString()); + //System.out.print(expectedResult); + throw new IOException("exportSubtree does not output expected result"); + } + } + catch( Exception e ) { + e.printStackTrace(); + } + } + + static String ls = System.getProperty("line.separator"); + static String importPrefs = + "" + + "" + + "" + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + ""; + + static String expectedResult = + "" + + ls + "" + + ls + "" + + ls + " " + + ls + " " + + ls + " " + + ls + " " + + ls + " " + + ls + " " + + ls + " " + + ls + " " + + ls + " " + + ls + " " + + ls + " " + + ls + " " + + ls + " " + + ls + "" + ls; +} diff --git a/jdk/test/java/util/prefs/PrefsSpi.java b/jdk/test/java/util/prefs/PrefsSpi.java new file mode 100644 index 00000000000..2009ae2d512 --- /dev/null +++ b/jdk/test/java/util/prefs/PrefsSpi.java @@ -0,0 +1,44 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + + +import java.util.prefs.Preferences; + +/* + * main class used by regtest PrefsSpi.sh + */ +public class PrefsSpi { + + public static void main (String[] args) throws Exception { + if (args.length != 1) + throw new Exception("Usage: java PrefsSpi REGEXP"); + + String className = Preferences.userRoot().getClass().getName(); + System.out.printf("className=%s%n", className); + + if (! className.matches(args[0])) + throw new Exception("Preferences class name \"" + className + + "\" does not match regular expression \"" + + args[0] + "\"."); + } +} diff --git a/jdk/test/java/util/prefs/PrefsSpi.sh b/jdk/test/java/util/prefs/PrefsSpi.sh new file mode 100644 index 00000000000..3d8e28b7afd --- /dev/null +++ b/jdk/test/java/util/prefs/PrefsSpi.sh @@ -0,0 +1,100 @@ +#!/bin/sh + +# +# Copyright 2009 Sun Microsystems, Inc. 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. +# +# 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +# CA 95054 USA or visit www.sun.com if you need additional information or +# have any questions. +# + +# @test +# @bug 4991526 6514993 +# @summary Unit test for Preferences jar providers +# +# @build PrefsSpi +# @run shell PrefsSpi.sh +# @author Martin Buchholz + +# Command-line usage: sh PrefsSpi.sh /path/to/build + +if [ -z "$TESTJAVA" ]; then + if [ $# -lt 1 ]; then exit 1; fi + TESTJAVA="$1"; shift + TESTSRC="`pwd`" + TESTCLASSES="`pwd`" +fi + + java="$TESTJAVA/bin/java" +javac="$TESTJAVA/bin/javac" + jar="$TESTJAVA/bin/jar" + +Die() { printf "%s\n" "$*"; exit 1; } + +Sys() { + printf "%s\n" "$*"; "$@"; rc="$?"; + test "$rc" -eq 0 || Die "Command \"$*\" failed with exitValue $rc"; +} + +cat > StubPreferences.java <<'EOF' +import java.util.prefs.*; + +public class StubPreferences extends AbstractPreferences { + public StubPreferences() { super(null, ""); } + public String getSpi(String x) { return null; } + public void putSpi(String x, String y) { } + public void removeSpi(String x) { } + public AbstractPreferences childSpi(String x) { return null; } + public void removeNodeSpi() { } + public String[] keysSpi() { return null; } + public String[] childrenNamesSpi() { return null; } + public void syncSpi() { } + public void flushSpi() { } +} +EOF + +cat > StubPreferencesFactory.java <<'EOF' +import java.util.prefs.*; + +public class StubPreferencesFactory implements PreferencesFactory { + public Preferences userRoot() { return new StubPreferences(); } + public Preferences systemRoot() { return new StubPreferences(); } +} +EOF + +Sys rm -rf jarDir extDir +Sys mkdir -p jarDir/META-INF/services extDir +echo "StubPreferencesFactory" \ + > "jarDir/META-INF/services/java.util.prefs.PreferencesFactory" +Sys "$javac" -d jarDir StubPreferencesFactory.java StubPreferences.java + +(cd jarDir && "$jar" "cf" "../extDir/PrefsSpi.jar" ".") + +case "`uname`" in Windows*|CYGWIN* ) CPS=';';; *) CPS=':';; esac + +Sys "$java" "-cp" "$TESTCLASSES${CPS}extDir/PrefsSpi.jar" \ + -Djava.util.prefs.PreferencesFactory=StubPreferencesFactory \ + PrefsSpi "StubPreferences" +Sys "$java" "-cp" "$TESTCLASSES" \ + PrefsSpi "java.util.prefs.*" +Sys "$java" "-cp" "$TESTCLASSES${CPS}extDir/PrefsSpi.jar" \ + PrefsSpi "StubPreferences" +Sys "$java" "-cp" "$TESTCLASSES" "-Djava.ext.dirs=extDir" \ + PrefsSpi "StubPreferences" + +rm -rf jarDir extDir diff --git a/jdk/test/java/util/prefs/RemoveReadOnlyNode.java b/jdk/test/java/util/prefs/RemoveReadOnlyNode.java new file mode 100644 index 00000000000..82409dfc637 --- /dev/null +++ b/jdk/test/java/util/prefs/RemoveReadOnlyNode.java @@ -0,0 +1,63 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + + +/* @test + @bug 6178148 + @summary check if wrong exception gets thrown if one of the child + nodes is readonly on underlying filesystem when node is + being removed. + */ + +import java.io.*; +import java.util.prefs.*; + +public class RemoveReadOnlyNode { + public static void main(String[] args) throws Exception { + String osName = System.getProperty("os.name"); + if (osName.startsWith("Windows")) + return; + Preferences root = Preferences.userRoot(); + Preferences node1 = root.node("node1"); + Preferences node1A = node1.node("node1A"); + Preferences node1B = node1.node("node1B"); + node1B.put("mykey", "myvalue"); + node1.flush(); + String node1BDirName = System.getProperty("user.home") + + "/.java/.userPrefs" + + "/node1/node1B"; + File node1BDir = new File(node1BDirName); + node1BDir.setReadOnly(); + try { + node1.removeNode(); + } + catch (BackingStoreException ex) { + //expected exception + } finally { + Runtime.getRuntime().exec("chmod 755 " + node1BDirName).waitFor(); + try { + node1.removeNode(); + } catch (Exception e) {} + } + } +} diff --git a/jdk/test/java/util/prefs/RemoveUnregedListener.java b/jdk/test/java/util/prefs/RemoveUnregedListener.java new file mode 100644 index 00000000000..d48e42b4cb7 --- /dev/null +++ b/jdk/test/java/util/prefs/RemoveUnregedListener.java @@ -0,0 +1,63 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + + +/* @test + * @bug 4705094 + * @summary Checks if correct exception gets thrown when removing an + * unregistered NodeChangeListener . + */ + +import java.util.prefs.*; +import java.util.*; + +public class RemoveUnregedListener { + public static void main(String[] args) throws Exception { + Preferences userRoot = null; + Preferences N1 = null; + NodeChangeListenerTestAdd ncl = new NodeChangeListenerTestAdd(); + NodeChangeListenerTestAdd ncl2 = new NodeChangeListenerTestAdd(); + NodeChangeListenerTestAdd ncl3 = new NodeChangeListenerTestAdd(); + try { + userRoot = Preferences.userRoot(); + N1 = userRoot.node("N1"); + userRoot.flush(); + + //add ncl nc2 + N1.addNodeChangeListener(ncl); + N1.addNodeChangeListener(ncl2); + N1.removeNodeChangeListener(ncl3); + throw new RuntimeException(); + } catch (IllegalArgumentException iae) { + System.out.println("Test Passed!"); + } catch (Exception e) { + System.out.println("Test Failed"); + throw e; + } + } + +} +class NodeChangeListenerTestAdd implements NodeChangeListener { + public void childAdded(NodeChangeEvent evt) {} + public void childRemoved(NodeChangeEvent evt) {} +} diff --git a/jdk/test/java/util/prefs/SerializeExceptions.java b/jdk/test/java/util/prefs/SerializeExceptions.java new file mode 100644 index 00000000000..04e4ae3e7dd --- /dev/null +++ b/jdk/test/java/util/prefs/SerializeExceptions.java @@ -0,0 +1,48 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + + +/* + * @test + * @bug 4811356 + * @summary Prefs exceptions were unintentionally not serializable + * @author Josh Bloch + */ + +import java.util.prefs.*; +import java.io.*; + +public class SerializeExceptions { + public static void main(String args[]) throws Exception { + test(new BackingStoreException("Hi")); + test(new InvalidPreferencesFormatException("Mom!")); + } + + static void test(Object o) throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream out = new ObjectOutputStream(bos); + out.writeObject(o); + out.flush(); + out.close(); + } +} From 94d23c375f9ee456c7175406a9321b8cdf79e7ec Mon Sep 17 00:00:00 2001 From: Xueming Shen Date: Fri, 14 Aug 2009 11:23:01 -0700 Subject: [PATCH 85/96] 6866397: (file) PathMatcher with regex syntax doesn't match as expected (win) Use unicode_case_insensitive for windows path matcher for now. Reviewed-by: alanb --- .../classes/sun/nio/fs/WindowsFileSystem.java | 18 +++------- jdk/test/java/nio/file/PathMatcher/Basic.java | 36 +++++++++++-------- 2 files changed, 25 insertions(+), 29 deletions(-) diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystem.java b/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystem.java index 54712098b67..2ad40cb7798 100644 --- a/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystem.java +++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystem.java @@ -283,25 +283,15 @@ class WindowsFileSystem } } - // match in uppercase - StringBuilder sb = new StringBuilder(expr.length()); - for (int i=0; i UNEXPECTED RESULT!"); + failures++; + } + } + + public static void main(String[] args) { // basic assertMatch("foo.html", "foo.html"); @@ -140,21 +154,13 @@ public class Basic { assertMatch("one*two", "one\\*two"); } - - // regex syntax - { - String pattern = ".*\\.html"; - System.out.format("Test regex pattern: %s", pattern); - Path file = Paths.get("foo.html"); - boolean matched = file.getFileSystem() - .getPathMatcher("regex:" + pattern).matches(file); - if (matched) { - System.out.println(" OKAY"); - } else { - System.out.println(" ==> UNEXPECTED RESULT!"); - failures++; - } + assertRegExMatch("foo.html", ".*\\.html"); + + if (System.getProperty("os.name").startsWith("Windows")) { + assertRegExMatch("foo012", "foo\\d+"); + assertRegExMatch("fo o", "fo\\so"); + assertRegExMatch("foo", "\\w+"); } // unknown syntax From efe409bf8b3b96c9def649601b5b86329a64a5f9 Mon Sep 17 00:00:00 2001 From: Xueming Shen Date: Fri, 14 Aug 2009 14:29:45 -0700 Subject: [PATCH 86/96] 6730652: CharsetEncoder.canEncode(char) returns incorrect values for some charsets Override the canEncode() in ISO2022_CN_CNS Reviewed-by: martin --- jdk/src/share/classes/sun/nio/cs/ext/ISO2022.java | 6 +++--- jdk/src/share/classes/sun/nio/cs/ext/ISO2022_CN_CNS.java | 9 +++++++++ jdk/test/sun/nio/cs/FindCanEncodeBugs.java | 6 ++---- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/jdk/src/share/classes/sun/nio/cs/ext/ISO2022.java b/jdk/src/share/classes/sun/nio/cs/ext/ISO2022.java index 242a841d46f..036dc04299d 100644 --- a/jdk/src/share/classes/sun/nio/cs/ext/ISO2022.java +++ b/jdk/src/share/classes/sun/nio/cs/ext/ISO2022.java @@ -388,9 +388,9 @@ abstract class ISO2022 protected static class Encoder extends CharsetEncoder { private final Surrogate.Parser sgp = new Surrogate.Parser(); - private final byte SS2 = (byte)0x8e; - private final byte PLANE2 = (byte)0xA2; - private final byte PLANE3 = (byte)0xA3; + public static final byte SS2 = (byte)0x8e; + public static final byte PLANE2 = (byte)0xA2; + public static final byte PLANE3 = (byte)0xA3; private final byte MSB = (byte)0x80; protected final byte maximumDesignatorLength = 4; diff --git a/jdk/src/share/classes/sun/nio/cs/ext/ISO2022_CN_CNS.java b/jdk/src/share/classes/sun/nio/cs/ext/ISO2022_CN_CNS.java index e5b5d719515..72e11ff1a76 100644 --- a/jdk/src/share/classes/sun/nio/cs/ext/ISO2022_CN_CNS.java +++ b/jdk/src/share/classes/sun/nio/cs/ext/ISO2022_CN_CNS.java @@ -76,6 +76,15 @@ public class ISO2022_CN_CNS extends ISO2022 implements HistoricallyNamedCharset } catch (Exception e) { } } + private byte[] bb = new byte[4]; + public boolean canEncode(char c) { + int n = 0; + return (c <= '\u007f' || + (n = ((EUC_TW.Encoder)ISOEncoder).toEUC(c, bb)) == 2 || + (n == 4 && bb[0] == SS2 && + (bb[1] == PLANE2 || bb[1] == PLANE3))); + } + /* * Since ISO2022-CN-CNS possesses a CharsetEncoder * without the corresponding CharsetDecoder half the diff --git a/jdk/test/sun/nio/cs/FindCanEncodeBugs.java b/jdk/test/sun/nio/cs/FindCanEncodeBugs.java index 7331934d5da..2fc6218995d 100644 --- a/jdk/test/sun/nio/cs/FindCanEncodeBugs.java +++ b/jdk/test/sun/nio/cs/FindCanEncodeBugs.java @@ -22,7 +22,7 @@ */ /* @test - @bug 5066863 5066867 5066874 5066879 5066884 5066887 5065777 + @bug 5066863 5066867 5066874 5066879 5066884 5066887 5065777 6730652 @summary canEncode() false iff encode() throws CharacterCodingException @run main/timeout=1200 FindCanEncodeBugs @author Martin Buchholz @@ -52,9 +52,7 @@ public class FindCanEncodeBugs { String csn = e.getKey(); Charset cs = e.getValue(); - if (! cs.canEncode() || - csn.matches("x-COMPOUND_TEXT") || - csn.matches("x-ISO-2022-CN-CNS")) // ISO2022_CN_CNS supports less + if (! cs.canEncode() || csn.matches("x-COMPOUND_TEXT")) continue; //System.out.println(csn); From afe6e91726c0f8316c33521094e49dd5beafb3a1 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Tue, 18 Aug 2009 10:20:50 +0800 Subject: [PATCH 87/96] 6829785: TextCallbackHandler does not honor PasswordCallback.isEchoOn() Reviewed-by: mullan --- .../auth/callback/TextCallbackHandler.java | 2 +- .../classes/sun/security/util/Password.java | 12 ++++- .../TextCallbackHandler/Password.java | 47 +++++++++++++++++++ 3 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 jdk/test/com/sun/security/auth/callback/TextCallbackHandler/Password.java diff --git a/jdk/src/share/classes/com/sun/security/auth/callback/TextCallbackHandler.java b/jdk/src/share/classes/com/sun/security/auth/callback/TextCallbackHandler.java index 9a21dc9ddfe..43d38d935dd 100644 --- a/jdk/src/share/classes/com/sun/security/auth/callback/TextCallbackHandler.java +++ b/jdk/src/share/classes/com/sun/security/auth/callback/TextCallbackHandler.java @@ -129,7 +129,7 @@ public class TextCallbackHandler implements CallbackHandler { System.err.print(pc.getPrompt()); System.err.flush(); - pc.setPassword(Password.readPassword(System.in)); + pc.setPassword(Password.readPassword(System.in, pc.isEchoOn())); } else if (callbacks[i] instanceof ConfirmationCallback) { confirmation = (ConfirmationCallback) callbacks[i]; diff --git a/jdk/src/share/classes/sun/security/util/Password.java b/jdk/src/share/classes/sun/security/util/Password.java index 5600ed60b17..9f767124d49 100644 --- a/jdk/src/share/classes/sun/security/util/Password.java +++ b/jdk/src/share/classes/sun/security/util/Password.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2009 Sun Microsystems, Inc. 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 @@ -37,6 +37,14 @@ import java.util.Arrays; public class Password { /** Reads user password from given input stream. */ public static char[] readPassword(InputStream in) throws IOException { + return readPassword(in, false); + } + + /** Reads user password from given input stream. + * @param isEchoOn true if the password should be echoed on the screen + */ + public static char[] readPassword(InputStream in, boolean isEchoOn) + throws IOException { char[] consoleEntered = null; byte[] consoleBytes = null; @@ -44,7 +52,7 @@ public class Password { try { // Use the new java.io.Console class Console con = null; - if (in == System.in && ((con = System.console()) != null)) { + if (!isEchoOn && in == System.in && ((con = System.console()) != null)) { consoleEntered = con.readPassword(); // readPassword returns "" if you just print ENTER, // to be compatible with old Password class, change to null diff --git a/jdk/test/com/sun/security/auth/callback/TextCallbackHandler/Password.java b/jdk/test/com/sun/security/auth/callback/TextCallbackHandler/Password.java new file mode 100644 index 00000000000..61330616f06 --- /dev/null +++ b/jdk/test/com/sun/security/auth/callback/TextCallbackHandler/Password.java @@ -0,0 +1,47 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6825240 + * @summary Password.readPassword() echos the input when System.Console is null + * @ignore run these by hand + */ + +import com.sun.security.auth.callback.TextCallbackHandler; +import javax.security.auth.callback.*; + +public class Password { + public static void main(String args[]) throws Exception { + TextCallbackHandler h = new TextCallbackHandler(); + PasswordCallback nc = new PasswordCallback("Invisible: ", false); + PasswordCallback nc2 = new PasswordCallback("Visible: ", true); + + System.out.println("Two passwords will be prompted for. The first one " + + "should have echo off, the second one on. Otherwise, this test fails"); + Callback[] callbacks = { nc, nc2 }; + h.handle(callbacks); + System.out.println("You input " + new String(nc.getPassword()) + + " and " + new String(nc2.getPassword())); + } +} From 7c86823f01722ef91d94da70382dbeb07f720c04 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Thu, 20 Aug 2009 11:24:42 +0800 Subject: [PATCH 88/96] 6867665: Problem with keytabs with multiple kvno's (key versions) Reviewed-by: valeriep, ohair --- .../security/krb5/internal/ktab/KeyTab.java | 72 +++--- .../sun/security/krb5/ktab/HighestKvno.java | 237 ++++++++++++++++++ 2 files changed, 271 insertions(+), 38 deletions(-) create mode 100644 jdk/test/sun/security/krb5/ktab/HighestKvno.java diff --git a/jdk/src/share/classes/sun/security/krb5/internal/ktab/KeyTab.java b/jdk/src/share/classes/sun/security/krb5/internal/ktab/KeyTab.java index d7c5484ec0c..388548b2eeb 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/ktab/KeyTab.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/ktab/KeyTab.java @@ -41,6 +41,7 @@ import java.io.IOException; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.File; +import java.util.Comparator; import java.util.StringTokenizer; /** @@ -229,10 +230,11 @@ public class KeyTab implements KeyTabConstants { /** * Reads the service key from the keytab file. * @param service the PrincipalName of the requested service. - * @return the last service key in the keytab + * @return the last service key in the keytab with the highest kvno */ public EncryptionKey readServiceKey(PrincipalName service) { KeyTabEntry entry = null; + EncryptionKey key = null; if (entries != null) { // Find latest entry for this service that has an etype // that has been configured for use @@ -240,9 +242,12 @@ public class KeyTab implements KeyTabConstants { entry = entries.elementAt(i); if (entry.service.match(service)) { if (EType.isSupported(entry.keyType)) { - return new EncryptionKey(entry.keyblock, + if (key == null || + entry.keyVersion > key.getKeyVersionNumber()) { + key = new EncryptionKey(entry.keyblock, entry.keyType, new Integer(entry.keyVersion)); + } } else if (DEBUG) { System.out.println("Found unsupported keytype (" + entry.keyType + ") for " + service); @@ -250,12 +255,13 @@ public class KeyTab implements KeyTabConstants { } } } - return null; + return key; } /** * Reads all keys for a service from the keytab file that have - * etypes that have been configured for use. + * etypes that have been configured for use. If there are multiple + * keys with same etype, the one with the highest kvno is returned. * @param service the PrincipalName of the requested service * @return an array containing all the service keys */ @@ -288,49 +294,39 @@ public class KeyTab implements KeyTabConstants { size = keys.size(); if (size == 0) return null; - EncryptionKey[] retVal = new EncryptionKey[size]; + EncryptionKey[] retVal = keys.toArray(new EncryptionKey[size]); // Sort keys according to default_tkt_enctypes - int pos = 0; - EncryptionKey k; if (DEBUG) { System.out.println("Ordering keys wrt default_tkt_enctypes list"); } - int[] etypes = EType.getDefaults("default_tkt_enctypes"); - if (etypes == null || etypes == EType.getBuiltInDefaults()) { - // Either no supported types specified in default_tkt_enctypes - // or no default_tkt_enctypes entry at all. For both cases, - // just return supported keys in the order retrieved - for (int i = 0; i < size; i++) { - retVal[pos++] = keys.get(i); - } - } else { - for (int j = 0; j < etypes.length && pos < size; j++) { - int target = etypes[j]; - for (int i = 0; i < size && pos < size; i++) { - k = keys.get(i); - if (k != null && k.getEType() == target) { - if (DEBUG) { - System.out.println(pos + ": " + k); + + final int[] etypes = EType.getDefaults("default_tkt_enctypes"); + + // Sort the keys, k1 is preferred than k2 if: + // 1. k1's etype appears earlier in etypes than k2's + // 2. If same, k1's KVNO is higher + Arrays.sort(retVal, new Comparator() { + @Override + public int compare(EncryptionKey o1, EncryptionKey o2) { + if (etypes != null && etypes != EType.getBuiltInDefaults()) { + int o1EType = o1.getEType(); + int o2EType = o2.getEType(); + if (o1EType != o2EType) { + for (int i=0; i Date: Thu, 20 Aug 2009 08:39:18 +0100 Subject: [PATCH 89/96] 6595866: File does work with symbolic links (win,vista) Reviewed-by: sherman --- .../native/java/io/WinNTFileSystem_md.c | 239 +++++++++-- jdk/test/java/io/File/SymLinks.java | 380 ++++++++++++++++++ 2 files changed, 594 insertions(+), 25 deletions(-) create mode 100644 jdk/test/java/io/File/SymLinks.java diff --git a/jdk/src/windows/native/java/io/WinNTFileSystem_md.c b/jdk/src/windows/native/java/io/WinNTFileSystem_md.c index f4cc691115b..30d0d371ce4 100644 --- a/jdk/src/windows/native/java/io/WinNTFileSystem_md.c +++ b/jdk/src/windows/native/java/io/WinNTFileSystem_md.c @@ -51,13 +51,25 @@ static struct { jfieldID path; } ids; +/** + * GetFinalPathNameByHandle is available on Windows Vista and newer + */ +typedef BOOL (WINAPI* GetFinalPathNameByHandleProc) (HANDLE, LPWSTR, DWORD, DWORD); +static GetFinalPathNameByHandleProc GetFinalPathNameByHandle_func; + JNIEXPORT void JNICALL Java_java_io_WinNTFileSystem_initIDs(JNIEnv *env, jclass cls) { + HANDLE handle; jclass fileClass = (*env)->FindClass(env, "java/io/File"); if (!fileClass) return; ids.path = (*env)->GetFieldID(env, fileClass, "path", "Ljava/lang/String;"); + handle = LoadLibrary("kernel32"); + if (handle != NULL) { + GetFinalPathNameByHandle_func = (GetFinalPathNameByHandleProc) + GetProcAddress(handle, "GetFinalPathNameByHandleW"); + } } /* -- Path operations -- */ @@ -65,6 +77,138 @@ Java_java_io_WinNTFileSystem_initIDs(JNIEnv *env, jclass cls) extern int wcanonicalize(const WCHAR *path, WCHAR *out, int len); extern int wcanonicalizeWithPrefix(const WCHAR *canonicalPrefix, const WCHAR *pathWithCanonicalPrefix, WCHAR *out, int len); +/** + * Retrieves the fully resolved (final) path for the given path or NULL + * if the function fails. + */ +static WCHAR* getFinalPath(const WCHAR *path) +{ + HANDLE h; + WCHAR *result; + DWORD error; + + /* Need Windows Vista or newer to get the final path */ + if (GetFinalPathNameByHandle_func == NULL) + return NULL; + + h = CreateFileW(path, + FILE_READ_ATTRIBUTES, + FILE_SHARE_DELETE | + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + NULL); + if (h == INVALID_HANDLE_VALUE) + return NULL; + + /** + * Allocate a buffer for the resolved path. For a long path we may need + * to allocate a larger buffer. + */ + result = (WCHAR*)malloc(MAX_PATH * sizeof(WCHAR)); + if (result != NULL) { + DWORD len = (*GetFinalPathNameByHandle_func)(h, result, MAX_PATH, 0); + if (len >= MAX_PATH) { + /* retry with a buffer of the right size */ + result = (WCHAR*)realloc(result, (len+1) * sizeof(WCHAR)); + if (result != NULL) { + len = (*GetFinalPathNameByHandle_func)(h, result, len, 0); + } else { + len = 0; + } + } + if (len > 0) { + /** + * Strip prefix (should be \\?\ or \\?\UNC) + */ + if (result[0] == L'\\' && result[1] == L'\\' && + result[2] == L'?' && result[3] == L'\\') + { + int isUnc = (result[4] == L'U' && + result[5] == L'N' && + result[6] == L'C'); + int prefixLen = (isUnc) ? 7 : 4; + /* actual result length (includes terminator) */ + int resultLen = len - prefixLen + (isUnc ? 1 : 0) + 1; + + /* copy result without prefix into new buffer */ + WCHAR *tmp = (WCHAR*)malloc(resultLen * sizeof(WCHAR)); + if (tmp == NULL) { + len = 0; + } else { + WCHAR *p = result; + p += prefixLen; + if (isUnc) { + WCHAR *p2 = tmp; + p2[0] = L'\\'; + p2++; + wcscpy(p2, p); + } else { + wcscpy(tmp, p); + } + free(result); + result = tmp; + } + } + } + + /* unable to get final path */ + if (len == 0 && result != NULL) { + free(result); + result = NULL; + } + } + + error = GetLastError(); + if (CloseHandle(h)) + SetLastError(error); + return result; +} + +/** + * Retrieves file information for the specified file. If the file is + * symbolic link then the information on fully resolved target is + * returned. + */ +static BOOL getFileInformation(const WCHAR *path, + BY_HANDLE_FILE_INFORMATION *finfo) +{ + BOOL result; + DWORD error; + HANDLE h = CreateFileW(path, + FILE_READ_ATTRIBUTES, + FILE_SHARE_DELETE | + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + NULL); + if (h == INVALID_HANDLE_VALUE) + return FALSE; + result = GetFileInformationByHandle(h, finfo); + error = GetLastError(); + if (CloseHandle(h)) + SetLastError(error); + return result; +} + +/** + * If the given attributes are the attributes of a reparse point, then + * read and return the attributes of the final target. + */ +DWORD getFinalAttributesIfReparsePoint(WCHAR *path, DWORD a) +{ + if ((a != INVALID_FILE_ATTRIBUTES) && + ((a & FILE_ATTRIBUTE_REPARSE_POINT) != 0)) + { + BY_HANDLE_FILE_INFORMATION finfo; + BOOL res = getFileInformation(path, &finfo); + a = (res) ? finfo.dwFileAttributes : INVALID_FILE_ATTRIBUTES; + } + return a; +} + JNIEXPORT jstring JNICALL Java_java_io_WinNTFileSystem_canonicalize0(JNIEnv *env, jobject this, jstring pathname) @@ -202,12 +346,15 @@ Java_java_io_WinNTFileSystem_getBooleanAttributes(JNIEnv *env, jobject this, return rv; if (!isReservedDeviceNameW(pathbuf)) { if (GetFileAttributesExW(pathbuf, GetFileExInfoStandard, &wfad)) { - rv = (java_io_FileSystem_BA_EXISTS - | ((wfad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - ? java_io_FileSystem_BA_DIRECTORY - : java_io_FileSystem_BA_REGULAR) - | ((wfad.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) - ? java_io_FileSystem_BA_HIDDEN : 0)); + DWORD a = getFinalAttributesIfReparsePoint(pathbuf, wfad.dwFileAttributes); + if (a != INVALID_FILE_ATTRIBUTES) { + rv = (java_io_FileSystem_BA_EXISTS + | ((a & FILE_ATTRIBUTE_DIRECTORY) + ? java_io_FileSystem_BA_DIRECTORY + : java_io_FileSystem_BA_REGULAR) + | ((a & FILE_ATTRIBUTE_HIDDEN) + ? java_io_FileSystem_BA_HIDDEN : 0)); + } } else { /* pagefile.sys is a special case */ if (GetLastError() == ERROR_SHARING_VIOLATION) { rv = java_io_FileSystem_BA_EXISTS; @@ -234,6 +381,7 @@ JNICALL Java_java_io_WinNTFileSystem_checkAccess(JNIEnv *env, jobject this, if (pathbuf == NULL) return JNI_FALSE; attr = GetFileAttributesW(pathbuf); + attr = getFinalAttributesIfReparsePoint(pathbuf, attr); free(pathbuf); if (attr == INVALID_FILE_ATTRIBUTES) return JNI_FALSE; @@ -272,6 +420,20 @@ Java_java_io_WinNTFileSystem_setPermission(JNIEnv *env, jobject this, if (pathbuf == NULL) return JNI_FALSE; a = GetFileAttributesW(pathbuf); + + /* if reparse point, get final target */ + if ((a != INVALID_FILE_ATTRIBUTES) && + ((a & FILE_ATTRIBUTE_REPARSE_POINT) != 0)) + { + WCHAR *fp = getFinalPath(pathbuf); + if (fp == NULL) { + a = INVALID_FILE_ATTRIBUTES; + } else { + free(pathbuf); + pathbuf = fp; + a = GetFileAttributesW(pathbuf); + } + } if (a != INVALID_FILE_ATTRIBUTES) { if (enable) a = a & ~FILE_ATTRIBUTE_READONLY; @@ -305,7 +467,7 @@ Java_java_io_WinNTFileSystem_getLastModifiedTime(JNIEnv *env, jobject this, /* Open existing or fail */ OPEN_EXISTING, /* Backup semantics for directories */ - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, + FILE_FLAG_BACKUP_SEMANTICS, /* No template file */ NULL); if (h != INVALID_HANDLE_VALUE) { @@ -332,7 +494,16 @@ Java_java_io_WinNTFileSystem_getLength(JNIEnv *env, jobject this, jobject file) if (GetFileAttributesExW(pathbuf, GetFileExInfoStandard, &wfad)) { - rv = wfad.nFileSizeHigh * ((jlong)MAXDWORD + 1) + wfad.nFileSizeLow; + if ((wfad.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) == 0) { + rv = wfad.nFileSizeHigh * ((jlong)MAXDWORD + 1) + wfad.nFileSizeLow; + } else { + /* file is a reparse point so read attributes of final target */ + BY_HANDLE_FILE_INFORMATION finfo; + if (getFileInformation(pathbuf, &finfo)) { + rv = finfo.nFileSizeHigh * ((jlong)MAXDWORD + 1) + + finfo.nFileSizeLow; + } + } } else { if (GetLastError() == ERROR_SHARING_VIOLATION) { /* The error is "share violation", which means the file/dir @@ -360,31 +531,29 @@ Java_java_io_WinNTFileSystem_createFileExclusively(JNIEnv *env, jclass cls, if (pathbuf == NULL) return JNI_FALSE; h = CreateFileW( - pathbuf, /* Wide char path name */ - GENERIC_READ | GENERIC_WRITE, /* Read and write permission */ + pathbuf, /* Wide char path name */ + GENERIC_READ | GENERIC_WRITE, /* Read and write permission */ FILE_SHARE_READ | FILE_SHARE_WRITE, /* File sharing flags */ - NULL, /* Security attributes */ - CREATE_NEW, /* creation disposition */ - FILE_ATTRIBUTE_NORMAL, /* flags and attributes */ + NULL, /* Security attributes */ + CREATE_NEW, /* creation disposition */ + FILE_ATTRIBUTE_NORMAL | + FILE_FLAG_OPEN_REPARSE_POINT, /* flags and attributes */ NULL); if (h == INVALID_HANDLE_VALUE) { DWORD error = GetLastError(); if ((error != ERROR_FILE_EXISTS) && (error != ERROR_ALREADY_EXISTS)) { - - // If a directory by the named path already exists, - // return false (behavior of solaris and linux) instead of - // throwing an exception - DWORD fattr = GetFileAttributesW(pathbuf); - if ((fattr == INVALID_FILE_ATTRIBUTES) || - (fattr & ~FILE_ATTRIBUTE_DIRECTORY)) { + // return false rather than throwing an exception when there is + // an existing file. + DWORD a = GetFileAttributesW(pathbuf); + if (a == INVALID_FILE_ATTRIBUTES) { SetLastError(error); JNU_ThrowIOExceptionWithLastError(env, "Could not open file"); } } free(pathbuf); return JNI_FALSE; - } + } free(pathbuf); CloseHandle(h); return JNI_TRUE; @@ -396,9 +565,9 @@ removeFileOrDirectory(const jchar *path) /* Returns 0 on success */ DWORD a; - SetFileAttributesW(path, 0); + SetFileAttributesW(path, FILE_ATTRIBUTE_NORMAL); a = GetFileAttributesW(path); - if (a == ((DWORD)-1)) { + if (a == INVALID_FILE_ATTRIBUTES) { return 1; } else if (a & FILE_ATTRIBUTE_DIRECTORY) { return !RemoveDirectoryW(path); @@ -578,8 +747,13 @@ Java_java_io_WinNTFileSystem_setLastModifiedTime(JNIEnv *env, jobject this, HANDLE h; if (pathbuf == NULL) return JNI_FALSE; - h = CreateFileW(pathbuf, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, 0); + h = CreateFileW(pathbuf, + FILE_WRITE_ATTRIBUTES, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + 0); if (h != INVALID_HANDLE_VALUE) { LARGE_INTEGER modTime; FILETIME t; @@ -607,6 +781,21 @@ Java_java_io_WinNTFileSystem_setReadOnly(JNIEnv *env, jobject this, if (pathbuf == NULL) return JNI_FALSE; a = GetFileAttributesW(pathbuf); + + /* if reparse point, get final target */ + if ((a != INVALID_FILE_ATTRIBUTES) && + ((a & FILE_ATTRIBUTE_REPARSE_POINT) != 0)) + { + WCHAR *fp = getFinalPath(pathbuf); + if (fp == NULL) { + a = INVALID_FILE_ATTRIBUTES; + } else { + free(pathbuf); + pathbuf = fp; + a = GetFileAttributesW(pathbuf); + } + } + if (a != INVALID_FILE_ATTRIBUTES) { if (SetFileAttributesW(pathbuf, a | FILE_ATTRIBUTE_READONLY)) rv = JNI_TRUE; diff --git a/jdk/test/java/io/File/SymLinks.java b/jdk/test/java/io/File/SymLinks.java new file mode 100644 index 00000000000..748f2086bd1 --- /dev/null +++ b/jdk/test/java/io/File/SymLinks.java @@ -0,0 +1,380 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* @test + * @bug 6595866 + * @summary Test java.io.File operations with sym links + */ + +import java.io.*; +import java.nio.file.Path; +import java.nio.file.attribute.*; +import static java.nio.file.LinkOption.*; + +public class SymLinks { + final static PrintStream out = System.out; + + final static File top = new File(System.getProperty("test.dir", ".")); + + // files used by the test + + final static File file = new File(top, "foofile"); + final static File link2file = new File(top, "link2file"); + final static File link2link2file = new File(top, "link2link2file"); + + final static File dir = new File(top, "foodir"); + final static File link2dir = new File(top, "link2dir"); + final static File link2link2dir = new File(top, "link2link2dir"); + + final static File link2nobody = new File(top, "link2nobody"); + final static File link2link2nobody = new File(top, "link2link2nobody"); + + /** + * Setup files, directories, and sym links used by test. + */ + static void setup() throws IOException { + // link2link2file -> link2file -> foofile + FileOutputStream fos = new FileOutputStream(file); + try { + fos.write(new byte[16*1024]); + } finally { + fos.close(); + } + mklink(link2file, file); + mklink(link2link2file, link2file); + + // link2link2dir -> link2dir -> dir + assertTrue(dir.mkdir()); + mklink(link2dir, dir); + mklink(link2link2dir, link2dir); + + // link2link2nobody -> link2nobody -> + mklink(link2nobody, new File(top, "DoesNotExist")); + mklink(link2link2nobody, link2nobody); + } + + /** + * Remove files, directories, and sym links used by test. + */ + static void cleanup() throws IOException { + if (file != null) + file.delete(); + if (link2file != null) + link2file.toPath().deleteIfExists(); + if (link2link2file != null) + link2link2file.toPath().deleteIfExists(); + if (dir != null) + dir.delete(); + if (link2dir != null) + link2dir.toPath().deleteIfExists(); + if (link2link2dir != null) + link2link2dir.toPath().deleteIfExists(); + if (link2nobody != null) + link2nobody.toPath().deleteIfExists(); + if (link2link2nobody != null) + link2link2nobody.toPath().deleteIfExists(); + } + + /** + * Creates a sym link source->target + */ + static void mklink(File source, File target) throws IOException { + source.toPath().createSymbolicLink(target.toPath()); + } + + /** + * Returns true if the "link" exists and is a sym link. + */ + static boolean isSymLink(File link) { + try { + BasicFileAttributes attrs = + Attributes.readBasicFileAttributes(link.toPath(), NOFOLLOW_LINKS); + return attrs.isSymbolicLink(); + } catch (IOException x) { + return false; + } + } + + /** + * Returns the last modified time of a sym link. + */ + static long lastModifiedOfSymLink(File link) throws IOException { + BasicFileAttributes attrs = + Attributes.readBasicFileAttributes(link.toPath(), NOFOLLOW_LINKS); + assertTrue(attrs.isSymbolicLink()); + return attrs.lastModifiedTime().toMillis(); + } + + /** + * Returns true if sym links are supported on the file system where + * "dir" exists. + */ + static boolean supportsSymLinks(File dir) { + Path link = dir.toPath().resolve("link"); + Path target = dir.toPath().resolve("target"); + try { + link.createSymbolicLink(target); + link.delete(); + return true; + } catch (UnsupportedOperationException x) { + return false; + } catch (IOException x) { + return false; + } + } + + static void assertTrue(boolean v) { + if (!v) throw new RuntimeException("Test failed"); + } + + static void assertFalse(boolean v) { + assertTrue(!v); + } + + static void header(String h) { + out.println(); + out.println(); + out.println("-- " + h + " --"); + } + + /** + * Tests go here. + */ + static void go() throws IOException { + + // check setup + assertTrue(file.isFile()); + assertTrue(isSymLink(link2file)); + assertTrue(isSymLink(link2link2file)); + assertTrue(dir.isDirectory()); + assertTrue(isSymLink(link2dir)); + assertTrue(isSymLink(link2link2dir)); + assertTrue(isSymLink(link2nobody)); + assertTrue(isSymLink(link2link2nobody)); + + header("createNewFile"); + + assertFalse(file.createNewFile()); + assertFalse(link2file.createNewFile()); + assertFalse(link2link2file.createNewFile()); + assertFalse(dir.createNewFile()); + assertFalse(link2dir.createNewFile()); + assertFalse(link2link2dir.createNewFile()); + assertFalse(link2nobody.createNewFile()); + assertFalse(link2link2nobody.createNewFile()); + + header("mkdir"); + + assertFalse(file.mkdir()); + assertFalse(link2file.mkdir()); + assertFalse(link2link2file.mkdir()); + assertFalse(dir.mkdir()); + assertFalse(link2dir.mkdir()); + assertFalse(link2link2dir.mkdir()); + assertFalse(link2nobody.mkdir()); + assertFalse(link2link2nobody.mkdir()); + + header("delete"); + + File link = new File(top, "mylink"); + try { + mklink(link, file); + assertTrue(link.delete()); + assertTrue(!isSymLink(link)); + assertTrue(file.exists()); + + mklink(link, link2file); + assertTrue(link.delete()); + assertTrue(!isSymLink(link)); + assertTrue(link2file.exists()); + + mklink(link, dir); + assertTrue(link.delete()); + assertTrue(!isSymLink(link)); + assertTrue(dir.exists()); + + mklink(link, link2dir); + assertTrue(link.delete()); + assertTrue(!isSymLink(link)); + assertTrue(link2dir.exists()); + + mklink(link, link2nobody); + assertTrue(link.delete()); + assertTrue(!isSymLink(link)); + assertTrue(isSymLink(link2nobody)); + + } finally { + link.toPath().deleteIfExists(); + } + + header("renameTo"); + + File newlink = new File(top, "newlink"); + assertTrue(link2file.renameTo(newlink)); + try { + assertTrue(file.exists()); + assertTrue(isSymLink(newlink)); + assertTrue(!isSymLink(link2file)); + } finally { + newlink.renameTo(link2file); // restore link + } + + assertTrue(link2dir.renameTo(newlink)); + try { + assertTrue(dir.exists()); + assertTrue(isSymLink(newlink)); + assertTrue(!isSymLink(link2dir)); + } finally { + newlink.renameTo(link2dir); // restore link + } + + header("list"); + + final String name = "entry"; + File entry = new File(dir, name); + try { + assertTrue(dir.list().length == 0); // directory should be empty + assertTrue(link2dir.list().length == 0); + assertTrue(link2link2dir.list().length == 0); + + assertTrue(entry.createNewFile()); + assertTrue(dir.list().length == 1); + assertTrue(dir.list()[0].equals(name)); + + // access directory by following links + assertTrue(link2dir.list().length == 1); + assertTrue(link2dir.list()[0].equals(name)); + assertTrue(link2link2dir.list().length == 1); + assertTrue(link2link2dir.list()[0].equals(name)); + + // files that are not directories + assertTrue(link2file.list() == null); + assertTrue(link2nobody.list() == null); + + } finally { + entry.delete(); + } + + header("isXXX"); + + assertTrue(file.isFile()); + assertTrue(link2file.isFile()); + assertTrue(link2link2file.isFile()); + + assertTrue(dir.isDirectory()); + assertTrue(link2dir.isDirectory()); + assertTrue(link2link2dir.isDirectory()); + + // on Windows we test with the DOS hidden attribute set + if (System.getProperty("os.name").startsWith("Windows")) { + DosFileAttributeView view = file.toPath() + .getFileAttributeView(DosFileAttributeView.class); + view.setHidden(true); + try { + assertTrue(file.isHidden()); + assertTrue(link2file.isHidden()); + assertTrue(link2link2file.isHidden()); + } finally { + view.setHidden(false); + } + assertFalse(file.isHidden()); + assertFalse(link2file.isHidden()); + assertFalse(link2link2file.isHidden()); + } + + header("length"); + + long len = file.length(); + assertTrue(len > 0L); + // these tests should follow links + assertTrue(link2file.length() == len); + assertTrue(link2link2file.length() == len); + assertTrue(link2nobody.length() == 0L); + + header("lastModified / setLastModified"); + + // need time to diff between link and file + long origLastModified = file.lastModified(); + assertTrue(origLastModified != 0L); + try { Thread.sleep(2000); } catch (InterruptedException x) { } + file.setLastModified(System.currentTimeMillis()); + + long lastModified = file.lastModified(); + assertTrue(lastModified != origLastModified); + assertTrue(lastModifiedOfSymLink(link2file) != lastModified); + assertTrue(lastModifiedOfSymLink(link2link2file) != lastModified); + assertTrue(link2file.lastModified() == lastModified); + assertTrue(link2link2file.lastModified() == lastModified); + assertTrue(link2nobody.lastModified() == 0L); + + origLastModified = dir.lastModified(); + assertTrue(origLastModified != 0L); + dir.setLastModified(0L); + assertTrue(dir.lastModified() == 0L); + assertTrue(link2dir.lastModified() == 0L); + assertTrue(link2link2dir.lastModified() == 0L); + dir.setLastModified(origLastModified); + + header("setXXX / canXXX"); + + assertTrue(file.canRead()); + assertTrue(file.canWrite()); + assertTrue(link2file.canRead()); + assertTrue(link2file.canWrite()); + assertTrue(link2link2file.canRead()); + assertTrue(link2link2file.canWrite()); + + if (file.setReadOnly()) { + assertFalse(file.canWrite()); + assertFalse(link2file.canWrite()); + assertFalse(link2link2file.canWrite()); + + assertTrue(file.setWritable(true)); // make writable + assertTrue(file.canWrite()); + assertTrue(link2file.canWrite()); + assertTrue(link2link2file.canWrite()); + + assertTrue(link2file.setReadOnly()); // make read only + assertFalse(file.canWrite()); + assertFalse(link2file.canWrite()); + assertFalse(link2link2file.canWrite()); + + assertTrue(link2link2file.setWritable(true)); // make writable + assertTrue(file.canWrite()); + assertTrue(link2file.canWrite()); + assertTrue(link2link2file.canWrite()); + } + } + + public static void main(String[] args) throws IOException { + if (supportsSymLinks(top)) { + try { + setup(); + go(); + } finally { + cleanup(); + } + } + } + +} From 97e10327edc4dc3610612823708d7c4e80beab4f Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Thu, 20 Aug 2009 08:42:38 +0100 Subject: [PATCH 90/96] 6870926: (file) Path.toRealPath performance can be improved (win) Reviewed-by: sherman --- .../sun/nio/fs/WindowsFileAttributes.java | 19 ++- .../sun/nio/fs/WindowsLinkSupport.java | 133 +++++++++--------- .../sun/nio/fs/WindowsNativeDispatcher.java | 2 + .../sun/nio/fs/WindowsNativeDispatcher.c | 5 +- 4 files changed, 86 insertions(+), 73 deletions(-) diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributes.java b/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributes.java index 9a1e0bd1a15..69105a96834 100644 --- a/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributes.java +++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributes.java @@ -246,8 +246,8 @@ class WindowsFileAttributes long lastWriteTime = unsafe.getLong(address + OFFSETOF_FIND_DATA_LASTWRITETIME); long size = ((long)(unsafe.getInt(address + OFFSETOF_FIND_DATA_SIZEHIGH)) << 32) + (unsafe.getInt(address + OFFSETOF_FIND_DATA_SIZELOW) & 0xFFFFFFFFL); - int reparseTag = ((fileAttrs & FILE_ATTRIBUTE_REPARSE_POINT) != 0) ? - + unsafe.getInt(address + OFFSETOF_FIND_DATA_RESERVED0) : 0; + int reparseTag = isReparsePoint(fileAttrs) ? + unsafe.getInt(address + OFFSETOF_FIND_DATA_RESERVED0) : 0; return new WindowsFileAttributes(fileAttrs, creationTime, lastAccessTime, @@ -275,7 +275,7 @@ class WindowsFileAttributes int reparseTag = 0; int fileAttrs = unsafe .getInt(address + OFFSETOF_FILE_INFORMATION_ATTRIBUTES); - if ((fileAttrs & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { + if (isReparsePoint(fileAttrs)) { int size = MAXIMUM_REPARSE_DATA_BUFFER_SIZE; NativeBuffer reparseBuffer = NativeBuffers.getNativeBuffer(size); try { @@ -311,7 +311,7 @@ class WindowsFileAttributes // just return the attributes int fileAttrs = unsafe .getInt(address + OFFSETOF_FILE_ATTRIBUTE_DATA_ATTRIBUTES); - if ((fileAttrs & FILE_ATTRIBUTE_REPARSE_POINT) == 0) + if (!isReparsePoint(fileAttrs)) return fromFileAttributeData(address, 0); } catch (WindowsException x) { if (x.lastError() != ERROR_SHARING_VIOLATION) @@ -358,7 +358,7 @@ class WindowsFileAttributes } /** - * Returns true if the attribtues are of the same file - both files must + * Returns true if the attributes are of the same file - both files must * be open. */ static boolean isSameFile(WindowsFileAttributes attrs1, @@ -370,6 +370,13 @@ class WindowsFileAttributes (attrs1.fileIndexLow == attrs2.fileIndexLow); } + /** + * Returns true if the attributes are of a file with a reparse point. + */ + static boolean isReparsePoint(int attributes) { + return (attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0; + } + // package-private int attributes() { return fileAttrs; @@ -420,7 +427,7 @@ class WindowsFileAttributes // package private boolean isReparsePoint() { - return (fileAttrs & FILE_ATTRIBUTE_REPARSE_POINT) != 0; + return isReparsePoint(fileAttrs); } boolean isDirectoryLink() { diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsLinkSupport.java b/jdk/src/windows/classes/sun/nio/fs/WindowsLinkSupport.java index 9ad84818927..bb0ccdb84f6 100644 --- a/jdk/src/windows/classes/sun/nio/fs/WindowsLinkSupport.java +++ b/jdk/src/windows/classes/sun/nio/fs/WindowsLinkSupport.java @@ -62,6 +62,30 @@ class WindowsLinkSupport { } } + /** + * Returns the final path (all symbolic links resolved) or null if this + * operation is not supported. + */ + private static String getFinalPath(WindowsPath input) throws IOException { + long h = 0; + try { + h = input.openForReadAttributeAccess(true); + } catch (WindowsException x) { + x.rethrowAsIOException(input); + } + try { + return stripPrefix(GetFinalPathNameByHandle(h)); + } catch (WindowsException x) { + // ERROR_INVALID_LEVEL is the error returned when not supported + // (a sym link to file on FAT32 or Samba server for example) + if (x.lastError() != ERROR_INVALID_LEVEL) + x.rethrowAsIOException(input); + } finally { + CloseHandle(h); + } + return null; + } + /** * Returns the final path of a given path as a String. This should be used * prior to calling Win32 system calls that do not follow links. @@ -70,7 +94,6 @@ class WindowsLinkSupport { throws IOException { WindowsFileSystem fs = input.getFileSystem(); - try { // if not following links then don't need final path if (!followLinks || !fs.supportsLinks()) @@ -84,25 +107,10 @@ class WindowsLinkSupport { x.rethrowAsIOException(input); } - // The file is a symbolic link so we open it and try to get the - // normalized path. This should succeed on NTFS but may fail if there - // is a link to a non-NFTS file system. - long h = 0; - try { - h = input.openForReadAttributeAccess(true); - } catch (WindowsException x) { - x.rethrowAsIOException(input); - } - try { - return stripPrefix(GetFinalPathNameByHandle(h)); - } catch (WindowsException x) { - // ERROR_INVALID_LEVEL is the error returned when not supported by - // the file system - if (x.lastError() != ERROR_INVALID_LEVEL) - x.rethrowAsIOException(input); - } finally { - CloseHandle(h); - } + // The file is a symbolic link so attempt to get the final path + String result = getFinalPath(input); + if (result != null) + return result; // Fallback: read target of link, resolve against parent, and repeat // until file is not a link. @@ -149,31 +157,9 @@ class WindowsLinkSupport { throws IOException { WindowsFileSystem fs = input.getFileSystem(); - if (!fs.supportsLinks()) + if (resolveLinks && !fs.supportsLinks()) resolveLinks = false; - // On Vista use GetFinalPathNameByHandle. This should succeed on NTFS - // but may fail if there is a link to a non-NFTS file system. - if (resolveLinks) { - long h = 0; - try { - h = input.openForReadAttributeAccess(true); - } catch (WindowsException x) { - x.rethrowAsIOException(input); - } - try { - return stripPrefix(GetFinalPathNameByHandle(h)); - } catch (WindowsException x) { - if (x.lastError() != ERROR_INVALID_LEVEL) - x.rethrowAsIOException(input); - } finally { - CloseHandle(h); - } - } - - // Not resolving links or we are on Windows Vista (or newer) with a - // link to non-NFTS file system. - // Start with absolute path String path = null; try { @@ -183,15 +169,12 @@ class WindowsLinkSupport { } // Collapse "." and ".." - try { - path = GetFullPathName(path); - } catch (WindowsException x) { - x.rethrowAsIOException(input); - } - - // eliminate all symbolic links - if (resolveLinks) { - path = resolveAllLinks(WindowsPath.createFromNormalizedPath(fs, path)); + if (path.indexOf('.') >= 0) { + try { + path = GetFullPathName(path); + } catch (WindowsException x) { + x.rethrowAsIOException(input); + } } // string builder to build up components of path @@ -229,12 +212,15 @@ class WindowsLinkSupport { throw new AssertionError("path type not recognized"); } - // check root directory exists - try { - FirstFile fileData = FindFirstFile(sb.toString() + "*"); - FindClose(fileData.handle()); - } catch (WindowsException x) { - x.rethrowAsIOException(path); + // if the result is only a root component then we simply check it exists + if (start >= path.length()) { + String result = sb.toString(); + try { + GetFileAttributes(result); + } catch (WindowsException x) { + x.rethrowAsIOException(path); + } + return result; } // iterate through each component to get its actual name in the @@ -246,13 +232,28 @@ class WindowsLinkSupport { String search = sb.toString() + path.substring(curr, end); try { FirstFile fileData = FindFirstFile(addLongPathPrefixIfNeeded(search)); - try { - sb.append(fileData.name()); - if (next != -1) { - sb.append('\\'); + FindClose(fileData.handle()); + + // if a reparse point is encountered then we must return the + // final path. + if (resolveLinks && + WindowsFileAttributes.isReparsePoint(fileData.attributes())) + { + String result = getFinalPath(input); + if (result == null) { + // Fallback to slow path, usually because there is a sym + // link to a file system that doesn't support sym links. + WindowsPath resolved = resolveAllLinks( + WindowsPath.createFromNormalizedPath(fs, path)); + result = getRealPath(resolved, false); } - } finally { - FindClose(fileData.handle()); + return result; + } + + // add the name to the result + sb.append(fileData.name()); + if (next != -1) { + sb.append('\\'); } } catch (WindowsException e) { e.rethrowAsIOException(path); @@ -342,7 +343,7 @@ class WindowsLinkSupport { /** * Resolve all symbolic-links in a given absolute and normalized path */ - private static String resolveAllLinks(WindowsPath path) + private static WindowsPath resolveAllLinks(WindowsPath path) throws IOException { assert path.isAbsolute(); @@ -401,7 +402,7 @@ class WindowsLinkSupport { } } - return path.toString(); + return path; } /** diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java b/jdk/src/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java index a116bf81190..0ad876755be 100644 --- a/jdk/src/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java +++ b/jdk/src/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java @@ -180,10 +180,12 @@ class WindowsNativeDispatcher { static class FirstFile { private long handle; private String name; + private int attributes; private FirstFile() { } public long handle() { return handle; } public String name() { return name; } + public int attributes() { return attributes; } } private static native void FindFirstFile0(long lpFileName, FirstFile obj) throws WindowsException; diff --git a/jdk/src/windows/native/sun/nio/fs/WindowsNativeDispatcher.c b/jdk/src/windows/native/sun/nio/fs/WindowsNativeDispatcher.c index d5195c4f7b3..8e07bde64b6 100644 --- a/jdk/src/windows/native/sun/nio/fs/WindowsNativeDispatcher.c +++ b/jdk/src/windows/native/sun/nio/fs/WindowsNativeDispatcher.c @@ -48,6 +48,7 @@ */ static jfieldID findFirst_handle; static jfieldID findFirst_name; +static jfieldID findFirst_attributes; static jfieldID findStream_handle; static jfieldID findStream_name; @@ -134,6 +135,7 @@ Java_sun_nio_fs_WindowsNativeDispatcher_initIDs(JNIEnv* env, jclass this) } findFirst_handle = (*env)->GetFieldID(env, clazz, "handle", "J"); findFirst_name = (*env)->GetFieldID(env, clazz, "name", "Ljava/lang/String;"); + findFirst_attributes = (*env)->GetFieldID(env, clazz, "attributes", "I"); clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$FirstStream"); if (clazz == NULL) { @@ -371,6 +373,7 @@ Java_sun_nio_fs_WindowsNativeDispatcher_FindFirstFile0(JNIEnv* env, jclass this, return; (*env)->SetLongField(env, obj, findFirst_handle, ptr_to_jlong(handle)); (*env)->SetObjectField(env, obj, findFirst_name, name); + (*env)->SetIntField(env, obj, findFirst_attributes, data.dwFileAttributes); } else { throwWindowsException(env, GetLastError()); } @@ -387,7 +390,7 @@ Java_sun_nio_fs_WindowsNativeDispatcher_FindFirstFile1(JNIEnv* env, jclass this, if (handle == INVALID_HANDLE_VALUE) { throwWindowsException(env, GetLastError()); } - return ptr_to_jlong(handle); + return ptr_to_jlong(handle); } JNIEXPORT jstring JNICALL From b458f8ca650b27f133953e12a4bee00e012f1c43 Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Thu, 20 Aug 2009 08:48:29 +0100 Subject: [PATCH 91/96] 6866804: (file) Path calls checkPermission insteadof checkXXX (sol) Reviewed-by: sherman --- .../solaris/classes/sun/nio/fs/UnixPath.java | 39 +- .../sun/nio/fs/WindowsFileAttributeViews.java | 1 + .../java/nio/file/Path/CheckPermissions.java | 695 ++++++++++++++++++ jdk/test/java/nio/file/Path/Misc.java | 2 +- 4 files changed, 704 insertions(+), 33 deletions(-) create mode 100644 jdk/test/java/nio/file/Path/CheckPermissions.java diff --git a/jdk/src/solaris/classes/sun/nio/fs/UnixPath.java b/jdk/src/solaris/classes/sun/nio/fs/UnixPath.java index 9d5db356255..2741915e55d 100644 --- a/jdk/src/solaris/classes/sun/nio/fs/UnixPath.java +++ b/jdk/src/solaris/classes/sun/nio/fs/UnixPath.java @@ -65,9 +65,6 @@ class UnixPath // array of offsets of elements in path (created lazily) private volatile int[] offsets; - // file permissions (created lazily) - private volatile FilePermission[] perms; - UnixPath(UnixFileSystem fs, byte[] path) { this.fs = fs; this.path = path; @@ -768,45 +765,23 @@ class UnixPath } } - // create file permissions used for read and write checks - private void checkReadOrWrite(boolean checkRead) { - SecurityManager sm = System.getSecurityManager(); - if (sm == null) - return; - if (perms == null) { - synchronized (this) { - if (perms == null) { - FilePermission[] p = new FilePermission[2]; - String pathForPermCheck = getPathForPermissionCheck(); - p[0] = new FilePermission(pathForPermCheck, - SecurityConstants.FILE_READ_ACTION); - p[1] = new FilePermission(pathForPermCheck, - SecurityConstants.FILE_WRITE_ACTION); - perms = p; - } - } - } - if (checkRead) { - sm.checkPermission(perms[0]); - } else { - sm.checkPermission(perms[1]); - } - } void checkRead() { - checkReadOrWrite(true); + SecurityManager sm = System.getSecurityManager(); + if (sm != null) + sm.checkRead(getPathForPermissionCheck()); } void checkWrite() { - checkReadOrWrite(false); + SecurityManager sm = System.getSecurityManager(); + if (sm != null) + sm.checkWrite(getPathForPermissionCheck()); } void checkDelete() { SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - // permission not cached + if (sm != null) sm.checkDelete(getPathForPermissionCheck()); - } } @Override diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributeViews.java b/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributeViews.java index 5af9876f33c..44cdb276de2 100644 --- a/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributeViews.java +++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributeViews.java @@ -46,6 +46,7 @@ class WindowsFileAttributeViews { @Override public WindowsFileAttributes readAttributes() throws IOException { + file.checkRead(); try { return WindowsFileAttributes.get(file, followLinks); } catch (WindowsException x) { diff --git a/jdk/test/java/nio/file/Path/CheckPermissions.java b/jdk/test/java/nio/file/Path/CheckPermissions.java new file mode 100644 index 00000000000..a8aef0f91f2 --- /dev/null +++ b/jdk/test/java/nio/file/Path/CheckPermissions.java @@ -0,0 +1,695 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* @test + * @bug 6866804 + * @summary Unit test for java.nio.file.Path + * @library .. + */ + +import java.nio.ByteBuffer; +import java.nio.file.*; +import java.nio.file.attribute.*; +import java.nio.channels.SeekableByteChannel; +import java.security.Permission; +import java.io.*; +import java.util.*; + +/** + * Checks each method that accesses the file system does the right permission + * check when there is a security manager set. + */ + +public class CheckPermissions { + + static class Checks { + private List permissionsChecked = new ArrayList(); + private Set propertiesChecked = new HashSet(); + private List readsChecked = new ArrayList(); + private List writesChecked = new ArrayList(); + private List deletesChecked = new ArrayList(); + private List execsChecked = new ArrayList(); + + List permissionsChecked() { return permissionsChecked; } + Set propertiesChecked() { return propertiesChecked; } + List readsChecked() { return readsChecked; } + List writesChecked() { return writesChecked; } + List deletesChecked() { return deletesChecked; } + List execsChecked() { return execsChecked; } + } + + static ThreadLocal myChecks = + new ThreadLocal() { + @Override protected Checks initialValue() { + return null; + } + }; + + static void prepare() { + myChecks.set(new Checks()); + } + + static void assertCheckPermission(Class type, + String name) + { + for (Permission perm: myChecks.get().permissionsChecked()) { + if (type.isInstance(perm) && perm.getName().equals(name)) + return; + } + throw new RuntimeException(type.getName() + "\"" + name + "\") not checked"); + } + + static void assertCheckPropertyAccess(String key) { + if (!myChecks.get().propertiesChecked().contains(key)) + throw new RuntimeException("Property " + key + " not checked"); + } + + static void assertChecked(Path file, List list) { + String s = file.toString(); + for (String f: list) { + if (f.endsWith(s)) + return; + } + throw new RuntimeException("Access not checked"); + } + + static void assertCheckRead(Path file) { + assertChecked(file, myChecks.get().readsChecked()); + } + + static void assertCheckWrite(Path file) { + assertChecked(file, myChecks.get().writesChecked()); + } + + static void assertCheckDelete(Path file) { + assertChecked(file, myChecks.get().deletesChecked()); + } + + static void assertCheckExec(Path file) { + assertChecked(file, myChecks.get().execsChecked()); + } + + static class LoggingSecurityManager extends SecurityManager { + static void install() { + System.setSecurityManager(new LoggingSecurityManager()); + } + + @Override + public void checkPermission(Permission perm) { + Checks checks = myChecks.get(); + if (checks != null) + checks.permissionsChecked().add(perm); + } + + @Override + public void checkPropertyAccess(String key) { + Checks checks = myChecks.get(); + if (checks != null) + checks.propertiesChecked().add(key); + } + + @Override + public void checkRead(String file) { + Checks checks = myChecks.get(); + if (checks != null) + checks.readsChecked().add(file); + } + + @Override + public void checkWrite(String file) { + Checks checks = myChecks.get(); + if (checks != null) + checks.writesChecked().add(file); + } + + @Override + public void checkDelete(String file) { + Checks checks = myChecks.get(); + if (checks != null) + checks.deletesChecked().add(file); + } + + @Override + public void checkExec(String file) { + Checks checks = myChecks.get(); + if (checks != null) + checks.execsChecked().add(file); + } + } + + static void testBasicFileAttributeView(BasicFileAttributeView view, Path file) + throws IOException + { + prepare(); + view.readAttributes(); + assertCheckRead(file); + + prepare(); + FileTime now = FileTime.fromMillis(System.currentTimeMillis()); + view.setTimes(null, now, now); + assertCheckWrite(file); + } + + static void testPosixFileAttributeView(PosixFileAttributeView view, Path file) + throws IOException + { + prepare(); + PosixFileAttributes attrs = view.readAttributes(); + assertCheckRead(file); + assertCheckPermission(RuntimePermission.class, "accessUserInformation"); + + prepare(); + view.setPermissions(attrs.permissions()); + assertCheckWrite(file); + assertCheckPermission(RuntimePermission.class, "accessUserInformation"); + + prepare(); + view.setOwner(attrs.owner()); + assertCheckWrite(file); + assertCheckPermission(RuntimePermission.class, "accessUserInformation"); + + prepare(); + view.setOwner(attrs.owner()); + assertCheckWrite(file); + assertCheckPermission(RuntimePermission.class, "accessUserInformation"); + } + + public static void main(String[] args) throws IOException { + Path dir = Paths.get(System.getProperty("test.src", ".")); + Path file = dir.resolve("file1234").createFile(); + try { + LoggingSecurityManager.install(); + + // -- checkAccess -- + + prepare(); + file.checkAccess(); + assertCheckRead(file); + + prepare(); + file.checkAccess(AccessMode.READ); + assertCheckRead(file); + + prepare(); + file.checkAccess(AccessMode.WRITE); + assertCheckWrite(file); + + prepare(); + try { + file.checkAccess(AccessMode.EXECUTE); + } catch (AccessDeniedException x) { } + assertCheckExec(file); + + prepare(); + try { + file.checkAccess(AccessMode.READ, AccessMode.WRITE, AccessMode.EXECUTE); + } catch (AccessDeniedException x) { } + assertCheckRead(file); + assertCheckWrite(file); + assertCheckExec(file); + + // -- copyTo -- + + Path target = dir.resolve("target1234"); + prepare(); + file.copyTo(target); + try { + assertCheckRead(file); + assertCheckWrite(target); + } finally { + target.delete(); + } + + if (TestUtil.supportsLinks(dir)) { + Path link = dir.resolve("link1234").createSymbolicLink(file); + try { + prepare(); + link.copyTo(target, LinkOption.NOFOLLOW_LINKS); + try { + assertCheckRead(link); + assertCheckWrite(target); + assertCheckPermission(LinkPermission.class, "symbolic"); + } finally { + target.delete(); + } + } finally { + link.delete(); + } + } + + // -- createDirectory -- + + Path subdir = dir.resolve("subdir1234"); + prepare(); + subdir.createDirectory(); + try { + assertCheckWrite(subdir); + } finally { + subdir.delete(); + } + + // -- createFile -- + + Path fileToCreate = dir.resolve("file7890"); + prepare(); + try { + fileToCreate.createFile(); + assertCheckWrite(fileToCreate); + } finally { + fileToCreate.delete(); + } + + // -- createSymbolicLink -- + + if (TestUtil.supportsLinks(dir)) { + prepare(); + Path link = dir.resolve("link1234").createSymbolicLink(file); + try { + assertCheckWrite(link); + assertCheckPermission(LinkPermission.class, "symbolic"); + } finally { + link.delete(); + } + } + + // -- delete/deleteIfExists -- + + Path fileToDelete = dir.resolve("file7890"); + + fileToDelete.createFile(); + prepare(); + fileToDelete.delete(); + assertCheckDelete(fileToDelete); + + fileToDelete.createFile(); + prepare(); + fileToDelete.deleteIfExists(); + assertCheckDelete(fileToDelete); + + // -- exists/notExists -- + + prepare(); + file.exists(); + assertCheckRead(file); + + prepare(); + file.notExists(); + assertCheckRead(file); + + // -- getFileStore -- + + prepare(); + file.getFileStore(); + assertCheckRead(file); + assertCheckPermission(RuntimePermission.class, "getFileStoreAttributes"); + + // -- isSameFile -- + + prepare(); + file.isSameFile(dir); + assertCheckRead(file); + assertCheckRead(dir); + + // -- moveTo -- + + Path target2 = dir.resolve("target1234"); + prepare(); + file.moveTo(target2); + try { + assertCheckWrite(file); + assertCheckWrite(target2); + } finally { + // restore file + target2.moveTo(file); + } + + // -- newByteChannel -- + + SeekableByteChannel sbc; + + prepare(); + sbc = file.newByteChannel(); + try { + assertCheckRead(file); + } finally { + sbc.close(); + } + prepare(); + sbc = file.newByteChannel(StandardOpenOption.WRITE); + try { + assertCheckWrite(file); + } finally { + sbc.close(); + } + prepare(); + sbc = file.newByteChannel(StandardOpenOption.READ, StandardOpenOption.WRITE); + try { + assertCheckRead(file); + assertCheckWrite(file); + } finally { + sbc.close(); + } + + prepare(); + sbc = file.newByteChannel(StandardOpenOption.DELETE_ON_CLOSE); + try { + assertCheckRead(file); + assertCheckDelete(file); + } finally { + sbc.close(); + } + file.createFile(); // restore file + + + // -- newInputStream/newOutptuStream -- + + prepare(); + InputStream in = file.newInputStream(); + try { + assertCheckRead(file); + } finally { + in.close(); + } + prepare(); + OutputStream out = file.newOutputStream(); + try { + assertCheckWrite(file); + } finally { + out.close(); + } + + // -- newDirectoryStream -- + + prepare(); + DirectoryStream stream = dir.newDirectoryStream(); + try { + assertCheckRead(dir); + + if (stream instanceof SecureDirectoryStream) { + Path entry; + SecureDirectoryStream sds = + (SecureDirectoryStream)stream; + + // newByteChannel + entry = file.getName(); + prepare(); + sbc = sds.newByteChannel(entry, EnumSet.of(StandardOpenOption.READ)); + try { + assertCheckRead(file); + } finally { + sbc.close(); + } + prepare(); + sbc = sds.newByteChannel(entry, EnumSet.of(StandardOpenOption.WRITE)); + try { + assertCheckWrite(file); + } finally { + sbc.close(); + } + + // deleteFile + entry = file.getName(); + prepare(); + sds.deleteFile(entry); + assertCheckDelete(file); + dir.resolve(entry).createFile(); // restore file + + // deleteDirectory + entry = Paths.get("subdir1234"); + dir.resolve(entry).createDirectory(); + prepare(); + sds.deleteDirectory(entry); + assertCheckDelete(dir.resolve(entry)); + + // move + entry = Paths.get("tempname1234"); + prepare(); + sds.move(file.getName(), sds, entry); + assertCheckWrite(file); + assertCheckWrite(dir.resolve(entry)); + sds.move(entry, sds, file.getName()); // restore file + + // newDirectoryStream + entry = Paths.get("subdir1234"); + dir.resolve(entry).createDirectory(); + try { + prepare(); + sds.newDirectoryStream(entry).close(); + assertCheckRead(dir.resolve(entry)); + } finally { + dir.resolve(entry).delete(); + } + + // getFileAttributeView to access attributes of directory + testBasicFileAttributeView(sds + .getFileAttributeView(BasicFileAttributeView.class), dir); + testPosixFileAttributeView(sds + .getFileAttributeView(PosixFileAttributeView.class), dir); + + // getFileAttributeView to access attributes of entry + entry = file.getName(); + testBasicFileAttributeView(sds + .getFileAttributeView(entry, BasicFileAttributeView.class), file); + testPosixFileAttributeView(sds + .getFileAttributeView(entry, PosixFileAttributeView.class), file); + + } else { + System.out.println("SecureDirectoryStream not tested"); + } + + } finally { + stream.close(); + } + + // -- toAbsolutePath -- + + prepare(); + file.getName().toAbsolutePath(); + assertCheckPropertyAccess("user.dir"); + + // -- toRealPath -- + + prepare(); + file.toRealPath(true); + assertCheckRead(file); + + prepare(); + file.toRealPath(false); + assertCheckRead(file); + + prepare(); + Paths.get(".").toRealPath(true); + assertCheckPropertyAccess("user.dir"); + + prepare(); + Paths.get(".").toRealPath(false); + assertCheckPropertyAccess("user.dir"); + + // -- register -- + + WatchService watcher = FileSystems.getDefault().newWatchService(); + try { + prepare(); + dir.register(watcher, StandardWatchEventKind.ENTRY_DELETE); + assertCheckRead(dir); + } finally { + watcher.close(); + } + + // -- getAttribute/setAttribute/readAttributes -- + + prepare(); + file.getAttribute("size"); + assertCheckRead(file); + + prepare(); + file.setAttribute("lastModifiedTime", + FileTime.fromMillis(System.currentTimeMillis())); + assertCheckWrite(file); + + prepare(); + file.readAttributes("*"); + assertCheckRead(file); + + // -- BasicFileAttributeView -- + testBasicFileAttributeView(file + .getFileAttributeView(BasicFileAttributeView.class), file); + + // -- PosixFileAttributeView -- + + { + PosixFileAttributeView view = + file.getFileAttributeView(PosixFileAttributeView.class); + if (view != null && + file.getFileStore().supportsFileAttributeView(PosixFileAttributeView.class)) + { + testPosixFileAttributeView(view, file); + } else { + System.out.println("PosixFileAttributeView not tested"); + } + } + + // -- DosFileAttributeView -- + + { + DosFileAttributeView view = + file.getFileAttributeView(DosFileAttributeView.class); + if (view != null && + file.getFileStore().supportsFileAttributeView(DosFileAttributeView.class)) + { + prepare(); + view.readAttributes(); + assertCheckRead(file); + + prepare(); + view.setArchive(false); + assertCheckWrite(file); + + prepare(); + view.setHidden(false); + assertCheckWrite(file); + + prepare(); + view.setReadOnly(false); + assertCheckWrite(file); + + prepare(); + view.setSystem(false); + assertCheckWrite(file); + } else { + System.out.println("DosFileAttributeView not tested"); + } + } + + // -- FileOwnerAttributeView -- + + { + FileOwnerAttributeView view = + file.getFileAttributeView(FileOwnerAttributeView.class); + if (view != null && + file.getFileStore().supportsFileAttributeView(FileOwnerAttributeView.class)) + { + prepare(); + UserPrincipal owner = view.getOwner(); + assertCheckRead(file); + assertCheckPermission(RuntimePermission.class, "accessUserInformation"); + + prepare(); + view.setOwner(owner); + assertCheckWrite(file); + assertCheckPermission(RuntimePermission.class, "accessUserInformation"); + + } else { + System.out.println("FileOwnerAttributeView not tested"); + } + } + + // -- UserDefinedFileAttributeView -- + + { + UserDefinedFileAttributeView view = + file.getFileAttributeView(UserDefinedFileAttributeView.class); + if (view != null && + file.getFileStore().supportsFileAttributeView(UserDefinedFileAttributeView.class)) + { + prepare(); + view.write("test", ByteBuffer.wrap(new byte[100])); + assertCheckWrite(file); + assertCheckPermission(RuntimePermission.class, + "accessUserDefinedAttributes"); + + prepare(); + view.read("test", ByteBuffer.allocate(100)); + assertCheckRead(file); + assertCheckPermission(RuntimePermission.class, + "accessUserDefinedAttributes"); + + prepare(); + view.size("test"); + assertCheckRead(file); + assertCheckPermission(RuntimePermission.class, + "accessUserDefinedAttributes"); + + prepare(); + view.list(); + assertCheckRead(file); + assertCheckPermission(RuntimePermission.class, + "accessUserDefinedAttributes"); + + prepare(); + view.delete("test"); + assertCheckWrite(file); + assertCheckPermission(RuntimePermission.class, + "accessUserDefinedAttributes"); + } else { + System.out.println("UserDefinedFileAttributeView not tested"); + } + } + + // -- AclFileAttributeView -- + { + AclFileAttributeView view = + file.getFileAttributeView(AclFileAttributeView.class); + if (view != null && + file.getFileStore().supportsFileAttributeView(AclFileAttributeView.class)) + { + prepare(); + List acl = view.getAcl(); + assertCheckRead(file); + assertCheckPermission(RuntimePermission.class, "accessUserInformation"); + prepare(); + view.setAcl(acl); + assertCheckWrite(file); + assertCheckPermission(RuntimePermission.class, "accessUserInformation"); + } else { + System.out.println("AclFileAttributeView not tested"); + } + } + + // -- UserPrincipalLookupService + + UserPrincipalLookupService lookupService = + FileSystems.getDefault().getUserPrincipalLookupService(); + UserPrincipal owner = Attributes.getOwner(file); + + prepare(); + lookupService.lookupPrincipalByName(owner.getName()); + assertCheckPermission(RuntimePermission.class, + "lookupUserInformation"); + + try { + UserPrincipal group = Attributes.readPosixFileAttributes(file).group(); + prepare(); + lookupService.lookupPrincipalByGroupName(group.getName()); + assertCheckPermission(RuntimePermission.class, + "lookupUserInformation"); + } catch (UnsupportedOperationException ignore) { + System.out.println("lookupPrincipalByGroupName not tested"); + } + + + } finally { + file.deleteIfExists(); + } + } +} diff --git a/jdk/test/java/nio/file/Path/Misc.java b/jdk/test/java/nio/file/Path/Misc.java index 07418844fd8..9e5452c8988 100644 --- a/jdk/test/java/nio/file/Path/Misc.java +++ b/jdk/test/java/nio/file/Path/Misc.java @@ -22,7 +22,7 @@ */ /* @test - * @bug 4313887 6838333 6866804 + * @bug 4313887 6838333 6867101 * @summary Unit test for java.nio.file.Path for miscellenous methods not * covered by other tests * @library .. From 980873244b9f410cfc2da617072e5e455b23c7af Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Fri, 21 Aug 2009 11:31:18 -0700 Subject: [PATCH 92/96] 6378701: (enum) Unclear purpose of EnumConstantNotPresentException Reviewed-by: lancea, andrew, alanb --- .../classes/java/lang/EnumConstantNotPresentException.java | 4 ++++ jdk/src/share/classes/java/lang/TypeNotPresentException.java | 4 ++++ .../classes/java/lang/annotation/AnnotationFormatError.java | 4 ++++ .../lang/annotation/AnnotationTypeMismatchException.java | 4 ++++ .../java/lang/annotation/IncompleteAnnotationException.java | 4 ++++ .../share/classes/java/lang/reflect/AnnotatedElement.java | 5 +++++ 6 files changed, 25 insertions(+) diff --git a/jdk/src/share/classes/java/lang/EnumConstantNotPresentException.java b/jdk/src/share/classes/java/lang/EnumConstantNotPresentException.java index 4807691b210..a16b0e5bdfb 100644 --- a/jdk/src/share/classes/java/lang/EnumConstantNotPresentException.java +++ b/jdk/src/share/classes/java/lang/EnumConstantNotPresentException.java @@ -28,8 +28,12 @@ package java.lang; /** * Thrown when an application tries to access an enum constant by name * and the enum type contains no constant with the specified name. + * This exception can be thrown by the {@linkplain + * java.lang.reflect.AnnotatedElement API used to read annotations + * reflectively}. * * @author Josh Bloch + * @see java.lang.reflect.AnnotatedElement * @since 1.5 */ public class EnumConstantNotPresentException extends RuntimeException { diff --git a/jdk/src/share/classes/java/lang/TypeNotPresentException.java b/jdk/src/share/classes/java/lang/TypeNotPresentException.java index d7fa0d6bdeb..72b708393d1 100644 --- a/jdk/src/share/classes/java/lang/TypeNotPresentException.java +++ b/jdk/src/share/classes/java/lang/TypeNotPresentException.java @@ -35,8 +35,12 @@ package java.lang; *

    Note that this exception may be used when undefined type variables * are accessed as well as when types (e.g., classes, interfaces or * annotation types) are loaded. + * In particular, this exception can be thrown by the {@linkplain + * java.lang.reflect.AnnotatedElement API used to read annotations + * reflectively}. * * @author Josh Bloch + * @see java.lang.reflect.AnnotatedElement * @since 1.5 */ public class TypeNotPresentException extends RuntimeException { diff --git a/jdk/src/share/classes/java/lang/annotation/AnnotationFormatError.java b/jdk/src/share/classes/java/lang/annotation/AnnotationFormatError.java index 0bc2fd15169..0263907cdba 100644 --- a/jdk/src/share/classes/java/lang/annotation/AnnotationFormatError.java +++ b/jdk/src/share/classes/java/lang/annotation/AnnotationFormatError.java @@ -28,8 +28,12 @@ package java.lang.annotation; /** * Thrown when the annotation parser attempts to read an annotation * from a class file and determines that the annotation is malformed. + * This error can be thrown by the {@linkplain + * java.lang.reflect.AnnotatedElement API used to read annotations + * reflectively}. * * @author Josh Bloch + * @see java.lang.reflect.AnnotatedElement * @since 1.5 */ public class AnnotationFormatError extends Error { diff --git a/jdk/src/share/classes/java/lang/annotation/AnnotationTypeMismatchException.java b/jdk/src/share/classes/java/lang/annotation/AnnotationTypeMismatchException.java index c4cb7534c31..830b1f98dfe 100644 --- a/jdk/src/share/classes/java/lang/annotation/AnnotationTypeMismatchException.java +++ b/jdk/src/share/classes/java/lang/annotation/AnnotationTypeMismatchException.java @@ -30,8 +30,12 @@ import java.lang.reflect.Method; * Thrown to indicate that a program has attempted to access an element of * an annotation whose type has changed after the annotation was compiled * (or serialized). + * This exception can be thrown by the {@linkplain + * java.lang.reflect.AnnotatedElement API used to read annotations + * reflectively}. * * @author Josh Bloch + * @see java.lang.reflect.AnnotatedElement * @since 1.5 */ public class AnnotationTypeMismatchException extends RuntimeException { diff --git a/jdk/src/share/classes/java/lang/annotation/IncompleteAnnotationException.java b/jdk/src/share/classes/java/lang/annotation/IncompleteAnnotationException.java index 04070a1bbd4..9d5f43e1ad6 100644 --- a/jdk/src/share/classes/java/lang/annotation/IncompleteAnnotationException.java +++ b/jdk/src/share/classes/java/lang/annotation/IncompleteAnnotationException.java @@ -30,8 +30,12 @@ package java.lang.annotation; * an annotation type that was added to the annotation type definition after * the annotation was compiled (or serialized). This exception will not be * thrown if the new element has a default value. + * This exception can be thrown by the {@linkplain + * java.lang.reflect.AnnotatedElement API used to read annotations + * reflectively}. * * @author Josh Bloch + * @see java.lang.reflect.AnnotatedElement * @since 1.5 */ public class IncompleteAnnotationException extends RuntimeException { diff --git a/jdk/src/share/classes/java/lang/reflect/AnnotatedElement.java b/jdk/src/share/classes/java/lang/reflect/AnnotatedElement.java index 41436d63c0e..0601168a0a0 100644 --- a/jdk/src/share/classes/java/lang/reflect/AnnotatedElement.java +++ b/jdk/src/share/classes/java/lang/reflect/AnnotatedElement.java @@ -50,6 +50,11 @@ import java.lang.annotation.Annotation; * java.lang.annotation.AnnotationTypeMismatchException} or an * {@link java.lang.annotation.IncompleteAnnotationException}. * + * @see java.lang.EnumConstantNotPresentException + * @see java.lang.TypeNotPresentException + * @see java.lang.annotation.AnnotationFormatError + * @see java.lang.annotation.AnnotationTypeMismatchException + * @see java.lang.annotation.IncompleteAnnotationException * @since 1.5 * @author Josh Bloch */ From 7fa9df60cee542a228ab07b1e7bd132c2802003d Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Sat, 22 Aug 2009 17:40:18 +0100 Subject: [PATCH 93/96] 6874521: Remove @note tags Reviewed-by: andrew, darcy --- jdk/src/share/classes/java/nio/channels/Channels.java | 2 -- jdk/src/share/classes/java/nio/channels/FileChannel.java | 6 +----- jdk/src/share/classes/java/nio/channels/FileLock.java | 5 +---- jdk/src/share/classes/java/nio/channels/package-info.java | 1 - jdk/src/share/classes/java/nio/file/FileRef.java | 2 -- jdk/src/share/classes/java/util/Scanner.java | 2 -- 6 files changed, 2 insertions(+), 16 deletions(-) diff --git a/jdk/src/share/classes/java/nio/channels/Channels.java b/jdk/src/share/classes/java/nio/channels/Channels.java index 4fdcef8abb0..88f5e0eb8cf 100644 --- a/jdk/src/share/classes/java/nio/channels/Channels.java +++ b/jdk/src/share/classes/java/nio/channels/Channels.java @@ -182,7 +182,6 @@ public final class Channels { } /** - * {@note new} * Constructs a stream that reads bytes from the given channel. * *

    The stream will not be buffered, and it will not support the {@link @@ -258,7 +257,6 @@ public final class Channels { } /** - * {@note new} * Constructs a stream that writes bytes to the given channel. * *

    The stream will not be buffered. The stream will be safe for access diff --git a/jdk/src/share/classes/java/nio/channels/FileChannel.java b/jdk/src/share/classes/java/nio/channels/FileChannel.java index ab780a520a9..2a7713bd312 100644 --- a/jdk/src/share/classes/java/nio/channels/FileChannel.java +++ b/jdk/src/share/classes/java/nio/channels/FileChannel.java @@ -39,8 +39,7 @@ import java.util.Collections; /** * A channel for reading, writing, mapping, and manipulating a file. * - *

    {@note revised} - * A file channel is a {@link SeekableByteChannel} that is connected to + *

    A file channel is a {@link SeekableByteChannel} that is connected to * a file. It has a current position within its file which can * be both {@link #position() queried} and {@link #position(long) * modified}. The file itself contains a variable-length sequence @@ -151,7 +150,6 @@ import java.util.Collections; * @author Mike McCloskey * @author JSR-51 Expert Group * @since 1.4 - * @updated 1.7 */ public abstract class FileChannel @@ -164,7 +162,6 @@ public abstract class FileChannel protected FileChannel() { } /** - * {@note new} * Opens or creates a file, returning a file channel to access the file. * *

    The {@code options} parameter determines how the file is opened. @@ -293,7 +290,6 @@ public abstract class FileChannel private static final FileAttribute[] NO_ATTRIBUTES = new FileAttribute[0]; /** - * {@note new} * Opens or creates a file, returning a file channel to access the file. * *

    An invocation of this method behaves in exactly the same way as the diff --git a/jdk/src/share/classes/java/nio/channels/FileLock.java b/jdk/src/share/classes/java/nio/channels/FileLock.java index b0ec37f1ba5..8e1321144b5 100644 --- a/jdk/src/share/classes/java/nio/channels/FileLock.java +++ b/jdk/src/share/classes/java/nio/channels/FileLock.java @@ -114,7 +114,6 @@ import java.io.IOException; * @author Mark Reinhold * @author JSR-51 Expert Group * @since 1.4 - * @updated 1.7 */ public abstract class FileLock { @@ -161,7 +160,7 @@ public abstract class FileLock { } /** - * {@note new} Initializes a new instance of this class. + * Initializes a new instance of this class. * * @param channel * The channel upon whose file this lock is held @@ -199,7 +198,6 @@ public abstract class FileLock { } /** - * {@note revised} * Returns the file channel upon whose file this lock was acquired. * *

    This method has been superseded by the {@link #acquiredBy acquiredBy} @@ -213,7 +211,6 @@ public abstract class FileLock { } /** - * {@note new} * Returns the channel upon whose file this lock was acquired. * * @return The channel upon whose file this lock was acquired. diff --git a/jdk/src/share/classes/java/nio/channels/package-info.java b/jdk/src/share/classes/java/nio/channels/package-info.java index 36a40840260..d5bf5110e31 100644 --- a/jdk/src/share/classes/java/nio/channels/package-info.java +++ b/jdk/src/share/classes/java/nio/channels/package-info.java @@ -285,7 +285,6 @@ * java.lang.NullPointerException NullPointerException} to be thrown. * * @since 1.4 - * @updated 1.7 * @author Mark Reinhold * @author JSR-51 Expert Group */ diff --git a/jdk/src/share/classes/java/nio/file/FileRef.java b/jdk/src/share/classes/java/nio/file/FileRef.java index 8a19ce285c2..c2bfee92916 100644 --- a/jdk/src/share/classes/java/nio/file/FileRef.java +++ b/jdk/src/share/classes/java/nio/file/FileRef.java @@ -39,8 +39,6 @@ import java.io.IOException; * metadata or file attributes. * * @since 1.7 - * @see java.io.Inputs - * @see java.io.Outputs * @see java.nio.file.attribute.Attributes * @see java.io.File#toPath */ diff --git a/jdk/src/share/classes/java/util/Scanner.java b/jdk/src/share/classes/java/util/Scanner.java index c1032337bd2..b7ec4b847d2 100644 --- a/jdk/src/share/classes/java/util/Scanner.java +++ b/jdk/src/share/classes/java/util/Scanner.java @@ -674,7 +674,6 @@ public final class Scanner implements Iterator { } /** - * {@note new} * Constructs a new Scanner that produces values scanned * from the specified file. Bytes from the file are converted into * characters using the underlying platform's @@ -694,7 +693,6 @@ public final class Scanner implements Iterator { } /** - * {@note new} * Constructs a new Scanner that produces values scanned * from the specified file. Bytes from the file are converted into * characters using the specified charset. From aecf7417ad67ed1fe14b9b2e706990308e025454 Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Sun, 23 Aug 2009 12:53:45 +0100 Subject: [PATCH 94/96] 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101 Reviewed-by: sherman --- jdk/make/java/nio/FILES_java.gmk | 1 - .../nio/channels/AsynchronousByteChannel.java | 108 ++-- .../nio/channels/AsynchronousChannel.java | 53 +- .../channels/AsynchronousDatagramChannel.java | 316 +++------- .../nio/channels/AsynchronousFileChannel.java | 264 +++++---- .../AsynchronousServerSocketChannel.java | 39 +- .../channels/AsynchronousSocketChannel.java | 177 +++--- .../java/nio/channels/CompletionHandler.java | 17 +- .../classes/java/nio/channels/exceptions | 2 +- .../classes/sun/nio/ch/AbstractFuture.java | 63 -- .../nio/ch/AsynchronousChannelGroupImpl.java | 41 +- .../nio/ch/AsynchronousFileChannelImpl.java | 75 +++ .../AsynchronousServerSocketChannelImpl.java | 24 + .../nio/ch/AsynchronousSocketChannelImpl.java | 190 +++--- .../classes/sun/nio/ch/CompletedFuture.java | 46 +- jdk/src/share/classes/sun/nio/ch/Invoker.java | 197 ++++--- .../classes/sun/nio/ch/PendingFuture.java | 81 ++- ...SimpleAsynchronousDatagramChannelImpl.java | 171 ++++-- .../ch/SimpleAsynchronousFileChannelImpl.java | 169 +++--- .../solaris/classes/sun/nio/ch/EPollPort.java | 5 +- jdk/src/solaris/classes/sun/nio/ch/Port.java | 4 +- .../classes/sun/nio/ch/SolarisEventPort.java | 5 +- ...ixAsynchronousServerSocketChannelImpl.java | 160 ++--- .../ch/UnixAsynchronousSocketChannelImpl.java | 552 ++++++++++-------- jdk/src/windows/classes/sun/nio/ch/Iocp.java | 24 +- .../WindowsAsynchronousFileChannelImpl.java | 151 +++-- ...wsAsynchronousServerSocketChannelImpl.java | 52 +- .../WindowsAsynchronousSocketChannelImpl.java | 114 ++-- jdk/src/windows/native/sun/nio/ch/Iocp.c | 10 + .../AsynchronousChannelGroup/GroupOfOne.java | 10 +- .../AsynchronousChannelGroup/Identity.java | 9 +- .../AsynchronousChannelGroup/Restart.java | 4 +- .../AsynchronousChannelGroup/Unbounded.java | 6 +- .../AsynchronousDatagramChannel/Basic.java | 59 +- .../AsynchronousFileChannel/Basic.java | 61 +- .../CustomThreadPool.java | 4 +- .../AsynchronousFileChannel/Lock.java | 4 +- .../Basic.java | 4 +- .../AsynchronousSocketChannel/Basic.java | 113 ++-- .../DieBeforeComplete.java | 136 +++++ .../StressLoopback.java | 6 +- .../FileChannel/ReleaseOnCloseDeadlock.java | 4 +- 42 files changed, 1883 insertions(+), 1648 deletions(-) delete mode 100644 jdk/src/share/classes/sun/nio/ch/AbstractFuture.java create mode 100644 jdk/test/java/nio/channels/AsynchronousSocketChannel/DieBeforeComplete.java diff --git a/jdk/make/java/nio/FILES_java.gmk b/jdk/make/java/nio/FILES_java.gmk index 4fb524a7dd4..f3ba8254868 100644 --- a/jdk/make/java/nio/FILES_java.gmk +++ b/jdk/make/java/nio/FILES_java.gmk @@ -160,7 +160,6 @@ FILES_src = \ \ sun/nio/ByteBuffered.java \ \ - sun/nio/ch/AbstractFuture.java \ sun/nio/ch/AbstractPollArrayWrapper.java \ sun/nio/ch/AllocatedNativeObject.java \ sun/nio/ch/AsynchronousChannelGroupImpl.java \ diff --git a/jdk/src/share/classes/java/nio/channels/AsynchronousByteChannel.java b/jdk/src/share/classes/java/nio/channels/AsynchronousByteChannel.java index 7bc43357479..2b2c8226d4f 100644 --- a/jdk/src/share/classes/java/nio/channels/AsynchronousByteChannel.java +++ b/jdk/src/share/classes/java/nio/channels/AsynchronousByteChannel.java @@ -56,18 +56,18 @@ public interface AsynchronousByteChannel /** * Reads a sequence of bytes from this channel into the given buffer. * - *

    This method initiates an operation to read a sequence of bytes from - * this channel into the given buffer. The method returns a {@link Future} - * representing the pending result of the operation. The result of the - * operation, obtained by invoking the {@code Future} 's {@link - * Future#get() get} method, is the number of bytes read or {@code -1} if - * all bytes have been read and the channel has reached end-of-stream. + *

    This method initiates an asynchronous read operation to read a + * sequence of bytes from this channel into the given buffer. The {@code + * handler} parameter is a completion handler that is invoked when the read + * operation completes (or fails). The result passed to the completion + * handler is the number of bytes read or {@code -1} if no bytes could be + * read because the channel has reached end-of-stream. * - *

    This method initiates a read operation to read up to r bytes - * from the channel, where r is the number of bytes remaining in the - * buffer, that is, {@code dst.remaining()} at the time that the read is - * attempted. Where r is 0, the read operation completes immediately - * with a result of {@code 0} without initiating an I/O operation. + *

    The read operation may read up to r bytes from the channel, + * where r is the number of bytes remaining in the buffer, that is, + * {@code dst.remaining()} at the time that the read is attempted. Where + * r is 0, the read operation completes immediately with a result of + * {@code 0} without initiating an I/O operation. * *

    Suppose that a byte sequence of length n is read, where * 0 < n <= r. @@ -79,44 +79,46 @@ public interface AsynchronousByteChannel * p + n; its limit will not have changed. * *

    Buffers are not safe for use by multiple concurrent threads so care - * should be taken to not to access the buffer until the operaton has completed. + * should be taken to not access the buffer until the operation has + * completed. * *

    This method may be invoked at any time. Some channel types may not * allow more than one read to be outstanding at any given time. If a thread * initiates a read operation before a previous read operation has * completed then a {@link ReadPendingException} will be thrown. * - *

    The handler parameter is used to specify a {@link - * CompletionHandler}. When the read operation completes the handler's - * {@link CompletionHandler#completed completed} method is executed. - * - * * @param dst * The buffer into which bytes are to be transferred * @param attachment * The object to attach to the I/O operation; can be {@code null} * @param handler - * The completion handler object; can be {@code null} - * - * @return A Future representing the result of the operation + * The completion handler * * @throws IllegalArgumentException * If the buffer is read-only * @throws ReadPendingException * If the channel does not allow more than one read to be outstanding * and a previous read has not completed + * @throws ShutdownChannelGroupException + * If the channel is associated with a {@link AsynchronousChannelGroup + * group} that has terminated */ - Future read(ByteBuffer dst, - A attachment, - CompletionHandler handler); + void read(ByteBuffer dst, + A attachment, + CompletionHandler handler); /** * Reads a sequence of bytes from this channel into the given buffer. * - *

    An invocation of this method of the form c.read(dst) - * behaves in exactly the same manner as the invocation - *

    -     * c.read(dst, null, null);
    + *

    This method initiates an asynchronous read operation to read a + * sequence of bytes from this channel into the given buffer. The method + * behaves in exactly the same manner as the {@link + * #read(ByteBuffer,Object,CompletionHandler) + * read(ByteBuffer,Object,CompletionHandler)} method except that instead + * of specifying a completion handler, this method returns a {@code Future} + * representing the pending result. The {@code Future}'s {@link Future#get() + * get} method returns the number of bytes read or {@code -1} if no bytes + * could be read because the channel has reached end-of-stream. * * @param dst * The buffer into which bytes are to be transferred @@ -134,17 +136,17 @@ public interface AsynchronousByteChannel /** * Writes a sequence of bytes to this channel from the given buffer. * - *

    This method initiates an operation to write a sequence of bytes to - * this channel from the given buffer. This method returns a {@link - * Future} representing the pending result of the operation. The result - * of the operation, obtained by invoking the Future's {@link - * Future#get() get} method, is the number of bytes written, possibly zero. + *

    This method initiates an asynchronous write operation to write a + * sequence of bytes to this channel from the given buffer. The {@code + * handler} parameter is a completion handler that is invoked when the write + * operation completes (or fails). The result passed to the completion + * handler is the number of bytes written. * - *

    This method initiates a write operation to write up to r bytes - * to the channel, where r is the number of bytes remaining in the - * buffer, that is, {@code src.remaining()} at the moment the write is - * attempted. Where r is 0, the write operation completes immediately - * with a result of {@code 0} without initiating an I/O operation. + *

    The write operation may write up to r bytes to the channel, + * where r is the number of bytes remaining in the buffer, that is, + * {@code src.remaining()} at the time that the write is attempted. Where + * r is 0, the write operation completes immediately with a result of + * {@code 0} without initiating an I/O operation. * *

    Suppose that a byte sequence of length n is written, where * 0 < n <= r. @@ -156,41 +158,43 @@ public interface AsynchronousByteChannel * p + n; its limit will not have changed. * *

    Buffers are not safe for use by multiple concurrent threads so care - * should be taken to not to access the buffer until the operaton has completed. + * should be taken to not access the buffer until the operation has + * completed. * *

    This method may be invoked at any time. Some channel types may not * allow more than one write to be outstanding at any given time. If a thread * initiates a write operation before a previous write operation has * completed then a {@link WritePendingException} will be thrown. * - *

    The handler parameter is used to specify a {@link - * CompletionHandler}. When the write operation completes the handler's - * {@link CompletionHandler#completed completed} method is executed. - * * @param src * The buffer from which bytes are to be retrieved * @param attachment * The object to attach to the I/O operation; can be {@code null} * @param handler - * The completion handler object; can be {@code null} - * - * @return A Future representing the result of the operation + * The completion handler object * * @throws WritePendingException * If the channel does not allow more than one write to be outstanding * and a previous write has not completed + * @throws ShutdownChannelGroupException + * If the channel is associated with a {@link AsynchronousChannelGroup + * group} that has terminated */ - Future write(ByteBuffer src, - A attachment, - CompletionHandler handler); + void write(ByteBuffer src, + A attachment, + CompletionHandler handler); /** * Writes a sequence of bytes to this channel from the given buffer. * - *

    An invocation of this method of the form c.write(src) - * behaves in exactly the same manner as the invocation - *

    -     * c.write(src, null, null);
    + *

    This method initiates an asynchronous write operation to write a + * sequence of bytes to this channel from the given buffer. The method + * behaves in exactly the same manner as the {@link + * #write(ByteBuffer,Object,CompletionHandler) + * write(ByteBuffer,Object,CompletionHandler)} method except that instead + * of specifying a completion handler, this method returns a {@code Future} + * representing the pending result. The {@code Future}'s {@link Future#get() + * get} method returns the number of bytes written. * * @param src * The buffer from which bytes are to be retrieved diff --git a/jdk/src/share/classes/java/nio/channels/AsynchronousChannel.java b/jdk/src/share/classes/java/nio/channels/AsynchronousChannel.java index f3e4ffe4ea5..69ee8bd65d7 100644 --- a/jdk/src/share/classes/java/nio/channels/AsynchronousChannel.java +++ b/jdk/src/share/classes/java/nio/channels/AsynchronousChannel.java @@ -34,7 +34,8 @@ import java.util.concurrent.Future; // javadoc * *

      *
    1. {@link Future}<V> operation(...)
    2. - *
    3. Future<V> operation(... A attachment, {@link CompletionHandler}<V,? super A> handler)
    4. + *
    5. void operation(... A attachment, {@link
      + *   CompletionHandler}<V,? super A> handler)
    6. *
    * * where operation is the name of the I/O operation (read or write for @@ -48,7 +49,7 @@ import java.util.concurrent.Future; // javadoc * interface may be used to check if the operation has completed, wait for its * completion, and to retrieve the result. In the second form, a {@link * CompletionHandler} is invoked to consume the result of the I/O operation when - * it completes, fails, or is cancelled. + * it completes or fails. * *

    A channel that implements this interface is asynchronously * closeable: If an I/O operation is outstanding on the channel and the @@ -63,33 +64,33 @@ import java.util.concurrent.Future; // javadoc *

    Cancellation

    * *

    The {@code Future} interface defines the {@link Future#cancel cancel} - * method to cancel execution of a task. + * method to cancel execution. This causes all threads waiting on the result of + * the I/O operation to throw {@link java.util.concurrent.CancellationException}. + * Whether the underlying I/O operation can be cancelled is highly implementation + * specific and therefore not specified. Where cancellation leaves the channel, + * or the entity to which it is connected, in an inconsistent state, then the + * channel is put into an implementation specific error state that + * prevents further attempts to initiate I/O operations that are similar + * to the operation that was cancelled. For example, if a read operation is + * cancelled but the implementation cannot guarantee that bytes have not been + * read from the channel then it puts the channel into an error state; further + * attempts to initiate a {@code read} operation cause an unspecified runtime + * exception to be thrown. Similarly, if a write operation is cancelled but the + * implementation cannot guarantee that bytes have not been written to the + * channel then subsequent attempts to initiate a {@code write} will fail with + * an unspecified runtime exception. * - *

    Where the {@code cancel} method is invoked with the {@code + *

    Where the {@link Future#cancel cancel} method is invoked with the {@code * mayInterruptIfRunning} parameter set to {@code true} then the I/O operation - * may be interrupted by closing the channel. This will cause any other I/O - * operations outstanding on the channel to complete with the exception {@link - * AsynchronousCloseException}. - * - *

    If a {@code CompletionHandler} is specified when initiating an I/O - * operation, and the {@code cancel} method is invoked to cancel the I/O - * operation before it completes, then the {@code CompletionHandler}'s {@link - * CompletionHandler#cancelled cancelled} method is invoked. - * - *

    If an implementation of this interface supports a means to cancel I/O - * operations, and where cancellation may leave the channel, or the entity to - * which it is connected, in an inconsistent state, then the channel is put into - * an implementation specific error state that prevents further - * attempts to initiate I/O operations on the channel. For example, if a read - * operation is cancelled but the implementation cannot guarantee that bytes - * have not been read from the channel then it puts the channel into error state - * state; further attempts to initiate a {@code read} operation causes an - * unspecified runtime exception to be thrown. + * may be interrupted by closing the channel. In that case all threads waiting + * on the result of the I/O operation throw {@code CancellationException} and + * any other I/O operations outstanding on the channel complete with the + * exception {@link AsynchronousCloseException}. * *

    Where the {@code cancel} method is invoked to cancel read or write - * operations then it recommended that all buffers used in the I/O operations be - * discarded or care taken to ensure that the buffers are not accessed while the - * channel remains open. + * operations then it is recommended that all buffers used in the I/O operations + * be discarded or care taken to ensure that the buffers are not accessed while + * the channel remains open. * * @since 1.7 */ @@ -102,7 +103,7 @@ public interface AsynchronousChannel * *

    Any outstanding asynchronous operations upon this channel will * complete with the exception {@link AsynchronousCloseException}. After a - * channel is closed then further attempts to initiate asynchronous I/O + * channel is closed, further attempts to initiate asynchronous I/O * operations complete immediately with cause {@link ClosedChannelException}. * *

    This method otherwise behaves exactly as specified by the {@link diff --git a/jdk/src/share/classes/java/nio/channels/AsynchronousDatagramChannel.java b/jdk/src/share/classes/java/nio/channels/AsynchronousDatagramChannel.java index 65b90d0f29d..a229ce62737 100644 --- a/jdk/src/share/classes/java/nio/channels/AsynchronousDatagramChannel.java +++ b/jdk/src/share/classes/java/nio/channels/AsynchronousDatagramChannel.java @@ -109,19 +109,13 @@ import java.nio.ByteBuffer; * // print the source address of all packets that we receive * dc.receive(buffer, buffer, new CompletionHandler<SocketAddress,ByteBuffer>() { * public void completed(SocketAddress sa, ByteBuffer buffer) { - * try { - * System.out.println(sa); - * - * buffer.clear(); - * dc.receive(buffer, buffer, this); - * } catch (...) { ... } + * System.out.println(sa); + * buffer.clear(); + * dc.receive(buffer, buffer, this); * } * public void failed(Throwable exc, ByteBuffer buffer) { * ... * } - * public void cancelled(ByteBuffer buffer) { - * ... - * } * }); *

    * @@ -314,10 +308,10 @@ public abstract class AsynchronousDatagramChannel /** * Receives a datagram via this channel. * - *

    This method initiates the receiving of a datagram, returning a - * {@code Future} representing the pending result of the operation. - * The {@code Future}'s {@link Future#get() get} method returns - * the source address of the datagram upon successful completion. + *

    This method initiates the receiving of a datagram into the given + * buffer. The {@code handler} parameter is a completion handler that is + * invoked when the receive operation completes (or fails). The result + * passed to the completion handler is the datagram's source address. * *

    The datagram is transferred into the given byte buffer starting at * its current position, as if by a regular {@link AsynchronousByteChannel#read @@ -350,28 +344,26 @@ public abstract class AsynchronousDatagramChannel * @param attachment * The object to attach to the I/O operation; can be {@code null} * @param handler - * The handler for consuming the result; can be {@code null} - * - * @return a {@code Future} object representing the pending result + * The handler for consuming the result * * @throws IllegalArgumentException * If the timeout is negative or the buffer is read-only * @throws ShutdownChannelGroupException - * If a handler is specified, and the channel group is shutdown + * If the channel group has terminated */ - public abstract Future receive(ByteBuffer dst, - long timeout, - TimeUnit unit, - A attachment, - CompletionHandler handler); + public abstract void receive(ByteBuffer dst, + long timeout, + TimeUnit unit, + A attachment, + CompletionHandler handler); /** * Receives a datagram via this channel. * - *

    This method initiates the receiving of a datagram, returning a - * {@code Future} representing the pending result of the operation. - * The {@code Future}'s {@link Future#get() get} method returns - * the source address of the datagram upon successful completion. + *

    This method initiates the receiving of a datagram into the given + * buffer. The {@code handler} parameter is a completion handler that is + * invoked when the receive operation completes (or fails). The result + * passed to the completion handler is the datagram's source address. * *

    This method is equivalent to invoking {@link * #receive(ByteBuffer,long,TimeUnit,Object,CompletionHandler)} with a @@ -382,34 +374,30 @@ public abstract class AsynchronousDatagramChannel * @param attachment * The object to attach to the I/O operation; can be {@code null} * @param handler - * The handler for consuming the result; can be {@code null} - * - * @return a {@code Future} object representing the pending result + * The handler for consuming the result * * @throws IllegalArgumentException * If the buffer is read-only * @throws ShutdownChannelGroupException - * If a handler is specified, and the channel group is shutdown + * If the channel group has terminated */ - public final Future receive(ByteBuffer dst, - A attachment, - CompletionHandler handler) + public final void receive(ByteBuffer dst, + A attachment, + CompletionHandler handler) { - return receive(dst, 0L, TimeUnit.MILLISECONDS, attachment, handler); + receive(dst, 0L, TimeUnit.MILLISECONDS, attachment, handler); } /** * Receives a datagram via this channel. * - *

    This method initiates the receiving of a datagram, returning a - * {@code Future} representing the pending result of the operation. - * The {@code Future}'s {@link Future#get() get} method returns - * the source address of the datagram upon successful completion. - * - *

    This method is equivalent to invoking {@link - * #receive(ByteBuffer,long,TimeUnit,Object,CompletionHandler)} with a - * timeout of {@code 0L}, and an attachment and completion handler - * of {@code null}. + *

    This method initiates the receiving of a datagram into the given + * buffer. The method behaves in exactly the same manner as the {@link + * #receive(ByteBuffer,Object,CompletionHandler) + * receive(ByteBuffer,Object,CompletionHandler)} method except that instead + * of specifying a completion handler, this method returns a {@code Future} + * representing the pending result. The {@code Future}'s {@link Future#get() + * get} method returns the datagram's source address. * * @param dst * The buffer into which the datagram is to be transferred @@ -419,84 +407,19 @@ public abstract class AsynchronousDatagramChannel * @throws IllegalArgumentException * If the buffer is read-only */ - public final Future receive(ByteBuffer dst) { - return receive(dst, 0L, TimeUnit.MILLISECONDS, null, null); - } + public abstract Future receive(ByteBuffer dst); /** * Sends a datagram via this channel. * - *

    This method initiates sending of a datagram, returning a - * {@code Future} representing the pending result of the operation. - * The operation sends the remaining bytes in the given buffer as a single - * datagram to the given target address. The result of the operation, obtained - * by invoking the {@code Future}'s {@link Future#get() get} - * method, is the number of bytes sent. + *

    This method initiates sending of a datagram from the given buffer to + * the given address. The {@code handler} parameter is a completion handler + * that is invoked when the send completes (or fails). The result passed to + * the completion handler is the number of bytes sent. * - *

    The datagram is transferred from the byte buffer as if by a regular - * {@link AsynchronousByteChannel#write write} operation. - * - *

    If a timeout is specified and the timeout elapses before the operation - * completes then the operation completes with the exception {@link - * InterruptedByTimeoutException}. When a timeout elapses then the state of - * the {@link ByteBuffer} is not defined. The buffers should be discarded or - * at least care must be taken to ensure that the buffer is not accessed - * while the channel remains open. - * - *

    If there is a security manager installed and the channel is not - * connected then this method verifies that the target address and port number - * are permitted by the security manager's {@link SecurityManager#checkConnect - * checkConnect} method. The overhead of this security check can be avoided - * by first connecting the socket via the {@link #connect connect} method. - * - * @param src - * The buffer containing the datagram to be sent - * @param target - * The address to which the datagram is to be sent - * @param timeout - * The timeout, or {@code 0L} for no timeout - * @param unit - * The time unit of the {@code timeout} argument - * @param attachment - * The object to attach to the I/O operation; can be {@code null} - * @param handler - * The handler for consuming the result; can be {@code null} - * - * @return a {@code Future} object representing the pending result - * - * @throws UnresolvedAddressException - * If the given remote address is not fully resolved - * @throws UnsupportedAddressTypeException - * If the type of the given remote address is not supported - * @throws IllegalArgumentException - * If the timeout is negative, or if the channel's socket is - * connected to an address that is not equal to {@code target} - * @throws SecurityException - * If a security manager has been installed and it does not permit - * datagrams to be sent to the given address - * @throws ShutdownChannelGroupException - * If a handler is specified, and the channel group is shutdown - */ - public abstract Future send(ByteBuffer src, - SocketAddress target, - long timeout, - TimeUnit unit, - A attachment, - CompletionHandler handler); - - /** - * Sends a datagram via this channel. - * - *

    This method initiates sending of a datagram, returning a - * {@code Future} representing the pending result of the operation. - * The operation sends the remaining bytes in the given buffer as a single - * datagram to the given target address. The result of the operation, obtained - * by invoking the {@code Future}'s {@link Future#get() get} - * method, is the number of bytes sent. - * - *

    This method is equivalent to invoking {@link - * #send(ByteBuffer,SocketAddress,long,TimeUnit,Object,CompletionHandler)} - * with a timeout of {@code 0L}. + *

    Otherwise this method works in the same manner as the {@link + * AsynchronousByteChannel#write(ByteBuffer,Object,CompletionHandler)} + * method. * * @param src * The buffer containing the datagram to be sent @@ -505,9 +428,7 @@ public abstract class AsynchronousDatagramChannel * @param attachment * The object to attach to the I/O operation; can be {@code null} * @param handler - * The handler for consuming the result; can be {@code null} - * - * @return a {@code Future} object representing the pending result + * The handler for consuming the result * * @throws UnresolvedAddressException * If the given remote address is not fully resolved @@ -520,30 +441,23 @@ public abstract class AsynchronousDatagramChannel * If a security manager has been installed and it does not permit * datagrams to be sent to the given address * @throws ShutdownChannelGroupException - * If a handler is specified, and the channel group is shutdown + * If the channel group has terminated */ - public final Future send(ByteBuffer src, - SocketAddress target, - A attachment, - CompletionHandler handler) - { - return send(src, target, 0L, TimeUnit.MILLISECONDS, attachment, handler); - } + public abstract void send(ByteBuffer src, + SocketAddress target, + A attachment, + CompletionHandler handler); /** * Sends a datagram via this channel. * - *

    This method initiates sending of a datagram, returning a - * {@code Future} representing the pending result of the operation. - * The operation sends the remaining bytes in the given buffer as a single - * datagram to the given target address. The result of the operation, obtained - * by invoking the {@code Future}'s {@link Future#get() get} - * method, is the number of bytes sent. - * - *

    This method is equivalent to invoking {@link - * #send(ByteBuffer,SocketAddress,long,TimeUnit,Object,CompletionHandler)} - * with a timeout of {@code 0L} and an attachment and completion handler - * of {@code null}. + *

    This method initiates sending of a datagram from the given buffer to + * the given address. The method behaves in exactly the same manner as the + * {@link #send(ByteBuffer,SocketAddress,Object,CompletionHandler) + * send(ByteBuffer,SocketAddress,Object,CompletionHandler)} method except + * that instead of specifying a completion handler, this method returns a + * {@code Future} representing the pending result. The {@code Future}'s + * {@link Future#get() get} method returns the number of bytes sent. * * @param src * The buffer containing the datagram to be sent @@ -563,17 +477,15 @@ public abstract class AsynchronousDatagramChannel * If a security manager has been installed and it does not permit * datagrams to be sent to the given address */ - public final Future send(ByteBuffer src, SocketAddress target) { - return send(src, target, 0L, TimeUnit.MILLISECONDS, null, null); - } + public abstract Future send(ByteBuffer src, SocketAddress target); /** * Receives a datagram via this channel. * - *

    This method initiates the receiving of a datagram, returning a - * {@code Future} representing the pending result of the operation. - * The {@code Future}'s {@link Future#get() get} method returns - * the number of bytes transferred upon successful completion. + *

    This method initiates the receiving of a datagram into the given + * buffer. The {@code handler} parameter is a completion handler that is + * invoked when the receive operation completes (or fails). The result + * passed to the completion handler is number of bytes read. * *

    This method may only be invoked if this channel is connected, and it * only accepts datagrams from the peer that the channel is connected too. @@ -599,120 +511,62 @@ public abstract class AsynchronousDatagramChannel * @param attachment * The object to attach to the I/O operation; can be {@code null} * @param handler - * The handler for consuming the result; can be {@code null} - * - * @return a {@code Future} object representing the pending result + * The handler for consuming the result * * @throws IllegalArgumentException * If the timeout is negative or buffer is read-only * @throws NotYetConnectedException * If this channel is not connected * @throws ShutdownChannelGroupException - * If a handler is specified, and the channel group is shutdown + * If the channel group has terminated */ - public abstract Future read(ByteBuffer dst, - long timeout, - TimeUnit unit, - A attachment, - CompletionHandler handler); + public abstract void read(ByteBuffer dst, + long timeout, + TimeUnit unit, + A attachment, + CompletionHandler handler); /** * @throws NotYetConnectedException * If this channel is not connected * @throws ShutdownChannelGroupException - * If a handler is specified, and the channel group is shutdown + * If the channel group has terminated */ @Override - public final Future read(ByteBuffer dst, - A attachment, - CompletionHandler handler) + public final void read(ByteBuffer dst, + A attachment, + CompletionHandler handler) { - return read(dst, 0L, TimeUnit.MILLISECONDS, attachment, handler); + read(dst, 0L, TimeUnit.MILLISECONDS, attachment, handler); } /** * @throws NotYetConnectedException * If this channel is not connected * @throws ShutdownChannelGroupException - * If a handler is specified, and the channel group is shutdown + * If the channel group has terminated */ @Override - public final Future read(ByteBuffer dst) { - return read(dst, 0L, TimeUnit.MILLISECONDS, null, null); - } - - /** - * Writes a datagram to this channel. - * - *

    This method initiates sending of a datagram, returning a - * {@code Future} representing the pending result of the operation. - * The operation sends the remaining bytes in the given buffer as a single - * datagram. The result of the operation, obtained by invoking the - * {@code Future}'s {@link Future#get() get} method, is the - * number of bytes sent. - * - *

    The datagram is transferred from the byte buffer as if by a regular - * {@link AsynchronousByteChannel#write write} operation. - * - *

    This method may only be invoked if this channel is connected, - * in which case it sends datagrams directly to the socket's peer. Otherwise - * it behaves exactly as specified in the {@link - * AsynchronousByteChannel} interface. - * - *

    If a timeout is specified and the timeout elapses before the operation - * completes then the operation completes with the exception {@link - * InterruptedByTimeoutException}. When a timeout elapses then the state of - * the {@link ByteBuffer} is not defined. The buffers should be discarded or - * at least care must be taken to ensure that the buffer is not accessed - * while the channel remains open. - * - * @param src - * The buffer containing the datagram to be sent - * @param timeout - * The timeout, or {@code 0L} for no timeout - * @param unit - * The time unit of the {@code timeout} argument - * @param attachment - * The object to attach to the I/O operation; can be {@code null} - * @param handler - * The handler for consuming the result; can be {@code null} - * - * @return a {@code Future} object representing the pending result - * - * @throws IllegalArgumentException - * If the timeout is negative - * @throws NotYetConnectedException - * If this channel is not connected - * @throws ShutdownChannelGroupException - * If a handler is specified, and the channel group is shutdown - */ - public abstract Future write(ByteBuffer src, - long timeout, - TimeUnit unit, - A attachment, - CompletionHandler handler); - /** - * @throws NotYetConnectedException - * If this channel is not connected - * @throws ShutdownChannelGroupException - * If a handler is specified, and the channel group is shutdown - */ - @Override - public final Future write(ByteBuffer src, - A attachment, - CompletionHandler handler) - { - return write(src, 0L, TimeUnit.MILLISECONDS, attachment, handler); - } + public abstract Future read(ByteBuffer dst); /** * @throws NotYetConnectedException * If this channel is not connected * @throws ShutdownChannelGroupException - * If a handler is specified, and the channel group is shutdown + * If the channel group has terminated */ @Override - public final Future write(ByteBuffer src) { - return write(src, 0L, TimeUnit.MILLISECONDS, null, null); - } + public abstract void write(ByteBuffer src, + A attachment, + CompletionHandler handler); + + + /** + * @throws NotYetConnectedException + * If this channel is not connected + * @throws ShutdownChannelGroupException + * If the channel group has terminated + */ + @Override + public abstract Future write(ByteBuffer src); } diff --git a/jdk/src/share/classes/java/nio/channels/AsynchronousFileChannel.java b/jdk/src/share/classes/java/nio/channels/AsynchronousFileChannel.java index a9bff5f16d4..9d37b9d8da8 100644 --- a/jdk/src/share/classes/java/nio/channels/AsynchronousFileChannel.java +++ b/jdk/src/share/classes/java/nio/channels/AsynchronousFileChannel.java @@ -48,7 +48,12 @@ import java.util.Collections; * *

    An asynchronous file channel does not have a current position * within the file. Instead, the file position is specified to each read and - * write operation. + * write methd that initiate asynchronous operations. A {@link CompletionHandler} + * is specified as a parameter and is invoked to consume the result of the I/O + * operation. This class also defines read and write methods that initiate + * asynchronous operations, returning a {@link Future} to represent the pending + * result of the operation. The {@code Future} may be used to check if the + * operation has completed, to wait for its completion. * *

    In addition to read and write operations, this class defines the * following operations:

    @@ -59,18 +64,11 @@ import java.util.Collections; * out} to the underlying storage device, ensuring that data are not * lost in the event of a system crash.

  • * - *
  • A region of a file may be {@link FileLock locked} - * against access by other programs.

  • + *
  • A region of a file may be {@link #lock locked} against + * access by other programs.

  • * * * - *

    The {@link #read read}, {@link #write write}, and {@link #lock lock} - * methods defined by this class are asynchronous and return a {@link Future} - * to represent the pending result of the operation. This may be used to check - * if the operation has completed, to wait for its completion, and to retrieve - * the result. These method may optionally specify a {@link CompletionHandler} - * that is invoked to consume the result of the I/O operation when it completes. - * *

    An {@code AsynchronousFileChannel} is associated with a thread pool to * which tasks are submitted to handle I/O events and dispatch to completion * handlers that consume the results of I/O operations on the channel. The @@ -122,22 +120,6 @@ public abstract class AsynchronousFileChannel protected AsynchronousFileChannel() { } - /** - * Closes this channel. - * - *

    If this channel is associated with its own thread pool then closing - * the channel causes the thread pool to shutdown after all actively - * executing completion handlers have completed. No attempt is made to stop - * or interrupt actively completion handlers. - * - *

    This method otherwise behaves exactly as specified by the {@link - * AsynchronousChannel} interface. - * - * @throws IOException {@inheritDoc} - */ - @Override - public abstract void close() throws IOException; - /** * Opens or creates a file for reading and/or writing, returning an * asynchronous file channel to access the file. @@ -215,9 +197,8 @@ public abstract class AsynchronousFileChannel * should be taken when configuring the {@code Executor}. Minimally it * should support an unbounded work queue and should not run tasks on the * caller thread of the {@link ExecutorService#execute execute} method. - * {@link #close Closing} the channel results in the orderly {@link - * ExecutorService#shutdown shutdown} of the executor service. Shutting down - * the executor service by other means results in unspecified behavior. + * Shutting down the executor service while the channel is open results in + * unspecified behavior. * *

    The {@code attrs} parameter is an optional array of file {@link * FileAttribute file-attributes} to set atomically when creating the file. @@ -276,7 +257,8 @@ public abstract class AsynchronousFileChannel *

    An invocation of this method behaves in exactly the same way as the * invocation *

    -     *     ch.{@link #open(Path,Set,ExecutorService,FileAttribute[]) open}(file, opts, null, new FileAttribute<?>[0]);
    +     *     ch.{@link #open(Path,Set,ExecutorService,FileAttribute[])
    +     *       open}(file, opts, null, new FileAttribute<?>[0]);
          * 
    * where {@code opts} is a {@code Set} containing the options specified to * this method. @@ -405,10 +387,11 @@ public abstract class AsynchronousFileChannel /** * Acquires a lock on the given region of this channel's file. * - *

    This method initiates an operation to acquire a lock on the given region - * of this channel's file. The method returns a {@code Future} representing - * the pending result of the operation. Its {@link Future#get() get} - * method returns the {@link FileLock} on successful completion. + *

    This method initiates an operation to acquire a lock on the given + * region of this channel's file. The {@code handler} parameter is a + * completion handler that is invoked when the lock is acquired (or the + * operation fails). The result passed to the completion handler is the + * resulting {@code FileLock}. * *

    The region specified by the {@code position} and {@code size} * parameters need not be contained within, or even overlap, the actual @@ -455,9 +438,7 @@ public abstract class AsynchronousFileChannel * @param attachment * The object to attach to the I/O operation; can be {@code null} * @param handler - * The handler for consuming the result; can be {@code null} - * - * @return a {@code Future} object representing the pending result + * The handler for consuming the result * * @throws OverlappingFileLockException * If a lock that overlaps the requested region is already held by @@ -466,26 +447,24 @@ public abstract class AsynchronousFileChannel * @throws IllegalArgumentException * If the preconditions on the parameters do not hold * @throws NonReadableChannelException - * If {@code shared} is true this channel but was not opened for reading + * If {@code shared} is true but this channel was not opened for reading * @throws NonWritableChannelException * If {@code shared} is false but this channel was not opened for writing - * @throws ShutdownChannelGroupException - * If a handler is specified, the channel is closed, and the channel - * was originally created with its own thread pool */ - public abstract Future lock(long position, - long size, - boolean shared, - A attachment, - CompletionHandler handler); + public abstract void lock(long position, + long size, + boolean shared, + A attachment, + CompletionHandler handler); /** * Acquires an exclusive lock on this channel's file. * - *

    This method initiates an operation to acquire an exclusive lock on this - * channel's file. The method returns a {@code Future} representing - * the pending result of the operation. Its {@link Future#get() get} - * method returns the {@link FileLock} on successful completion. + *

    This method initiates an operation to acquire a lock on the given + * region of this channel's file. The {@code handler} parameter is a + * completion handler that is invoked when the lock is acquired (or the + * operation fails). The result passed to the completion handler is the + * resulting {@code FileLock}. * *

    An invocation of this method of the form {@code ch.lock(att,handler)} * behaves in exactly the same way as the invocation @@ -496,7 +475,70 @@ public abstract class AsynchronousFileChannel * @param attachment * The object to attach to the I/O operation; can be {@code null} * @param handler - * The handler for consuming the result; can be {@code null} + * The handler for consuming the result + * + * @throws OverlappingFileLockException + * If a lock is already held by this Java virtual machine, or there + * is already a pending attempt to lock a region + * @throws NonWritableChannelException + * If this channel was not opened for writing + */ + public final void lock(A attachment, + CompletionHandler handler) + { + lock(0L, Long.MAX_VALUE, false, attachment, handler); + } + + /** + * Acquires a lock on the given region of this channel's file. + * + *

    This method initiates an operation to acquire a lock on the given + * region of this channel's file. The method behaves in exactly the same + * manner as the {@link #lock(long, long, boolean, Object, CompletionHandler)} + * method except that instead of specifying a completion handler, this + * method returns a {@code Future} representing the pending result. The + * {@code Future}'s {@link Future#get() get} method returns the {@link + * FileLock} on successful completion. + * + * @param position + * The position at which the locked region is to start; must be + * non-negative + * @param size + * The size of the locked region; must be non-negative, and the sum + * {@code position} + {@code size} must be non-negative + * @param shared + * {@code true} to request a shared lock, in which case this + * channel must be open for reading (and possibly writing); + * {@code false} to request an exclusive lock, in which case this + * channel must be open for writing (and possibly reading) + * + * @return a {@code Future} object representing the pending result + * + * @throws OverlappingFileLockException + * If a lock is already held by this Java virtual machine, or there + * is already a pending attempt to lock a region + * @throws IllegalArgumentException + * If the preconditions on the parameters do not hold + * @throws NonReadableChannelException + * If {@code shared} is true but this channel was not opened for reading + * @throws NonWritableChannelException + * If {@code shared} is false but this channel was not opened for writing + */ + public abstract Future lock(long position, long size, boolean shared); + + /** + * Acquires an exclusive lock on this channel's file. + * + *

    This method initiates an operation to acquire an exclusive lock on this + * channel's file. The method returns a {@code Future} representing the + * pending result of the operation. The {@code Future}'s {@link Future#get() + * get} method returns the {@link FileLock} on successful completion. + * + *

    An invocation of this method behaves in exactly the same way as the + * invocation + *

    +     *     ch.{@link #lock(long,long,boolean) lock}(0L, Long.MAX_VALUE, false)
    +     * 
    * * @return a {@code Future} object representing the pending result * @@ -505,40 +547,9 @@ public abstract class AsynchronousFileChannel * is already a pending attempt to lock a region * @throws NonWritableChannelException * If this channel was not opened for writing - * @throws ShutdownChannelGroupException - * If a handler is specified, the channel is closed, and the channel - * was originally created with its own thread pool - */ - public final Future lock(A attachment, - CompletionHandler handler) - { - return lock(0L, Long.MAX_VALUE, false, attachment, handler); - } - - /** - * Acquires an exclusive lock on this channel's file. - * - *

    This method initiates an operation to acquire an exclusive lock on this - * channel's file. The method returns a {@code Future} representing the - * pending result of the operation. Its {@link Future#get() get} method - * returns the {@link FileLock} on successful completion. - * - *

    An invocation of this method behaves in exactly the same way as the - * invocation - *

    -     *     ch.{@link #lock(long,long,boolean,Object,CompletionHandler) lock}(0L, Long.MAX_VALUE, false, null, null)
    -     * 
    - * - * @return A {@code Future} object representing the pending result - * - * @throws OverlappingFileLockException - * If a lock is already held by this Java virtual machine, or there - * is already a pending attempt to lock a region - * @throws NonWritableChannelException - * If this channel was not opened for writing */ public final Future lock() { - return lock(0L, Long.MAX_VALUE, false, null, null); + return lock(0L, Long.MAX_VALUE, false); } /** @@ -576,7 +587,7 @@ public abstract class AsynchronousFileChannel * blocked in this method and is attempting to lock an overlapping * region of the same file * @throws NonReadableChannelException - * If {@code shared} is true this channel but was not opened for reading + * If {@code shared} is true but this channel was not opened for reading * @throws NonWritableChannelException * If {@code shared} is false but this channel was not opened for writing * @@ -629,11 +640,10 @@ public abstract class AsynchronousFileChannel * starting at the given file position. * *

    This method initiates the reading of a sequence of bytes from this - * channel into the given buffer, starting at the given file position. This - * method returns a {@code Future} representing the pending result of the - * operation. The Future's {@link Future#get() get} method returns the - * number of bytes read or {@code -1} if the given position is greater than - * or equal to the file's size at the time that the read is attempted. + * channel into the given buffer, starting at the given file position. The + * result of the read is the number of bytes read or {@code -1} if the given + * position is greater than or equal to the file's size at the time that the + * read is attempted. * *

    This method works in the same manner as the {@link * AsynchronousByteChannel#read(ByteBuffer,Object,CompletionHandler)} @@ -649,22 +659,17 @@ public abstract class AsynchronousFileChannel * @param attachment * The object to attach to the I/O operation; can be {@code null} * @param handler - * The handler for consuming the result; can be {@code null} - * - * @return A {@code Future} object representing the pending result + * The handler for consuming the result * * @throws IllegalArgumentException * If the position is negative or the buffer is read-only * @throws NonReadableChannelException * If this channel was not opened for reading - * @throws ShutdownChannelGroupException - * If a handler is specified, the channel is closed, and the channel - * was originally created with its own thread pool */ - public abstract Future read(ByteBuffer dst, - long position, - A attachment, - CompletionHandler handler); + public abstract void read(ByteBuffer dst, + long position, + A attachment, + CompletionHandler handler); /** * Reads a sequence of bytes from this channel into the given buffer, @@ -673,13 +678,15 @@ public abstract class AsynchronousFileChannel *

    This method initiates the reading of a sequence of bytes from this * channel into the given buffer, starting at the given file position. This * method returns a {@code Future} representing the pending result of the - * operation. The Future's {@link Future#get() get} method returns the - * number of bytes read or {@code -1} if the given position is greater + * operation. The {@code Future}'s {@link Future#get() get} method returns + * the number of bytes read or {@code -1} if the given position is greater * than or equal to the file's size at the time that the read is attempted. * - *

    This method is equivalent to invoking {@link - * #read(ByteBuffer,long,Object,CompletionHandler)} with the {@code attachment} - * and handler parameters set to {@code null}. + *

    This method works in the same manner as the {@link + * AsynchronousByteChannel#read(ByteBuffer)} method, except that bytes are + * read starting at the given file position. If the given file position is + * greater than the file's size at the time that the read is attempted then + * no bytes are read. * * @param dst * The buffer into which bytes are to be transferred @@ -694,20 +701,12 @@ public abstract class AsynchronousFileChannel * @throws NonReadableChannelException * If this channel was not opened for reading */ - public final Future read(ByteBuffer dst, long position) { - return read(dst, position, null, null); - } + public abstract Future read(ByteBuffer dst, long position); /** * Writes a sequence of bytes to this channel from the given buffer, starting * at the given file position. * - *

    This method initiates the writing of a sequence of bytes to this channel - * from the given buffer, starting at the given file position. The method - * returns a {@code Future} representing the pending result of the write - * operation. The Future's {@link Future#get() get} method returns the - * number of bytes written. - * *

    This method works in the same manner as the {@link * AsynchronousByteChannel#write(ByteBuffer,Object,CompletionHandler)} * method, except that bytes are written starting at the given file position. @@ -724,36 +723,35 @@ public abstract class AsynchronousFileChannel * @param attachment * The object to attach to the I/O operation; can be {@code null} * @param handler - * The handler for consuming the result; can be {@code null} - * - * @return A {@code Future} object representing the pending result + * The handler for consuming the result * * @throws IllegalArgumentException * If the position is negative * @throws NonWritableChannelException * If this channel was not opened for writing - * @throws ShutdownChannelGroupException - * If a handler is specified, the channel is closed, and the channel - * was originally created with its own thread pool */ - public abstract Future write(ByteBuffer src, - long position, - A attachment, - CompletionHandler handler); + public abstract void write(ByteBuffer src, + long position, + A attachment, + CompletionHandler handler); /** * Writes a sequence of bytes to this channel from the given buffer, starting * at the given file position. * - *

    This method initiates the writing of a sequence of bytes to this channel - * from the given buffer, starting at the given file position. The method - * returns a {@code Future} representing the pending result of the write - * operation. The Future's {@link Future#get() get} method returns the - * number of bytes written. + *

    This method initiates the writing of a sequence of bytes to this + * channel from the given buffer, starting at the given file position. The + * method returns a {@code Future} representing the pending result of the + * write operation. The {@code Future}'s {@link Future#get() get} method + * returns the number of bytes written. * - *

    This method is equivalent to invoking {@link - * #write(ByteBuffer,long,Object,CompletionHandler)} with the {@code attachment} - * and handler parameters set to {@code null}. + *

    This method works in the same manner as the {@link + * AsynchronousByteChannel#write(ByteBuffer)} method, except that bytes are + * written starting at the given file position. If the given position is + * greater than the file's size, at the time that the write is attempted, + * then the file will be grown to accommodate the new bytes; the values of + * any bytes between the previous end-of-file and the newly-written bytes + * are unspecified. * * @param src * The buffer from which bytes are to be transferred @@ -768,7 +766,5 @@ public abstract class AsynchronousFileChannel * @throws NonWritableChannelException * If this channel was not opened for writing */ - public final Future write(ByteBuffer src, long position) { - return write(src, position, null, null); - } + public abstract Future write(ByteBuffer src, long position); } diff --git a/jdk/src/share/classes/java/nio/channels/AsynchronousServerSocketChannel.java b/jdk/src/share/classes/java/nio/channels/AsynchronousServerSocketChannel.java index 99c56fa59c0..9428f1a5ea6 100644 --- a/jdk/src/share/classes/java/nio/channels/AsynchronousServerSocketChannel.java +++ b/jdk/src/share/classes/java/nio/channels/AsynchronousServerSocketChannel.java @@ -85,9 +85,6 @@ import java.io.IOException; * public void failed(Throwable exc, Void att) { * ... * } - * public void cancelled(Void att) { - * ... - * } * }); * * @@ -240,11 +237,11 @@ public abstract class AsynchronousServerSocketChannel /** * Accepts a connection. * - *

    This method initiates accepting a connection made to this channel's - * socket, returning a {@link Future} representing the pending result - * of the operation. The {@code Future}'s {@link Future#get() get} - * method will return the {@link AsynchronousSocketChannel} for the new - * connection on successful completion. + *

    This method initiates an asynchronous operation to accept a + * connection made to this channel's socket. The {@code handler} parameter is + * a completion handler that is invoked when a connection is accepted (or + * the operation fails). The result passed to the completion handler is + * the {@link AsynchronousSocketChannel} to the new connection. * *

    When a new connection is accepted then the resulting {@code * AsynchronousSocketChannel} will be bound to the same {@link @@ -269,35 +266,35 @@ public abstract class AsynchronousServerSocketChannel * @param attachment * The object to attach to the I/O operation; can be {@code null} * @param handler - * The handler for consuming the result; can be {@code null} - * - * @return an Future object representing the pending result + * The handler for consuming the result * * @throws AcceptPendingException * If an accept operation is already in progress on this channel * @throws NotYetBoundException * If this channel's socket has not yet been bound * @throws ShutdownChannelGroupException - * If a handler is specified, and the channel group is shutdown + * If the channel group has terminated */ - public abstract Future - accept(A attachment, CompletionHandler handler); + public abstract void accept(A attachment, + CompletionHandler handler); /** * Accepts a connection. * - *

    This method is equivalent to invoking {@link - * #accept(Object,CompletionHandler)} with the {@code attachment} - * and {@code handler} parameters set to {@code null}. + *

    This method initiates an asynchronous operation to accept a + * connection made to this channel's socket. The method behaves in exactly + * the same manner as the {@link #accept(Object, CompletionHandler)} method + * except that instead of specifying a completion handler, this method + * returns a {@code Future} representing the pending result. The {@code + * Future}'s {@link Future#get() get} method returns the {@link + * AsynchronousSocketChannel} to the new connection on successful completion. * - * @return an Future object representing the pending result + * @return a {@code Future} object representing the pending result * * @throws AcceptPendingException * If an accept operation is already in progress on this channel * @throws NotYetBoundException * If this channel's socket has not yet been bound */ - public final Future accept() { - return accept(null, null); - } + public abstract Future accept(); } diff --git a/jdk/src/share/classes/java/nio/channels/AsynchronousSocketChannel.java b/jdk/src/share/classes/java/nio/channels/AsynchronousSocketChannel.java index b6a5da8105d..a6d80490e1d 100644 --- a/jdk/src/share/classes/java/nio/channels/AsynchronousSocketChannel.java +++ b/jdk/src/share/classes/java/nio/channels/AsynchronousSocketChannel.java @@ -274,14 +274,11 @@ public abstract class AsynchronousSocketChannel /** * Connects this channel. * - *

    This method initiates an operation to connect this channel, returning - * a {@code Future} representing the pending result of the operation. If - * the connection is successfully established then the {@code Future}'s - * {@link Future#get() get} method will return {@code null}. If the - * connection cannot be established then the channel is closed. In that case, - * invoking the {@code get} method throws {@link - * java.util.concurrent.ExecutionException} with an {@code IOException} as - * the cause. + *

    This method initiates an operation to connect this channel. The + * {@code handler} parameter is a completion handler that is invoked when + * the connection is successfully established or connection cannot be + * established. If the connection cannot be established then the channel is + * closed. * *

    This method performs exactly the same security checks as the {@link * java.net.Socket} class. That is, if a security manager has been @@ -294,9 +291,7 @@ public abstract class AsynchronousSocketChannel * @param attachment * The object to attach to the I/O operation; can be {@code null} * @param handler - * The handler for consuming the result; can be {@code null} - * - * @return A {@code Future} object representing the pending result + * The handler for consuming the result * * @throws UnresolvedAddressException * If the given remote address is not fully resolved @@ -307,23 +302,26 @@ public abstract class AsynchronousSocketChannel * @throws ConnectionPendingException * If a connection operation is already in progress on this channel * @throws ShutdownChannelGroupException - * If a handler is specified, and the channel group is shutdown + * If the channel group has terminated * @throws SecurityException * If a security manager has been installed * and it does not permit access to the given remote endpoint * * @see #getRemoteAddress */ - public abstract Future connect(SocketAddress remote, - A attachment, - CompletionHandler handler); + public abstract void connect(SocketAddress remote, + A attachment, + CompletionHandler handler); /** * Connects this channel. * - *

    This method is equivalent to invoking {@link - * #connect(SocketAddress,Object,CompletionHandler)} with the {@code attachment} - * and handler parameters set to {@code null}. + *

    This method initiates an operation to connect this channel. This + * method behaves in exactly the same manner as the {@link + * #connect(SocketAddress, Object, CompletionHandler)} method except that + * instead of specifying a completion handler, this method returns a {@code + * Future} representing the pending result. The {@code Future}'s {@link + * Future#get() get} method returns {@code null} on successful completion. * * @param remote * The remote address to which this channel is to be connected @@ -342,18 +340,17 @@ public abstract class AsynchronousSocketChannel * If a security manager has been installed * and it does not permit access to the given remote endpoint */ - public final Future connect(SocketAddress remote) { - return connect(remote, null, null); - } + public abstract Future connect(SocketAddress remote); /** * Reads a sequence of bytes from this channel into the given buffer. * - *

    This method initiates the reading of a sequence of bytes from this - * channel into the given buffer, returning a {@code Future} representing - * the pending result of the operation. The {@code Future}'s {@link - * Future#get() get} method returns the number of bytes read or {@code -1} - * if all bytes have been read and channel has reached end-of-stream. + *

    This method initiates an asynchronous read operation to read a + * sequence of bytes from this channel into the given buffer. The {@code + * handler} parameter is a completion handler that is invoked when the read + * operation completes (or fails). The result passed to the completion + * handler is the number of bytes read or {@code -1} if no bytes could be + * read because the channel has reached end-of-stream. * *

    If a timeout is specified and the timeout elapses before the operation * completes then the operation completes with the exception {@link @@ -376,9 +373,7 @@ public abstract class AsynchronousSocketChannel * @param attachment * The object to attach to the I/O operation; can be {@code null} * @param handler - * The handler for consuming the result; can be {@code null} - * - * @return A {@code Future} object representing the pending result + * The handler for consuming the result * * @throws IllegalArgumentException * If the {@code timeout} parameter is negative or the buffer is @@ -388,13 +383,13 @@ public abstract class AsynchronousSocketChannel * @throws NotYetConnectedException * If this channel is not yet connected * @throws ShutdownChannelGroupException - * If a handler is specified, and the channel group is shutdown + * If the channel group has terminated */ - public abstract Future read(ByteBuffer dst, - long timeout, - TimeUnit unit, - A attachment, - CompletionHandler handler); + public abstract void read(ByteBuffer dst, + long timeout, + TimeUnit unit, + A attachment, + CompletionHandler handler); /** * @throws IllegalArgumentException {@inheritDoc} @@ -402,14 +397,14 @@ public abstract class AsynchronousSocketChannel * @throws NotYetConnectedException * If this channel is not yet connected * @throws ShutdownChannelGroupException - * If a handler is specified, and the channel group is shutdown + * If the channel group has terminated */ @Override - public final Future read(ByteBuffer dst, - A attachment, - CompletionHandler handler) + public final void read(ByteBuffer dst, + A attachment, + CompletionHandler handler) { - return read(dst, 0L, TimeUnit.MILLISECONDS, attachment, handler); + read(dst, 0L, TimeUnit.MILLISECONDS, attachment, handler); } /** @@ -419,16 +414,18 @@ public abstract class AsynchronousSocketChannel * If this channel is not yet connected */ @Override - public final Future read(ByteBuffer dst) { - return read(dst, 0L, TimeUnit.MILLISECONDS, null, null); - } + public abstract Future read(ByteBuffer dst); /** * Reads a sequence of bytes from this channel into a subsequence of the * given buffers. This operation, sometimes called a scattering read, * is often useful when implementing network protocols that group data into * segments consisting of one or more fixed-length headers followed by a - * variable-length body. + * variable-length body. The {@code handler} parameter is a completion + * handler that is invoked when the read operation completes (or fails). The + * result passed to the completion handler is the number of bytes read or + * {@code -1} if no bytes could be read because the channel has reached + * end-of-stream. * *

    This method initiates a read of up to r bytes from this channel, * where r is the total number of bytes remaining in the specified @@ -456,11 +453,6 @@ public abstract class AsynchronousSocketChannel * I/O operation is performed with the maximum number of buffers allowed by * the operating system. * - *

    The return value from this method is a {@code Future} representing - * the pending result of the operation. The {@code Future}'s {@link - * Future#get() get} method returns the number of bytes read or {@code -1L} - * if all bytes have been read and the channel has reached end-of-stream. - * *

    If a timeout is specified and the timeout elapses before the operation * completes then it completes with the exception {@link * InterruptedByTimeoutException}. Where a timeout occurs, and the @@ -485,9 +477,7 @@ public abstract class AsynchronousSocketChannel * @param attachment * The object to attach to the I/O operation; can be {@code null} * @param handler - * The handler for consuming the result; can be {@code null} - * - * @return A {@code Future} object representing the pending result + * The handler for consuming the result * * @throws IndexOutOfBoundsException * If the pre-conditions for the {@code offset} and {@code length} @@ -500,23 +490,24 @@ public abstract class AsynchronousSocketChannel * @throws NotYetConnectedException * If this channel is not yet connected * @throws ShutdownChannelGroupException - * If a handler is specified, and the channel group is shutdown + * If the channel group has terminated */ - public abstract Future read(ByteBuffer[] dsts, - int offset, - int length, - long timeout, - TimeUnit unit, - A attachment, - CompletionHandler handler); + public abstract void read(ByteBuffer[] dsts, + int offset, + int length, + long timeout, + TimeUnit unit, + A attachment, + CompletionHandler handler); /** * Writes a sequence of bytes to this channel from the given buffer. * - *

    This method initiates the writing of a sequence of bytes to this channel - * from the given buffer, returning a {@code Future} representing the - * pending result of the operation. The {@code Future}'s {@link Future#get() - * get} method will return the number of bytes written. + *

    This method initiates an asynchronous write operation to write a + * sequence of bytes to this channel from the given buffer. The {@code + * handler} parameter is a completion handler that is invoked when the write + * operation completes (or fails). The result passed to the completion + * handler is the number of bytes written. * *

    If a timeout is specified and the timeout elapses before the operation * completes then it completes with the exception {@link @@ -539,9 +530,7 @@ public abstract class AsynchronousSocketChannel * @param attachment * The object to attach to the I/O operation; can be {@code null} * @param handler - * The handler for consuming the result; can be {@code null} - * - * @return A {@code Future} object representing the pending result + * The handler for consuming the result * * @throws IllegalArgumentException * If the {@code timeout} parameter is negative @@ -550,28 +539,28 @@ public abstract class AsynchronousSocketChannel * @throws NotYetConnectedException * If this channel is not yet connected * @throws ShutdownChannelGroupException - * If a handler is specified, and the channel group is shutdown + * If the channel group has terminated */ - public abstract Future write(ByteBuffer src, - long timeout, - TimeUnit unit, - A attachment, - CompletionHandler handler); + public abstract void write(ByteBuffer src, + long timeout, + TimeUnit unit, + A attachment, + CompletionHandler handler); /** * @throws WritePendingException {@inheritDoc} * @throws NotYetConnectedException * If this channel is not yet connected * @throws ShutdownChannelGroupException - * If a handler is specified, and the channel group is shutdown + * If the channel group has terminated */ @Override - public final Future write(ByteBuffer src, - A attachment, - CompletionHandler handler) + public final void write(ByteBuffer src, + A attachment, + CompletionHandler handler) { - return write(src, 0L, TimeUnit.MILLISECONDS, attachment, handler); + write(src, 0L, TimeUnit.MILLISECONDS, attachment, handler); } /** @@ -580,16 +569,16 @@ public abstract class AsynchronousSocketChannel * If this channel is not yet connected */ @Override - public final Future write(ByteBuffer src) { - return write(src, 0L, TimeUnit.MILLISECONDS, null, null); - } + public abstract Future write(ByteBuffer src); /** * Writes a sequence of bytes to this channel from a subsequence of the given * buffers. This operation, sometimes called a gathering write, is * often useful when implementing network protocols that group data into * segments consisting of one or more fixed-length headers followed by a - * variable-length body. + * variable-length body. The {@code handler} parameter is a completion + * handler that is invoked when the write operation completes (or fails). + * The result passed to the completion handler is the number of bytes written. * *

    This method initiates a write of up to r bytes to this channel, * where r is the total number of bytes remaining in the specified @@ -616,10 +605,6 @@ public abstract class AsynchronousSocketChannel * remaining), exceeds this limit, then the I/O operation is performed with * the maximum number of buffers allowed by the operating system. * - *

    The return value from this method is a {@code Future} representing - * the pending result of the operation. The {@code Future}'s {@link - * Future#get() get} method will return the number of bytes written. - * *

    If a timeout is specified and the timeout elapses before the operation * completes then it completes with the exception {@link * InterruptedByTimeoutException}. Where a timeout occurs, and the @@ -644,9 +629,7 @@ public abstract class AsynchronousSocketChannel * @param attachment * The object to attach to the I/O operation; can be {@code null} * @param handler - * The handler for consuming the result; can be {@code null} - * - * @return A {@code Future} object representing the pending result + * The handler for consuming the result * * @throws IndexOutOfBoundsException * If the pre-conditions for the {@code offset} and {@code length} @@ -658,13 +641,13 @@ public abstract class AsynchronousSocketChannel * @throws NotYetConnectedException * If this channel is not yet connected * @throws ShutdownChannelGroupException - * If a handler is specified, and the channel group is shutdown + * If the channel group has terminated */ - public abstract Future write(ByteBuffer[] srcs, - int offset, - int length, - long timeout, - TimeUnit unit, - A attachment, - CompletionHandler handler); + public abstract void write(ByteBuffer[] srcs, + int offset, + int length, + long timeout, + TimeUnit unit, + A attachment, + CompletionHandler handler); } diff --git a/jdk/src/share/classes/java/nio/channels/CompletionHandler.java b/jdk/src/share/classes/java/nio/channels/CompletionHandler.java index c4d4add8ff9..43e5abeafb4 100644 --- a/jdk/src/share/classes/java/nio/channels/CompletionHandler.java +++ b/jdk/src/share/classes/java/nio/channels/CompletionHandler.java @@ -32,11 +32,9 @@ package java.nio.channels; * handler to be specified to consume the result of an asynchronous operation. * The {@link #completed completed} method is invoked when the I/O operation * completes successfully. The {@link #failed failed} method is invoked if the - * I/O operations fails. The {@link #cancelled cancelled} method is invoked when - * the I/O operation is cancelled by invoking the {@link - * java.util.concurrent.Future#cancel cancel} method. The implementations of - * these methods should complete in a timely manner so as to avoid keeping the - * invoking thread from dispatching to other completion handlers. + * I/O operations fails. The implementations of these methods should complete + * in a timely manner so as to avoid keeping the invoking thread from dispatching + * to other completion handlers. * * @param The result type of the I/O operation * @param The type of the object attached to the I/O operation @@ -65,13 +63,4 @@ public interface CompletionHandler { * The object attached to the I/O operation when it was initiated. */ void failed(Throwable exc, A attachment); - - /** - * Invoked when an operation is cancelled by invoking the {@link - * java.util.concurrent.Future#cancel cancel} method. - * - * @param attachment - * The object attached to the I/O operation when it was initiated. - */ - void cancelled(A attachment); } diff --git a/jdk/src/share/classes/java/nio/channels/exceptions b/jdk/src/share/classes/java/nio/channels/exceptions index fed9f72ab2e..d78ea57738f 100644 --- a/jdk/src/share/classes/java/nio/channels/exceptions +++ b/jdk/src/share/classes/java/nio/channels/exceptions @@ -190,5 +190,5 @@ gen WritePendingException " gen ShutdownChannelGroupException " * Unchecked exception thrown when an attempt is made to construct a channel in * a group that is shutdown or the completion handler for an I/O operation - * cannot be invoked because the channel group is shutdown." \ + * cannot be invoked because the channel group has terminated." \ -3903801676350154157L diff --git a/jdk/src/share/classes/sun/nio/ch/AbstractFuture.java b/jdk/src/share/classes/sun/nio/ch/AbstractFuture.java deleted file mode 100644 index f79dc7abbbf..00000000000 --- a/jdk/src/share/classes/sun/nio/ch/AbstractFuture.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2008-2009 Sun Microsystems, Inc. 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. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package sun.nio.ch; - -import java.nio.channels.AsynchronousChannel; -import java.util.concurrent.Future; - -/** - * Base implementation of Future used for asynchronous I/O - */ - -abstract class AbstractFuture - implements Future -{ - private final AsynchronousChannel channel; - private final A attachment; - - protected AbstractFuture(AsynchronousChannel channel, A attachment) { - this.channel = channel; - this.attachment = attachment; - } - - final AsynchronousChannel channel() { - return channel; - } - - final A attachment() { - return attachment; - } - - /** - * Returns the result of the operation if it has completed successfully. - */ - abstract V value(); - - /** - * Returns the exception if the operation has failed. - */ - abstract Throwable exception(); -} diff --git a/jdk/src/share/classes/sun/nio/ch/AsynchronousChannelGroupImpl.java b/jdk/src/share/classes/sun/nio/ch/AsynchronousChannelGroupImpl.java index 14e33ffe9d1..5bfc94e36c5 100644 --- a/jdk/src/share/classes/sun/nio/ch/AsynchronousChannelGroupImpl.java +++ b/jdk/src/share/classes/sun/nio/ch/AsynchronousChannelGroupImpl.java @@ -32,8 +32,8 @@ import java.io.IOException; import java.io.FileDescriptor; import java.util.Queue; import java.util.concurrent.*; -import java.util.concurrent.locks.*; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicBoolean; import java.security.PrivilegedAction; import java.security.AccessController; import java.security.AccessControlContext; @@ -65,11 +65,8 @@ abstract class AsynchronousChannelGroupImpl private final Queue taskQueue; // group shutdown - // shutdownLock is RW lock so as to allow for concurrent queuing of tasks - // when using a fixed thread pool. - private final ReadWriteLock shutdownLock = new ReentrantReadWriteLock(); + private final AtomicBoolean shutdown = new AtomicBoolean(); private final Object shutdownNowLock = new Object(); - private volatile boolean shutdown; private volatile boolean terminateInitiated; AsynchronousChannelGroupImpl(AsynchronousChannelProvider provider, @@ -214,7 +211,7 @@ abstract class AsynchronousChannelGroupImpl @Override public final boolean isShutdown() { - return shutdown; + return shutdown.get(); } @Override @@ -260,17 +257,10 @@ abstract class AsynchronousChannelGroupImpl @Override public final void shutdown() { - shutdownLock.writeLock().lock(); - try { - if (shutdown) { - // already shutdown - return; - } - shutdown = true; - } finally { - shutdownLock.writeLock().unlock(); + if (shutdown.getAndSet(true)) { + // already shutdown + return; } - // if there are channels in the group then shutdown will continue // when the last channel is closed if (!isEmpty()) { @@ -289,12 +279,7 @@ abstract class AsynchronousChannelGroupImpl @Override public final void shutdownNow() throws IOException { - shutdownLock.writeLock().lock(); - try { - shutdown = true; - } finally { - shutdownLock.writeLock().unlock(); - } + shutdown.set(true); synchronized (shutdownNowLock) { if (!terminateInitiated) { terminateInitiated = true; @@ -305,6 +290,18 @@ abstract class AsynchronousChannelGroupImpl } } + /** + * For use by AsynchronousFileChannel to release resources without shutting + * down the thread pool. + */ + final void detachFromThreadPool() { + if (shutdown.getAndSet(true)) + throw new AssertionError("Already shutdown"); + if (!isEmpty()) + throw new AssertionError("Group not empty"); + shutdownHandlerTasks(); + } + @Override public final boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException diff --git a/jdk/src/share/classes/sun/nio/ch/AsynchronousFileChannelImpl.java b/jdk/src/share/classes/sun/nio/ch/AsynchronousFileChannelImpl.java index 180238d8413..8757b999c9d 100644 --- a/jdk/src/share/classes/sun/nio/ch/AsynchronousFileChannelImpl.java +++ b/jdk/src/share/classes/sun/nio/ch/AsynchronousFileChannelImpl.java @@ -25,8 +25,10 @@ package sun.nio.ch; +import java.nio.ByteBuffer; import java.nio.channels.*; import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; import java.util.concurrent.locks.*; import java.io.FileDescriptor; import java.io.IOException; @@ -101,6 +103,33 @@ abstract class AsynchronousFileChannelImpl // -- file locking -- + abstract Future implLock(long position, + long size, + boolean shared, + A attachment, + CompletionHandler handler); + + @Override + public final Future lock(long position, + long size, + boolean shared) + + { + return implLock(position, size, shared, null, null); + } + + @Override + public final void lock(long position, + long size, + boolean shared, + A attachment, + CompletionHandler handler) + { + if (handler == null) + throw new NullPointerException("'handler' is null"); + implLock(position, size, shared, attachment, handler); + } + private volatile FileLockTable fileLockTable; final void ensureFileLockTableInitialized() throws IOException { @@ -175,4 +204,50 @@ abstract class AsynchronousFileChannelImpl end(); } } + + + // -- reading and writing -- + + abstract Future implRead(ByteBuffer dst, + long position, + A attachment, + CompletionHandler handler); + + @Override + public final Future read(ByteBuffer dst, long position) { + return implRead(dst, position, null, null); + } + + @Override + public final void read(ByteBuffer dst, + long position, + A attachment, + CompletionHandler handler) + { + if (handler == null) + throw new NullPointerException("'handler' is null"); + implRead(dst, position, attachment, handler); + } + + abstract Future implWrite(ByteBuffer src, + long position, + A attachment, + CompletionHandler handler); + + + @Override + public final Future write(ByteBuffer src, long position) { + return implWrite(src, position, null, null); + } + + @Override + public final void write(ByteBuffer src, + long position, + A attachment, + CompletionHandler handler) + { + if (handler == null) + throw new NullPointerException("'handler' is null"); + implWrite(src, position, attachment, handler); + } } diff --git a/jdk/src/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java b/jdk/src/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java index 49231930159..47bf820d6be 100644 --- a/jdk/src/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java +++ b/jdk/src/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java @@ -35,6 +35,7 @@ import java.io.IOException; import java.util.Set; import java.util.HashSet; import java.util.Collections; +import java.util.concurrent.Future; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import sun.net.NetHooks; @@ -108,6 +109,29 @@ abstract class AsynchronousServerSocketChannelImpl implClose(); } + /** + * Invoked by accept to accept connection + */ + abstract Future + implAccept(Object attachment, + CompletionHandler handler); + + + @Override + public final Future accept() { + return implAccept(null, null); + } + + @Override + @SuppressWarnings("unchecked") + public final void accept(A attachment, + CompletionHandler handler) + { + if (handler == null) + throw new NullPointerException("'handler' is null"); + implAccept(attachment, (CompletionHandler)handler); + } + final boolean isAcceptKilled() { return acceptKilled; } diff --git a/jdk/src/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java b/jdk/src/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java index 84b81a0c8b0..d378320716e 100644 --- a/jdk/src/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java +++ b/jdk/src/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java @@ -183,29 +183,54 @@ abstract class AsynchronousSocketChannelImpl killWriting(); } + /** + * Invoked by connect to initiate the connect operation. + */ + abstract Future implConnect(SocketAddress remote, + A attachment, + CompletionHandler handler); + + @Override + public final Future connect(SocketAddress remote) { + return implConnect(remote, null, null); + } + + @Override + public final void connect(SocketAddress remote, + A attachment, + CompletionHandler handler) + { + if (handler == null) + throw new NullPointerException("'handler' is null"); + implConnect(remote, attachment, handler); + } + /** * Invoked by read to initiate the I/O operation. */ - abstract Future readImpl(ByteBuffer[] dsts, - boolean isScatteringRead, + abstract Future implRead(boolean isScatteringRead, + ByteBuffer dst, + ByteBuffer[] dsts, long timeout, TimeUnit unit, A attachment, CompletionHandler handler); @SuppressWarnings("unchecked") - private Future read(ByteBuffer[] dsts, - boolean isScatteringRead, + private Future read(boolean isScatteringRead, + ByteBuffer dst, + ByteBuffer[] dsts, long timeout, TimeUnit unit, - A attachment, + A att, CompletionHandler handler) { if (!isOpen()) { - CompletedFuture result = CompletedFuture - .withFailure(this, new ClosedChannelException(), attachment); - Invoker.invoke(handler, result); - return result; + Throwable e = new ClosedChannelException(); + if (handler == null) + return CompletedFuture.withFailure(e); + Invoker.invoke(this, handler, att, null, e); + return null; } if (remoteAddress == null) @@ -213,13 +238,13 @@ abstract class AsynchronousSocketChannelImpl if (timeout < 0L) throw new IllegalArgumentException("Negative timeout"); - boolean hasSpaceToRead = isScatteringRead || dsts[0].hasRemaining(); + boolean hasSpaceToRead = isScatteringRead || dst.hasRemaining(); boolean shutdown = false; // check and update state synchronized (readLock) { if (readKilled) - throw new RuntimeException("Reading not allowed due to timeout or cancellation"); + throw new IllegalStateException("Reading not allowed due to timeout or cancellation"); if (reading) throw new ReadPendingException(); if (readShutdown) { @@ -234,44 +259,53 @@ abstract class AsynchronousSocketChannelImpl // immediately complete with -1 if shutdown for read // immediately complete with 0 if no space remaining if (shutdown || !hasSpaceToRead) { - CompletedFuture result; + Number result; if (isScatteringRead) { - Long value = (shutdown) ? Long.valueOf(-1L) : Long.valueOf(0L); - result = (CompletedFuture)CompletedFuture.withResult(this, value, attachment); + result = (shutdown) ? Long.valueOf(-1L) : Long.valueOf(0L); } else { - int value = (shutdown) ? -1 : 0; - result = (CompletedFuture)CompletedFuture.withResult(this, value, attachment); + result = (shutdown) ? -1 : 0; } - Invoker.invoke(handler, result); - return result; + if (handler == null) + return CompletedFuture.withResult((V)result); + Invoker.invoke(this, handler, att, (V)result, null); + return null; } - return readImpl(dsts, isScatteringRead, timeout, unit, attachment, handler); + return implRead(isScatteringRead, dst, dsts, timeout, unit, att, handler); } @Override - public final Future read(ByteBuffer dst, - long timeout, - TimeUnit unit, - A attachment, - CompletionHandler handler) - { + public final Future read(ByteBuffer dst) { if (dst.isReadOnly()) throw new IllegalArgumentException("Read-only buffer"); - ByteBuffer[] bufs = new ByteBuffer[1]; - bufs[0] = dst; - return read(bufs, false, timeout, unit, attachment, handler); + return read(false, dst, null, 0L, TimeUnit.MILLISECONDS, null, null); } @Override - public final Future read(ByteBuffer[] dsts, - int offset, - int length, - long timeout, - TimeUnit unit, - A attachment, - CompletionHandler handler) + public final void read(ByteBuffer dst, + long timeout, + TimeUnit unit, + A attachment, + CompletionHandler handler) { + if (handler == null) + throw new NullPointerException("'handler' is null"); + if (dst.isReadOnly()) + throw new IllegalArgumentException("Read-only buffer"); + read(false, dst, null, timeout, unit, attachment, handler); + } + + @Override + public final void read(ByteBuffer[] dsts, + int offset, + int length, + long timeout, + TimeUnit unit, + A attachment, + CompletionHandler handler) + { + if (handler == null) + throw new NullPointerException("'handler' is null"); if ((offset < 0) || (length < 0) || (offset > dsts.length - length)) throw new IndexOutOfBoundsException(); ByteBuffer[] bufs = Util.subsequence(dsts, offset, length); @@ -279,39 +313,41 @@ abstract class AsynchronousSocketChannelImpl if (bufs[i].isReadOnly()) throw new IllegalArgumentException("Read-only buffer"); } - return read(bufs, true, timeout, unit, attachment, handler); + read(true, null, bufs, timeout, unit, attachment, handler); } /** * Invoked by write to initiate the I/O operation. */ - abstract Future writeImpl(ByteBuffer[] srcs, - boolean isGatheringWrite, + abstract Future implWrite(boolean isGatheringWrite, + ByteBuffer src, + ByteBuffer[] srcs, long timeout, TimeUnit unit, A attachment, CompletionHandler handler); @SuppressWarnings("unchecked") - private Future write(ByteBuffer[] srcs, - boolean isGatheringWrite, + private Future write(boolean isGatheringWrite, + ByteBuffer src, + ByteBuffer[] srcs, long timeout, TimeUnit unit, - A attachment, + A att, CompletionHandler handler) { - boolean hasDataToWrite = isGatheringWrite || srcs[0].hasRemaining(); + boolean hasDataToWrite = isGatheringWrite || src.hasRemaining(); boolean closed = false; if (isOpen()) { if (remoteAddress == null) throw new NotYetConnectedException(); - if (timeout < 0L) + if (timeout < 0L) throw new IllegalArgumentException("Negative timeout"); // check and update state synchronized (writeLock) { if (writeKilled) - throw new RuntimeException("Writing not allowed due to timeout or cancellation"); + throw new IllegalStateException("Writing not allowed due to timeout or cancellation"); if (writing) throw new WritePendingException(); if (writeShutdown) { @@ -327,52 +363,57 @@ abstract class AsynchronousSocketChannelImpl // channel is closed or shutdown for write if (closed) { - CompletedFuture result = CompletedFuture - .withFailure(this, new ClosedChannelException(), attachment); - Invoker.invoke(handler, result); - return result; + Throwable e = new ClosedChannelException(); + if (handler == null) + return CompletedFuture.withFailure(e); + Invoker.invoke(this, handler, att, null, e); + return null; } // nothing to write so complete immediately if (!hasDataToWrite) { - CompletedFuture result; - if (isGatheringWrite) { - result = (CompletedFuture)CompletedFuture.withResult(this, 0L, attachment); - } else { - result = (CompletedFuture)CompletedFuture.withResult(this, 0, attachment); - } - Invoker.invoke(handler, result); - return result; + Number result = (isGatheringWrite) ? (Number)0L : (Number)0; + if (handler == null) + return CompletedFuture.withResult((V)result); + Invoker.invoke(this, handler, att, (V)result, null); + return null; } - return writeImpl(srcs, isGatheringWrite, timeout, unit, attachment, handler); + return implWrite(isGatheringWrite, src, srcs, timeout, unit, att, handler); } @Override - public final Future write(ByteBuffer src, - long timeout, - TimeUnit unit, - A attachment, - CompletionHandler handler) - { - ByteBuffer[] bufs = new ByteBuffer[1]; - bufs[0] = src; - return write(bufs, false, timeout, unit, attachment, handler); + public final Future write(ByteBuffer src) { + return write(false, src, null, 0L, TimeUnit.MILLISECONDS, null, null); } @Override - public final Future write(ByteBuffer[] srcs, - int offset, - int length, - long timeout, - TimeUnit unit, - A attachment, - CompletionHandler handler) + public final void write(ByteBuffer src, + long timeout, + TimeUnit unit, + A attachment, + CompletionHandler handler) { + if (handler == null) + throw new NullPointerException("'handler' is null"); + write(false, src, null, timeout, unit, attachment, handler); + } + + @Override + public final void write(ByteBuffer[] srcs, + int offset, + int length, + long timeout, + TimeUnit unit, + A attachment, + CompletionHandler handler) + { + if (handler == null) + throw new NullPointerException("'handler' is null"); if ((offset < 0) || (length < 0) || (offset > srcs.length - length)) throw new IndexOutOfBoundsException(); srcs = Util.subsequence(srcs, offset, length); - return write(srcs, true, timeout, unit, attachment, handler); + write(true, null, srcs, timeout, unit, attachment, handler); } @Override @@ -461,7 +502,6 @@ abstract class AsynchronousSocketChannelImpl } @Override - @SuppressWarnings("unchecked") public final SocketAddress getRemoteAddress() throws IOException { if (!isOpen()) throw new ClosedChannelException(); diff --git a/jdk/src/share/classes/sun/nio/ch/CompletedFuture.java b/jdk/src/share/classes/sun/nio/ch/CompletedFuture.java index 221b9f8f5f7..c3152db6097 100644 --- a/jdk/src/share/classes/sun/nio/ch/CompletedFuture.java +++ b/jdk/src/share/classes/sun/nio/ch/CompletedFuture.java @@ -25,7 +25,7 @@ package sun.nio.ch; -import java.nio.channels.AsynchronousChannel; +import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.ExecutionException; import java.io.IOException; @@ -35,39 +35,35 @@ import java.io.IOException; * completed. */ -final class CompletedFuture - extends AbstractFuture -{ +final class CompletedFuture implements Future { private final V result; private final Throwable exc; - private CompletedFuture(AsynchronousChannel channel, - V result, - Throwable exc, - A attachment) - { - super(channel, attachment); + private CompletedFuture(V result, Throwable exc) { this.result = result; this.exc = exc; } @SuppressWarnings("unchecked") - static CompletedFuture withResult(AsynchronousChannel channel, - V result, - A attachment) - { - return new CompletedFuture(channel, result, null, attachment); + static CompletedFuture withResult(V result) { + return new CompletedFuture(result, null); } @SuppressWarnings("unchecked") - static CompletedFuture withFailure(AsynchronousChannel channel, - Throwable exc, - A attachment) - { + static CompletedFuture withFailure(Throwable exc) { // exception must be IOException or SecurityException if (!(exc instanceof IOException) && !(exc instanceof SecurityException)) exc = new IOException(exc); - return new CompletedFuture(channel, null, exc, attachment); + return new CompletedFuture(null, exc); + } + + @SuppressWarnings("unchecked") + static CompletedFuture withResult(V result, Throwable exc) { + if (exc == null) { + return withResult(result); + } else { + return withFailure(exc); + } } @Override @@ -100,14 +96,4 @@ final class CompletedFuture public boolean cancel(boolean mayInterruptIfRunning) { return false; } - - @Override - Throwable exception() { - return exc; - } - - @Override - V value() { - return result; - } } diff --git a/jdk/src/share/classes/sun/nio/ch/Invoker.java b/jdk/src/share/classes/sun/nio/ch/Invoker.java index 182f7989a46..c4fcfb98041 100644 --- a/jdk/src/share/classes/sun/nio/ch/Invoker.java +++ b/jdk/src/share/classes/sun/nio/ch/Invoker.java @@ -117,33 +117,32 @@ class Invoker { * Invoke handler without checking the thread identity or number of handlers * on the thread stack. */ - @SuppressWarnings("unchecked") static void invokeUnchecked(CompletionHandler handler, - AbstractFuture result) + A attachment, + V value, + Throwable exc) { - if (handler != null && !result.isCancelled()) { - Throwable exc = result.exception(); - if (exc == null) { - handler.completed(result.value(), result.attachment()); - } else { - handler.failed(exc, result.attachment()); - } - - // clear interrupt - Thread.interrupted(); + if (exc == null) { + handler.completed(value, attachment); + } else { + handler.failed(exc, attachment); } + + // clear interrupt + Thread.interrupted(); } - /** - * Invoke handler after incrementing the invoke count. + * Invoke handler assuming thread identity already checked */ static void invokeDirect(GroupAndInvokeCount myGroupAndInvokeCount, CompletionHandler handler, - AbstractFuture result) + A attachment, + V result, + Throwable exc) { myGroupAndInvokeCount.incrementInvokeCount(); - invokeUnchecked(handler, result); + Invoker.invokeUnchecked(handler, attachment, result, exc); } /** @@ -151,64 +150,64 @@ class Invoker { * thread pool then the handler is invoked directly, otherwise it is * invoked indirectly. */ - static void invoke(CompletionHandler handler, - AbstractFuture result) + static void invoke(AsynchronousChannel channel, + CompletionHandler handler, + A attachment, + V result, + Throwable exc) { - if (handler != null) { - boolean invokeDirect = false; - boolean identityOkay = false; - GroupAndInvokeCount thisGroupAndInvokeCount = myGroupAndInvokeCount.get(); - if (thisGroupAndInvokeCount != null) { - AsynchronousChannel channel = result.channel(); - if ((thisGroupAndInvokeCount.group() == ((Groupable)channel).group())) - identityOkay = true; - if (identityOkay && - (thisGroupAndInvokeCount.invokeCount() < maxHandlerInvokeCount)) - { - // group match - invokeDirect = true; - } + boolean invokeDirect = false; + boolean identityOkay = false; + GroupAndInvokeCount thisGroupAndInvokeCount = myGroupAndInvokeCount.get(); + if (thisGroupAndInvokeCount != null) { + if ((thisGroupAndInvokeCount.group() == ((Groupable)channel).group())) + identityOkay = true; + if (identityOkay && + (thisGroupAndInvokeCount.invokeCount() < maxHandlerInvokeCount)) + { + // group match + invokeDirect = true; } - if (invokeDirect) { - thisGroupAndInvokeCount.incrementInvokeCount(); - invokeUnchecked(handler, result); - } else { - try { - invokeIndirectly(handler, result); - } catch (RejectedExecutionException ree) { - // channel group shutdown; fallback to invoking directly - // if the current thread has the right identity. - if (identityOkay) { - invokeUnchecked(handler, result); - } else { - throw new ShutdownChannelGroupException(); - } + } + if (invokeDirect) { + invokeDirect(thisGroupAndInvokeCount, handler, attachment, result, exc); + } else { + try { + invokeIndirectly(channel, handler, attachment, result, exc); + } catch (RejectedExecutionException ree) { + // channel group shutdown; fallback to invoking directly + // if the current thread has the right identity. + if (identityOkay) { + invokeDirect(thisGroupAndInvokeCount, + handler, attachment, result, exc); + } else { + throw new ShutdownChannelGroupException(); } } } } /** - * Invokes the handler "indirectly" in the channel group's thread pool. + * Invokes the handler indirectly via the channel group's thread pool. */ - static void invokeIndirectly(final CompletionHandler handler, - final AbstractFuture result) + static void invokeIndirectly(AsynchronousChannel channel, + final CompletionHandler handler, + final A attachment, + final V result, + final Throwable exc) { - if (handler != null) { - AsynchronousChannel channel = result.channel(); - try { - ((Groupable)channel).group().executeOnPooledThread(new Runnable() { - public void run() { - GroupAndInvokeCount thisGroupAndInvokeCount = - myGroupAndInvokeCount.get(); - if (thisGroupAndInvokeCount != null) - thisGroupAndInvokeCount.setInvokeCount(1); - invokeUnchecked(handler, result); - } - }); - } catch (RejectedExecutionException ree) { - throw new ShutdownChannelGroupException(); - } + try { + ((Groupable)channel).group().executeOnPooledThread(new Runnable() { + public void run() { + GroupAndInvokeCount thisGroupAndInvokeCount = + myGroupAndInvokeCount.get(); + if (thisGroupAndInvokeCount != null) + thisGroupAndInvokeCount.setInvokeCount(1); + invokeUnchecked(handler, attachment, result, exc); + } + }); + } catch (RejectedExecutionException ree) { + throw new ShutdownChannelGroupException(); } } @@ -216,19 +215,19 @@ class Invoker { * Invokes the handler "indirectly" in the given Executor */ static void invokeIndirectly(final CompletionHandler handler, - final AbstractFuture result, + final A attachment, + final V value, + final Throwable exc, Executor executor) { - if (handler != null) { - try { - executor.execute(new Runnable() { - public void run() { - invokeUnchecked(handler, result); - } - }); - } catch (RejectedExecutionException ree) { - throw new ShutdownChannelGroupException(); - } + try { + executor.execute(new Runnable() { + public void run() { + invokeUnchecked(handler, attachment, value, exc); + } + }); + } catch (RejectedExecutionException ree) { + throw new ShutdownChannelGroupException(); } } @@ -258,4 +257,52 @@ class Invoker { throw new ShutdownChannelGroupException(); } } + + /** + * Invoke handler with completed result. This method does not check the + * thread identity or the number of handlers on the thread stack. + */ + static void invokeUnchecked(PendingFuture future) { + assert future.isDone(); + CompletionHandler handler = future.handler(); + if (handler != null) { + invokeUnchecked(handler, + future.attachment(), + future.value(), + future.exception()); + } + } + + /** + * Invoke handler with completed result. If the current thread is in the + * channel group's thread pool then the handler is invoked directly, + * otherwise it is invoked indirectly. + */ + static void invoke(PendingFuture future) { + assert future.isDone(); + CompletionHandler handler = future.handler(); + if (handler != null) { + invoke(future.channel(), + handler, + future.attachment(), + future.value(), + future.exception()); + } + } + + /** + * Invoke handler with completed result. The handler is invoked indirectly, + * via the channel group's thread pool. + */ + static void invokeIndirectly(PendingFuture future) { + assert future.isDone(); + CompletionHandler handler = future.handler(); + if (handler != null) { + invokeIndirectly(future.channel(), + handler, + future.attachment(), + future.value(), + future.exception()); + } + } } diff --git a/jdk/src/share/classes/sun/nio/ch/PendingFuture.java b/jdk/src/share/classes/sun/nio/ch/PendingFuture.java index d88cf233a82..3b1899a62da 100644 --- a/jdk/src/share/classes/sun/nio/ch/PendingFuture.java +++ b/jdk/src/share/classes/sun/nio/ch/PendingFuture.java @@ -34,13 +34,13 @@ import java.io.IOException; * attachment of an additional arbitrary context object and a timer task. */ -final class PendingFuture - extends AbstractFuture -{ +final class PendingFuture implements Future { private static final CancellationException CANCELLED = new CancellationException(); + private final AsynchronousChannel channel; private final CompletionHandler handler; + private final A attachment; // true if result (or exception) is available private volatile boolean haveResult; @@ -56,14 +56,14 @@ final class PendingFuture // optional context object private volatile Object context; - PendingFuture(AsynchronousChannel channel, CompletionHandler handler, A attachment, Object context) { - super(channel, attachment); + this.channel = channel; this.handler = handler; + this.attachment = attachment; this.context = context; } @@ -71,14 +71,31 @@ final class PendingFuture CompletionHandler handler, A attachment) { - super(channel, attachment); + this.channel = channel; this.handler = handler; + this.attachment = attachment; + } + + PendingFuture(AsynchronousChannel channel) { + this(channel, null, null); + } + + PendingFuture(AsynchronousChannel channel, Object context) { + this(channel, null, null, context); + } + + AsynchronousChannel channel() { + return channel; } CompletionHandler handler() { return handler; } + A attachment() { + return attachment; + } + void setContext(Object context) { this.context = context; } @@ -113,36 +130,45 @@ final class PendingFuture /** * Sets the result, or a no-op if the result or exception is already set. */ - boolean setResult(V res) { + void setResult(V res) { synchronized (this) { if (haveResult) - return false; + return; result = res; haveResult = true; if (timeoutTask != null) timeoutTask.cancel(false); if (latch != null) latch.countDown(); - return true; } } /** * Sets the result, or a no-op if the result or exception is already set. */ - boolean setFailure(Throwable x) { + void setFailure(Throwable x) { if (!(x instanceof IOException) && !(x instanceof SecurityException)) x = new IOException(x); synchronized (this) { if (haveResult) - return false; + return; exc = x; haveResult = true; if (timeoutTask != null) timeoutTask.cancel(false); if (latch != null) latch.countDown(); - return true; + } + } + + /** + * Sets the result + */ + void setResult(V res, Throwable x) { + if (x == null) { + setResult(res); + } else { + setFailure(x); } } @@ -178,12 +204,10 @@ final class PendingFuture return result; } - @Override Throwable exception() { return (exc != CANCELLED) ? exc : null; } - @Override V value() { return result; } @@ -204,33 +228,6 @@ final class PendingFuture if (haveResult) return false; // already completed - // A shutdown of the channel group will close all channels and - // shutdown the executor. To ensure that the completion handler - // is executed we queue the task while holding the lock. - if (handler != null) { - prepareForWait(); - Runnable cancelTask = new Runnable() { - public void run() { - while (!haveResult) { - try { - latch.await(); - } catch (InterruptedException ignore) { } - } - handler.cancelled(attachment()); - } - }; - AsynchronousChannel ch = channel(); - if (ch instanceof Groupable) { - ((Groupable)ch).group().executeOnPooledThread(cancelTask); - } else { - if (ch instanceof AsynchronousFileChannelImpl) { - ((AsynchronousFileChannelImpl)ch).executor().execute(cancelTask); - } else { - throw new AssertionError("Should not get here"); - } - } - } - // notify channel if (channel() instanceof Cancellable) ((Cancellable)channel()).onCancel(this); @@ -249,7 +246,7 @@ final class PendingFuture } catch (IOException ignore) { } } - // release waiters (this also releases the invoker) + // release waiters if (latch != null) latch.countDown(); return true; diff --git a/jdk/src/share/classes/sun/nio/ch/SimpleAsynchronousDatagramChannelImpl.java b/jdk/src/share/classes/sun/nio/ch/SimpleAsynchronousDatagramChannelImpl.java index 47c3b2abd29..e504da338a2 100644 --- a/jdk/src/share/classes/sun/nio/ch/SimpleAsynchronousDatagramChannelImpl.java +++ b/jdk/src/share/classes/sun/nio/ch/SimpleAsynchronousDatagramChannelImpl.java @@ -317,51 +317,71 @@ class SimpleAsynchronousDatagramChannelImpl return new WrappedMembershipKey(this, key); } - @Override - public Future send(ByteBuffer src, - SocketAddress target, - long timeout, - TimeUnit unit, - A attachment, - CompletionHandler handler) + private Future implSend(ByteBuffer src, + SocketAddress target, + A attachment, + CompletionHandler handler) { - if (timeout < 0L) - throw new IllegalArgumentException("Negative timeout"); - if (unit == null) - throw new NullPointerException(); - - CompletedFuture result; + int n = 0; + Throwable exc = null; try { - int n = dc.send(src, target); - result = CompletedFuture.withResult(this, n, attachment); + n = dc.send(src, target); } catch (IOException ioe) { - result = CompletedFuture.withFailure(this, ioe, attachment); + exc = ioe; } - Invoker.invoke(handler, result); - return result; + if (handler == null) + return CompletedFuture.withResult(n, exc); + Invoker.invoke(this, handler, attachment, n, exc); + return null; } @Override - public Future write(ByteBuffer src, - long timeout, - TimeUnit unit, - A attachment, - CompletionHandler handler) - { - if (timeout < 0L) - throw new IllegalArgumentException("Negative timeout"); - if (unit == null) - throw new NullPointerException(); + public Future send(ByteBuffer src, SocketAddress target) { + return implSend(src, target, null, null); + } - CompletedFuture result; + @Override + public void send(ByteBuffer src, + SocketAddress target, + A attachment, + CompletionHandler handler) + { + if (handler == null) + throw new NullPointerException("'handler' is null"); + implSend(src, target, attachment, handler); + } + + private Future implWrite(ByteBuffer src, + A attachment, + CompletionHandler handler) + { + int n = 0; + Throwable exc = null; try { - int n = dc.write(src); - result = CompletedFuture.withResult(this, n, attachment); + n = dc.write(src); } catch (IOException ioe) { - result = CompletedFuture.withFailure(this, ioe, attachment); + exc = ioe; } - Invoker.invoke(handler, result); - return result; + if (handler == null) + return CompletedFuture.withResult(n, exc); + Invoker.invoke(this, handler, attachment, n, exc); + return null; + + } + + @Override + public Future write(ByteBuffer src) { + return implWrite(src, null, null); + } + + @Override + public void write(ByteBuffer src, + A attachment, + CompletionHandler handler) + { + if (handler == null) + throw new NullPointerException("'handler' is null"); + implWrite(src, attachment, handler); } /** @@ -390,12 +410,11 @@ class SimpleAsynchronousDatagramChannelImpl } } - @Override - public Future receive(final ByteBuffer dst, - final long timeout, - final TimeUnit unit, - A attachment, - final CompletionHandler handler) + private Future implReceive(final ByteBuffer dst, + final long timeout, + final TimeUnit unit, + A attachment, + final CompletionHandler handler) { if (dst.isReadOnly()) throw new IllegalArgumentException("Read-only buffer"); @@ -406,10 +425,11 @@ class SimpleAsynchronousDatagramChannelImpl // complete immediately if channel closed if (!isOpen()) { - CompletedFuture result = CompletedFuture.withFailure(this, - new ClosedChannelException(), attachment); - Invoker.invoke(handler, result); - return result; + Throwable exc = new ClosedChannelException(); + if (handler == null) + return CompletedFuture.withFailure(exc); + Invoker.invoke(this, handler, attachment, null, exc); + return null; } final AccessControlContext acc = (System.getSecurityManager() == null) ? @@ -471,7 +491,7 @@ class SimpleAsynchronousDatagramChannelImpl x = new AsynchronousCloseException(); result.setFailure(x); } - Invoker.invokeUnchecked(handler, result); + Invoker.invokeUnchecked(result); } }; try { @@ -483,11 +503,27 @@ class SimpleAsynchronousDatagramChannelImpl } @Override - public Future read(final ByteBuffer dst, - final long timeout, - final TimeUnit unit, - A attachment, - final CompletionHandler handler) + public Future receive(ByteBuffer dst) { + return implReceive(dst, 0L, TimeUnit.MILLISECONDS, null, null); + } + + @Override + public void receive(ByteBuffer dst, + long timeout, + TimeUnit unit, + A attachment, + CompletionHandler handler) + { + if (handler == null) + throw new NullPointerException("'handler' is null"); + implReceive(dst, timeout, unit, attachment, handler); + } + + private Future implRead(final ByteBuffer dst, + final long timeout, + final TimeUnit unit, + A attachment, + final CompletionHandler handler) { if (dst.isReadOnly()) throw new IllegalArgumentException("Read-only buffer"); @@ -495,18 +531,20 @@ class SimpleAsynchronousDatagramChannelImpl throw new IllegalArgumentException("Negative timeout"); if (unit == null) throw new NullPointerException(); - // another thread may disconnect before read is initiated - if (!dc.isConnected()) - throw new NotYetConnectedException(); // complete immediately if channel closed if (!isOpen()) { - CompletedFuture result = CompletedFuture.withFailure(this, - new ClosedChannelException(), attachment); - Invoker.invoke(handler, result); - return result; + Throwable exc = new ClosedChannelException(); + if (handler == null) + return CompletedFuture.withFailure(exc); + Invoker.invoke(this, handler, attachment, null, exc); + return null; } + // another thread may disconnect before read is initiated + if (!dc.isConnected()) + throw new NotYetConnectedException(); + final PendingFuture result = new PendingFuture(this, handler, attachment); Runnable task = new Runnable() { @@ -563,7 +601,7 @@ class SimpleAsynchronousDatagramChannelImpl x = new AsynchronousCloseException(); result.setFailure(x); } - Invoker.invokeUnchecked(handler, result); + Invoker.invokeUnchecked(result); } }; try { @@ -574,6 +612,23 @@ class SimpleAsynchronousDatagramChannelImpl return result; } + @Override + public Future read(ByteBuffer dst) { + return implRead(dst, 0L, TimeUnit.MILLISECONDS, null, null); + } + + @Override + public void read(ByteBuffer dst, + long timeout, + TimeUnit unit, + A attachment, + CompletionHandler handler) + { + if (handler == null) + throw new NullPointerException("'handler' is null"); + implRead(dst, timeout, unit, attachment, handler); + } + @Override public AsynchronousDatagramChannel bind(SocketAddress local) throws IOException diff --git a/jdk/src/share/classes/sun/nio/ch/SimpleAsynchronousFileChannelImpl.java b/jdk/src/share/classes/sun/nio/ch/SimpleAsynchronousFileChannelImpl.java index fb82f330be4..ef9ff8fec41 100644 --- a/jdk/src/share/classes/sun/nio/ch/SimpleAsynchronousFileChannelImpl.java +++ b/jdk/src/share/classes/sun/nio/ch/SimpleAsynchronousFileChannelImpl.java @@ -50,9 +50,6 @@ public class SimpleAsynchronousFileChannelImpl // Used to make native read and write calls private static final FileDispatcher nd = new FileDispatcherImpl(); - // indicates if the associated thread pool is the default thread pool - private final boolean isDefaultExecutor; - // Thread-safe set of IDs of native threads, for signalling private final NativeThreadSet threads = new NativeThreadSet(2); @@ -60,11 +57,9 @@ public class SimpleAsynchronousFileChannelImpl SimpleAsynchronousFileChannelImpl(FileDescriptor fdObj, boolean reading, boolean writing, - ExecutorService executor, - boolean isDefaultexecutor) + ExecutorService executor) { super(fdObj, reading, writing, executor); - this.isDefaultExecutor = isDefaultexecutor; } public static AsynchronousFileChannel open(FileDescriptor fdo, @@ -73,17 +68,9 @@ public class SimpleAsynchronousFileChannelImpl ThreadPool pool) { // Executor is either default or based on pool parameters - ExecutorService executor; - boolean isDefaultexecutor; - if (pool == null) { - executor = DefaultExecutorHolder.defaultExecutor; - isDefaultexecutor = true; - } else { - executor = pool.executor(); - isDefaultexecutor = false; - } - return new SimpleAsynchronousFileChannelImpl(fdo, - reading, writing, executor, isDefaultexecutor); + ExecutorService executor = (pool == null) ? + DefaultExecutorHolder.defaultExecutor : pool.executor(); + return new SimpleAsynchronousFileChannelImpl(fdo, reading, writing, executor); } @Override @@ -114,16 +101,6 @@ public class SimpleAsynchronousFileChannelImpl // close file nd.close(fdObj); - - // shutdown executor if specific to this channel - if (!isDefaultExecutor) { - AccessController.doPrivileged(new PrivilegedAction() { - public Void run() { - executor.shutdown(); - return null; - } - }); - } } @Override @@ -194,11 +171,11 @@ public class SimpleAsynchronousFileChannelImpl } @Override - public Future lock(final long position, - final long size, - final boolean shared, - A attachment, - final CompletionHandler handler) + Future implLock(final long position, + final long size, + final boolean shared, + final A attachment, + final CompletionHandler handler) { if (shared && !reading) throw new NonReadableChannelException(); @@ -208,16 +185,19 @@ public class SimpleAsynchronousFileChannelImpl // add to lock table final FileLockImpl fli = addToFileLockTable(position, size, shared); if (fli == null) { - CompletedFuture result = CompletedFuture - .withFailure(this, new ClosedChannelException(), attachment); - Invoker.invokeIndirectly(handler, result, executor); - return result; + Throwable exc = new ClosedChannelException(); + if (handler == null) + return CompletedFuture.withFailure(exc); + Invoker.invokeIndirectly(handler, attachment, null, exc, executor); + return null; } - final PendingFuture result = - new PendingFuture(this, handler, attachment); + final PendingFuture result = (handler == null) ? + new PendingFuture(this) : null; Runnable task = new Runnable() { public void run() { + Throwable exc = null; + int ti = threads.add(); try { int n; @@ -226,31 +206,36 @@ public class SimpleAsynchronousFileChannelImpl do { n = nd.lock(fdObj, true, position, size, shared); } while ((n == FileDispatcher.INTERRUPTED) && isOpen()); - if (n == FileDispatcher.LOCKED && isOpen()) { - result.setResult(fli); - } else { + if (n != FileDispatcher.LOCKED || !isOpen()) { throw new AsynchronousCloseException(); } } catch (IOException x) { removeFromFileLockTable(fli); if (!isOpen()) x = new AsynchronousCloseException(); - result.setFailure(x); + exc = x; } finally { end(); } } finally { threads.remove(ti); } - Invoker.invokeUnchecked(handler, result); + if (handler == null) { + result.setResult(fli, exc); + } else { + Invoker.invokeUnchecked(handler, attachment, fli, exc); + } } }; + boolean executed = false; try { executor.execute(task); - } catch (RejectedExecutionException ree) { - // rollback - removeFromFileLockTable(fli); - throw new ShutdownChannelGroupException(); + executed = true; + } finally { + if (!executed) { + // rollback + removeFromFileLockTable(fli); + } } return result; } @@ -301,10 +286,10 @@ public class SimpleAsynchronousFileChannelImpl } @Override - public Future read(final ByteBuffer dst, - final long position, - A attachment, - final CompletionHandler handler) + Future implRead(final ByteBuffer dst, + final long position, + final A attachment, + final CompletionHandler handler) { if (position < 0) throw new IllegalArgumentException("Negative position"); @@ -315,55 +300,52 @@ public class SimpleAsynchronousFileChannelImpl // complete immediately if channel closed or no space remaining if (!isOpen() || (dst.remaining() == 0)) { - CompletedFuture result; - if (isOpen()) { - result = CompletedFuture.withResult(this, 0, attachment); - } else { - result = CompletedFuture.withFailure(this, - new ClosedChannelException(), attachment); - } - Invoker.invokeIndirectly(handler, result, executor); - return result; + Throwable exc = (isOpen()) ? null : new ClosedChannelException(); + if (handler == null) + return CompletedFuture.withResult(0, exc); + Invoker.invokeIndirectly(handler, attachment, 0, exc, executor); + return null; } - final PendingFuture result = - new PendingFuture(this, handler, attachment); + final PendingFuture result = (handler == null) ? + new PendingFuture(this) : null; Runnable task = new Runnable() { public void run() { + int n = 0; + Throwable exc = null; + int ti = threads.add(); try { begin(); - int n; do { n = IOUtil.read(fdObj, dst, position, nd, null); } while ((n == IOStatus.INTERRUPTED) && isOpen()); if (n < 0 && !isOpen()) throw new AsynchronousCloseException(); - result.setResult(n); } catch (IOException x) { if (!isOpen()) x = new AsynchronousCloseException(); - result.setFailure(x); + exc = x; } finally { end(); threads.remove(ti); } - Invoker.invokeUnchecked(handler, result); + if (handler == null) { + result.setResult(n, exc); + } else { + Invoker.invokeUnchecked(handler, attachment, n, exc); + } } }; - try { - executor.execute(task); - } catch (RejectedExecutionException ree) { - throw new ShutdownChannelGroupException(); - } + executor.execute(task); return result; } @Override - public Future write(final ByteBuffer src, - final long position, - A attachment, - final CompletionHandler handler) + Future implWrite(final ByteBuffer src, + final long position, + final A attachment, + final CompletionHandler handler) { if (position < 0) throw new IllegalArgumentException("Negative position"); @@ -372,47 +354,44 @@ public class SimpleAsynchronousFileChannelImpl // complete immediately if channel is closed or no bytes remaining if (!isOpen() || (src.remaining() == 0)) { - CompletedFuture result; - if (isOpen()) { - result = CompletedFuture.withResult(this, 0, attachment); - } else { - result = CompletedFuture.withFailure(this, - new ClosedChannelException(), attachment); - } - Invoker.invokeIndirectly(handler, result, executor); - return result; + Throwable exc = (isOpen()) ? null : new ClosedChannelException(); + if (handler == null) + return CompletedFuture.withResult(0, exc); + Invoker.invokeIndirectly(handler, attachment, 0, exc, executor); + return null; } - final PendingFuture result = - new PendingFuture(this, handler, attachment); + final PendingFuture result = (handler == null) ? + new PendingFuture(this) : null; Runnable task = new Runnable() { public void run() { + int n = 0; + Throwable exc = null; + int ti = threads.add(); try { begin(); - int n; do { n = IOUtil.write(fdObj, src, position, nd, null); } while ((n == IOStatus.INTERRUPTED) && isOpen()); if (n < 0 && !isOpen()) throw new AsynchronousCloseException(); - result.setResult(n); } catch (IOException x) { if (!isOpen()) x = new AsynchronousCloseException(); - result.setFailure(x); + exc = x; } finally { end(); threads.remove(ti); } - Invoker.invokeUnchecked(handler, result); + if (handler == null) { + result.setResult(n, exc); + } else { + Invoker.invokeUnchecked(handler, attachment, n, exc); + } } }; - try { - executor.execute(task); - } catch (RejectedExecutionException ree) { - throw new ShutdownChannelGroupException(); - } + executor.execute(task); return result; } } diff --git a/jdk/src/solaris/classes/sun/nio/ch/EPollPort.java b/jdk/src/solaris/classes/sun/nio/ch/EPollPort.java index a79cb731841..5618cd8fba0 100644 --- a/jdk/src/solaris/classes/sun/nio/ch/EPollPort.java +++ b/jdk/src/solaris/classes/sun/nio/ch/EPollPort.java @@ -248,12 +248,13 @@ final class EPollPort public void run() { Invoker.GroupAndInvokeCount myGroupAndInvokeCount = Invoker.getGroupAndInvokeCount(); + final boolean isPooledThread = (myGroupAndInvokeCount != null); boolean replaceMe = false; Event ev; try { for (;;) { // reset invoke count - if (myGroupAndInvokeCount != null) + if (isPooledThread) myGroupAndInvokeCount.resetInvokeCount(); try { @@ -289,7 +290,7 @@ final class EPollPort // process event try { - ev.channel().onEvent(ev.events()); + ev.channel().onEvent(ev.events(), isPooledThread); } catch (Error x) { replaceMe = true; throw x; } catch (RuntimeException x) { diff --git a/jdk/src/solaris/classes/sun/nio/ch/Port.java b/jdk/src/solaris/classes/sun/nio/ch/Port.java index 8b19637bc2a..db623265b2b 100644 --- a/jdk/src/solaris/classes/sun/nio/ch/Port.java +++ b/jdk/src/solaris/classes/sun/nio/ch/Port.java @@ -49,7 +49,7 @@ abstract class Port extends AsynchronousChannelGroupImpl { * Implemented by clients registered with this port. */ interface PollableChannel extends Closeable { - void onEvent(int events); + void onEvent(int events, boolean mayInvokeDirect); } // maps fd to "pollable" channel @@ -121,7 +121,7 @@ abstract class Port extends AsynchronousChannelGroupImpl { final Object attachForeignChannel(final Channel channel, FileDescriptor fd) { int fdVal = IOUtil.fdVal(fd); register(fdVal, new PollableChannel() { - public void onEvent(int events) { } + public void onEvent(int events, boolean mayInvokeDirect) { } public void close() throws IOException { channel.close(); } diff --git a/jdk/src/solaris/classes/sun/nio/ch/SolarisEventPort.java b/jdk/src/solaris/classes/sun/nio/ch/SolarisEventPort.java index 908eecce024..1df7a0ba044 100644 --- a/jdk/src/solaris/classes/sun/nio/ch/SolarisEventPort.java +++ b/jdk/src/solaris/classes/sun/nio/ch/SolarisEventPort.java @@ -151,12 +151,13 @@ class SolarisEventPort public void run() { Invoker.GroupAndInvokeCount myGroupAndInvokeCount = Invoker.getGroupAndInvokeCount(); + final boolean isPooledThread = (myGroupAndInvokeCount != null); boolean replaceMe = false; long address = unsafe.allocateMemory(SIZEOF_PORT_EVENT); try { for (;;) { // reset invoke count - if (myGroupAndInvokeCount != null) + if (isPooledThread) myGroupAndInvokeCount.resetInvokeCount(); // wait for I/O completion event @@ -205,7 +206,7 @@ class SolarisEventPort if (ch != null) { replaceMe = true; // no need to translate events - ch.onEvent(events); + ch.onEvent(events, isPooledThread); } } } finally { diff --git a/jdk/src/solaris/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java b/jdk/src/solaris/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java index 1a8c92352d2..15fab5e1812 100644 --- a/jdk/src/solaris/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java +++ b/jdk/src/solaris/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java @@ -59,10 +59,13 @@ class UnixAsynchronousServerSocketChannelImpl private final Object updateLock = new Object(); // pending accept - private PendingFuture pendingAccept; + private boolean acceptPending; + private CompletionHandler acceptHandler; + private Object acceptAttachment; + private PendingFuture acceptFuture; // context for permission check when security manager set - private AccessControlContext acc; + private AccessControlContext acceptAcc; UnixAsynchronousServerSocketChannelImpl(Port port) @@ -83,15 +86,6 @@ class UnixAsynchronousServerSocketChannelImpl port.register(fdVal, this); } - // returns and clears the result of a pending accept - private PendingFuture grabPendingAccept() { - synchronized (updateLock) { - PendingFuture result = pendingAccept; - pendingAccept = null; - return result; - } - } - @Override void implClose() throws IOException { // remove the mapping @@ -101,17 +95,27 @@ class UnixAsynchronousServerSocketChannelImpl nd.close(fd); // if there is a pending accept then complete it - final PendingFuture result = - grabPendingAccept(); - if (result != null) { - // discard the stack trace as otherwise it may appear that implClose - // has thrown the exception. - AsynchronousCloseException x = new AsynchronousCloseException(); - x.setStackTrace(new StackTraceElement[0]); - result.setFailure(x); + CompletionHandler handler; + Object att; + PendingFuture future; + synchronized (updateLock) { + if (!acceptPending) + return; // no pending accept + acceptPending = false; + handler = acceptHandler; + att = acceptAttachment; + future = acceptFuture; + } + // discard the stack trace as otherwise it may appear that implClose + // has thrown the exception. + AsynchronousCloseException x = new AsynchronousCloseException(); + x.setStackTrace(new StackTraceElement[0]); + if (handler == null) { + future.setFailure(x); + } else { // invoke by submitting task rather than directly - Invoker.invokeIndirectly(result.handler(), result); + Invoker.invokeIndirectly(this, handler, att, null, x); } } @@ -124,15 +128,17 @@ class UnixAsynchronousServerSocketChannelImpl * Invoked by event handling thread when listener socket is polled */ @Override - public void onEvent(int events) { - PendingFuture result = grabPendingAccept(); - if (result == null) - return; // may have been grabbed by asynchronous close + public void onEvent(int events, boolean mayInvokeDirect) { + synchronized (updateLock) { + if (!acceptPending) + return; // may have been grabbed by asynchronous close + acceptPending = false; + } // attempt to accept connection FileDescriptor newfd = new FileDescriptor(); InetSocketAddress[] isaa = new InetSocketAddress[1]; - boolean accepted = false; + Throwable exc = null; try { begin(); int n = accept0(this.fd, newfd, isaa); @@ -140,49 +146,52 @@ class UnixAsynchronousServerSocketChannelImpl // spurious wakeup, is this possible? if (n == IOStatus.UNAVAILABLE) { synchronized (updateLock) { - this.pendingAccept = result; + acceptPending = true; } port.startPoll(fdVal, Port.POLLIN); return; } - // connection accepted - accepted = true; - } catch (Throwable x) { if (x instanceof ClosedChannelException) x = new AsynchronousCloseException(); - enableAccept(); - result.setFailure(x); + exc = x; } finally { end(); } // Connection accepted so finish it when not holding locks. AsynchronousSocketChannel child = null; - if (accepted) { + if (exc == null) { try { - child = finishAccept(newfd, isaa[0], acc); - enableAccept(); - result.setResult(child); + child = finishAccept(newfd, isaa[0], acceptAcc); } catch (Throwable x) { - enableAccept(); if (!(x instanceof IOException) && !(x instanceof SecurityException)) x = new IOException(x); - result.setFailure(x); + exc = x; } } - // if an async cancel has already cancelled the operation then - // close the new channel so as to free resources - if (child != null && result.isCancelled()) { - try { - child.close(); - } catch (IOException ignore) { } - } + // copy field befores accept is re-renabled + CompletionHandler handler = acceptHandler; + Object att = acceptAttachment; + PendingFuture future = acceptFuture; - // invoke the handler - Invoker.invoke(result.handler(), result); + // re-enable accepting and invoke handler + enableAccept(); + + if (handler == null) { + future.setResult(child, exc); + // if an async cancel has already cancelled the operation then + // close the new channel so as to free resources + if (child != null && future.isCancelled()) { + try { + child.close(); + } catch (IOException ignore) { } + } + } else { + Invoker.invoke(this, handler, att, child, exc); + } } /** @@ -234,16 +243,18 @@ class UnixAsynchronousServerSocketChannelImpl } @Override - @SuppressWarnings("unchecked") - public Future accept(A attachment, - final CompletionHandler handler) + Future implAccept(Object att, + CompletionHandler handler) { // complete immediately if channel is closed if (!isOpen()) { - CompletedFuture result = CompletedFuture - .withFailure(this, new ClosedChannelException(), attachment); - Invoker.invokeIndirectly(handler, result); - return result; + Throwable e = new ClosedChannelException(); + if (handler == null) { + return CompletedFuture.withFailure(e); + } else { + Invoker.invoke(this, handler, att, null, e); + return null; + } } if (localAddress == null) throw new NotYetBoundException(); @@ -258,25 +269,31 @@ class UnixAsynchronousServerSocketChannelImpl throw new AcceptPendingException(); // attempt accept - AbstractFuture result = null; FileDescriptor newfd = new FileDescriptor(); InetSocketAddress[] isaa = new InetSocketAddress[1]; + Throwable exc = null; try { begin(); int n = accept0(this.fd, newfd, isaa); if (n == IOStatus.UNAVAILABLE) { - // no connection to accept - result = new PendingFuture(this, handler, attachment); // need calling context when there is security manager as // permission check may be done in a different thread without // any application call frames on the stack - synchronized (this) { - this.acc = (System.getSecurityManager() == null) ? + PendingFuture result = null; + synchronized (updateLock) { + if (handler == null) { + this.acceptHandler = null; + result = new PendingFuture(this); + this.acceptFuture = result; + } else { + this.acceptHandler = handler; + this.acceptAttachment = att; + } + this.acceptAcc = (System.getSecurityManager() == null) ? null : AccessController.getContext(); - this.pendingAccept = - (PendingFuture)result; + this.acceptPending = true; } // register for connections @@ -287,25 +304,30 @@ class UnixAsynchronousServerSocketChannelImpl // accept failed if (x instanceof ClosedChannelException) x = new AsynchronousCloseException(); - result = CompletedFuture.withFailure(this, x, attachment); + exc = x; } finally { end(); } - // connection accepted immediately - if (result == null) { + AsynchronousSocketChannel child = null; + if (exc == null) { + // connection accepted immediately try { - AsynchronousSocketChannel ch = finishAccept(newfd, isaa[0], null); - result = CompletedFuture.withResult(this, ch, attachment); + child = finishAccept(newfd, isaa[0], null); } catch (Throwable x) { - result = CompletedFuture.withFailure(this, x, attachment); + exc = x; } } - // re-enable accepting and invoke handler + // re-enable accepting before invoking handler enableAccept(); - Invoker.invokeIndirectly(handler, result); - return result; + + if (handler == null) { + return CompletedFuture.withResult(child, exc); + } else { + Invoker.invokeIndirectly(this, handler, att, child, exc); + return null; + } } // -- Native methods -- diff --git a/jdk/src/solaris/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java b/jdk/src/solaris/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java index e80f202bdff..536b0e2ca83 100644 --- a/jdk/src/solaris/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java +++ b/jdk/src/solaris/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java @@ -61,20 +61,33 @@ class UnixAsynchronousSocketChannelImpl private final Object updateLock = new Object(); // pending connect (updateLock) - private PendingFuture pendingConnect; + private boolean connectPending; + private CompletionHandler connectHandler; + private Object connectAttachment; + private PendingFuture connectFuture; - // pending remote address (statLock) + // pending remote address (stateLock) private SocketAddress pendingRemote; // pending read (updateLock) + private boolean readPending; + private boolean isScatteringRead; + private ByteBuffer readBuffer; private ByteBuffer[] readBuffers; - private boolean scatteringRead; - private PendingFuture pendingRead; + private CompletionHandler readHandler; + private Object readAttachment; + private PendingFuture readFuture; + private Future readTimer; // pending write (updateLock) + private boolean writePending; + private boolean isGatheringWrite; + private ByteBuffer writeBuffer; private ByteBuffer[] writeBuffers; - private boolean gatheringWrite; - private PendingFuture pendingWrite; + private CompletionHandler writeHandler; + private Object writeAttachment; + private PendingFuture writeFuture; + private Future writeTimer; UnixAsynchronousSocketChannelImpl(Port port) @@ -128,43 +141,36 @@ class UnixAsynchronousSocketChannelImpl private void updateEvents() { assert Thread.holdsLock(updateLock); int events = 0; - if (pendingRead != null) + if (readPending) events |= Port.POLLIN; - if (pendingConnect != null || pendingWrite != null) + if (connectPending || writePending) events |= Port.POLLOUT; if (events != 0) port.startPoll(fdVal, events); } - /** - * Invoked by event handler thread when file descriptor is polled - */ - @Override - public void onEvent(int events) { - boolean readable = (events & Port.POLLIN) > 0; - boolean writable = (events & Port.POLLOUT) > 0; - if ((events & (Port.POLLERR | Port.POLLHUP)) > 0) { - readable = true; - writable = true; - } - - PendingFuture connectResult = null; - PendingFuture readResult = null; - PendingFuture writeResult = null; + // invoke to finish read and/or write operations + private void finish(boolean mayInvokeDirect, + boolean readable, + boolean writable) + { + boolean finishRead = false; + boolean finishWrite = false; + boolean finishConnect = false; // map event to pending result synchronized (updateLock) { - if (readable && (pendingRead != null)) { - readResult = pendingRead; - pendingRead = null; + if (readable && this.readPending) { + this.readPending = false; + finishRead = true; } if (writable) { - if (pendingWrite != null) { - writeResult = pendingWrite; - pendingWrite = null; - } else if (pendingConnect != null) { - connectResult = pendingConnect; - pendingConnect = null; + if (this.writePending) { + this.writePending = false; + finishWrite = true; + } else if (this.connectPending) { + this.connectPending = false; + finishConnect = true; } } } @@ -172,36 +178,32 @@ class UnixAsynchronousSocketChannelImpl // complete the I/O operation. Special case for when channel is // ready for both reading and writing. In that case, submit task to // complete write if write operation has a completion handler. - if (readResult != null) { - if (writeResult != null) - finishWrite(writeResult, false); - finishRead(readResult, true); + if (finishRead) { + if (finishWrite) + finishWrite(false); + finishRead(mayInvokeDirect); return; } - if (writeResult != null) { - finishWrite(writeResult, true); + if (finishWrite) { + finishWrite(mayInvokeDirect); } - if (connectResult != null) { - finishConnect(connectResult, true); + if (finishConnect) { + finishConnect(mayInvokeDirect); } } - // returns and clears the result of a pending read - PendingFuture grabPendingRead() { - synchronized (updateLock) { - PendingFuture result = pendingRead; - pendingRead = null; - return result; - } - } - - // returns and clears the result of a pending write - PendingFuture grabPendingWrite() { - synchronized (updateLock) { - PendingFuture result = pendingWrite; - pendingWrite = null; - return result; + /** + * Invoked by event handler thread when file descriptor is polled + */ + @Override + public void onEvent(int events, boolean mayInvokeDirect) { + boolean readable = (events & Port.POLLIN) > 0; + boolean writable = (events & Port.POLLOUT) > 0; + if ((events & (Port.POLLERR | Port.POLLHUP)) > 0) { + readable = true; + writable = true; } + finish(mayInvokeDirect, readable, writable); } @Override @@ -213,26 +215,7 @@ class UnixAsynchronousSocketChannelImpl nd.close(fd); // All outstanding I/O operations are required to fail - final PendingFuture readyToConnect; - final PendingFuture readyToRead; - final PendingFuture readyToWrite; - synchronized (updateLock) { - readyToConnect = pendingConnect; - pendingConnect = null; - readyToRead = pendingRead; - pendingRead = null; - readyToWrite = pendingWrite; - pendingWrite = null; - } - if (readyToConnect != null) { - finishConnect(readyToConnect, false); - } - if (readyToRead != null) { - finishRead(readyToRead, false); - } - if (readyToWrite != null) { - finishWrite(readyToWrite, false); - } + finish(false, true, true); } @Override @@ -240,9 +223,9 @@ class UnixAsynchronousSocketChannelImpl if (task.getContext() == OpType.CONNECT) killConnect(); if (task.getContext() == OpType.READ) - killConnect(); + killReading(); if (task.getContext() == OpType.WRITE) - killConnect(); + killWriting(); } // -- connect -- @@ -255,15 +238,12 @@ class UnixAsynchronousSocketChannelImpl } } - private void finishConnect(PendingFuture result, - boolean invokeDirect) - { + private void finishConnect(boolean mayInvokeDirect) { Throwable e = null; try { begin(); checkConnect(fdVal); setConnected(); - result.setResult(null); } catch (Throwable x) { if (x instanceof ClosedChannelException) x = new AsynchronousCloseException(); @@ -276,26 +256,38 @@ class UnixAsynchronousSocketChannelImpl try { close(); } catch (IOException ignore) { } - result.setFailure(e); } - if (invokeDirect) { - Invoker.invoke(result.handler(), result); + + + // invoke handler and set result + CompletionHandler handler = connectHandler; + Object att = connectAttachment; + PendingFuture future = connectFuture; + if (handler == null) { + future.setResult(null, e); } else { - Invoker.invokeIndirectly(result.handler(), result); + if (mayInvokeDirect) { + Invoker.invokeUnchecked(handler, att, null, e); + } else { + Invoker.invokeIndirectly(this, handler, att, null, e); + } } } @Override @SuppressWarnings("unchecked") - public Future connect(SocketAddress remote, - A attachment, - CompletionHandler handler) + Future implConnect(SocketAddress remote, + A attachment, + CompletionHandler handler) { if (!isOpen()) { - CompletedFuture result = CompletedFuture - .withFailure(this, new ClosedChannelException(), attachment); - Invoker.invoke(handler, result); - return result; + Throwable e = new ClosedChannelException(); + if (handler == null) { + return CompletedFuture.withFailure(e); + } else { + Invoker.invoke(this, handler, attachment, null, e); + return null; + } } InetSocketAddress isa = Net.checkAddress(remote); @@ -317,7 +309,6 @@ class UnixAsynchronousSocketChannelImpl notifyBeforeTcpConnect = (localAddress == null); } - AbstractFuture result = null; Throwable e = null; try { begin(); @@ -327,15 +318,21 @@ class UnixAsynchronousSocketChannelImpl int n = Net.connect(fd, isa.getAddress(), isa.getPort()); if (n == IOStatus.UNAVAILABLE) { // connection could not be established immediately - result = new PendingFuture(this, handler, attachment, OpType.CONNECT); + PendingFuture result = null; synchronized (updateLock) { - this.pendingConnect = (PendingFuture)result; + if (handler == null) { + result = new PendingFuture(this, OpType.CONNECT); + this.connectFuture = (PendingFuture)result; + } else { + this.connectHandler = (CompletionHandler)handler; + this.connectAttachment = attachment; + } + this.connectPending = true; updateEvents(); } return result; } setConnected(); - result = CompletedFuture.withResult(this, null, attachment); } catch (Throwable x) { if (x instanceof ClosedChannelException) x = new AsynchronousCloseException(); @@ -349,84 +346,111 @@ class UnixAsynchronousSocketChannelImpl try { close(); } catch (IOException ignore) { } - result = CompletedFuture.withFailure(this, e, attachment); } - - Invoker.invoke(handler, result); - return result; + if (handler == null) { + return CompletedFuture.withResult(null, e); + } else { + Invoker.invoke(this, handler, attachment, null, e); + return null; + } } // -- read -- - @SuppressWarnings("unchecked") - private void finishRead(PendingFuture result, - boolean invokeDirect) - { + private void finishRead(boolean mayInvokeDirect) { int n = -1; - PendingFuture pending = null; + Throwable exc = null; + + // copy fields as we can't access them after reading is re-enabled. + boolean scattering = isScatteringRead; + CompletionHandler handler = readHandler; + Object att = readAttachment; + PendingFuture future = readFuture; + Future timeout = readTimer; + try { begin(); - ByteBuffer[] dsts = readBuffers; - if (dsts.length == 1) { - n = IOUtil.read(fd, dsts[0], -1, nd, null); + if (scattering) { + n = (int)IOUtil.read(fd, readBuffers, nd); } else { - n = (int)IOUtil.read(fd, dsts, nd); + n = IOUtil.read(fd, readBuffer, -1, nd, null); } if (n == IOStatus.UNAVAILABLE) { // spurious wakeup, is this possible? - pending = result; + synchronized (updateLock) { + readPending = true; + } return; } - // allow buffer(s) to be GC'ed. - readBuffers = null; + // allow objects to be GC'ed. + this.readBuffer = null; + this.readBuffers = null; + this.readAttachment = null; // allow another read to be initiated - boolean wasScatteringRead = scatteringRead; enableReading(); - // result is Integer or Long - if (wasScatteringRead) { - result.setResult(Long.valueOf(n)); - } else { - result.setResult(Integer.valueOf(n)); - } - } catch (Throwable x) { enableReading(); if (x instanceof ClosedChannelException) x = new AsynchronousCloseException(); - result.setFailure(x); + exc = x; } finally { // restart poll in case of concurrent write synchronized (updateLock) { - if (pending != null) - this.pendingRead = pending; updateEvents(); } end(); } - if (invokeDirect) { - Invoker.invoke(result.handler(), result); + // cancel the associated timer + if (timeout != null) + timeout.cancel(false); + + // create result + Number result = (exc != null) ? null : (scattering) ? + (Number)Long.valueOf(n) : (Number)Integer.valueOf(n); + + // invoke handler or set result + if (handler == null) { + future.setResult(result, exc); } else { - Invoker.invokeIndirectly(result.handler(), result); + if (mayInvokeDirect) { + Invoker.invokeUnchecked(handler, att, result, exc); + } else { + Invoker.invokeIndirectly(this, handler, att, result, exc); + } } } private Runnable readTimeoutTask = new Runnable() { public void run() { - PendingFuture result = grabPendingRead(); - if (result == null) - return; // already completed + CompletionHandler handler = null; + Object att = null; + PendingFuture future = null; + + synchronized (updateLock) { + if (!readPending) + return; + readPending = false; + handler = readHandler; + att = readAttachment; + future = readFuture; + } // kill further reading before releasing waiters enableReading(true); - // set completed and invoke handler - result.setFailure(new InterruptedByTimeoutException()); - Invoker.invokeIndirectly(result.handler(), result); + // invoke handler or set result + Exception exc = new InterruptedByTimeoutException(); + if (handler == null) { + future.setFailure(exc); + } else { + AsynchronousChannel ch = UnixAsynchronousSocketChannelImpl.this; + Invoker.invokeIndirectly(ch, handler, att, null, exc); + } } }; @@ -435,8 +459,9 @@ class UnixAsynchronousSocketChannelImpl */ @Override @SuppressWarnings("unchecked") - Future readImpl(ByteBuffer[] dsts, - boolean isScatteringRead, + Future implRead(boolean isScatteringRead, + ByteBuffer dst, + ByteBuffer[] dsts, long timeout, TimeUnit unit, A attachment, @@ -450,144 +475,178 @@ class UnixAsynchronousSocketChannelImpl boolean invokeDirect = false; boolean attemptRead = false; if (!disableSynchronousRead) { - myGroupAndInvokeCount = Invoker.getGroupAndInvokeCount(); - invokeDirect = Invoker.mayInvokeDirect(myGroupAndInvokeCount, port); - attemptRead = (handler == null) || invokeDirect || - !port.isFixedThreadPool(); // okay to attempt read with user thread pool + if (handler == null) { + attemptRead = true; + } else { + myGroupAndInvokeCount = Invoker.getGroupAndInvokeCount(); + invokeDirect = Invoker.mayInvokeDirect(myGroupAndInvokeCount, port); + // okay to attempt read with user thread pool + attemptRead = invokeDirect || !port.isFixedThreadPool(); + } } - AbstractFuture result; + int n = IOStatus.UNAVAILABLE; + Throwable exc = null; + boolean pending = false; + try { begin(); - int n; if (attemptRead) { if (isScatteringRead) { n = (int)IOUtil.read(fd, dsts, nd); } else { - n = IOUtil.read(fd, dsts[0], -1, nd, null); + n = IOUtil.read(fd, dst, -1, nd, null); } - } else { - n = IOStatus.UNAVAILABLE; } if (n == IOStatus.UNAVAILABLE) { - result = new PendingFuture(this, handler, attachment, OpType.READ); - - // update evetns so that read will complete asynchronously + PendingFuture result = null; synchronized (updateLock) { + this.isScatteringRead = isScatteringRead; + this.readBuffer = dst; this.readBuffers = dsts; - this.scatteringRead = isScatteringRead; - this.pendingRead = (PendingFuture)result; + if (handler == null) { + this.readHandler = null; + result = new PendingFuture(this, OpType.READ); + this.readFuture = (PendingFuture)result; + this.readAttachment = null; + } else { + this.readHandler = (CompletionHandler)handler; + this.readAttachment = attachment; + this.readFuture = null; + } + if (timeout > 0L) { + this.readTimer = port.schedule(readTimeoutTask, timeout, unit); + } + this.readPending = true; updateEvents(); } - - // schedule timeout - if (timeout > 0L) { - Future timeoutTask = - port.schedule(readTimeoutTask, timeout, unit); - ((PendingFuture)result).setTimeoutTask(timeoutTask); - } + pending = true; return result; } - - // data available - enableReading(); - - // result type is Long or Integer - if (isScatteringRead) { - result = (CompletedFuture)CompletedFuture - .withResult(this, Long.valueOf(n), attachment); - } else { - result = (CompletedFuture)CompletedFuture - .withResult(this, Integer.valueOf(n), attachment); - } } catch (Throwable x) { - enableReading(); if (x instanceof ClosedChannelException) x = new AsynchronousCloseException(); - result = CompletedFuture.withFailure(this, x, attachment); + exc = x; } finally { + if (!pending) + enableReading(); end(); } - if (invokeDirect) { - Invoker.invokeDirect(myGroupAndInvokeCount, handler, result); + Number result = (exc != null) ? null : (isScatteringRead) ? + (Number)Long.valueOf(n) : (Number)Integer.valueOf(n); + + // read completed immediately + if (handler != null) { + if (invokeDirect) { + Invoker.invokeDirect(myGroupAndInvokeCount, handler, attachment, (V)result, exc); + } else { + Invoker.invokeIndirectly(this, handler, attachment, (V)result, exc); + } + return null; } else { - Invoker.invokeIndirectly(handler, result); + return CompletedFuture.withResult((V)result, exc); } - return result; } // -- write -- - private void finishWrite(PendingFuture result, - boolean invokeDirect) - { - PendingFuture pending = null; + private void finishWrite(boolean mayInvokeDirect) { + int n = -1; + Throwable exc = null; + + // copy fields as we can't access them after reading is re-enabled. + boolean gathering = this.isGatheringWrite; + CompletionHandler handler = this.writeHandler; + Object att = this.writeAttachment; + PendingFuture future = this.writeFuture; + Future timer = this.writeTimer; + try { begin(); - ByteBuffer[] srcs = writeBuffers; - int n; - if (srcs.length == 1) { - n = IOUtil.write(fd, srcs[0], -1, nd, null); + if (gathering) { + n = (int)IOUtil.write(fd, writeBuffers, nd); } else { - n = (int)IOUtil.write(fd, srcs, nd); + n = IOUtil.write(fd, writeBuffer, -1, nd, null); } if (n == IOStatus.UNAVAILABLE) { // spurious wakeup, is this possible? - pending = result; + synchronized (updateLock) { + writePending = true; + } return; } - // allow buffer(s) to be GC'ed. - writeBuffers = null; + // allow objects to be GC'ed. + this.writeBuffer = null; + this.writeBuffers = null; + this.writeAttachment = null; // allow another write to be initiated - boolean wasGatheringWrite = gatheringWrite; enableWriting(); - // result is a Long or Integer - if (wasGatheringWrite) { - result.setResult(Long.valueOf(n)); - } else { - result.setResult(Integer.valueOf(n)); - } - } catch (Throwable x) { enableWriting(); if (x instanceof ClosedChannelException) x = new AsynchronousCloseException(); - result.setFailure(x); + exc = x; } finally { - // restart poll in case of concurrent read - synchronized (this) { - if (pending != null) - this.pendingWrite = pending; + // restart poll in case of concurrent write + synchronized (updateLock) { updateEvents(); } end(); } - if (invokeDirect) { - Invoker.invoke(result.handler(), result); + + // cancel the associated timer + if (timer != null) + timer.cancel(false); + + // create result + Number result = (exc != null) ? null : (gathering) ? + (Number)Long.valueOf(n) : (Number)Integer.valueOf(n); + + // invoke handler or set result + if (handler == null) { + future.setResult(result, exc); } else { - Invoker.invokeIndirectly(result.handler(), result); + if (mayInvokeDirect) { + Invoker.invokeUnchecked(handler, att, result, exc); + } else { + Invoker.invokeIndirectly(this, handler, att, result, exc); + } } } private Runnable writeTimeoutTask = new Runnable() { public void run() { - PendingFuture result = grabPendingWrite(); - if (result == null) - return; // already completed + CompletionHandler handler = null; + Object att = null; + PendingFuture future = null; + + synchronized (updateLock) { + if (!writePending) + return; + writePending = false; + handler = writeHandler; + att = writeAttachment; + future = writeFuture; + } // kill further writing before releasing waiters enableWriting(true); - // set completed and invoke handler - result.setFailure(new InterruptedByTimeoutException()); - Invoker.invokeIndirectly(result.handler(), result); + // invoke handler or set result + Exception exc = new InterruptedByTimeoutException(); + if (handler != null) { + Invoker.invokeIndirectly(UnixAsynchronousSocketChannelImpl.this, + handler, att, null, exc); + } else { + future.setFailure(exc); + } } }; @@ -596,8 +655,9 @@ class UnixAsynchronousSocketChannelImpl */ @Override @SuppressWarnings("unchecked") - Future writeImpl(ByteBuffer[] srcs, - boolean isGatheringWrite, + Future implWrite(boolean isGatheringWrite, + ByteBuffer src, + ByteBuffer[] srcs, long timeout, TimeUnit unit, A attachment, @@ -607,66 +667,72 @@ class UnixAsynchronousSocketChannelImpl Invoker.getGroupAndInvokeCount(); boolean invokeDirect = Invoker.mayInvokeDirect(myGroupAndInvokeCount, port); boolean attemptWrite = (handler == null) || invokeDirect || - !port.isFixedThreadPool(); // okay to attempt read with user thread pool + !port.isFixedThreadPool(); // okay to attempt write with user thread pool + + int n = IOStatus.UNAVAILABLE; + Throwable exc = null; + boolean pending = false; - AbstractFuture result; try { begin(); - int n; if (attemptWrite) { if (isGatheringWrite) { n = (int)IOUtil.write(fd, srcs, nd); } else { - n = IOUtil.write(fd, srcs[0], -1, nd, null); + n = IOUtil.write(fd, src, -1, nd, null); } - } else { - n = IOStatus.UNAVAILABLE; } if (n == IOStatus.UNAVAILABLE) { - result = new PendingFuture(this, handler, attachment, OpType.WRITE); - - // update evetns so that read will complete asynchronously + PendingFuture result = null; synchronized (updateLock) { + this.isGatheringWrite = isGatheringWrite; + this.writeBuffer = src; this.writeBuffers = srcs; - this.gatheringWrite = isGatheringWrite; - this.pendingWrite = (PendingFuture)result; + if (handler == null) { + this.writeHandler = null; + result = new PendingFuture(this, OpType.WRITE); + this.writeFuture = (PendingFuture)result; + this.writeAttachment = null; + } else { + this.writeHandler = (CompletionHandler)handler; + this.writeAttachment = attachment; + this.writeFuture = null; + } + if (timeout > 0L) { + this.writeTimer = port.schedule(writeTimeoutTask, timeout, unit); + } + this.writePending = true; updateEvents(); } - - // schedule timeout - if (timeout > 0L) { - Future timeoutTask = - port.schedule(writeTimeoutTask, timeout, unit); - ((PendingFuture)result).setTimeoutTask(timeoutTask); - } + pending = true; return result; } - - // data available - enableWriting(); - if (isGatheringWrite) { - result = (CompletedFuture)CompletedFuture - .withResult(this, Long.valueOf(n), attachment); - } else { - result = (CompletedFuture)CompletedFuture - .withResult(this, Integer.valueOf(n), attachment); - } } catch (Throwable x) { - enableWriting(); if (x instanceof ClosedChannelException) x = new AsynchronousCloseException(); - result = CompletedFuture.withFailure(this, x, attachment); + exc = x; } finally { + if (!pending) + enableWriting(); end(); } - if (invokeDirect) { - Invoker.invokeDirect(myGroupAndInvokeCount, handler, result); + + Number result = (exc != null) ? null : (isGatheringWrite) ? + (Number)Long.valueOf(n) : (Number)Integer.valueOf(n); + + // write completed immediately + if (handler != null) { + if (invokeDirect) { + Invoker.invokeDirect(myGroupAndInvokeCount, handler, attachment, (V)result, exc); + } else { + Invoker.invokeIndirectly(this, handler, attachment, (V)result, exc); + } + return null; } else { - Invoker.invokeIndirectly(handler, result); + return CompletedFuture.withResult((V)result, exc); } - return result; } // -- Native methods -- diff --git a/jdk/src/windows/classes/sun/nio/ch/Iocp.java b/jdk/src/windows/classes/sun/nio/ch/Iocp.java index b4c2cdef61e..97467fc7c00 100644 --- a/jdk/src/windows/classes/sun/nio/ch/Iocp.java +++ b/jdk/src/windows/classes/sun/nio/ch/Iocp.java @@ -34,6 +34,8 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.security.AccessController; +import sun.security.action.GetPropertyAction; import sun.misc.Unsafe; /** @@ -44,6 +46,7 @@ import sun.misc.Unsafe; class Iocp extends AsynchronousChannelGroupImpl { private static final Unsafe unsafe = Unsafe.getUnsafe(); private static final long INVALID_HANDLE_VALUE = -1L; + private static final boolean supportsThreadAgnosticIo; // maps completion key to channel private final ReadWriteLock keyToChannelLock = new ReentrantReadWriteLock(); @@ -87,6 +90,13 @@ class Iocp extends AsynchronousChannelGroupImpl { PendingFuture getByOverlapped(long overlapped); } + /** + * Indicates if this operating system supports thread agnostic I/O. + */ + static boolean supportsThreadAgnosticIo() { + return supportsThreadAgnosticIo; + } + // release all resources void implClose() { synchronized (this) { @@ -216,8 +226,9 @@ class Iocp extends AsynchronousChannelGroupImpl { } while ((key == 0) || keyToChannel.containsKey(key)); // associate with I/O completion port - if (handle != 0L) + if (handle != 0L) { createIoCompletionPort(handle, port, key, 0); + } // setup mapping keyToChannel.put(key, ch); @@ -282,7 +293,7 @@ class Iocp extends AsynchronousChannelGroupImpl { /** * Invoked if the I/O operation completes successfully. */ - public void completed(int bytesTransferred); + public void completed(int bytesTransferred, boolean canInvokeDirect); /** * Invoked if the I/O operation fails. @@ -305,6 +316,7 @@ class Iocp extends AsynchronousChannelGroupImpl { public void run() { Invoker.GroupAndInvokeCount myGroupAndInvokeCount = Invoker.getGroupAndInvokeCount(); + boolean canInvokeDirect = (myGroupAndInvokeCount != null); CompletionStatus ioResult = new CompletionStatus(); boolean replaceMe = false; @@ -382,7 +394,7 @@ class Iocp extends AsynchronousChannelGroupImpl { ResultHandler rh = (ResultHandler)result.getContext(); replaceMe = true; // (if error/exception then replace thread) if (error == 0) { - rh.completed(ioResult.bytesTransferred()); + rh.completed(ioResult.bytesTransferred(), canInvokeDirect); } else { rh.failed(error, translateErrorToIOException(error)); } @@ -433,5 +445,11 @@ class Iocp extends AsynchronousChannelGroupImpl { static { Util.load(); initIDs(); + + // thread agnostic I/O on Vista/2008 or newer + String osversion = AccessController.doPrivileged( + new GetPropertyAction("os.version")); + String vers[] = osversion.split("\\."); + supportsThreadAgnosticIo = Integer.parseInt(vers[0]) >= 6; } } diff --git a/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousFileChannelImpl.java b/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousFileChannelImpl.java index e08f460d919..0b43ab0d516 100644 --- a/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousFileChannelImpl.java +++ b/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousFileChannelImpl.java @@ -146,10 +146,12 @@ public class WindowsAsynchronousFileChannelImpl // waits until all I/O operations have completed ioCache.close(); - // disassociate from port and shutdown thread pool if not default + // disassociate from port iocp.disassociate(completionKey); + + // for the non-default group close the port if (!isDefaultIocp) - iocp.shutdown(); + iocp.detachFromThreadPool(); } @Override @@ -258,14 +260,18 @@ public class WindowsAsynchronousFileChannelImpl } // invoke completion handler - Invoker.invoke(result.handler(), result); + Invoker.invoke(result); } @Override - public void completed(int bytesTransferred) { + public void completed(int bytesTransferred, boolean canInvokeDirect) { // release waiters and invoke completion handler result.setResult(fli); - Invoker.invoke(result.handler(), result); + if (canInvokeDirect) { + Invoker.invokeUnchecked(result); + } else { + Invoker.invoke(result); + } } @Override @@ -279,16 +285,16 @@ public class WindowsAsynchronousFileChannelImpl } else { result.setFailure(new AsynchronousCloseException()); } - Invoker.invoke(result.handler(), result); + Invoker.invoke(result); } } @Override - public Future lock(long position, - long size, - boolean shared, - A attachment, - CompletionHandler handler) + Future implLock(final long position, + final long size, + final boolean shared, + A attachment, + final CompletionHandler handler) { if (shared && !reading) throw new NonReadableChannelException(); @@ -298,10 +304,11 @@ public class WindowsAsynchronousFileChannelImpl // add to lock table FileLockImpl fli = addToFileLockTable(position, size, shared); if (fli == null) { - CompletedFuture result = CompletedFuture - .withFailure(this, new ClosedChannelException(), attachment); - Invoker.invoke(handler, result); - return result; + Throwable exc = new ClosedChannelException(); + if (handler == null) + return CompletedFuture.withFailure(exc); + Invoker.invoke(this, handler, attachment, null, exc); + return null; } // create Future and task that will be invoked to acquire lock @@ -310,13 +317,20 @@ public class WindowsAsynchronousFileChannelImpl LockTask lockTask = new LockTask(position, fli, result); result.setContext(lockTask); - // initiate I/O (can only be done from thread in thread pool) - try { - Invoker.invokeOnThreadInThreadPool(this, lockTask); - } catch (ShutdownChannelGroupException e) { - // rollback - removeFromFileLockTable(fli); - throw e; + // initiate I/O + if (Iocp.supportsThreadAgnosticIo()) { + lockTask.run(); + } else { + boolean executed = false; + try { + Invoker.invokeOnThreadInThreadPool(this, lockTask); + executed = true; + } finally { + if (!executed) { + // rollback + removeFromFileLockTable(fli); + } + } } return result; } @@ -461,14 +475,14 @@ public class WindowsAsynchronousFileChannelImpl releaseBufferIfSubstituted(); // invoke completion handler - Invoker.invoke(result.handler(), result); + Invoker.invoke(result); } /** * Executed when the I/O has completed */ @Override - public void completed(int bytesTransferred) { + public void completed(int bytesTransferred, boolean canInvokeDirect) { updatePosition(bytesTransferred); // return direct buffer to cache if substituted @@ -476,14 +490,18 @@ public class WindowsAsynchronousFileChannelImpl // release waiters and invoke completion handler result.setResult(bytesTransferred); - Invoker.invoke(result.handler(), result); + if (canInvokeDirect) { + Invoker.invokeUnchecked(result); + } else { + Invoker.invoke(result); + } } @Override public void failed(int error, IOException x) { // if EOF detected asynchronously then it is reported as error if (error == ERROR_HANDLE_EOF) { - completed(-1); + completed(-1, false); } else { // return direct buffer to cache if substituted releaseBufferIfSubstituted(); @@ -494,16 +512,16 @@ public class WindowsAsynchronousFileChannelImpl } else { result.setFailure(new AsynchronousCloseException()); } - Invoker.invoke(result.handler(), result); + Invoker.invoke(result); } } } @Override - public Future read(ByteBuffer dst, - long position, - A attachment, - CompletionHandler handler) + Future implRead(ByteBuffer dst, + long position, + A attachment, + CompletionHandler handler) { if (!reading) throw new NonReadableChannelException(); @@ -514,10 +532,11 @@ public class WindowsAsynchronousFileChannelImpl // check if channel is closed if (!isOpen()) { - CompletedFuture result = CompletedFuture - .withFailure(this, new ClosedChannelException(), attachment); - Invoker.invoke(handler, result); - return result; + Throwable exc = new ClosedChannelException(); + if (handler == null) + return CompletedFuture.withFailure(exc); + Invoker.invoke(this, handler, attachment, null, exc); + return null; } int pos = dst.position(); @@ -527,10 +546,10 @@ public class WindowsAsynchronousFileChannelImpl // no space remaining if (rem == 0) { - CompletedFuture result = - CompletedFuture.withResult(this, 0, attachment); - Invoker.invoke(handler, result); - return result; + if (handler == null) + return CompletedFuture.withResult(0); + Invoker.invoke(this, handler, attachment, 0, null); + return null; } // create Future and task that initiates read @@ -539,8 +558,12 @@ public class WindowsAsynchronousFileChannelImpl ReadTask readTask = new ReadTask(dst, pos, rem, position, result); result.setContext(readTask); - // initiate I/O (can only be done from thread in thread pool) - Invoker.invokeOnThreadInThreadPool(this, readTask); + // initiate I/O + if (Iocp.supportsThreadAgnosticIo()) { + readTask.run(); + } else { + Invoker.invokeOnThreadInThreadPool(this, readTask); + } return result; } @@ -639,14 +662,14 @@ public class WindowsAsynchronousFileChannelImpl } // invoke completion handler - Invoker.invoke(result.handler(), result); + Invoker.invoke(result); } /** * Executed when the I/O has completed */ @Override - public void completed(int bytesTransferred) { + public void completed(int bytesTransferred, boolean canInvokeDirect) { updatePosition(bytesTransferred); // return direct buffer to cache if substituted @@ -654,7 +677,11 @@ public class WindowsAsynchronousFileChannelImpl // release waiters and invoke completion handler result.setResult(bytesTransferred); - Invoker.invoke(result.handler(), result); + if (canInvokeDirect) { + Invoker.invokeUnchecked(result); + } else { + Invoker.invoke(result); + } } @Override @@ -668,15 +695,14 @@ public class WindowsAsynchronousFileChannelImpl } else { result.setFailure(new AsynchronousCloseException()); } - Invoker.invoke(result.handler(), result); + Invoker.invoke(result); } } - @Override - public Future write(ByteBuffer src, - long position, - A attachment, - CompletionHandler handler) + Future implWrite(ByteBuffer src, + long position, + A attachment, + CompletionHandler handler) { if (!writing) throw new NonWritableChannelException(); @@ -685,10 +711,11 @@ public class WindowsAsynchronousFileChannelImpl // check if channel is closed if (!isOpen()) { - CompletedFuture result = CompletedFuture - .withFailure(this, new ClosedChannelException(), attachment); - Invoker.invoke(handler, result); - return result; + Throwable exc = new ClosedChannelException(); + if (handler == null) + return CompletedFuture.withFailure(exc); + Invoker.invoke(this, handler, attachment, null, exc); + return null; } int pos = src.position(); @@ -698,10 +725,10 @@ public class WindowsAsynchronousFileChannelImpl // nothing to write if (rem == 0) { - CompletedFuture result = - CompletedFuture.withResult(this, 0, attachment); - Invoker.invoke(handler, result); - return result; + if (handler == null) + return CompletedFuture.withResult(0); + Invoker.invoke(this, handler, attachment, 0, null); + return null; } // create Future and task to initiate write @@ -710,8 +737,12 @@ public class WindowsAsynchronousFileChannelImpl WriteTask writeTask = new WriteTask(src, pos, rem, position, result); result.setContext(writeTask); - // initiate I/O (can only be done from thread in thread pool) - Invoker.invokeOnThreadInThreadPool(this, writeTask); + // initiate I/O + if (Iocp.supportsThreadAgnosticIo()) { + writeTask.run(); + } else { + Invoker.invokeOnThreadInThreadPool(this, writeTask); + } return result; } diff --git a/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousServerSocketChannelImpl.java b/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousServerSocketChannelImpl.java index 8efb10d75e6..4c85952ac5f 100644 --- a/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousServerSocketChannelImpl.java +++ b/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousServerSocketChannelImpl.java @@ -113,14 +113,14 @@ class WindowsAsynchronousServerSocketChannelImpl /** * Task to initiate accept operation and to handle result. */ - private class AcceptTask implements Runnable, Iocp.ResultHandler { + private class AcceptTask implements Runnable, Iocp.ResultHandler { private final WindowsAsynchronousSocketChannelImpl channel; private final AccessControlContext acc; - private final PendingFuture result; + private final PendingFuture result; AcceptTask(WindowsAsynchronousSocketChannelImpl channel, AccessControlContext acc, - PendingFuture result) + PendingFuture result) { this.channel = channel; this.acc = acc; @@ -222,14 +222,14 @@ class WindowsAsynchronousServerSocketChannelImpl } // invoke completion handler - Invoker.invokeIndirectly(result.handler(), result); + Invoker.invokeIndirectly(result); } /** * Executed when the I/O has completed */ @Override - public void completed(int bytesTransferred) { + public void completed(int bytesTransferred, boolean canInvokeDirect) { try { // connection accept after group has shutdown if (iocp.isShutdown()) { @@ -269,7 +269,7 @@ class WindowsAsynchronousServerSocketChannelImpl } // invoke handler (but not directly) - Invoker.invokeIndirectly(result.handler(), result); + Invoker.invokeIndirectly(result); } @Override @@ -283,19 +283,20 @@ class WindowsAsynchronousServerSocketChannelImpl } else { result.setFailure(new AsynchronousCloseException()); } - Invoker.invokeIndirectly(result.handler(), result); + Invoker.invokeIndirectly(result); } } @Override - public Future accept(A attachment, - final CompletionHandler handler) + Future implAccept(Object attachment, + final CompletionHandler handler) { if (!isOpen()) { - CompletedFuture result = CompletedFuture - .withFailure(this, new ClosedChannelException(), attachment); - Invoker.invokeIndirectly(handler, result); - return result; + Throwable exc = new ClosedChannelException(); + if (handler == null) + return CompletedFuture.withFailure(exc); + Invoker.invokeIndirectly(this, handler, attachment, null, exc); + return null; } if (isAcceptKilled()) throw new RuntimeException("Accept not allowed due to cancellation"); @@ -319,10 +320,10 @@ class WindowsAsynchronousServerSocketChannelImpl end(); } if (ioe != null) { - CompletedFuture result = - CompletedFuture.withFailure(this, ioe, attachment); - Invoker.invokeIndirectly(handler, result); - return result; + if (handler == null) + return CompletedFuture.withFailure(ioe); + Invoker.invokeIndirectly(this, handler, attachment, null, ioe); + return null; } // need calling context when there is security manager as @@ -331,20 +332,21 @@ class WindowsAsynchronousServerSocketChannelImpl AccessControlContext acc = (System.getSecurityManager() == null) ? null : AccessController.getContext(); - PendingFuture result = - new PendingFuture(this, handler, attachment); - AcceptTask task = new AcceptTask(ch, acc, result); + PendingFuture result = + new PendingFuture(this, handler, attachment); + AcceptTask task = new AcceptTask(ch, acc, result); result.setContext(task); // check and set flag to prevent concurrent accepting if (!accepting.compareAndSet(false, true)) throw new AcceptPendingException(); - // initiate accept. As I/O operations are tied to the initiating thread - // then it will only be invoked direcly if this thread is in the thread - // pool. If this thread is not in the thread pool when a task is - // submitted to initiate the accept. - Invoker.invokeOnThreadInThreadPool(this, task); + // initiate I/O + if (Iocp.supportsThreadAgnosticIo()) { + task.run(); + } else { + Invoker.invokeOnThreadInThreadPool(this, task); + } return result; } diff --git a/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java b/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java index 5ec0af0468f..80c32ff56dc 100644 --- a/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java +++ b/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java @@ -250,14 +250,14 @@ class WindowsAsynchronousSocketChannelImpl closeChannel(); result.setFailure(toIOException(exc)); } - Invoker.invoke(result.handler(), result); + Invoker.invoke(result); } /** * Invoked by handler thread when connection established. */ @Override - public void completed(int bytesTransferred) { + public void completed(int bytesTransferred, boolean canInvokeDirect) { Throwable exc = null; try { begin(); @@ -276,7 +276,11 @@ class WindowsAsynchronousSocketChannelImpl result.setFailure(toIOException(exc)); } - Invoker.invoke(result.handler(), result); + if (canInvokeDirect) { + Invoker.invokeUnchecked(result); + } else { + Invoker.invoke(result); + } } /** @@ -290,20 +294,21 @@ class WindowsAsynchronousSocketChannelImpl } else { result.setFailure(new AsynchronousCloseException()); } - Invoker.invoke(result.handler(), result); + Invoker.invoke(result); } } @Override - public Future connect(SocketAddress remote, - A attachment, - CompletionHandler handler) + Future implConnect(SocketAddress remote, + A attachment, + CompletionHandler handler) { if (!isOpen()) { - CompletedFuture result = CompletedFuture - .withFailure(this, new ClosedChannelException(), attachment); - Invoker.invoke(handler, result); - return result; + Throwable exc = new ClosedChannelException(); + if (handler == null) + return CompletedFuture.withFailure(exc); + Invoker.invoke(this, handler, attachment, null, exc); + return null; } InetSocketAddress isa = Net.checkAddress(remote); @@ -337,10 +342,10 @@ class WindowsAsynchronousSocketChannelImpl try { close(); } catch (IOException ignore) { } - CompletedFuture result = CompletedFuture - .withFailure(this, bindException, attachment); - Invoker.invoke(handler, result); - return result; + if (handler == null) + return CompletedFuture.withFailure(bindException); + Invoker.invoke(this, handler, attachment, null, bindException); + return null; } // setup task @@ -349,8 +354,12 @@ class WindowsAsynchronousSocketChannelImpl ConnectTask task = new ConnectTask(isa, result); result.setContext(task); - // initiate I/O (can only be done from thread in thread pool) - Invoker.invokeOnThreadInThreadPool(this, task); + // initiate I/O + if (Iocp.supportsThreadAgnosticIo()) { + task.run(); + } else { + Invoker.invokeOnThreadInThreadPool(this, task); + } return result; } @@ -514,7 +523,7 @@ class WindowsAsynchronousSocketChannelImpl } // invoke completion handler - Invoker.invoke(result.handler(), result); + Invoker.invoke(result); } /** @@ -522,7 +531,7 @@ class WindowsAsynchronousSocketChannelImpl */ @Override @SuppressWarnings("unchecked") - public void completed(int bytesTransferred) { + public void completed(int bytesTransferred, boolean canInvokeDirect) { if (bytesTransferred == 0) { bytesTransferred = -1; // EOF } else { @@ -543,7 +552,11 @@ class WindowsAsynchronousSocketChannelImpl result.setResult((V)Integer.valueOf(bytesTransferred)); } } - Invoker.invoke(result.handler(), result); + if (canInvokeDirect) { + Invoker.invokeUnchecked(result); + } else { + Invoker.invoke(result); + } } @Override @@ -561,7 +574,7 @@ class WindowsAsynchronousSocketChannelImpl enableReading(); result.setFailure(x); } - Invoker.invoke(result.handler(), result); + Invoker.invoke(result); } /** @@ -579,13 +592,14 @@ class WindowsAsynchronousSocketChannelImpl } // invoke handler without any locks - Invoker.invoke(result.handler(), result); + Invoker.invoke(result); } } @Override - Future readImpl(ByteBuffer[] bufs, - boolean scatteringRead, + Future implRead(boolean isScatteringRead, + ByteBuffer dst, + ByteBuffer[] dsts, long timeout, TimeUnit unit, A attachment, @@ -594,7 +608,14 @@ class WindowsAsynchronousSocketChannelImpl // setup task PendingFuture result = new PendingFuture(this, handler, attachment); - final ReadTask readTask = new ReadTask(bufs, scatteringRead, result); + ByteBuffer[] bufs; + if (isScatteringRead) { + bufs = dsts; + } else { + bufs = new ByteBuffer[1]; + bufs[0] = dst; + } + final ReadTask readTask = new ReadTask(bufs, isScatteringRead, result); result.setContext(readTask); // schedule timeout @@ -607,8 +628,12 @@ class WindowsAsynchronousSocketChannelImpl result.setTimeoutTask(timeoutTask); } - // initiate I/O (can only be done from thread in thread pool) - Invoker.invokeOnThreadInThreadPool(this, readTask); + // initiate I/O + if (Iocp.supportsThreadAgnosticIo()) { + readTask.run(); + } else { + Invoker.invokeOnThreadInThreadPool(this, readTask); + } return result; } @@ -710,7 +735,7 @@ class WindowsAsynchronousSocketChannelImpl } @Override - @SuppressWarnings("unchecked") + //@SuppressWarnings("unchecked") public void run() { long overlapped = 0L; boolean prepared = false; @@ -759,7 +784,7 @@ class WindowsAsynchronousSocketChannelImpl } // invoke completion handler - Invoker.invoke(result.handler(), result); + Invoker.invoke(result); } /** @@ -767,7 +792,7 @@ class WindowsAsynchronousSocketChannelImpl */ @Override @SuppressWarnings("unchecked") - public void completed(int bytesTransferred) { + public void completed(int bytesTransferred, boolean canInvokeDirect) { updateBuffers(bytesTransferred); // return direct buffer to cache if substituted @@ -784,7 +809,11 @@ class WindowsAsynchronousSocketChannelImpl result.setResult((V)Integer.valueOf(bytesTransferred)); } } - Invoker.invoke(result.handler(), result); + if (canInvokeDirect) { + Invoker.invokeUnchecked(result); + } else { + Invoker.invoke(result); + } } @Override @@ -802,7 +831,7 @@ class WindowsAsynchronousSocketChannelImpl enableWriting(); result.setFailure(x); } - Invoker.invoke(result.handler(), result); + Invoker.invoke(result); } /** @@ -820,13 +849,14 @@ class WindowsAsynchronousSocketChannelImpl } // invoke handler without any locks - Invoker.invoke(result.handler(), result); + Invoker.invoke(result); } } @Override - Future writeImpl(ByteBuffer[] bufs, - boolean gatheringWrite, + Future implWrite(boolean gatheringWrite, + ByteBuffer src, + ByteBuffer[] srcs, long timeout, TimeUnit unit, A attachment, @@ -835,6 +865,13 @@ class WindowsAsynchronousSocketChannelImpl // setup task PendingFuture result = new PendingFuture(this, handler, attachment); + ByteBuffer[] bufs; + if (gatheringWrite) { + bufs = srcs; + } else { + bufs = new ByteBuffer[1]; + bufs[0] = src; + } final WriteTask writeTask = new WriteTask(bufs, gatheringWrite, result); result.setContext(writeTask); @@ -849,7 +886,12 @@ class WindowsAsynchronousSocketChannelImpl } // initiate I/O (can only be done from thread in thread pool) - Invoker.invokeOnThreadInThreadPool(this, writeTask); + // initiate I/O + if (Iocp.supportsThreadAgnosticIo()) { + writeTask.run(); + } else { + Invoker.invokeOnThreadInThreadPool(this, writeTask); + } return result; } diff --git a/jdk/src/windows/native/sun/nio/ch/Iocp.c b/jdk/src/windows/native/sun/nio/ch/Iocp.c index 9568189ee6b..e80cd91205c 100644 --- a/jdk/src/windows/native/sun/nio/ch/Iocp.c +++ b/jdk/src/windows/native/sun/nio/ch/Iocp.c @@ -58,6 +58,16 @@ Java_sun_nio_ch_Iocp_initIDs(JNIEnv* env, jclass this) completionStatus_overlapped = (*env)->GetFieldID(env, clazz, "overlapped", "J"); } +JNIEXPORT jint JNICALL +Java_sun_nio_ch_Iocp_osMajorVersion(JNIEnv* env, jclass this) +{ + OSVERSIONINFOEX ver; + ver.dwOSVersionInfoSize = sizeof(ver); + GetVersionEx((OSVERSIONINFO *) &ver); + return (ver.dwPlatformId == VER_PLATFORM_WIN32_NT) ? + (jint)(ver.dwMajorVersion) : (jint)0; +} + JNIEXPORT jlong JNICALL Java_sun_nio_ch_Iocp_createIoCompletionPort(JNIEnv* env, jclass this, jlong handle, jlong existingPort, jint completionKey, jint concurrency) diff --git a/jdk/test/java/nio/channels/AsynchronousChannelGroup/GroupOfOne.java b/jdk/test/java/nio/channels/AsynchronousChannelGroup/GroupOfOne.java index 4478c9bd851..3988ab8c568 100644 --- a/jdk/test/java/nio/channels/AsynchronousChannelGroup/GroupOfOne.java +++ b/jdk/test/java/nio/channels/AsynchronousChannelGroup/GroupOfOne.java @@ -22,7 +22,7 @@ */ /* @test - * @bug 4607272 + * @bug 4607272 6842687 * @summary Unit test for AsynchronousChannelGroup */ @@ -50,8 +50,6 @@ public class GroupOfOne { } public void failed(Throwable exc, Void att) { } - public void cancelled(Void att) { - } }); int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort(); @@ -97,9 +95,6 @@ public class GroupOfOne { System.out.println("Read failed (expected)"); latch.countDown(); } - public void cancelled(Void att) { - throw new RuntimeException(); - } }); // close channel or shutdown group @@ -122,9 +117,6 @@ public class GroupOfOne { public void failed(Throwable exc, Void att) { throw new RuntimeException(exc); } - public void cancelled(Void att) { - throw new RuntimeException(); - } }); latch.await(); diff --git a/jdk/test/java/nio/channels/AsynchronousChannelGroup/Identity.java b/jdk/test/java/nio/channels/AsynchronousChannelGroup/Identity.java index 6214df2e1f5..6756187ce00 100644 --- a/jdk/test/java/nio/channels/AsynchronousChannelGroup/Identity.java +++ b/jdk/test/java/nio/channels/AsynchronousChannelGroup/Identity.java @@ -22,7 +22,7 @@ */ /* @test - * @bug 4607272 + * @bug 4607272 6842687 * @summary Unit test for AsynchronousChannelGroup */ @@ -90,14 +90,10 @@ public class Identity { } public void failed(Throwable exc, Void att) { } - public void cancelled(Void att) { - } }); } public void failed(Throwable exc, Void att) { } - public void cancelled(Void att) { - } }); int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort(); SocketAddress sa = new InetSocketAddress(InetAddress.getLocalHost(), port); @@ -141,9 +137,6 @@ public class Identity { public void failed(Throwable exc, Integer groupId) { fail(exc.getMessage()); } - public void cancelled(Integer groupId) { - fail("I/O operation was cancelled"); - } }); // wait until diff --git a/jdk/test/java/nio/channels/AsynchronousChannelGroup/Restart.java b/jdk/test/java/nio/channels/AsynchronousChannelGroup/Restart.java index f2132270e50..1645246efda 100644 --- a/jdk/test/java/nio/channels/AsynchronousChannelGroup/Restart.java +++ b/jdk/test/java/nio/channels/AsynchronousChannelGroup/Restart.java @@ -22,7 +22,7 @@ */ /* @test - * @bug 4607272 + * @bug 4607272 6842687 * @summary Unit test for AsynchronousChannelGroup * @build Restart * @run main/othervm -XX:-UseVMInterruptibleIO Restart @@ -111,8 +111,6 @@ public class Restart { } public void failed(Throwable exc, Void att) { } - public void cancelled(Void att) { - } }); // establish loopback connection which should cause completion diff --git a/jdk/test/java/nio/channels/AsynchronousChannelGroup/Unbounded.java b/jdk/test/java/nio/channels/AsynchronousChannelGroup/Unbounded.java index f77f2fc3c2d..7b947d949e6 100644 --- a/jdk/test/java/nio/channels/AsynchronousChannelGroup/Unbounded.java +++ b/jdk/test/java/nio/channels/AsynchronousChannelGroup/Unbounded.java @@ -22,7 +22,7 @@ */ /* @test - * @bug 4607272 + * @bug 4607272 6842687 * @summary Unit test for AsynchronousChannelGroup */ @@ -52,8 +52,6 @@ public class Unbounded { } public void failed(Throwable exc, Void att) { } - public void cancelled(Void att) { - } }); System.out.println("Listener created."); @@ -97,8 +95,6 @@ public class Unbounded { } public void failed(Throwable exc, AsynchronousSocketChannel ch) { } - public void cancelled(AsynchronousSocketChannel ch) { - } }); } System.out.println("All read operations outstanding."); diff --git a/jdk/test/java/nio/channels/AsynchronousDatagramChannel/Basic.java b/jdk/test/java/nio/channels/AsynchronousDatagramChannel/Basic.java index f90800f392d..9c390105716 100644 --- a/jdk/test/java/nio/channels/AsynchronousDatagramChannel/Basic.java +++ b/jdk/test/java/nio/channels/AsynchronousDatagramChannel/Basic.java @@ -22,7 +22,7 @@ */ /* @test - * @bug 4527345 + * @bug 4527345 6842687 * @summary Unit test for AsynchronousDatagramChannel */ @@ -72,8 +72,6 @@ public class Basic { } public void failed (Throwable exc, Void att) { } - public void cancelled(Void att) { - } }); Thread.sleep(2000); sender.send(ByteBuffer.wrap(msg), sa); @@ -88,8 +86,6 @@ public class Basic { public void failed (Throwable exc, Void att) { exception.set(exc); } - public void cancelled(Void att) { - } }); Throwable result; while ((result = exception.get()) == null) { @@ -107,8 +103,6 @@ public class Basic { public void failed (Throwable exc, Void att) { exception.set(exc); } - public void cancelled(Void att) { - } }); ch.close(); while ((result = exception.get()) == null) { @@ -162,8 +156,6 @@ public class Basic { } public void failed (Throwable exc, Void att) { } - public void cancelled(Void att) { - } }); Thread.sleep(2000); sender.send(ByteBuffer.wrap(msg), sa); @@ -178,8 +170,6 @@ public class Basic { public void failed (Throwable exc, Void att) { exception.set(exc); } - public void cancelled(Void att) { - } }); Throwable result; while ((result = exception.get()) == null) { @@ -197,8 +187,6 @@ public class Basic { public void failed (Throwable exc, Void att) { exception.set(exc); } - public void cancelled(Void att) { - } }); ch.close(); while ((result = exception.get()) == null) { @@ -246,8 +234,6 @@ public class Basic { } public void failed (Throwable exc, Void att) { } - public void cancelled(Void att) { - } }); l2.await(5, TimeUnit.SECONDS); @@ -272,8 +258,6 @@ public class Basic { throw new RuntimeException(exc); } } - public void cancelled(Void att) { - } }); l3.await(5, TimeUnit.SECONDS); @@ -323,8 +307,6 @@ public class Basic { } public void failed (Throwable exc, Void att) { } - public void cancelled(Void att) { - } }); l2.await(5, TimeUnit.SECONDS); @@ -340,7 +322,7 @@ public class Basic { reader.close(); } - static void cancelAndCheck(Future result, CountDownLatch latch) + static void cancelAndCheck(Future result) throws InterruptedException { boolean cancelled = result.cancel(false); @@ -356,37 +338,22 @@ public class Basic { } catch (ExecutionException e) { throw new RuntimeException("Should not fail"); } - - // make sure that completion handler is invoked - latch.await(); } // basic cancel tests static void doCancelTests() throws Exception { InetAddress lh = InetAddress.getLocalHost(); - // timed and non-timed receive + // receive for (int i=0; i<2; i++) { AsynchronousDatagramChannel ch = AsynchronousDatagramChannel.open().bind(new InetSocketAddress(0)); - final CountDownLatch latch = new CountDownLatch(1); - long timeout = (i == 0) ? 0L : 60L; - Future remote = ch - .receive(ByteBuffer.allocate(100), timeout, TimeUnit.SECONDS, (Void)null, - new CompletionHandler() { - public void completed(SocketAddress source, Void att) { - } - public void failed (Throwable exc, Void att) { - } - public void cancelled(Void att) { - latch.countDown(); - } - }); - cancelAndCheck(remote, latch); + Future remote = ch.receive(ByteBuffer.allocate(100)); + cancelAndCheck(remote); ch.close(); } - // timed and non-timed read + // read for (int i=0; i<2; i++) { AsynchronousDatagramChannel ch = AsynchronousDatagramChannel.open().bind(new InetSocketAddress(0)); @@ -394,18 +361,8 @@ public class Basic { ((InetSocketAddress)(ch.getLocalAddress())).getPort())); final CountDownLatch latch = new CountDownLatch(1); long timeout = (i == 0) ? 0L : 60L; - Future result = ch - .read(ByteBuffer.allocate(100), timeout, TimeUnit.SECONDS, (Void)null, - new CompletionHandler() { - public void completed(Integer bytesRead, Void att) { - } - public void failed (Throwable exc, Void att) { - } - public void cancelled(Void att) { - latch.countDown(); - } - }); - cancelAndCheck(result, latch); + Future result = ch.read(ByteBuffer.allocate(100)); + cancelAndCheck(result); ch.close(); } } diff --git a/jdk/test/java/nio/channels/AsynchronousFileChannel/Basic.java b/jdk/test/java/nio/channels/AsynchronousFileChannel/Basic.java index 92241536642..75bd1348ef5 100644 --- a/jdk/test/java/nio/channels/AsynchronousFileChannel/Basic.java +++ b/jdk/test/java/nio/channels/AsynchronousFileChannel/Basic.java @@ -22,7 +22,7 @@ */ /* @test - * @bug 4607272 6822643 6830721 + * @bug 4607272 6822643 6830721 6842687 * @summary Unit test for AsynchronousFileChannel */ @@ -195,8 +195,6 @@ public class Basic { } public void failed(Throwable exc, Void att) { } - public void cancelled(Void att) { - } }); throw new RuntimeException("OverlappingFileLockException expected"); } catch (OverlappingFileLockException x) { @@ -229,8 +227,6 @@ public class Basic { } public void failed(Throwable exc, Void att) { } - public void cancelled(Void att) { - } }); // wait for handler to complete @@ -318,8 +314,6 @@ public class Basic { } public void failed(Throwable exc, Void att) { } - public void cancelled(Void att) { - } }); await(latch); @@ -338,8 +332,41 @@ public class Basic { } } finally { ch.close(); + executor.shutdown(); } } + + + // test sharing a thread pool between many channels + ExecutorService executor = Executors + .newFixedThreadPool(1+rand.nextInt(10), threadFactory); + final int n = 50 + rand.nextInt(50); + AsynchronousFileChannel[] channels = new AsynchronousFileChannel[n]; + try { + for (int i=0; i opts = EnumSet.of(WRITE); + channels[i] = AsynchronousFileChannel.open(file, opts, executor); + final CountDownLatch latch = new CountDownLatch(1); + channels[i].write(genBuffer(), 0L, (Void)null, new CompletionHandler() { + public void completed(Integer result, Void att) { + latch.countDown(); + } + public void failed(Throwable exc, Void att) { + } + }); + await(latch); + + // close ~half the channels + if (rand.nextBoolean()) + channels[i].close(); + } + } finally { + // close remaining channels + for (int i=0; i res = ch.write(genBuffer(), 0L, (Void)null, - new CompletionHandler() { - public void completed(Integer result, Void att) { - } - public void failed(Throwable exc, Void att) { - } - public void cancelled(Void att) { - latch.countDown(); - } - }); + Future res = ch.write(genBuffer(), 0L); // cancel operation boolean cancelled = res.cancel(mayInterruptIfRunning); @@ -456,10 +473,6 @@ public class Basic { throw new RuntimeException(x); } - // check that cancelled method is invoked - if (cancelled) - await(latch); - ch.close(); } } @@ -547,8 +560,6 @@ public class Basic { } public void failed(Throwable exc, Long position) { } - public void cancelled(Long position) { - } }); // wait for writes to complete @@ -574,8 +585,6 @@ public class Basic { } public void failed(Throwable exc, Long position) { } - public void cancelled(Long position) { - } }); // wait for reads to complete diff --git a/jdk/test/java/nio/channels/AsynchronousFileChannel/CustomThreadPool.java b/jdk/test/java/nio/channels/AsynchronousFileChannel/CustomThreadPool.java index 9f9025dd232..610124d2061 100644 --- a/jdk/test/java/nio/channels/AsynchronousFileChannel/CustomThreadPool.java +++ b/jdk/test/java/nio/channels/AsynchronousFileChannel/CustomThreadPool.java @@ -22,7 +22,7 @@ */ /* @test - * @bug 4607272 + * @bug 4607272 6842687 * @summary Unit test for java.nio.channels.AsynchronousFileChannel * @build CustomThreadPool MyThreadFactory * @run main/othervm -Djava.nio.channels.DefaultThreadPool.threadFactory=MyThreadFactory CustomThreadPool @@ -51,8 +51,6 @@ public class CustomThreadPool { } public void failed(Throwable exc, AtomicReference invoker) { } - public void cancelled(AtomicReference invoker) { - } }); Thread t; while ((t = invoker.get()) == null) { diff --git a/jdk/test/java/nio/channels/AsynchronousFileChannel/Lock.java b/jdk/test/java/nio/channels/AsynchronousFileChannel/Lock.java index f8b55cc44f8..2b41c86766f 100644 --- a/jdk/test/java/nio/channels/AsynchronousFileChannel/Lock.java +++ b/jdk/test/java/nio/channels/AsynchronousFileChannel/Lock.java @@ -23,7 +23,7 @@ /* @test - * @bug 4607272 6814948 + * @bug 4607272 6814948 6842687 * @summary Unit test for AsynchronousFileChannel#lock method */ @@ -97,7 +97,7 @@ public class Lock { slave.lock(0, 10, false); // this VM acquires lock on non-overlapping range - fl = ch.lock(10, 10, false, null, null).get(); + fl = ch.lock(10, 10, false).get(); fl.release(); // done diff --git a/jdk/test/java/nio/channels/AsynchronousServerSocketChannel/Basic.java b/jdk/test/java/nio/channels/AsynchronousServerSocketChannel/Basic.java index e648b78a911..3ff2151fed7 100644 --- a/jdk/test/java/nio/channels/AsynchronousServerSocketChannel/Basic.java +++ b/jdk/test/java/nio/channels/AsynchronousServerSocketChannel/Basic.java @@ -22,7 +22,7 @@ */ /* @test - * @bug 4607272 + * @bug 4607272 6842687 * @summary Unit test for AsynchronousServerSocketChannel * @run main/timeout=180 Basic */ @@ -104,8 +104,6 @@ public class Basic { public void failed(Throwable exc, Void att) { exception.set(exc); } - public void cancelled(Void att) { - } }); // check AcceptPendingException diff --git a/jdk/test/java/nio/channels/AsynchronousSocketChannel/Basic.java b/jdk/test/java/nio/channels/AsynchronousSocketChannel/Basic.java index 3c04635312b..88c4c16e2cd 100644 --- a/jdk/test/java/nio/channels/AsynchronousSocketChannel/Basic.java +++ b/jdk/test/java/nio/channels/AsynchronousSocketChannel/Basic.java @@ -22,7 +22,7 @@ */ /* @test - * @bug 4607272 + * @bug 4607272 6842687 * @summary Unit test for AsynchronousSocketChannel * @run main/timeout=600 Basic */ @@ -187,8 +187,6 @@ public class Basic { public void failed(Throwable exc, Void att) { connectException.set(exc); } - public void cancelled(Void att) { - } }); while (connectException.get() == null) { Thread.sleep(100); @@ -289,8 +287,6 @@ public class Basic { public void failed(Throwable x, AsynchronousSocketChannel ch) { writeException.set(x); } - public void cancelled(AsynchronousSocketChannel ch) { - } }); // give time for socket buffer to fill up. @@ -330,18 +326,8 @@ public class Basic { SocketChannel peer = server.accept(); // start read operation - final CountDownLatch latch = new CountDownLatch(1); ByteBuffer buf = ByteBuffer.allocate(1); - Future res = ch.read(buf, (Void)null, - new CompletionHandler() { - public void completed(Integer result, Void att) { - } - public void failed(Throwable exc, Void att) { - } - public void cancelled(Void att) { - latch.countDown(); - } - }); + Future res = ch.read(buf); // cancel operation boolean cancelled = res.cancel(mayInterruptIfRunning); @@ -362,8 +348,11 @@ public class Basic { } catch (CancellationException x) { } - // check that completion handler executed. - latch.await(); + // check that the cancel doesn't impact writing to the channel + if (!mayInterruptIfRunning) { + buf = ByteBuffer.wrap("a".getBytes()); + ch.write(buf).get(); + } ch.close(); peer.close(); @@ -408,8 +397,6 @@ public class Basic { } public void failed(Throwable exc, Void att) { } - public void cancelled(Void att) { - } }); latch.await(); @@ -460,8 +447,6 @@ public class Basic { } public void failed(Throwable exc, Void att) { } - public void cancelled(Void att) { - } }); // trickle the writing @@ -507,26 +492,24 @@ public class Basic { } // scattering read that completes ascynhronously - final CountDownLatch latch = new CountDownLatch(1); + final CountDownLatch l1 = new CountDownLatch(1); ch.read(dsts, 0, dsts.length, 0L, TimeUnit.SECONDS, (Void)null, new CompletionHandler() { public void completed(Long result, Void att) { long n = result; if (n <= 0) throw new RuntimeException("No bytes read"); - latch.countDown(); + l1.countDown(); } public void failed(Throwable exc, Void att) { } - public void cancelled(Void att) { - } }); // write some bytes sc.write(genBuffer()); // read should now complete - latch.await(); + l1.await(); // write more bytes sc.write(genBuffer()); @@ -535,10 +518,20 @@ public class Basic { for (int i=0; i() { + public void completed(Long result, Void att) { + long n = result; + if (n <= 0) + throw new RuntimeException("No bytes read"); + l2.countDown(); + } + public void failed(Throwable exc, Void att) { + } + }); + l2.await(); ch.close(); sc.close(); @@ -574,8 +567,6 @@ public class Basic { } public void failed(Throwable exc, Void att) { } - public void cancelled(Void att) { - } }); // read to EOF or buffer full @@ -613,19 +604,29 @@ public class Basic { ch.connect(server.address()).get(); SocketChannel sc = server.accept(); + // number of bytes written + final AtomicLong bytesWritten = new AtomicLong(0); + // write buffers (should complete immediately) ByteBuffer[] srcs = genBuffers(1); - long n = ch - .write(srcs, 0, srcs.length, 0L, TimeUnit.SECONDS, (Void)null, null).get(); - if (n <= 0) - throw new RuntimeException("No bytes written"); + final CountDownLatch l1 = new CountDownLatch(1); + ch.write(srcs, 0, srcs.length, 0L, TimeUnit.SECONDS, (Void)null, + new CompletionHandler() { + public void completed(Long result, Void att) { + long n = result; + if (n <= 0) + throw new RuntimeException("No bytes read"); + bytesWritten.addAndGet(n); + l1.countDown(); + } + public void failed(Throwable exc, Void att) { + } + }); + l1.await(); // set to true to signal that no more buffers should be written final AtomicBoolean continueWriting = new AtomicBoolean(true); - // number of bytes written - final AtomicLong bytesWritten = new AtomicLong(n); - // write until socket buffer is full so as to create the conditions // for when a write does not complete immediately srcs = genBuffers(1); @@ -644,8 +645,6 @@ public class Basic { } public void failed(Throwable exc, Void att) { } - public void cancelled(Void att) { - } }); // give time for socket buffer to fill up. @@ -658,7 +657,7 @@ public class Basic { ByteBuffer buf = ByteBuffer.allocateDirect(4096); long total = 0L; do { - n = sc.read(buf); + int n = sc.read(buf); if (n <= 0) throw new RuntimeException("No bytes read"); buf.rewind(); @@ -714,15 +713,27 @@ public class Basic { System.out.println("-- timeout when reading --"); - // this read should timeout ByteBuffer dst = ByteBuffer.allocate(512); - try { - ch.read(dst, 3, TimeUnit.SECONDS, (Void)null, null).get(); - throw new RuntimeException("Read did not timeout"); - } catch (ExecutionException x) { - if (!(x.getCause() instanceof InterruptedByTimeoutException)) - throw new RuntimeException("InterruptedByTimeoutException expected"); + + final AtomicReference readException = new AtomicReference(); + + // this read should timeout + ch.read(dst, 3, TimeUnit.SECONDS, (Void)null, + new CompletionHandler() + { + public void completed(Integer result, Void att) { + throw new RuntimeException("Should not complete"); + } + public void failed(Throwable exc, Void att) { + readException.set(exc); + } + }); + // wait for exception + while (readException.get() == null) { + Thread.sleep(100); } + if (!(readException.get() instanceof InterruptedByTimeoutException)) + throw new RuntimeException("InterruptedByTimeoutException expected"); // after a timeout then further reading should throw unspecified runtime exception boolean exceptionThrown = false; @@ -752,8 +763,6 @@ public class Basic { public void failed(Throwable exc, AsynchronousSocketChannel ch) { writeException.set(exc); } - public void cancelled(AsynchronousSocketChannel ch) { - } }); // wait for exception diff --git a/jdk/test/java/nio/channels/AsynchronousSocketChannel/DieBeforeComplete.java b/jdk/test/java/nio/channels/AsynchronousSocketChannel/DieBeforeComplete.java new file mode 100644 index 00000000000..1f4efb845df --- /dev/null +++ b/jdk/test/java/nio/channels/AsynchronousSocketChannel/DieBeforeComplete.java @@ -0,0 +1,136 @@ +/* + * Copyright 2008-2009 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* @test + * @bug 6842687 + * @summary Unit test for AsynchronousSocketChannel/AsynchronousServerSocketChannel + */ +import java.nio.ByteBuffer; +import java.nio.channels.*; +import java.net.*; +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicReference; + +/** + * Initiates I/O operation on a thread that terminates before the I/O completes. + */ + +public class DieBeforeComplete { + + public static void main(String[] args) throws Exception { + final AsynchronousServerSocketChannel listener = + AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(0)); + + InetAddress lh = InetAddress.getLocalHost(); + int port = ((InetSocketAddress) (listener.getLocalAddress())).getPort(); + final SocketAddress sa = new InetSocketAddress(lh, port); + + // -- accept -- + + // initiate accept in a thread that dies before connection is established + Future r1 = + initiateAndDie(new Task() { + public Future run() { + return listener.accept(); + }}); + + // establish and accept connection + SocketChannel peer = SocketChannel.open(sa); + final AsynchronousSocketChannel channel = r1.get(); + + // --- read -- + + // initiate read in a thread that dies befores bytes are available + final ByteBuffer dst = ByteBuffer.allocate(100); + Future r2 = initiateAndDie(new Task() { + public Future run() { + return channel.read(dst); + }}); + + // send bytes + peer.write(ByteBuffer.wrap("hello".getBytes())); + int nread = r2.get(); + if (nread <= 0) + throw new RuntimeException("Should have read at least one byte"); + + // -- write -- + + // initiate writes in threads that dies + boolean completedImmediately; + Future r3; + do { + final ByteBuffer src = ByteBuffer.wrap(new byte[10000]); + r3 = initiateAndDie(new Task() { + public Future run() { + return channel.write(src); + }}); + try { + int nsent = r3.get(5, TimeUnit.SECONDS); + if (nsent <= 0) + throw new RuntimeException("Should have wrote at least one byte"); + completedImmediately = true; + } catch (TimeoutException x) { + completedImmediately = false; + } + } while (completedImmediately); + + // drain connection + peer.configureBlocking(false); + ByteBuffer src = ByteBuffer.allocateDirect(10000); + do { + src.clear(); + nread = peer.read(src); + if (nread == 0) { + Thread.sleep(100); + nread = peer.read(src); + } + } while (nread > 0); + + // write should complete now + int nsent = r3.get(); + if (nsent <= 0) + throw new RuntimeException("Should have wrote at least one byte"); + } + + static interface Task { + Future run(); + } + + static Future initiateAndDie(final Task task) { + final AtomicReference> result = new AtomicReference>(); + Runnable r = new Runnable() { + public void run() { + result.set(task.run()); + } + }; + Thread t = new Thread(r); + t.start(); + while (t.isAlive()) { + try { + t.join(); + } catch (InterruptedException x) { + } + } + return result.get(); + } +} diff --git a/jdk/test/java/nio/channels/AsynchronousSocketChannel/StressLoopback.java b/jdk/test/java/nio/channels/AsynchronousSocketChannel/StressLoopback.java index a3c0db687e6..bb77552fcb0 100644 --- a/jdk/test/java/nio/channels/AsynchronousSocketChannel/StressLoopback.java +++ b/jdk/test/java/nio/channels/AsynchronousSocketChannel/StressLoopback.java @@ -22,7 +22,7 @@ */ /* @test - * @bug 6834246 + * @bug 6834246 6842687 * @summary Stress test connections through the loopback interface */ @@ -114,8 +114,6 @@ public class StressLoopback { exc.printStackTrace(); closeUnchecked(channel); } - public void cancelled(Void att) { - } }); } @@ -156,8 +154,6 @@ public class StressLoopback { exc.printStackTrace(); closeUnchecked(channel); } - public void cancelled(Void att) { - } }); } diff --git a/jdk/test/java/nio/channels/FileChannel/ReleaseOnCloseDeadlock.java b/jdk/test/java/nio/channels/FileChannel/ReleaseOnCloseDeadlock.java index c7ed16a9204..055ff55e8f1 100644 --- a/jdk/test/java/nio/channels/FileChannel/ReleaseOnCloseDeadlock.java +++ b/jdk/test/java/nio/channels/FileChannel/ReleaseOnCloseDeadlock.java @@ -22,7 +22,7 @@ */ /* @test - * @bug 6543863 + * @bug 6543863 6842687 * @summary Try to cause a deadlock between (Asynchronous)FileChannel.close * and FileLock.release */ @@ -56,7 +56,7 @@ public class ReleaseOnCloseDeadlock { AsynchronousFileChannel ch = AsynchronousFileChannel.open(file, READ, WRITE); for (int i=0; i Date: Mon, 24 Aug 2009 18:37:48 +0800 Subject: [PATCH 95/96] 6875033: regression: test of 6867665 fail Reviewed-by: xuelei --- jdk/test/sun/security/krb5/ktab/HighestKvno.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/jdk/test/sun/security/krb5/ktab/HighestKvno.java b/jdk/test/sun/security/krb5/ktab/HighestKvno.java index 09880ae9346..3f315f81d92 100644 --- a/jdk/test/sun/security/krb5/ktab/HighestKvno.java +++ b/jdk/test/sun/security/krb5/ktab/HighestKvno.java @@ -23,6 +23,7 @@ /* * @test * @bug 6867665 + * @bug 6875033 * @summary Problem with keytabs with multiple kvno's (key versions) */ @@ -223,9 +224,6 @@ public class HighestKvno { KeyTab ktab = KeyTab.getInstance("kt"); PrincipalName pn = new PrincipalName("me@MAD.LOCAL"); EncryptionKey[] keys = ktab.readServiceKeys(pn); - if (keys.length != 9) { - throw new Exception("Count error"); - } if (keys[0].getKeyVersionNumber() != 5) { throw new Exception("Highest not first"); } From 1b8f98b70e6b82c9b234f08ba721cd9c64853835 Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Mon, 24 Aug 2009 09:57:30 -0700 Subject: [PATCH 96/96] 6853636: Fix warnings in jdwpgen, add jdwpgen NetBeans project Reviewed-by: andrew, alanb, tbell, swamyv --- jdk/.hgignore | 3 + jdk/make/netbeans/jdwpgen/build.xml | 74 ++ .../netbeans/jdwpgen/nbproject/build-impl.xml | 642 ++++++++++++++++++ .../jdwpgen/nbproject/findbugs.settings | 72 ++ .../jdwpgen/nbproject/genfiles.properties | 8 + .../jdwpgen/nbproject/project.properties | 65 ++ .../netbeans/jdwpgen/nbproject/project.xml | 16 + .../netbeans/jdwpgen/nbproject/sqe.properties | 2 + .../tools/jdwpgen/AbstractNamedNode.java | 2 +- .../src/build/tools/jdwpgen/AltNode.java | 2 +- .../build/tools/jdwpgen/ConstantSetNode.java | 11 +- .../tools/src/build/tools/jdwpgen/Main.java | 5 +- .../tools/src/build/tools/jdwpgen/Node.java | 6 +- .../tools/src/build/tools/jdwpgen/Parse.java | 8 +- .../src/build/tools/jdwpgen/RepeatNode.java | 2 +- .../src/build/tools/jdwpgen/SelectNode.java | 2 +- 16 files changed, 898 insertions(+), 22 deletions(-) create mode 100644 jdk/make/netbeans/jdwpgen/build.xml create mode 100644 jdk/make/netbeans/jdwpgen/nbproject/build-impl.xml create mode 100644 jdk/make/netbeans/jdwpgen/nbproject/findbugs.settings create mode 100644 jdk/make/netbeans/jdwpgen/nbproject/genfiles.properties create mode 100644 jdk/make/netbeans/jdwpgen/nbproject/project.properties create mode 100644 jdk/make/netbeans/jdwpgen/nbproject/project.xml create mode 100644 jdk/make/netbeans/jdwpgen/nbproject/sqe.properties diff --git a/jdk/.hgignore b/jdk/.hgignore index ca1b0b21ee2..be55e3a7c83 100644 --- a/jdk/.hgignore +++ b/jdk/.hgignore @@ -1,3 +1,6 @@ ^build/ ^dist/ ^nbproject/private/ +^make/netbeans/.*/nbproject/private/ +^make/netbeans/.*/build/ +^make/netbeans/.*/dist/ diff --git a/jdk/make/netbeans/jdwpgen/build.xml b/jdk/make/netbeans/jdwpgen/build.xml new file mode 100644 index 00000000000..da67672e2af --- /dev/null +++ b/jdk/make/netbeans/jdwpgen/build.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + Builds, tests, and runs the project jdwpgen. + + + diff --git a/jdk/make/netbeans/jdwpgen/nbproject/build-impl.xml b/jdk/make/netbeans/jdwpgen/nbproject/build-impl.xml new file mode 100644 index 00000000000..9997d00d9e7 --- /dev/null +++ b/jdk/make/netbeans/jdwpgen/nbproject/build-impl.xml @@ -0,0 +1,642 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + + + + + + java -cp "${run.classpath.with.dist.jar}" ${main.class} + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + diff --git a/jdk/make/netbeans/jdwpgen/nbproject/findbugs.settings b/jdk/make/netbeans/jdwpgen/nbproject/findbugs.settings new file mode 100644 index 00000000000..cb205d1aa21 --- /dev/null +++ b/jdk/make/netbeans/jdwpgen/nbproject/findbugs.settings @@ -0,0 +1,72 @@ +#FindBugs User Preferences +#Mon Jun 15 13:37:16 PDT 2009 +detectorAbnormalFinallyBlockReturn=AbnormalFinallyBlockReturn|false +detectorAbstractClassEmptyMethods=AbstractClassEmptyMethods|false +detectorAbstractOverriddenMethod=AbstractOverriddenMethod|false +detectorArrayBasedCollections=ArrayBasedCollections|false +detectorArrayWrappedCallByReference=ArrayWrappedCallByReference|false +detectorBloatedAssignmentScope=BloatedAssignmentScope|false +detectorBloatedSynchronizedBlock=BloatedSynchronizedBlock|false +detectorClassEnvy=ClassEnvy|false +detectorCollectStatistics=CollectStatistics|false +detectorConfusingAutoboxedOverloading=ConfusingAutoboxedOverloading|false +detectorConstantListIndex=ConstantListIndex|false +detectorCopiedOverriddenMethod=CopiedOverriddenMethod|false +detectorCustomBuiltXML=CustomBuiltXML|false +detectorCyclomaticComplexity=CyclomaticComplexity|false +detectorDateComparison=DateComparison|false +detectorDeclaredRuntimeException=DeclaredRuntimeException|false +detectorDeletingWhileIterating=DeletingWhileIterating|false +detectorDubiousListCollection=DubiousListCollection|false +detectorFieldCouldBeLocal=FieldCouldBeLocal|false +detectorFinalParameters=FinalParameters|false +detectorFloatingPointLoops=FloatingPointLoops|false +detectorInefficientStringBuffering=InefficientStringBuffering|false +detectorInheritanceTypeChecking=InheritanceTypeChecking|false +detectorJDBCVendorReliance=JDBCVendorReliance|false +detectorListIndexedIterating=ListIndexedIterating|false +detectorLiteralStringComparison=LiteralStringComparison|false +detectorLocalSynchronizedCollection=LocalSynchronizedCollection|false +detectorLostExceptionStackTrace=LostExceptionStackTrace|false +detectorManualArrayCopy=ManualArrayCopy|false +detectorMethodReturnsConstant=MethodReturnsConstant|false +detectorNeedlessAutoboxing=NeedlessAutoboxing|false +detectorNeedlessCustomSerialization=NeedlessCustomSerialization|false +detectorNeedlessInstanceRetrieval=NeedlessInstanceRetrieval|false +detectorNeedlessMemberCollectionSynchronization=NeedlessMemberCollectionSynchronization|false +detectorNonCollectionMethodUse=NonCollectionMethodUse|false +detectorNonOwnedSynchronization=NonOwnedSynchronization|false +detectorNonRecycleableTaglibs=NonRecycleableTaglibs|false +detectorOrphanedDOMNode=OrphanedDOMNode|false +detectorOverlyConcreteParameter=OverlyConcreteParameter|false +detectorParallelLists=ParallelLists|false +detectorPartiallyConstructedObjectAccess=PartiallyConstructedObjectAccess|false +detectorPossibleIncompleteSerialization=PossibleIncompleteSerialization|false +detectorPossibleMemoryBloat=PossibleMemoryBloat|false +detectorPossiblyRedundantMethodCalls=PossiblyRedundantMethodCalls|false +detectorSQLInLoop=SQLInLoop|false +detectorSection508Compliance=Section508Compliance|false +detectorSillynessPotPourri=SillynessPotPourri|false +detectorSloppyClassReflection=SloppyClassReflection|false +detectorSluggishGui=SluggishGui|false +detectorSpoiledChildInterfaceImplementor=SpoiledChildInterfaceImplementor|false +detectorSpuriousThreadStates=SpuriousThreadStates|false +detectorStaticArrayCreatedInMethod=StaticArrayCreatedInMethod|false +detectorStaticMethodInstanceInvocation=StaticMethodInstanceInvocation|false +detectorSuspiciousComparatorReturnValues=SuspiciousComparatorReturnValues|false +detectorSuspiciousJDKVersionUse=SuspiciousJDKVersionUse|false +detectorSuspiciousWaitOnConcurrentObject=SuspiciousWaitOnConcurrentObject|false +detectorSyncCollectionIterators=SyncCollectionIterators|false +detectorTailRecursion=TailRecursion|false +detectorUnnecessaryStoreBeforeReturn=UnnecessaryStoreBeforeReturn|false +detectorUnrelatedCollectionContents=UnrelatedCollectionContents|false +detectorUnrelatedReturnValues=UnrelatedReturnValues|false +detectorUseAddAll=UseAddAll|false +detectorUseCharacterParameterizedMethod=UseCharacterParameterizedMethod|false +detectorUseEnumCollections=UseEnumCollections|false +detectorUseSplit=UseSplit|false +detectorUseToArray=UseToArray|false +detector_threshold=2 +effort=default +filter_settings=Medium|BAD_PRACTICE,CORRECTNESS,I18N,MALICIOUS_CODE,MT_CORRECTNESS,PERFORMANCE,SECURITY,STYLE|false +filter_settings_neg=| diff --git a/jdk/make/netbeans/jdwpgen/nbproject/genfiles.properties b/jdk/make/netbeans/jdwpgen/nbproject/genfiles.properties new file mode 100644 index 00000000000..a82838d7b0f --- /dev/null +++ b/jdk/make/netbeans/jdwpgen/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=b40e775f +build.xml.script.CRC32=af8dc3cb +build.xml.stylesheet.CRC32=958a1d3e +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=b40e775f +nbproject/build-impl.xml.script.CRC32=624d12c5 +nbproject/build-impl.xml.stylesheet.CRC32=65b8de21 diff --git a/jdk/make/netbeans/jdwpgen/nbproject/project.properties b/jdk/make/netbeans/jdwpgen/nbproject/project.properties new file mode 100644 index 00000000000..19b2cffc991 --- /dev/null +++ b/jdk/make/netbeans/jdwpgen/nbproject/project.properties @@ -0,0 +1,65 @@ +application.title=jdwpgen +application.vendor=sun +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/jdwpgen.jar +dist.javadoc.dir=${dist.dir}/javadoc +excludes= +file.reference.tools-jdwpgen=../../tools/src/build/tools/jdwpgen +file.reference.tools-src=../../tools/src +includes=build/tools/jdwpgen/** +jar.compress=false +javac.classpath= +# Space-separated list of extra javac options +javac.compilerargs=-Xlint:all +javac.deprecation=false +javac.source=1.5 +javac.target=1.5 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir}:\ + ${libs.junit.classpath}:\ + ${libs.junit_4.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=true +javadoc.nonavbar=true +javadoc.notree=true +javadoc.private=true +javadoc.splitindex=false +javadoc.use=false +javadoc.version=false +javadoc.windowtitle= +main.class=jdwpgen.Main +manifest.file=manifest.mf +meta.inf.dir=${src.dir}/META-INF +platform.active=default_platform +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project +# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value +# or test-sys-prop.name=value to set system properties for unit tests): +run.jvmargs= +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.src.dir=${file.reference.tools-src} +test.src.dir=test diff --git a/jdk/make/netbeans/jdwpgen/nbproject/project.xml b/jdk/make/netbeans/jdwpgen/nbproject/project.xml new file mode 100644 index 00000000000..c7bf8edefc0 --- /dev/null +++ b/jdk/make/netbeans/jdwpgen/nbproject/project.xml @@ -0,0 +1,16 @@ + + + org.netbeans.modules.java.j2seproject + + + jdwpgen + 1.6.5 + + + + + + + + + diff --git a/jdk/make/netbeans/jdwpgen/nbproject/sqe.properties b/jdk/make/netbeans/jdwpgen/nbproject/sqe.properties new file mode 100644 index 00000000000..978ef5bc013 --- /dev/null +++ b/jdk/make/netbeans/jdwpgen/nbproject/sqe.properties @@ -0,0 +1,2 @@ +#Path to FindbugsSettingsFile (relative) +findbugs.settings.file=findbugs.settings diff --git a/jdk/make/tools/src/build/tools/jdwpgen/AbstractNamedNode.java b/jdk/make/tools/src/build/tools/jdwpgen/AbstractNamedNode.java index 442019676dc..ea362356fc3 100644 --- a/jdk/make/tools/src/build/tools/jdwpgen/AbstractNamedNode.java +++ b/jdk/make/tools/src/build/tools/jdwpgen/AbstractNamedNode.java @@ -30,7 +30,7 @@ import java.io.*; abstract class AbstractNamedNode extends Node { - NameNode nameNode; + NameNode nameNode = null; String name; public String name() { diff --git a/jdk/make/tools/src/build/tools/jdwpgen/AltNode.java b/jdk/make/tools/src/build/tools/jdwpgen/AltNode.java index b4aeae90b58..76b5ed423ff 100644 --- a/jdk/make/tools/src/build/tools/jdwpgen/AltNode.java +++ b/jdk/make/tools/src/build/tools/jdwpgen/AltNode.java @@ -30,7 +30,7 @@ import java.io.*; class AltNode extends AbstractGroupNode implements TypeNode { - SelectNode select; + SelectNode select = null; void constrain(Context ctx) { super.constrain(ctx); diff --git a/jdk/make/tools/src/build/tools/jdwpgen/ConstantSetNode.java b/jdk/make/tools/src/build/tools/jdwpgen/ConstantSetNode.java index 56ca041c4ff..86196612d37 100644 --- a/jdk/make/tools/src/build/tools/jdwpgen/ConstantSetNode.java +++ b/jdk/make/tools/src/build/tools/jdwpgen/ConstantSetNode.java @@ -33,13 +33,7 @@ class ConstantSetNode extends AbstractNamedNode { /** * The mapping between a constant and its value. */ - protected static Map constantMap; - - ConstantSetNode(){ - if (constantMap == null) { - constantMap = new HashMap(); - } - } + protected static final Map constantMap = new HashMap(); void prune() { List addons = new ArrayList(); @@ -95,9 +89,6 @@ class ConstantSetNode extends AbstractNamedNode { } public static String getConstant(String key){ - if (constantMap == null) { - return ""; - } String com = constantMap.get(key); if(com == null){ return ""; diff --git a/jdk/make/tools/src/build/tools/jdwpgen/Main.java b/jdk/make/tools/src/build/tools/jdwpgen/Main.java index 2562dd10da6..c7ce8e3c86d 100644 --- a/jdk/make/tools/src/build/tools/jdwpgen/Main.java +++ b/jdk/make/tools/src/build/tools/jdwpgen/Main.java @@ -25,13 +25,11 @@ package build.tools.jdwpgen; -import java.util.*; import java.io.*; class Main { static String specSource; - static Map nameMap = new HashMap(); static boolean genDebug = true; static void usage() { @@ -43,7 +41,6 @@ class Main { System.err.println("-doc "); System.err.println("-jdi "); System.err.println("-include "); - System.exit(1); } public static void main(String args[]) throws IOException { @@ -66,6 +63,7 @@ class Main { } else { System.err.println("Invalid option: " + arg); usage(); + return; } } else { specSource = arg; @@ -75,6 +73,7 @@ class Main { if (reader == null) { System.err.println(" must be specified"); usage(); + return; } Parse parse = new Parse(reader); diff --git a/jdk/make/tools/src/build/tools/jdwpgen/Node.java b/jdk/make/tools/src/build/tools/jdwpgen/Node.java index 2f79688186a..4dd33d07a11 100644 --- a/jdk/make/tools/src/build/tools/jdwpgen/Node.java +++ b/jdk/make/tools/src/build/tools/jdwpgen/Node.java @@ -36,7 +36,7 @@ abstract class Node { int lineno; List commentList = new ArrayList(); Node parent = null; - Context context; + Context context = null; static final int maxStructIndent = 5; static int structIndent = 0; // horrible hack @@ -82,7 +82,7 @@ abstract class Node { } void indent(PrintWriter writer, int depth) { - for (int i = depth; i > 0; --i) { + for (int i = 0; i < depth; i++) { writer.print(" "); } } @@ -195,6 +195,6 @@ abstract class Node { System.err.println(Main.specSource + ":" + lineno + ": " + kind + " - " + errmsg); System.err.println(); - System.exit(1); + throw new RuntimeException("Error: " + errmsg); } } diff --git a/jdk/make/tools/src/build/tools/jdwpgen/Parse.java b/jdk/make/tools/src/build/tools/jdwpgen/Parse.java index f5e3ebb9ed4..aac5b1f5290 100644 --- a/jdk/make/tools/src/build/tools/jdwpgen/Parse.java +++ b/jdk/make/tools/src/build/tools/jdwpgen/Parse.java @@ -146,8 +146,12 @@ class Parse { Node node = (Node)proto.getClass().newInstance(); node.set(kind, list, izer.lineno()); return node; - } catch (Exception exc) { + } catch (InstantiationException exc) { error(exc.toString()); + return null; + } catch (IllegalAccessException exc) { + error(exc.toString()); + return null; } } } else { @@ -166,6 +170,6 @@ class Parse { void error(String errmsg) { System.err.println(Main.specSource + ":" + izer.lineno() + ": " + errmsg); - System.exit(1); + throw new RuntimeException("Error: " + errmsg); } } diff --git a/jdk/make/tools/src/build/tools/jdwpgen/RepeatNode.java b/jdk/make/tools/src/build/tools/jdwpgen/RepeatNode.java index 107072a52d3..c841b913154 100644 --- a/jdk/make/tools/src/build/tools/jdwpgen/RepeatNode.java +++ b/jdk/make/tools/src/build/tools/jdwpgen/RepeatNode.java @@ -30,7 +30,7 @@ import java.io.*; class RepeatNode extends AbstractTypeNode { - Node member; + Node member = null; void constrain(Context ctx) { super.constrain(ctx); diff --git a/jdk/make/tools/src/build/tools/jdwpgen/SelectNode.java b/jdk/make/tools/src/build/tools/jdwpgen/SelectNode.java index cfe0c97cfe6..dd57afb7b07 100644 --- a/jdk/make/tools/src/build/tools/jdwpgen/SelectNode.java +++ b/jdk/make/tools/src/build/tools/jdwpgen/SelectNode.java @@ -30,7 +30,7 @@ import java.io.*; class SelectNode extends AbstractGroupNode implements TypeNode { - AbstractSimpleTypeNode typeNode; + AbstractSimpleTypeNode typeNode = null; void prune() { super.prune();