Showing the changes to java/pkg/com (1410 of 18352 files). Show all
Unified · Split
| @@ -0,0 +1,7 @@ | |||
| 1 | <../../../mkconfig | ||
| 2 | |||
| 3 | DIRS=\ | ||
| 4 | oracle\ | ||
| 5 | sun\ | ||
| 6 | |||
| 7 | <$ROOT/mkfiles/mksubdirs | ||
| @@ -0,0 +1,6 @@ | |||
| 1 | <../../../../mkconfig | ||
| 2 | |||
| 3 | DIRS=\ | ||
| 4 | net\ | ||
| 5 | |||
| 6 | <$ROOT/mkfiles/mksubdirs | ||
| @@ -0,0 +1,201 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.oracle.net; | ||
| 27 | |||
| 28 | import java.net.Socket; | ||
| 29 | import java.net.ServerSocket; | ||
| 30 | import java.net.SocketImpl; | ||
| 31 | import java.net.SocketImplFactory; | ||
| 32 | import java.net.SocketException; | ||
| 33 | import java.nio.channels.SocketChannel; | ||
| 34 | import java.nio.channels.ServerSocketChannel; | ||
| 35 | import java.io.IOException; | ||
| 36 | import java.io.FileDescriptor; | ||
| 37 | import java.security.AccessController; | ||
| 38 | import java.security.PrivilegedAction; | ||
| 39 | import java.lang.reflect.Constructor; | ||
| 40 | import java.lang.reflect.AccessibleObject; | ||
| 41 | import java.lang.reflect.InvocationTargetException; | ||
| 42 | |||
| 43 | import sun.net.sdp.SdpSupport; | ||
| 44 | |||
| 45 | /** | ||
| 46 | * This class consists exclusively of static methods that Sockets or Channels to | ||
| 47 | * sockets that support the InfiniBand Sockets Direct Protocol (SDP). | ||
| 48 | */ | ||
| 49 | |||
| 50 | public final class Sdp { | ||
| 51 | private Sdp() { } | ||
| 52 | |||
| 53 | /** | ||
| 54 | * The package-privage ServerSocket(SocketImpl) constructor | ||
| 55 | */ | ||
| 56 | private static final Constructor<ServerSocket> serverSocketCtor; | ||
| 57 | static { | ||
| 58 | try { | ||
| 59 | serverSocketCtor = (Constructor<ServerSocket>) | ||
| 60 | ServerSocket.class.getDeclaredConstructor(SocketImpl.class); | ||
| 61 | setAccessible(serverSocketCtor); | ||
| 62 | } catch (NoSuchMethodException e) { | ||
| 63 | throw new AssertionError(e); | ||
| 64 | } | ||
| 65 | } | ||
| 66 | |||
| 67 | /** | ||
| 68 | * The package-private SdpSocketImpl() constructor | ||
| 69 | */ | ||
| 70 | private static final Constructor<SocketImpl> socketImplCtor; | ||
| 71 | static { | ||
| 72 | try { | ||
| 73 | Class<?> cl = Class.forName("java.net.SdpSocketImpl", true, null); | ||
| 74 | socketImplCtor = (Constructor<SocketImpl>)cl.getDeclaredConstructor(); | ||
| 75 | setAccessible(socketImplCtor); | ||
| 76 | } catch (ClassNotFoundException e) { | ||
| 77 | throw new AssertionError(e); | ||
| 78 | } catch (NoSuchMethodException e) { | ||
| 79 | throw new AssertionError(e); | ||
| 80 | } | ||
| 81 | } | ||
| 82 | |||
| 83 | private static void setAccessible(final AccessibleObject o) { | ||
| 84 | AccessController.doPrivileged(new PrivilegedAction<Void>() { | ||
| 85 | public Void run() { | ||
| 86 | o.setAccessible(true); | ||
| 87 | return null; | ||
| 88 | } | ||
| 89 | }); | ||
| 90 | } | ||
| 91 | |||
| 92 | /** | ||
| 93 | * SDP enabled Socket. | ||
| 94 | */ | ||
| 95 | private static class SdpSocket extends Socket { | ||
| 96 | SdpSocket(SocketImpl impl) throws SocketException { | ||
| 97 | super(impl); | ||
| 98 | } | ||
| 99 | } | ||
| 100 | |||
| 101 | /** | ||
| 102 | * Creates a SDP enabled SocketImpl | ||
| 103 | */ | ||
| 104 | private static SocketImpl createSocketImpl() { | ||
| 105 | try { | ||
| 106 | return socketImplCtor.newInstance(); | ||
| 107 | } catch (InstantiationException x) { | ||
| 108 | throw new AssertionError(x); | ||
| 109 | } catch (IllegalAccessException x) { | ||
| 110 | throw new AssertionError(x); | ||
| 111 | } catch (InvocationTargetException x) { | ||
| 112 | throw new AssertionError(x); | ||
| 113 | } | ||
| 114 | } | ||
| 115 | |||
| 116 | /** | ||
| 117 | * Creates an unconnected and unbound SDP socket. The {@code Socket} is | ||
| 118 | * associated with a {@link java.net.SocketImpl} of the system-default type. | ||
| 119 | * | ||
| 120 | * @return a new Socket | ||
| 121 | * | ||
| 122 | * @throws UnsupportedOperationException | ||
| 123 | * If SDP is not supported | ||
| 124 | * @throws IOException | ||
| 125 | * If an I/O error occurs | ||
| 126 | */ | ||
| 127 | public static Socket openSocket() throws IOException { | ||
| 128 | SocketImpl impl = createSocketImpl(); | ||
| 129 | return new SdpSocket(impl); | ||
| 130 | } | ||
| 131 | |||
| 132 | /** | ||
| 133 | * Creates an unbound SDP server socket. The {@code ServerSocket} is | ||
| 134 | * associated with a {@link java.net.SocketImpl} of the system-default type. | ||
| 135 | * | ||
| 136 | * @return a new ServerSocket | ||
| 137 | * | ||
| 138 | * @throws UnsupportedOperationException | ||
| 139 | * If SDP is not supported | ||
| 140 | * @throws IOException | ||
| 141 | * If an I/O error occurs | ||
| 142 | */ | ||
| 143 | public static ServerSocket openServerSocket() throws IOException { | ||
| 144 | // create ServerSocket via package-private constructor | ||
| 145 | SocketImpl impl = createSocketImpl(); | ||
| 146 | try { | ||
| 147 | return serverSocketCtor.newInstance(impl); | ||
| 148 | } catch (IllegalAccessException x) { | ||
| 149 | throw new AssertionError(x); | ||
| 150 | } catch (InstantiationException x) { | ||
| 151 | throw new AssertionError(x); | ||
| 152 | } catch (InvocationTargetException x) { | ||
| 153 | Throwable cause = x.getCause(); | ||
| 154 | if (cause instanceof IOException) | ||
| 155 | throw (IOException)cause; | ||
| 156 | if (cause instanceof RuntimeException) | ||
| 157 | throw (RuntimeException)cause; | ||
| 158 | throw new RuntimeException(x); | ||
| 159 | } | ||
| 160 | } | ||
| 161 | |||
| 162 | /** | ||
| 163 | * Opens a socket channel to a SDP socket. | ||
| 164 | * | ||
| 165 | * <p> The channel will be associated with the system-wide default | ||
| 166 | * {@link java.nio.channels.spi.SelectorProvider SelectorProvider}. | ||
| 167 | * | ||
| 168 | * @return a new SocketChannel | ||
| 169 | * | ||
| 170 | * @throws UnsupportedOperationException | ||
| 171 | * If SDP is not supported or not supported by the default selector | ||
| 172 | * provider | ||
| 173 | * @throws IOException | ||
| 174 | * If an I/O error occurs. | ||
| 175 | */ | ||
| 176 | public static SocketChannel openSocketChannel() throws IOException { | ||
| 177 | FileDescriptor fd = SdpSupport.createSocket(); | ||
| 178 | return sun.nio.ch.Secrets.newSocketChannel(fd); | ||
| 179 | } | ||
| 180 | |||
| 181 | /** | ||
| 182 | * Opens a socket channel to a SDP socket. | ||
| 183 | * | ||
| 184 | * <p> The channel will be associated with the system-wide default | ||
| 185 | * {@link java.nio.channels.spi.SelectorProvider SelectorProvider}. | ||
| 186 | * | ||
| 187 | * @return a new ServerSocketChannel | ||
| 188 | * | ||
| 189 | * @throws UnsupportedOperationException | ||
| 190 | * If SDP is not supported or not supported by the default selector | ||
| 191 | * provider | ||
| 192 | * @throws IOException | ||
| 193 | * If an I/O error occurs | ||
| 194 | */ | ||
| 195 | public static ServerSocketChannel openServerSocketChannel() | ||
| 196 | throws IOException | ||
| 197 | { | ||
| 198 | FileDescriptor fd = SdpSupport.createSocket(); | ||
| 199 | return sun.nio.ch.Secrets.newServerSocketChannel(fd); | ||
| 200 | } | ||
| 201 | } | ||
| @@ -0,0 +1,8 @@ | |||
| 1 | <../../../../../mkconfig | ||
| 2 | |||
| 3 | TARG=\ | ||
| 4 | Sdp.dis\ | ||
| 5 | |||
| 6 | DISBIN=$ROOT/java/dis/java/java/com/oracle/net | ||
| 7 | |||
| 8 | <$ROOT/mkfiles/mkjava | ||
| @@ -0,0 +1,6 @@ | |||
| 1 | <../../../../../../mkconfig | ||
| 2 | |||
| 3 | DIRS=\ | ||
| 4 | resources\ | ||
| 5 | |||
| 6 | <$ROOT/mkfiles/mksubdirs | ||
| @@ -0,0 +1,146 @@ | |||
| 1 | # | ||
| 2 | # This properties file is used to create a PropertyResourceBundle | ||
| 3 | # It contains Locale specific strings used be the Accessibility package. | ||
| 4 | # | ||
| 5 | # When this file is read in, the strings are put into the | ||
| 6 | # defaults table. This is an implementation detail of the current | ||
| 7 | # workings of Accessibility. DO NOT DEPEND ON THIS. | ||
| 8 | # This may change in future versions of Accessibility as we improve | ||
| 9 | # localization support. | ||
| 10 | # | ||
| 11 | # @author Lynn Monsanto | ||
| 12 | |||
| 13 | # | ||
| 14 | # accessible roles | ||
| 15 | # | ||
| 16 | alert=alert | ||
| 17 | awtcomponent=AWT component | ||
| 18 | checkbox=check box | ||
| 19 | colorchooser=color chooser | ||
| 20 | columnheader=column header | ||
| 21 | combobox=combo box | ||
| 22 | canvas=canvas | ||
| 23 | desktopicon=desktop icon | ||
| 24 | desktoppane=desktop pane | ||
| 25 | dialog=dialog | ||
| 26 | directorypane=directory pane | ||
| 27 | glasspane=glass pane | ||
| 28 | filechooser=file chooser | ||
| 29 | filler=filler | ||
| 30 | frame=frame | ||
| 31 | internalframe=internal frame | ||
| 32 | label=label | ||
| 33 | layeredpane=layered pane | ||
| 34 | list=list | ||
| 35 | listitem=list item | ||
| 36 | menubar=menu bar | ||
| 37 | menu=menu | ||
| 38 | menuitem=menu item | ||
| 39 | optionpane=option pane | ||
| 40 | pagetab=page tab | ||
| 41 | pagetablist=page tab list | ||
| 42 | panel=panel | ||
| 43 | passwordtext=password text | ||
| 44 | popupmenu=popup menu | ||
| 45 | progressbar=progress bar | ||
| 46 | pushbutton=push button | ||
| 47 | radiobutton=radio button | ||
| 48 | rootpane=root pane | ||
| 49 | rowheader=row header | ||
| 50 | scrollbar=scroll bar | ||
| 51 | scrollpane=scroll pane | ||
| 52 | separator=separator | ||
| 53 | slider=slider | ||
| 54 | splitpane=split pane | ||
| 55 | swingcomponent=swing component | ||
| 56 | table=table | ||
| 57 | text=text | ||
| 58 | tree=tree | ||
| 59 | togglebutton=toggle button | ||
| 60 | toolbar=tool bar | ||
| 61 | tooltip=tool tip | ||
| 62 | unknown=unknown | ||
| 63 | viewport=viewport | ||
| 64 | window=window | ||
| 65 | # | ||
| 66 | # accessible relations | ||
| 67 | # | ||
| 68 | labelFor=label for | ||
| 69 | labeledBy=labeled by | ||
| 70 | memberOf=member of | ||
| 71 | controlledBy=controlledBy | ||
| 72 | controllerFor=controllerFor | ||
| 73 | # | ||
| 74 | # accessible states | ||
| 75 | # | ||
| 76 | active=active | ||
| 77 | armed=armed | ||
| 78 | busy=busy | ||
| 79 | checked=checked | ||
| 80 | collapsed=collapsed | ||
| 81 | editable=editable | ||
| 82 | expandable=expandable | ||
| 83 | expanded=expanded | ||
| 84 | enabled=enabled | ||
| 85 | focusable=focusable | ||
| 86 | focused=focused | ||
| 87 | iconified=iconified | ||
| 88 | modal=modal | ||
| 89 | multiline=multiple line | ||
| 90 | multiselectable=multiselectable | ||
| 91 | opaque=opaque | ||
| 92 | pressed=pressed | ||
| 93 | resizable=resizable | ||
| 94 | selectable=selectable | ||
| 95 | selected=selected | ||
| 96 | showing=showing | ||
| 97 | singleline=single line | ||
| 98 | transient=transient | ||
| 99 | visible=visible | ||
| 100 | vertical=vertical | ||
| 101 | horizontal=horizontal | ||
| 102 | # | ||
| 103 | # accessible actions | ||
| 104 | # | ||
| 105 | toggle expand=toggle expand | ||
| 106 | |||
| 107 | # new relations, roles and states for J2SE 1.5.0 | ||
| 108 | |||
| 109 | # | ||
| 110 | # accessible relations | ||
| 111 | # | ||
| 112 | flowsTo=flows to | ||
| 113 | flowsFrom=flows from | ||
| 114 | subwindowOf=subwindow of | ||
| 115 | parentWindowOf=parent window of | ||
| 116 | embeds=embeds | ||
| 117 | embeddedBy=embedded by | ||
| 118 | childNodeOf=child node of | ||
| 119 | |||
| 120 | # | ||
| 121 | # accessible roles | ||
| 122 | # | ||
| 123 | header=header | ||
| 124 | footer=footer | ||
| 125 | paragraph=paragraph | ||
| 126 | ruler=ruler | ||
| 127 | editbar=editbar | ||
| 128 | progressMonitor=progress monitor | ||
| 129 | |||
| 130 | # | ||
| 131 | # accessible states | ||
| 132 | # | ||
| 133 | managesDescendants=manages descendants | ||
| 134 | indeterminate=indeterminate | ||
| 135 | truncated=truncated | ||
| 136 | |||
| 137 | # new for J2SE 1.6.0 | ||
| 138 | |||
| 139 | # | ||
| 140 | # accessible roles | ||
| 141 | # | ||
| 142 | htmlcontainer=HTML container | ||
| 143 | |||
| 144 | # | ||
| 145 | # END OF MATERIAL TO LOCALIZE | ||
| 146 | # | ||
| @@ -0,0 +1,146 @@ | |||
| 1 | # | ||
| 2 | # This properties file is used to create a PropertyResourceBundle | ||
| 3 | # It contains Locale specific strings used be the Accessibility package. | ||
| 4 | # | ||
| 5 | # When this file is read in, the strings are put into the | ||
| 6 | # defaults table. This is an implementation detail of the current | ||
| 7 | # workings of Accessibility. DO NOT DEPEND ON THIS. | ||
| 8 | # This may change in future versions of Accessibility as we improve | ||
| 9 | # localization support. | ||
| 10 | # | ||
| 11 | # @author Lynn Monsanto | ||
| 12 | |||
| 13 | # | ||
| 14 | # accessible roles | ||
| 15 | # | ||
| 16 | alert=Alert | ||
| 17 | awtcomponent=AWT-Komponente | ||
| 18 | checkbox=Kontrollk\u00E4stchen | ||
| 19 | colorchooser=Farbauswahl | ||
| 20 | columnheader=Spalten-Header | ||
| 21 | combobox=Kombinationsfeld | ||
| 22 | canvas=Leinwand | ||
| 23 | desktopicon=Desktopsymbol | ||
| 24 | desktoppane=Desktopbereich | ||
| 25 | dialog=Dialogfeld | ||
| 26 | directorypane=Verzeichnisbereich | ||
| 27 | glasspane=Glass Pane | ||
| 28 | filechooser=Dateiauswahl | ||
| 29 | filler=F\u00FCllbereich | ||
| 30 | frame=Rahmen | ||
| 31 | internalframe=Innerer Rahmen | ||
| 32 | label=Label | ||
| 33 | layeredpane=Layered Pane | ||
| 34 | list=Liste | ||
| 35 | listitem=Listenelement | ||
| 36 | menubar=Men\u00FCleiste | ||
| 37 | menu=Men\u00FC | ||
| 38 | menuitem=Men\u00FCpunkt | ||
| 39 | optionpane=Optionsbereich | ||
| 40 | pagetab=Registerkarte | ||
| 41 | pagetablist=Registerkartenliste | ||
| 42 | panel=Bereich | ||
| 43 | passwordtext=Kennworttext | ||
| 44 | popupmenu=Popup-Men\u00FC | ||
| 45 | progressbar=Fortschrittsbalken | ||
| 46 | pushbutton=Schaltfl\u00E4che | ||
| 47 | radiobutton=Optionsfeld | ||
| 48 | rootpane=Root-Bereich | ||
| 49 | rowheader=Zeilen-Header | ||
| 50 | scrollbar=Bildlaufleiste | ||
| 51 | scrollpane=Bildlaufbereich | ||
| 52 | separator=Trennzeichen | ||
| 53 | slider=Schieberegler | ||
| 54 | splitpane=Split Pane | ||
| 55 | swingcomponent=Swing-Komponente | ||
| 56 | table=Tabelle | ||
| 57 | text=Text | ||
| 58 | tree=Baumstruktur | ||
| 59 | togglebutton=Umschaltfl\u00E4che | ||
| 60 | toolbar=Symbolleiste | ||
| 61 | tooltip=QuickInfo | ||
| 62 | unknown=Unbekannt | ||
| 63 | viewport=Viewport | ||
| 64 | window=Fenster | ||
| 65 | # | ||
| 66 | # accessible relations | ||
| 67 | # | ||
| 68 | labelFor=Label f\u00FCr | ||
| 69 | labeledBy=beschriftet von | ||
| 70 | memberOf=Mitglied von | ||
| 71 | controlledBy=controlledBy | ||
| 72 | controllerFor=controllerFor | ||
| 73 | # | ||
| 74 | # accessible states | ||
| 75 | # | ||
| 76 | active=aktiv | ||
| 77 | armed=aktiviert | ||
| 78 | busy=ausgelastet | ||
| 79 | checked=markiert | ||
| 80 | collapsed=ausgeblendet | ||
| 81 | editable=bearbeitbar | ||
| 82 | expandable=erweiterbar | ||
| 83 | expanded=eingeblendet | ||
| 84 | enabled=aktiviert | ||
| 85 | focusable=fokussierbar | ||
| 86 | focused=fokussiert | ||
| 87 | iconified=minimiert | ||
| 88 | modal=modal | ||
| 89 | multiline=mehrzeilig | ||
| 90 | multiselectable=mehrfach ausw\u00E4hlbar | ||
| 91 | opaque=nicht transparent | ||
| 92 | pressed=gedr\u00FCckt | ||
| 93 | resizable=skalierbar | ||
| 94 | selectable=w\u00E4hlbar | ||
| 95 | selected=ausgew\u00E4hlt | ||
| 96 | showing=angezeigt | ||
| 97 | singleline=einzeilig | ||
| 98 | transient=transient | ||
| 99 | visible=sichtbar | ||
| 100 | vertical=vertikal | ||
| 101 | horizontal=horizontal | ||
| 102 | # | ||
| 103 | # accessible actions | ||
| 104 | # | ||
| 105 | toggle expand=ein-/ausblenden | ||
| 106 | |||
| 107 | # new relations, roles and states for J2SE 1.5.0 | ||
| 108 | |||
| 109 | # | ||
| 110 | # accessible relations | ||
| 111 | # | ||
| 112 | flowsTo=flie\u00DFt zu | ||
| 113 | flowsFrom=flie\u00DFt von | ||
| 114 | subwindowOf=Unterfenster von | ||
| 115 | parentWindowOf=\u00FCbergeordnetes Fenster von | ||
| 116 | embeds=bettet ein | ||
| 117 | embeddedBy=eingebettet in | ||
| 118 | childNodeOf=untergeordneter Knoten von | ||
| 119 | |||
| 120 | # | ||
| 121 | # accessible roles | ||
| 122 | # | ||
| 123 | header=Header | ||
| 124 | footer=Footer | ||
| 125 | paragraph=Absatz | ||
| 126 | ruler=Lineal | ||
| 127 | editbar=Bearbeitungsleiste | ||
| 128 | progressMonitor=Fortschrittsmonitor | ||
| 129 | |||
| 130 | # | ||
| 131 | # accessible states | ||
| 132 | # | ||
| 133 | managesDescendants=verwaltet untergeordnete Objekte | ||
| 134 | indeterminate=unbestimmt | ||
| 135 | truncated=abgeschnitten | ||
| 136 | |||
| 137 | # new for J2SE 1.6.0 | ||
| 138 | |||
| 139 | # | ||
| 140 | # accessible roles | ||
| 141 | # | ||
| 142 | htmlcontainer=HTML-Container | ||
| 143 | |||
| 144 | # | ||
| 145 | # END OF MATERIAL TO LOCALIZE | ||
| 146 | # | ||
| @@ -0,0 +1,142 @@ | |||
| 1 | # | ||
| 2 | # This properties file is used to create a PropertyResourceBundle | ||
| 3 | # It contains Locale specific strings used be the Accessibility package. | ||
| 4 | # | ||
| 5 | # When this file is read in, the strings are put into the | ||
| 6 | # defaults table. This is an implementation detail of the current | ||
| 7 | # workings of Accessibility. DO NOT DEPEND ON THIS. | ||
| 8 | # This may change in future versions of Accessibility as we improve | ||
| 9 | # localization support. | ||
| 10 | # | ||
| 11 | # @author Lynn Monsanto | ||
| 12 | |||
| 13 | # | ||
| 14 | # accessible roles | ||
| 15 | # | ||
| 16 | alert=alert | ||
| 17 | awtcomponent=AWT component | ||
| 18 | checkbox=check box | ||
| 19 | colorchooser=color chooser | ||
| 20 | columnheader=column header | ||
| 21 | combobox=combo box | ||
| 22 | canvas=canvas | ||
| 23 | desktopicon=desktop icon | ||
| 24 | desktoppane=desktop pane | ||
| 25 | dialog=dialog | ||
| 26 | directorypane=directory pane | ||
| 27 | glasspane=glass pane | ||
| 28 | filechooser=file chooser | ||
| 29 | filler=filler | ||
| 30 | frame=frame | ||
| 31 | internalframe=internal frame | ||
| 32 | label=label | ||
| 33 | layeredpane=layered pane | ||
| 34 | list=list | ||
| 35 | listitem=list item | ||
| 36 | menubar=menu bar | ||
| 37 | menu=menu | ||
| 38 | menuitem=menu item | ||
| 39 | optionpane=option pane | ||
| 40 | pagetab=page tab | ||
| 41 | pagetablist=page tab list | ||
| 42 | panel=panel | ||
| 43 | passwordtext=password text | ||
| 44 | popupmenu=popup menu | ||
| 45 | progressbar=progress bar | ||
| 46 | pushbutton=push button | ||
| 47 | radiobutton=radio button | ||
| 48 | rootpane=root pane | ||
| 49 | rowheader=row header | ||
| 50 | scrollbar=scroll bar | ||
| 51 | scrollpane=scroll pane | ||
| 52 | separator=separator | ||
| 53 | slider=slider | ||
| 54 | splitpane=split pane | ||
| 55 | swingcomponent=swing component | ||
| 56 | table=table | ||
| 57 | text=text | ||
| 58 | tree=tree | ||
| 59 | togglebutton=toggle button | ||
| 60 | toolbar=tool bar | ||
| 61 | tooltip=tool tip | ||
| 62 | unknown=unknown | ||
| 63 | viewport=viewport | ||
| 64 | window=window | ||
| 65 | # | ||
| 66 | # accessible relations | ||
| 67 | # | ||
| 68 | labelFor=label for | ||
| 69 | labeledBy=labeled by | ||
| 70 | memberOf=member of | ||
| 71 | controlledBy=controlledBy | ||
| 72 | controllerFor=controllerFor | ||
| 73 | # | ||
| 74 | # accessible states | ||
| 75 | # | ||
| 76 | active=active | ||
| 77 | armed=armed | ||
| 78 | busy=busy | ||
| 79 | checked=checked | ||
| 80 | collapsed=collapsed | ||
| 81 | editable=editable | ||
| 82 | expandable=expandable | ||
| 83 | expanded=expanded | ||
| 84 | enabled=enabled | ||
| 85 | focusable=focusable | ||
| 86 | focused=focused | ||
| 87 | iconified=iconified | ||
| 88 | modal=modal | ||
| 89 | multiline=multiple line | ||
| 90 | multiselectable=multiselectable | ||
| 91 | opaque=opaque | ||
| 92 | pressed=pressed | ||
| 93 | resizable=resizable | ||
| 94 | selectable=selectable | ||
| 95 | selected=selected | ||
| 96 | showing=showing | ||
| 97 | singleline=single line | ||
| 98 | transient=transient | ||
| 99 | visible=visible | ||
| 100 | vertical=vertical | ||
| 101 | horizontal=horizontal | ||
| 102 | |||
| 103 | # new relations, roles and states for J2SE 1.5.0 | ||
| 104 | |||
| 105 | # | ||
| 106 | # accessible relations | ||
| 107 | # | ||
| 108 | flowsTo=flows to | ||
| 109 | flowsFrom=flows from | ||
| 110 | subwindowOf=subwindow of | ||
| 111 | parentWindowOf=parent window of | ||
| 112 | embeds=embeds | ||
| 113 | embeddedBy=embedded by | ||
| 114 | childNodeOf=child node of | ||
| 115 | |||
| 116 | # | ||
| 117 | # accessible roles | ||
| 118 | # | ||
| 119 | header=header | ||
| 120 | footer=footer | ||
| 121 | paragraph=paragraph | ||
| 122 | ruler=ruler | ||
| 123 | editbar=editbar | ||
| 124 | progressMonitor=progress monitor | ||
| 125 | |||
| 126 | # | ||
| 127 | # accessible states | ||
| 128 | # | ||
| 129 | managesDescendants=manages descendants | ||
| 130 | indeterminate=indeterminate | ||
| 131 | truncated=truncated | ||
| 132 | |||
| 133 | # new for J2SE 1.6.0 | ||
| 134 | |||
| 135 | # | ||
| 136 | # accessible roles | ||
| 137 | # | ||
| 138 | htmlcontainer=HTML container | ||
| 139 | |||
| 140 | # | ||
| 141 | # END OF MATERIAL TO LOCALIZE | ||
| 142 | # | ||
| @@ -0,0 +1,146 @@ | |||
| 1 | # | ||
| 2 | # This properties file is used to create a PropertyResourceBundle | ||
| 3 | # It contains Locale specific strings used be the Accessibility package. | ||
| 4 | # | ||
| 5 | # When this file is read in, the strings are put into the | ||
| 6 | # defaults table. This is an implementation detail of the current | ||
| 7 | # workings of Accessibility. DO NOT DEPEND ON THIS. | ||
| 8 | # This may change in future versions of Accessibility as we improve | ||
| 9 | # localization support. | ||
| 10 | # | ||
| 11 | # @author Lynn Monsanto | ||
| 12 | |||
| 13 | # | ||
| 14 | # accessible roles | ||
| 15 | # | ||
| 16 | alert=alerta | ||
| 17 | awtcomponent=componente AWT | ||
| 18 | checkbox=casilla de control | ||
| 19 | colorchooser=selector de color | ||
| 20 | columnheader=cabecera de columna | ||
| 21 | combobox=cuadro combinado | ||
| 22 | canvas=lienzo | ||
| 23 | desktopicon=icono de escritorio | ||
| 24 | desktoppane=panel de escritorio | ||
| 25 | dialog=cuadro de di\u00E1logo | ||
| 26 | directorypane=panel de directorio | ||
| 27 | glasspane=panel de cristal | ||
| 28 | filechooser=selector de archivos | ||
| 29 | filler=rellenador | ||
| 30 | frame=marco | ||
| 31 | internalframe=marco interno | ||
| 32 | label=etiqueta | ||
| 33 | layeredpane=panel en capas | ||
| 34 | list=lista | ||
| 35 | listitem=elemento de lista | ||
| 36 | menubar=barra de men\u00FAs | ||
| 37 | menu=men\u00FA | ||
| 38 | menuitem=elemento de men\u00FA | ||
| 39 | optionpane=panel de opciones | ||
| 40 | pagetab=separador de p\u00E1gina | ||
| 41 | pagetablist=lista de separadores de p\u00E1gina | ||
| 42 | panel=panel | ||
| 43 | passwordtext=texto de contrase\u00F1a | ||
| 44 | popupmenu=men\u00FA emergente | ||
| 45 | progressbar=barra de progreso | ||
| 46 | pushbutton=bot\u00F3n | ||
| 47 | radiobutton=bot\u00F3n de radio | ||
| 48 | rootpane=panel ra\u00EDz | ||
| 49 | rowheader=cabecera de filas | ||
| 50 | scrollbar=barra de desplazamiento | ||
| 51 | scrollpane=panel de desplazamiento | ||
| 52 | separator=separador | ||
| 53 | slider=deslizador | ||
| 54 | splitpane=panel de divisi\u00F3n | ||
| 55 | swingcomponent=componente swing | ||
| 56 | table=tabla | ||
| 57 | text=texto | ||
| 58 | tree=\u00E1rbol | ||
| 59 | togglebutton=bot\u00F3n conmutador | ||
| 60 | toolbar=barra de herramientas | ||
| 61 | tooltip=ayuda de burbuja | ||
| 62 | unknown=desconocido | ||
| 63 | viewport=viewport | ||
| 64 | window=ventana | ||
| 65 | # | ||
| 66 | # accessible relations | ||
| 67 | # | ||
| 68 | labelFor=etiqueta para | ||
| 69 | labeledBy=etiquetado por | ||
| 70 | memberOf=miembro de | ||
| 71 | controlledBy=controlledBy | ||
| 72 | controllerFor=controllerFor | ||
| 73 | # | ||
| 74 | # accessible states | ||
| 75 | # | ||
| 76 | active=activo | ||
| 77 | armed=armado | ||
| 78 | busy=ocupado | ||
| 79 | checked=activado | ||
| 80 | collapsed=reducido | ||
| 81 | editable=editable | ||
| 82 | expandable=ampliable | ||
| 83 | expanded=ampliado | ||
| 84 | enabled=activado | ||
| 85 | focusable=enfocable | ||
| 86 | focused=enfocado | ||
| 87 | iconified=convertido en icono | ||
| 88 | modal=modal | ||
| 89 | multiline=l\u00EDnea m\u00FAltiple | ||
| 90 | multiselectable=multiseleccionable | ||
| 91 | opaque=opaco | ||
| 92 | pressed=pulsado | ||
| 93 | resizable=redimensionable | ||
| 94 | selectable=seleccionable | ||
| 95 | selected=seleccionado | ||
| 96 | showing=mostrando | ||
| 97 | singleline=l\u00EDnea \u00FAnica | ||
| 98 | transient=transitorio | ||
| 99 | visible=visible | ||
| 100 | vertical=vertical | ||
| 101 | horizontal=horizontal | ||
| 102 | # | ||
| 103 | # accessible actions | ||
| 104 | # | ||
| 105 | toggle expand=activar/desactivar ampliaci\u00F3n | ||
| 106 | |||
| 107 | # new relations, roles and states for J2SE 1.5.0 | ||
| 108 | |||
| 109 | # | ||
| 110 | # accessible relations | ||
| 111 | # | ||
| 112 | flowsTo=llega a | ||
| 113 | flowsFrom=procede de | ||
| 114 | subwindowOf=ventana subordinada de | ||
| 115 | parentWindowOf=ventana principal de | ||
| 116 | embeds=embebe | ||
| 117 | embeddedBy=embebido por | ||
| 118 | childNodeOf=nodo secundario de | ||
| 119 | |||
| 120 | # | ||
| 121 | # accessible roles | ||
| 122 | # | ||
| 123 | header=cabecera | ||
| 124 | footer=pie | ||
| 125 | paragraph=p\u00E1rrafo | ||
| 126 | ruler=regla | ||
| 127 | editbar=barra de edici\u00F3n | ||
| 128 | progressMonitor=monitor de progreso | ||
| 129 | |||
| 130 | # | ||
| 131 | # accessible states | ||
| 132 | # | ||
| 133 | managesDescendants=gestiona descendientes | ||
| 134 | indeterminate=indeterminada | ||
| 135 | truncated=truncado | ||
| 136 | |||
| 137 | # new for J2SE 1.6.0 | ||
| 138 | |||
| 139 | # | ||
| 140 | # accessible roles | ||
| 141 | # | ||
| 142 | htmlcontainer=Contenedor HTML | ||
| 143 | |||
| 144 | # | ||
| 145 | # END OF MATERIAL TO LOCALIZE | ||
| 146 | # | ||
| @@ -0,0 +1,146 @@ | |||
| 1 | # | ||
| 2 | # This properties file is used to create a PropertyResourceBundle | ||
| 3 | # It contains Locale specific strings used be the Accessibility package. | ||
| 4 | # | ||
| 5 | # When this file is read in, the strings are put into the | ||
| 6 | # defaults table. This is an implementation detail of the current | ||
| 7 | # workings of Accessibility. DO NOT DEPEND ON THIS. | ||
| 8 | # This may change in future versions of Accessibility as we improve | ||
| 9 | # localization support. | ||
| 10 | # | ||
| 11 | # @author Lynn Monsanto | ||
| 12 | |||
| 13 | # | ||
| 14 | # accessible roles | ||
| 15 | # | ||
| 16 | alert=alerte | ||
| 17 | awtcomponent=composant AWT | ||
| 18 | checkbox=case \u00E0 cocher | ||
| 19 | colorchooser=s\u00E9lecteur de couleurs | ||
| 20 | columnheader=en-t\u00EAte de colonne | ||
| 21 | combobox=liste d\u00E9roulante | ||
| 22 | canvas=canevas | ||
| 23 | desktopicon=ic\u00F4ne de bureau | ||
| 24 | desktoppane=panneau de bureau | ||
| 25 | dialog=bo\u00EEte de dialogue | ||
| 26 | directorypane=panneau de r\u00E9pertoires | ||
| 27 | glasspane=panneau de grossissement | ||
| 28 | filechooser=s\u00E9lecteur de fichiers | ||
| 29 | filler=\u00E9l\u00E9ment de remplissage | ||
| 30 | frame=cadre | ||
| 31 | internalframe=cadre interne | ||
| 32 | label=libell\u00E9 | ||
| 33 | layeredpane=panneau superpos\u00E9 | ||
| 34 | list=liste | ||
| 35 | listitem=\u00E9l\u00E9ment de liste | ||
| 36 | menubar=barre de menus | ||
| 37 | menu=menu | ||
| 38 | menuitem=option de menu | ||
| 39 | optionpane=panneau d'options | ||
| 40 | pagetab=onglet de page | ||
| 41 | pagetablist=liste d'onglets de page | ||
| 42 | panel=panneau | ||
| 43 | passwordtext=texte de mot de passe | ||
| 44 | popupmenu=menu contextuel | ||
| 45 | progressbar=barre de progression | ||
| 46 | pushbutton=bouton | ||
| 47 | radiobutton=bouton radio | ||
| 48 | rootpane=panneau racine | ||
| 49 | rowheader=en-t\u00EAte de ligne | ||
| 50 | scrollbar=barre de d\u00E9filement | ||
| 51 | scrollpane=panneau de d\u00E9filement | ||
| 52 | separator=s\u00E9parateur | ||
| 53 | slider=curseur | ||
| 54 | splitpane=panneau divis\u00E9 | ||
| 55 | swingcomponent=composant Swing | ||
| 56 | table=tableau | ||
| 57 | text=texte | ||
| 58 | tree=arborescence | ||
| 59 | togglebutton=bouton de basculement | ||
| 60 | toolbar=barre d'outils | ||
| 61 | tooltip=info-bulle | ||
| 62 | unknown=inconnu | ||
| 63 | viewport=lucarne | ||
| 64 | window=fen\u00EAtre | ||
| 65 | # | ||
| 66 | # accessible relations | ||
| 67 | # | ||
| 68 | labelFor=libell\u00E9 de | ||
| 69 | labeledBy=libell\u00E9 par | ||
| 70 | memberOf=membre de | ||
| 71 | controlledBy=contr\u00F4l\u00E9 par | ||
| 72 | controllerFor=contr\u00F4leur pour | ||
| 73 | # | ||
| 74 | # accessible states | ||
| 75 | # | ||
| 76 | active=actif | ||
| 77 | armed=arm\u00E9 | ||
| 78 | busy=occup\u00E9 | ||
| 79 | checked=coch\u00E9 | ||
| 80 | collapsed=r\u00E9duit | ||
| 81 | editable=modifiable | ||
| 82 | expandable=extensible | ||
| 83 | expanded=d\u00E9velopp\u00E9 | ||
| 84 | enabled=activ\u00E9 | ||
| 85 | focusable=zone d'entr\u00E9e possible | ||
| 86 | focused=avec zone d'entr\u00E9e | ||
| 87 | iconified=r\u00E9duit \u00E0 une ic\u00F4ne | ||
| 88 | modal=modal | ||
| 89 | multiline=ligne multiple | ||
| 90 | multiselectable=multis\u00E9lectionnable | ||
| 91 | opaque=opaque | ||
| 92 | pressed=enfonc\u00E9 | ||
| 93 | resizable=redimensionnable | ||
| 94 | selectable=s\u00E9lectionnable | ||
| 95 | selected=s\u00E9lectionn\u00E9 | ||
| 96 | showing=montrant | ||
| 97 | singleline=ligne unique | ||
| 98 | transient=non persistant | ||
| 99 | visible=visible | ||
| 100 | vertical=vertical | ||
| 101 | horizontal=horizontal | ||
| 102 | # | ||
| 103 | # accessible actions | ||
| 104 | # | ||
| 105 | toggle expand=basculer le d\u00E9veloppement | ||
| 106 | |||
| 107 | # new relations, roles and states for J2SE 1.5.0 | ||
| 108 | |||
| 109 | # | ||
| 110 | # accessible relations | ||
| 111 | # | ||
| 112 | flowsTo=flux vers | ||
| 113 | flowsFrom=flux depuis | ||
| 114 | subwindowOf=sous-fen\u00EAtre de | ||
| 115 | parentWindowOf=fen\u00EAtre parente de | ||
| 116 | embeds=incorpore | ||
| 117 | embeddedBy=incorpor\u00E9 par | ||
| 118 | childNodeOf=noeud enfant de | ||
| 119 | |||
| 120 | # | ||
| 121 | # accessible roles | ||
| 122 | # | ||
| 123 | header=en-t\u00EAte | ||
| 124 | footer=pied de page | ||
| 125 | paragraph=paragraphe | ||
| 126 | ruler=r\u00E8gle | ||
| 127 | editbar=barre d'\u00E9dition | ||
| 128 | progressMonitor=contr\u00F4le de la progression | ||
| 129 | |||
| 130 | # | ||
| 131 | # accessible states | ||
| 132 | # | ||
| 133 | managesDescendants=g\u00E8re les descendants | ||
| 134 | indeterminate=ind\u00E9termin\u00E9 | ||
| 135 | truncated=tronqu\u00E9 | ||
| 136 | |||
| 137 | # new for J2SE 1.6.0 | ||
| 138 | |||
| 139 | # | ||
| 140 | # accessible roles | ||
| 141 | # | ||
| 142 | htmlcontainer=conteneur HTML | ||
| 143 | |||
| 144 | # | ||
| 145 | # END OF MATERIAL TO LOCALIZE | ||
| 146 | # | ||
| @@ -0,0 +1,146 @@ | |||
| 1 | # | ||
| 2 | # This properties file is used to create a PropertyResourceBundle | ||
| 3 | # It contains Locale specific strings used be the Accessibility package. | ||
| 4 | # | ||
| 5 | # When this file is read in, the strings are put into the | ||
| 6 | # defaults table. This is an implementation detail of the current | ||
| 7 | # workings of Accessibility. DO NOT DEPEND ON THIS. | ||
| 8 | # This may change in future versions of Accessibility as we improve | ||
| 9 | # localization support. | ||
| 10 | # | ||
| 11 | # @author Lynn Monsanto | ||
| 12 | |||
| 13 | # | ||
| 14 | # accessible roles | ||
| 15 | # | ||
| 16 | alert=avviso | ||
| 17 | awtcomponent=componente AWT | ||
| 18 | checkbox=casella di controllo | ||
| 19 | colorchooser=selezione colori | ||
| 20 | columnheader=intestazione colonna | ||
| 21 | combobox=casella combinata | ||
| 22 | canvas=sfondo | ||
| 23 | desktopicon=icona desktop | ||
| 24 | desktoppane=riquadro desktop | ||
| 25 | dialog=finestra di dialogo | ||
| 26 | directorypane=riquadro directory | ||
| 27 | glasspane=riquadro trasparente | ||
| 28 | filechooser=selezione file | ||
| 29 | filler=utilit\u00E0 riempimento | ||
| 30 | frame=cornice | ||
| 31 | internalframe=cornice interna | ||
| 32 | label=etichetta | ||
| 33 | layeredpane=riquadro a livelli | ||
| 34 | list=lista | ||
| 35 | listitem=voce lista | ||
| 36 | menubar=barra dei menu | ||
| 37 | menu=menu | ||
| 38 | menuitem=voce di menu | ||
| 39 | optionpane=riquadro opzioni | ||
| 40 | pagetab=scheda pagina | ||
| 41 | pagetablist=lista schede pagina | ||
| 42 | panel=pannello | ||
| 43 | passwordtext=testo della password | ||
| 44 | popupmenu=menu popup | ||
| 45 | progressbar=barra di avanzamento | ||
| 46 | pushbutton=pulsante | ||
| 47 | radiobutton=pulsante di scelta | ||
| 48 | rootpane=riquadro root | ||
| 49 | rowheader=intestazione di riga | ||
| 50 | scrollbar=barra di scorrimento | ||
| 51 | scrollpane=riquadro scorrimento | ||
| 52 | separator=separatore | ||
| 53 | slider=dispositivo di scorrimento | ||
| 54 | splitpane=riquadro doppio | ||
| 55 | swingcomponent=componente swing | ||
| 56 | table=tabella | ||
| 57 | text=testo | ||
| 58 | tree=albero | ||
| 59 | togglebutton=interruttore | ||
| 60 | toolbar=barra degli strumenti | ||
| 61 | tooltip=descrizione comandi | ||
| 62 | unknown=sconosciuto | ||
| 63 | viewport=viewport | ||
| 64 | window=finestra | ||
| 65 | # | ||
| 66 | # accessible relations | ||
| 67 | # | ||
| 68 | labelFor=etichetta per | ||
| 69 | labeledBy=etichetta di | ||
| 70 | memberOf=membro di | ||
| 71 | controlledBy=controlledBy | ||
| 72 | controllerFor=controllerFor | ||
| 73 | # | ||
| 74 | # accessible states | ||
| 75 | # | ||
| 76 | active=attivo | ||
| 77 | armed=abilitato | ||
| 78 | busy=occupato | ||
| 79 | checked=verificato | ||
| 80 | collapsed=compresso | ||
| 81 | editable=modificabile | ||
| 82 | expandable=espandibile | ||
| 83 | expanded=espanso | ||
| 84 | enabled=abilitato | ||
| 85 | focusable=attivabile in primo piano | ||
| 86 | focused=in primo piano | ||
| 87 | iconified=ridotto a icona | ||
| 88 | modal=modale | ||
| 89 | multiline=a righe multiple | ||
| 90 | multiselectable=multi-selezionabile | ||
| 91 | opaque=nascosto | ||
| 92 | pressed=premuto | ||
| 93 | resizable=ridimensionabile | ||
| 94 | selectable=selezionabile | ||
| 95 | selected=selezionato | ||
| 96 | showing=visualizzato | ||
| 97 | singleline=a riga singola | ||
| 98 | transient=transitorio | ||
| 99 | visible=visibile | ||
| 100 | vertical=verticale | ||
| 101 | horizontal=orizzontale | ||
| 102 | # | ||
| 103 | # accessible actions | ||
| 104 | # | ||
| 105 | toggle expand=abilita/disabilita espansione | ||
| 106 | |||
| 107 | # new relations, roles and states for J2SE 1.5.0 | ||
| 108 | |||
| 109 | # | ||
| 110 | # accessible relations | ||
| 111 | # | ||
| 112 | flowsTo=va verso | ||
| 113 | flowsFrom=proviene da | ||
| 114 | subwindowOf=sottofinestra di | ||
| 115 | parentWindowOf=finestra di livello superiore di | ||
| 116 | embeds=incorpora | ||
| 117 | embeddedBy=incorporato da | ||
| 118 | childNodeOf=nodo figlio di | ||
| 119 | |||
| 120 | # | ||
| 121 | # accessible roles | ||
| 122 | # | ||
| 123 | header=intestazione | ||
| 124 | footer=pi\u00E8 di pagina | ||
| 125 | paragraph=paragrafo | ||
| 126 | ruler=righello | ||
| 127 | editbar=barra di modifica | ||
| 128 | progressMonitor=stato avanzamento | ||
| 129 | |||
| 130 | # | ||
| 131 | # accessible states | ||
| 132 | # | ||
| 133 | managesDescendants=gestisce i discendenti | ||
| 134 | indeterminate=indeterminato | ||
| 135 | truncated=troncato | ||
| 136 | |||
| 137 | # new for J2SE 1.6.0 | ||
| 138 | |||
| 139 | # | ||
| 140 | # accessible roles | ||
| 141 | # | ||
| 142 | htmlcontainer=Contenitore HTML | ||
| 143 | |||
| 144 | # | ||
| 145 | # END OF MATERIAL TO LOCALIZE | ||
| 146 | # | ||
| @@ -0,0 +1,146 @@ | |||
| 1 | # | ||
| 2 | # This properties file is used to create a PropertyResourceBundle | ||
| 3 | # It contains Locale specific strings used be the Accessibility package. | ||
| 4 | # | ||
| 5 | # When this file is read in, the strings are put into the | ||
| 6 | # defaults table. This is an implementation detail of the current | ||
| 7 | # workings of Accessibility. DO NOT DEPEND ON THIS. | ||
| 8 | # This may change in future versions of Accessibility as we improve | ||
| 9 | # localization support. | ||
| 10 | # | ||
| 11 | # @author Lynn Monsanto | ||
| 12 | |||
| 13 | # | ||
| 14 | # accessible roles | ||
| 15 | # | ||
| 16 | alert=\u30A2\u30E9\u30FC\u30C8 | ||
| 17 | awtcomponent=AWT\u30B3\u30F3\u30DD\u30FC\u30CD\u30F3\u30C8 | ||
| 18 | checkbox=\u30C1\u30A7\u30C3\u30AF\u30FB\u30DC\u30C3\u30AF\u30B9 | ||
| 19 | colorchooser=\u30AB\u30E9\u30FC\u30FB\u30C1\u30E5\u30FC\u30B6 | ||
| 20 | columnheader=\u5217\u30D8\u30C3\u30C0\u30FC | ||
| 21 | combobox=\u30B3\u30F3\u30DC\u30FB\u30DC\u30C3\u30AF\u30B9 | ||
| 22 | canvas=\u30AD\u30E3\u30F3\u30D0\u30B9 | ||
| 23 | desktopicon=\u30C7\u30B9\u30AF\u30C8\u30C3\u30D7\u30FB\u30A2\u30A4\u30B3\u30F3 | ||
| 24 | desktoppane=\u30C7\u30B9\u30AF\u30C8\u30C3\u30D7\u533A\u753B | ||
| 25 | dialog=\u30C0\u30A4\u30A2\u30ED\u30B0 | ||
| 26 | directorypane=\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u533A\u753B | ||
| 27 | glasspane=\u30AC\u30E9\u30B9\u533A\u753B | ||
| 28 | filechooser=\u30D5\u30A1\u30A4\u30EB\u30FB\u30C1\u30E5\u30FC\u30B6 | ||
| 29 | filler=\u30D5\u30A3\u30E9\u30FC | ||
| 30 | frame=\u30D5\u30EC\u30FC\u30E0 | ||
| 31 | internalframe=\u5185\u90E8\u30D5\u30EC\u30FC\u30E0 | ||
| 32 | label=\u30E9\u30D9\u30EB | ||
| 33 | layeredpane=\u968E\u5C64\u5316\u3055\u308C\u305F\u533A\u753B | ||
| 34 | list=\u30EA\u30B9\u30C8 | ||
| 35 | listitem=\u30EA\u30B9\u30C8\u9805\u76EE | ||
| 36 | menubar=\u30E1\u30CB\u30E5\u30FC\u30FB\u30D0\u30FC | ||
| 37 | menu=\u30E1\u30CB\u30E5\u30FC | ||
| 38 | menuitem=\u30E1\u30CB\u30E5\u30FC\u9805\u76EE | ||
| 39 | optionpane=\u30AA\u30D7\u30B7\u30E7\u30F3\u533A\u753B | ||
| 40 | pagetab=\u30DA\u30FC\u30B8\u30FB\u30BF\u30D6 | ||
| 41 | pagetablist=\u30DA\u30FC\u30B8\u30FB\u30BF\u30D6\u30FB\u30EA\u30B9\u30C8 | ||
| 42 | panel=\u30D1\u30CD\u30EB | ||
| 43 | passwordtext=\u30D1\u30B9\u30EF\u30FC\u30C9\u30FB\u30C6\u30AD\u30B9\u30C8 | ||
| 44 | popupmenu=\u30DD\u30C3\u30D7\u30A2\u30C3\u30D7\u30FB\u30E1\u30CB\u30E5\u30FC | ||
| 45 | progressbar=\u9032\u6357\u30D0\u30FC | ||
| 46 | pushbutton=\u30D7\u30C3\u30B7\u30E5\u30FB\u30DC\u30BF\u30F3 | ||
| 47 | radiobutton=\u30E9\u30B8\u30AA\u30FB\u30DC\u30BF\u30F3 | ||
| 48 | rootpane=\u30EB\u30FC\u30C8\u533A\u753B | ||
| 49 | rowheader=\u884C\u30D8\u30C3\u30C0\u30FC | ||
| 50 | scrollbar=\u30B9\u30AF\u30ED\u30FC\u30EB\u30FB\u30D0\u30FC | ||
| 51 | scrollpane=\u30B9\u30AF\u30ED\u30FC\u30EB\u533A\u753B | ||
| 52 | separator=\u30BB\u30D1\u30EC\u30FC\u30BF | ||
| 53 | slider=\u30B9\u30E9\u30A4\u30C0 | ||
| 54 | splitpane=\u5206\u5272\u533A\u753B | ||
| 55 | swingcomponent=Swing\u30B3\u30F3\u30DD\u30FC\u30CD\u30F3\u30C8 | ||
| 56 | table=\u8868 | ||
| 57 | text=\u30C6\u30AD\u30B9\u30C8 | ||
| 58 | tree=\u30C4\u30EA\u30FC | ||
| 59 | togglebutton=\u30C8\u30B0\u30EB\u30FB\u30DC\u30BF\u30F3 | ||
| 60 | toolbar=\u30C4\u30FC\u30EB\u30D0\u30FC | ||
| 61 | tooltip=\u30C4\u30FC\u30EB\u30C1\u30C3\u30D7 | ||
| 62 | unknown=\u4E0D\u660E | ||
| 63 | viewport=\u30D3\u30E5\u30FC\u30DD\u30FC\u30C8 | ||
| 64 | window=\u30A6\u30A3\u30F3\u30C9\u30A6 | ||
| 65 | # | ||
| 66 | # accessible relations | ||
| 67 | # | ||
| 68 | labelFor=label for | ||
| 69 | labeledBy=labeled by | ||
| 70 | memberOf=member of | ||
| 71 | controlledBy=controlledBy | ||
| 72 | controllerFor=controllerFor | ||
| 73 | # | ||
| 74 | # accessible states | ||
| 75 | # | ||
| 76 | active=\u30A2\u30AF\u30C6\u30A3\u30D6 | ||
| 77 | armed=\u4F5C\u52D5\u6E96\u5099\u5B8C\u4E86 | ||
| 78 | busy=\u30D3\u30B8\u30FC | ||
| 79 | checked=\u30C1\u30A7\u30C3\u30AF | ||
| 80 | collapsed=\u77ED\u7E2E | ||
| 81 | editable=\u7DE8\u96C6\u53EF\u80FD | ||
| 82 | expandable=\u5C55\u958B\u53EF\u80FD | ||
| 83 | expanded=\u5C55\u958B | ||
| 84 | enabled=\u6709\u52B9 | ||
| 85 | focusable=\u30D5\u30A9\u30FC\u30AB\u30B9\u53EF\u80FD | ||
| 86 | focused=\u30D5\u30A9\u30FC\u30AB\u30B9 | ||
| 87 | iconified=\u30A2\u30A4\u30B3\u30F3\u5316 | ||
| 88 | modal=\u30E2\u30FC\u30C0\u30EB | ||
| 89 | multiline=\u8907\u6570\u884C | ||
| 90 | multiselectable=\u8907\u6570\u9078\u629E\u53EF\u80FD | ||
| 91 | opaque=\u4E0D\u900F\u660E | ||
| 92 | pressed=\u62BC\u4E0B | ||
| 93 | resizable=\u30B5\u30A4\u30BA\u5909\u66F4\u53EF\u80FD | ||
| 94 | selectable=\u9078\u629E\u53EF\u80FD | ||
| 95 | selected=\u9078\u629E | ||
| 96 | showing=\u8868\u793A | ||
| 97 | singleline=\u5358\u4E00\u884C | ||
| 98 | transient=\u4E00\u6642 | ||
| 99 | visible=\u53EF\u8996 | ||
| 100 | vertical=\u5782\u76F4 | ||
| 101 | horizontal=\u6C34\u5E73 | ||
| 102 | # | ||
| 103 | # accessible actions | ||
| 104 | # | ||
| 105 | toggle expand=\u30C8\u30B0\u30EB\u5C55\u958B | ||
| 106 | |||
| 107 | # new relations, roles and states for J2SE 1.5.0 | ||
| 108 | |||
| 109 | # | ||
| 110 | # accessible relations | ||
| 111 | # | ||
| 112 | flowsTo=flows to | ||
| 113 | flowsFrom=flows from | ||
| 114 | subwindowOf=subwindow of | ||
| 115 | parentWindowOf=parent window of | ||
| 116 | embeds=\u57CB\u8FBC\u307F | ||
| 117 | embeddedBy=embedded by | ||
| 118 | childNodeOf=child node of | ||
| 119 | |||
| 120 | # | ||
| 121 | # accessible roles | ||
| 122 | # | ||
| 123 | header=\u30D8\u30C3\u30C0\u30FC | ||
| 124 | footer=\u30D5\u30C3\u30BF\u30FC | ||
| 125 | paragraph=\u6BB5\u843D | ||
| 126 | ruler=\u30EB\u30FC\u30E9\u30FC | ||
| 127 | editbar=\u7DE8\u96C6\u30D0\u30FC | ||
| 128 | progressMonitor=\u9032\u6357\u30E2\u30CB\u30BF\u30FC | ||
| 129 | |||
| 130 | # | ||
| 131 | # accessible states | ||
| 132 | # | ||
| 133 | managesDescendants=\u5B50\u5B6B\u3092\u7BA1\u7406 | ||
| 134 | indeterminate=\u4E0D\u78BA\u5B9A | ||
| 135 | truncated=\u4E0D\u5B8C\u5168 | ||
| 136 | |||
| 137 | # new for J2SE 1.6.0 | ||
| 138 | |||
| 139 | # | ||
| 140 | # accessible roles | ||
| 141 | # | ||
| 142 | htmlcontainer=HTML\u30B3\u30F3\u30C6\u30CA | ||
| 143 | |||
| 144 | # | ||
| 145 | # END OF MATERIAL TO LOCALIZE | ||
| 146 | # | ||
| @@ -0,0 +1,146 @@ | |||
| 1 | # | ||
| 2 | # This properties file is used to create a PropertyResourceBundle | ||
| 3 | # It contains Locale specific strings used be the Accessibility package. | ||
| 4 | # | ||
| 5 | # When this file is read in, the strings are put into the | ||
| 6 | # defaults table. This is an implementation detail of the current | ||
| 7 | # workings of Accessibility. DO NOT DEPEND ON THIS. | ||
| 8 | # This may change in future versions of Accessibility as we improve | ||
| 9 | # localization support. | ||
| 10 | # | ||
| 11 | # @author Lynn Monsanto | ||
| 12 | |||
| 13 | # | ||
| 14 | # accessible roles | ||
| 15 | # | ||
| 16 | alert=\uACBD\uBCF4 | ||
| 17 | awtcomponent=AWT \uAD6C\uC131 \uC694\uC18C | ||
| 18 | checkbox=\uCCB4\uD06C \uBC15\uC2A4 | ||
| 19 | colorchooser=\uC0C9\uC0C1 \uC120\uD0DD\uAE30 | ||
| 20 | columnheader=\uC5F4 \uBA38\uB9AC\uAE00 | ||
| 21 | combobox=\uCF64\uBCF4 \uC0C1\uC790 | ||
| 22 | canvas=\uCE94\uBC84\uC2A4 | ||
| 23 | desktopicon=\uBC14\uD0D5 \uD654\uBA74 \uC544\uC774\uCF58 | ||
| 24 | desktoppane=\uBC14\uD0D5 \uD654\uBA74 \uCC3D | ||
| 25 | dialog=\uB300\uD654\uC0C1\uC790 | ||
| 26 | directorypane=\uB514\uB809\uD1A0\uB9AC \uCC3D | ||
| 27 | glasspane=\uAE00\uB798\uC2A4 \uCC3D | ||
| 28 | filechooser=\uD30C\uC77C \uC120\uD0DD\uAE30 | ||
| 29 | filler=\uD544\uB7EC | ||
| 30 | frame=\uD504\uB808\uC784 | ||
| 31 | internalframe=\uB0B4\uBD80 \uD504\uB808\uC784 | ||
| 32 | label=\uB808\uC774\uBE14 | ||
| 33 | layeredpane=\uACC4\uCE35\uC801 \uCC3D | ||
| 34 | list=\uBAA9\uB85D | ||
| 35 | listitem=\uBAA9\uB85D \uD56D\uBAA9 | ||
| 36 | menubar=\uBA54\uB274 \uD45C\uC2DC\uC904 | ||
| 37 | menu=\uBA54\uB274 | ||
| 38 | menuitem=\uBA54\uB274 \uD56D\uBAA9 | ||
| 39 | optionpane=\uC635\uC158 \uCC3D | ||
| 40 | pagetab=\uD398\uC774\uC9C0 \uD0ED | ||
| 41 | pagetablist=\uD398\uC774\uC9C0 \uD0ED \uBAA9\uB85D | ||
| 42 | panel=\uD328\uB110 | ||
| 43 | passwordtext=\uBE44\uBC00\uBC88\uD638 \uD14D\uC2A4\uD2B8 | ||
| 44 | popupmenu=\uD31D\uC5C5 \uBA54\uB274 | ||
| 45 | progressbar=\uC9C4\uD589 \uB9C9\uB300 | ||
| 46 | pushbutton=\uB204\uB984 \uB2E8\uCD94 | ||
| 47 | radiobutton=\uB77C\uB514\uC624 \uB2E8\uCD94 | ||
| 48 | rootpane=\uB8E8\uD2B8 \uCC3D | ||
| 49 | rowheader=\uD589 \uBA38\uB9AC\uAE00 | ||
| 50 | scrollbar=\uC2A4\uD06C\uB864 \uB9C9\uB300 | ||
| 51 | scrollpane=\uC2A4\uD06C\uB864 \uCC3D | ||
| 52 | separator=\uAD6C\uBD84 \uAE30\uD638 | ||
| 53 | slider=\uC2AC\uB77C\uC774\uB354 | ||
| 54 | splitpane=\uBD84\uD560 \uCC3D | ||
| 55 | swingcomponent=\uD68C\uC804 \uAD6C\uC131 \uC694\uC18C | ||
| 56 | table=\uD14C\uC774\uBE14 | ||
| 57 | text=\uD14D\uC2A4\uD2B8 | ||
| 58 | tree=\uD2B8\uB9AC | ||
| 59 | togglebutton=\uD1A0\uAE00 \uB2E8\uCD94 | ||
| 60 | toolbar=\uB3C4\uAD6C \uBAA8\uC74C | ||
| 61 | tooltip=\uB3C4\uAD6C \uC124\uBA85 | ||
| 62 | unknown=\uC54C \uC218 \uC5C6\uC74C | ||
| 63 | viewport=\uBDF0\uD3EC\uD2B8 | ||
| 64 | window=\uCC3D | ||
| 65 | # | ||
| 66 | # accessible relations | ||
| 67 | # | ||
| 68 | labelFor=\uB808\uC774\uBE14 \uB300\uC0C1 | ||
| 69 | labeledBy=\uB808\uC774\uBE14 \uC9C0\uC815\uC790 | ||
| 70 | memberOf=\uC18C\uC18D \uADF8\uB8F9 | ||
| 71 | controlledBy=controlledBy | ||
| 72 | controllerFor=controllerFor | ||
| 73 | # | ||
| 74 | # accessible states | ||
| 75 | # | ||
| 76 | active=\uD65C\uC131 | ||
| 77 | armed=\uD06C\uAE30 | ||
| 78 | busy=\uC0AC\uC6A9 \uC911 | ||
| 79 | checked=\uC120\uD0DD\uB428 | ||
| 80 | collapsed=\uCD95\uC18C\uB428 | ||
| 81 | editable=\uD3B8\uC9D1 \uAC00\uB2A5 | ||
| 82 | expandable=\uD655\uC7A5 \uAC00\uB2A5 | ||
| 83 | expanded=\uD655\uC7A5\uB428 | ||
| 84 | enabled=\uC0AC\uC6A9 | ||
| 85 | focusable=\uD3EC\uCEE4\uC2A4 \uAC00\uB2A5 | ||
| 86 | focused=\uD3EC\uCEE4\uC2A4\uB428 | ||
| 87 | iconified=\uC544\uC774\uCF58\uD654\uB428 | ||
| 88 | modal=\uBAA8\uB2EC | ||
| 89 | multiline=\uBCF5\uC218 \uD589 | ||
| 90 | multiselectable=\uB2E4\uC911 \uC120\uD0DD \uAC00\uB2A5 | ||
| 91 | opaque=\uBD88\uD22C\uBA85 | ||
| 92 | pressed=\uB204\uB984 | ||
| 93 | resizable=\uD06C\uAE30 \uC870\uC815 \uAC00\uB2A5 | ||
| 94 | selectable=\uC120\uD0DD \uAC00\uB2A5 | ||
| 95 | selected=\uC120\uD0DD\uB428 | ||
| 96 | showing=\uD45C\uC2DC | ||
| 97 | singleline=\uD55C \uC904 | ||
| 98 | transient=\uC77C\uC2DC | ||
| 99 | visible=\uD45C\uC2DC \uAC00\uB2A5 | ||
| 100 | vertical=\uC138\uB85C | ||
| 101 | horizontal=\uAC00\uB85C | ||
| 102 | # | ||
| 103 | # accessible actions | ||
| 104 | # | ||
| 105 | toggle \uD655\uC7A5=\uD1A0\uAE00 \uD655\uC7A5 | ||
| 106 | |||
| 107 | # new relations, roles and states for J2SE 1.5.0 | ||
| 108 | |||
| 109 | # | ||
| 110 | # accessible relations | ||
| 111 | # | ||
| 112 | flowsTo=\uD750\uB984 \uB300\uC0C1 | ||
| 113 | flowsFrom=\uD750\uB984 \uCD9C\uCC98 | ||
| 114 | subwindowOf=\uD558\uC704 \uCC3D | ||
| 115 | parentWindowOf=\uC0C1\uC704 \uCC3D | ||
| 116 | embeds=\uD3EC\uD568 | ||
| 117 | embeddedBy=\uD3EC\uD568 \uC8FC\uCCB4 | ||
| 118 | childNodeOf=\uD558\uC704 \uB178\uB4DC | ||
| 119 | |||
| 120 | # | ||
| 121 | # accessible roles | ||
| 122 | # | ||
| 123 | header=\uBA38\uB9AC\uAE00 | ||
| 124 | footer=\uBC14\uB2E5\uAE00 | ||
| 125 | paragraph=\uB2E8\uB77D | ||
| 126 | ruler=\uB208\uAE08\uC790 | ||
| 127 | editbar=\uD3B8\uC9D1 \uB3C4\uAD6C | ||
| 128 | progressMonitor=\uC9C4\uD589 \uBAA8\uB2C8\uD130 | ||
| 129 | |||
| 130 | # | ||
| 131 | # accessible states | ||
| 132 | # | ||
| 133 | managesDescendants=\uC885\uC18D \uD56D\uBAA9 \uAD00\uB9AC | ||
| 134 | indeterminate=\uD655\uC815\uB418\uC9C0 \uC54A\uC74C | ||
| 135 | truncated=\uC798\uB9BC | ||
| 136 | |||
| 137 | # new for J2SE 1.6.0 | ||
| 138 | |||
| 139 | # | ||
| 140 | # accessible roles | ||
| 141 | # | ||
| 142 | htmlcontainer=HTML \uCEE8\uD14C\uC774\uB108 | ||
| 143 | |||
| 144 | # | ||
| 145 | # END OF MATERIAL TO LOCALIZE | ||
| 146 | # | ||
| @@ -0,0 +1,146 @@ | |||
| 1 | # | ||
| 2 | # This properties file is used to create a PropertyResourceBundle | ||
| 3 | # It contains Locale specific strings used be the Accessibility package. | ||
| 4 | # | ||
| 5 | # When this file is read in, the strings are put into the | ||
| 6 | # defaults table. This is an implementation detail of the current | ||
| 7 | # workings of Accessibility. DO NOT DEPEND ON THIS. | ||
| 8 | # This may change in future versions of Accessibility as we improve | ||
| 9 | # localization support. | ||
| 10 | # | ||
| 11 | # @author Lynn Monsanto | ||
| 12 | |||
| 13 | # | ||
| 14 | # accessible roles | ||
| 15 | # | ||
| 16 | alert=alerta | ||
| 17 | awtcomponent=componente AWT | ||
| 18 | checkbox=caixa de sele\u00E7\u00E3o | ||
| 19 | colorchooser=seletor de cores | ||
| 20 | columnheader=cabe\u00E7alho da coluna | ||
| 21 | combobox=caixa de combina\u00E7\u00E3o | ||
| 22 | canvas=tela | ||
| 23 | desktopicon=\u00EDcone da \u00E1rea de trabalho | ||
| 24 | desktoppane=painel da \u00E1rea de trabalho | ||
| 25 | dialog=caixa de di\u00E1logo | ||
| 26 | directorypane=painel do diret\u00F3rio | ||
| 27 | glasspane=painel transparente | ||
| 28 | filechooser=seletor de arquivos | ||
| 29 | filler=preenchedor | ||
| 30 | frame=quadro | ||
| 31 | internalframe=quadro interno | ||
| 32 | label=r\u00F3tulo | ||
| 33 | layeredpane=painel em camadas | ||
| 34 | list=lista | ||
| 35 | listitem=item da lista | ||
| 36 | menubar=barra de menus | ||
| 37 | menu=menu | ||
| 38 | menuitem=item do menu | ||
| 39 | optionpane=painel de op\u00E7\u00F5es | ||
| 40 | pagetab=guia da p\u00E1gina | ||
| 41 | pagetablist=lista de guias da p\u00E1gina | ||
| 42 | panel=painel | ||
| 43 | passwordtext=texto da senha | ||
| 44 | popupmenu=menu pop-up | ||
| 45 | progressbar=barra de progresso | ||
| 46 | pushbutton=bot\u00E3o de a\u00E7\u00E3o | ||
| 47 | radiobutton=bot\u00E3o de op\u00E7\u00E3o | ||
| 48 | rootpane=painel base | ||
| 49 | rowheader=cabe\u00E7alho da linha | ||
| 50 | scrollbar=barra de rolagem | ||
| 51 | scrollpane=painel de rolagem | ||
| 52 | separator=separador | ||
| 53 | slider=controle deslizante | ||
| 54 | splitpane=painel dividido | ||
| 55 | swingcomponent=componente swing | ||
| 56 | table=tabela | ||
| 57 | text=texto | ||
| 58 | tree=\u00E1rvore | ||
| 59 | togglebutton=bot\u00E3o de altern\u00E2ncia | ||
| 60 | toolbar=barra de ferramentas | ||
| 61 | tooltip=dica de ferramenta | ||
| 62 | unknown=desconhecido | ||
| 63 | viewport=janela de visualiza\u00E7\u00E3o | ||
| 64 | window=janela | ||
| 65 | # | ||
| 66 | # accessible relations | ||
| 67 | # | ||
| 68 | labelFor=r\u00F3tulo de | ||
| 69 | labeledBy=rotulado por | ||
| 70 | memberOf=membro de | ||
| 71 | controlledBy=controlledBy | ||
| 72 | controllerFor=controllerFor | ||
| 73 | # | ||
| 74 | # accessible states | ||
| 75 | # | ||
| 76 | active=ativo | ||
| 77 | armed=armado | ||
| 78 | busy=ocupado | ||
| 79 | checked=selecionado | ||
| 80 | collapsed=recolhido | ||
| 81 | editable=edit\u00E1vel | ||
| 82 | expandable=expans\u00EDvel | ||
| 83 | expanded=expandido | ||
| 84 | enabled=ativado | ||
| 85 | focusable=focaliz\u00E1vel | ||
| 86 | focused=focalizado | ||
| 87 | iconified=iconizado | ||
| 88 | modal=modal | ||
| 89 | multiline=v\u00E1rias linhas | ||
| 90 | multiselectable=m\u00FAltipla escolha | ||
| 91 | opaque=opaco | ||
| 92 | pressed=pressionado | ||
| 93 | resizable=redimension\u00E1vel | ||
| 94 | selectable=selecion\u00E1vel | ||
| 95 | selected=selecionado | ||
| 96 | showing=mostrando | ||
| 97 | singleline=linha \u00FAnica | ||
| 98 | transient=transit\u00F3rio | ||
| 99 | visible=vis\u00EDvel | ||
| 100 | vertical=vertical | ||
| 101 | horizontal=horizontal | ||
| 102 | # | ||
| 103 | # accessible actions | ||
| 104 | # | ||
| 105 | toggle expandir=alternar expans\u00E3o | ||
| 106 | |||
| 107 | # new relations, roles and states for J2SE 1.5.0 | ||
| 108 | |||
| 109 | # | ||
| 110 | # accessible relations | ||
| 111 | # | ||
| 112 | flowsTo=fluxos para | ||
| 113 | flowsFrom=fluxos de | ||
| 114 | subwindowOf=subjanela de | ||
| 115 | parentWindowOf=janela pai de | ||
| 116 | embeds=integra | ||
| 117 | embeddedBy=integrado por | ||
| 118 | childNodeOf=n\u00F3 filho de | ||
| 119 | |||
| 120 | # | ||
| 121 | # accessible roles | ||
| 122 | # | ||
| 123 | header=cabe\u00E7alho | ||
| 124 | footer=rodap\u00E9 | ||
| 125 | paragraph=par\u00E1grafo | ||
| 126 | ruler=r\u00E9gua | ||
| 127 | editbar=barra de edi\u00E7\u00E3o | ||
| 128 | progressMonitor=monitor de progresso | ||
| 129 | |||
| 130 | # | ||
| 131 | # accessible states | ||
| 132 | # | ||
| 133 | managesDescendants=gerencia descendentes | ||
| 134 | indeterminate=indeterminado | ||
| 135 | truncated=truncado | ||
| 136 | |||
| 137 | # new for J2SE 1.6.0 | ||
| 138 | |||
| 139 | # | ||
| 140 | # accessible roles | ||
| 141 | # | ||
| 142 | htmlcontainer=Container de HTML | ||
| 143 | |||
| 144 | # | ||
| 145 | # END OF MATERIAL TO LOCALIZE | ||
| 146 | # | ||
| @@ -0,0 +1,146 @@ | |||
| 1 | # | ||
| 2 | # This properties file is used to create a PropertyResourceBundle | ||
| 3 | # It contains Locale specific strings used be the Accessibility package. | ||
| 4 | # | ||
| 5 | # When this file is read in, the strings are put into the | ||
| 6 | # defaults table. This is an implementation detail of the current | ||
| 7 | # workings of Accessibility. DO NOT DEPEND ON THIS. | ||
| 8 | # This may change in future versions of Accessibility as we improve | ||
| 9 | # localization support. | ||
| 10 | # | ||
| 11 | # @author Lynn Monsanto | ||
| 12 | |||
| 13 | # | ||
| 14 | # accessible roles | ||
| 15 | # | ||
| 16 | alert=avisering | ||
| 17 | awtcomponent=AWT-komponent | ||
| 18 | checkbox=kryssruta | ||
| 19 | colorchooser=f\u00E4rgv\u00E4ljare | ||
| 20 | columnheader=kolumnrubrik | ||
| 21 | combobox=kombinationsruta | ||
| 22 | canvas=rityta | ||
| 23 | desktopicon=skrivbordsikon | ||
| 24 | desktoppane=skrivbordsruta | ||
| 25 | dialog=dialogruta | ||
| 26 | directorypane=katalogruta | ||
| 27 | glasspane=glasruta | ||
| 28 | filechooser=filv\u00E4ljare | ||
| 29 | filler=utfyllnad | ||
| 30 | frame=ram | ||
| 31 | internalframe=intern ram | ||
| 32 | label=etikett | ||
| 33 | layeredpane=staplad ruta | ||
| 34 | list=lista | ||
| 35 | listitem=listobjekt | ||
| 36 | menubar=menyrad | ||
| 37 | menu=meny | ||
| 38 | menuitem=menyalternativ | ||
| 39 | optionpane=alternativruta | ||
| 40 | pagetab=sidflik | ||
| 41 | pagetablist=sidflikslista | ||
| 42 | panel=panel | ||
| 43 | passwordtext=l\u00F6senordstext | ||
| 44 | popupmenu=snabbmeny | ||
| 45 | progressbar=statusrad | ||
| 46 | pushbutton=knapp | ||
| 47 | radiobutton=alternativknapp | ||
| 48 | rootpane=grundruta | ||
| 49 | rowheader=radrubrik | ||
| 50 | scrollbar=rullningslist | ||
| 51 | scrollpane=rullningsruta | ||
| 52 | separator=avskiljare | ||
| 53 | slider=skjutreglage | ||
| 54 | splitpane=delad ruta | ||
| 55 | swingcomponent=swing-komponent | ||
| 56 | table=tabell | ||
| 57 | text=text | ||
| 58 | tree=tr\u00E4d | ||
| 59 | togglebutton=v\u00E4xlingsknapp | ||
| 60 | toolbar=verktygsrad | ||
| 61 | tooltip=knappbeskrivning | ||
| 62 | unknown=ok\u00E4nd | ||
| 63 | viewport=vyport | ||
| 64 | window=f\u00F6nster | ||
| 65 | # | ||
| 66 | # accessible relations | ||
| 67 | # | ||
| 68 | labelFor=etikett f\u00F6r | ||
| 69 | labeledBy=etikett av | ||
| 70 | memberOf=medlem i | ||
| 71 | controlledBy=controlledBy | ||
| 72 | controllerFor=controllerFor | ||
| 73 | # | ||
| 74 | # accessible states | ||
| 75 | # | ||
| 76 | active=aktiv | ||
| 77 | armed=redo | ||
| 78 | busy=upptagen | ||
| 79 | checked=markerad | ||
| 80 | collapsed=komprimerad | ||
| 81 | editable=redigerbar | ||
| 82 | expandable=ut\u00F6kningsbar | ||
| 83 | expanded=ut\u00F6kad | ||
| 84 | enabled=aktiverad | ||
| 85 | focusable=fokuseringsbar | ||
| 86 | focused=fokuserad | ||
| 87 | iconified=minimerad | ||
| 88 | modal=modal | ||
| 89 | multiline=flera rader | ||
| 90 | multiselectable=flerval | ||
| 91 | opaque=t\u00E4ckande | ||
| 92 | pressed=nedtryckt | ||
| 93 | resizable=storleks\u00E4ndringsbar | ||
| 94 | selectable=valbar | ||
| 95 | selected=vald | ||
| 96 | showing=visas | ||
| 97 | singleline=en rad | ||
| 98 | transient=tillf\u00E4llig | ||
| 99 | visible=synlig | ||
| 100 | vertical=vertikal | ||
| 101 | horizontal=horisontell | ||
| 102 | # | ||
| 103 | # accessible actions | ||
| 104 | # | ||
| 105 | toggle ut\u00F6ka=v\u00E4xla ut\u00F6ka | ||
| 106 | |||
| 107 | # new relations, roles and states for J2SE 1.5.0 | ||
| 108 | |||
| 109 | # | ||
| 110 | # accessible relations | ||
| 111 | # | ||
| 112 | flowsTo=fl\u00F6dar till | ||
| 113 | flowsFrom=fl\u00F6dar fr\u00E5n | ||
| 114 | subwindowOf=delf\u00F6nster av | ||
| 115 | parentWindowOf=\u00F6verordnat f\u00F6nster f\u00F6r | ||
| 116 | embeds=b\u00E4ddar in | ||
| 117 | embeddedBy=b\u00E4ddas in av | ||
| 118 | childNodeOf=underordnad nod f\u00F6r | ||
| 119 | |||
| 120 | # | ||
| 121 | # accessible roles | ||
| 122 | # | ||
| 123 | header=sidhuvud | ||
| 124 | footer=sidfot | ||
| 125 | paragraph=stycke | ||
| 126 | ruler=linjal | ||
| 127 | editbar=redigeringslist | ||
| 128 | progressMonitor=f\u00F6rlopps\u00F6vervakare | ||
| 129 | |||
| 130 | # | ||
| 131 | # accessible states | ||
| 132 | # | ||
| 133 | managesDescendants=hanterar underordnade | ||
| 134 | indeterminate=obest\u00E4mt | ||
| 135 | truncated=kapad | ||
| 136 | |||
| 137 | # new for J2SE 1.6.0 | ||
| 138 | |||
| 139 | # | ||
| 140 | # accessible roles | ||
| 141 | # | ||
| 142 | htmlcontainer=HTML-container | ||
| 143 | |||
| 144 | # | ||
| 145 | # END OF MATERIAL TO LOCALIZE | ||
| 146 | # | ||
| @@ -0,0 +1,146 @@ | |||
| 1 | # | ||
| 2 | # This properties file is used to create a PropertyResourceBundle | ||
| 3 | # It contains Locale specific strings used be the Accessibility package. | ||
| 4 | # | ||
| 5 | # When this file is read in, the strings are put into the | ||
| 6 | # defaults table. This is an implementation detail of the current | ||
| 7 | # workings of Accessibility. DO NOT DEPEND ON THIS. | ||
| 8 | # This may change in future versions of Accessibility as we improve | ||
| 9 | # localization support. | ||
| 10 | # | ||
| 11 | # @author Lynn Monsanto | ||
| 12 | |||
| 13 | # | ||
| 14 | # accessible roles | ||
| 15 | # | ||
| 16 | alert=\u9884\u8B66 | ||
| 17 | awtcomponent=AWT \u7EC4\u4EF6 | ||
| 18 | checkbox=\u590D\u9009\u6846 | ||
| 19 | colorchooser=\u989C\u8272\u9009\u62E9\u5668 | ||
| 20 | columnheader=\u5217\u6807\u9898 | ||
| 21 | combobox=\u7EC4\u5408\u6846 | ||
| 22 | canvas=\u753B\u5E03 | ||
| 23 | desktopicon=\u684C\u9762\u56FE\u6807 | ||
| 24 | desktoppane=\u684C\u9762\u7A97\u683C | ||
| 25 | dialog=\u5BF9\u8BDD | ||
| 26 | directorypane=\u76EE\u5F55\u7A97\u683C | ||
| 27 | glasspane=\u73BB\u7483\u7A97\u683C | ||
| 28 | filechooser=\u6587\u4EF6\u9009\u62E9\u5668 | ||
| 29 | filler=\u6F0F\u6597 | ||
| 30 | frame=\u5E27 | ||
| 31 | internalframe=\u5185\u90E8\u5E27 | ||
| 32 | label=\u6807\u7B7E | ||
| 33 | layeredpane=\u5206\u5C42\u7A97\u683C | ||
| 34 | list=\u5217\u8868 | ||
| 35 | listitem=\u5217\u8868\u9879 | ||
| 36 | menubar=\u83DC\u5355\u680F | ||
| 37 | menu=\u83DC\u5355 | ||
| 38 | menuitem=\u83DC\u5355\u9879 | ||
| 39 | optionpane=\u9009\u9879\u7A97\u683C | ||
| 40 | pagetab=\u9875\u6807\u7B7E | ||
| 41 | pagetablist=\u9875\u6807\u7B7E\u5217\u8868 | ||
| 42 | panel=\u9762\u677F | ||
| 43 | passwordtext=\u53E3\u4EE4\u6587\u672C | ||
| 44 | popupmenu=\u5F39\u51FA\u5F0F\u83DC\u5355 | ||
| 45 | progressbar=\u8FDB\u5EA6\u680F | ||
| 46 | pushbutton=\u6309\u94AE | ||
| 47 | radiobutton=\u5355\u9009\u6309\u94AE | ||
| 48 | rootpane=\u6839\u7A97\u683C | ||
| 49 | rowheader=\u884C\u6807\u9898 | ||
| 50 | scrollbar=\u6EDA\u52A8\u6761 | ||
| 51 | scrollpane=\u6EDA\u52A8\u7A97\u683C | ||
| 52 | separator=\u5206\u9694\u6761 | ||
| 53 | slider=\u6ED1\u5757 | ||
| 54 | splitpane=\u62C6\u5206\u7A97\u683C | ||
| 55 | swingcomponent=\u65CB\u8F6C\u7EC4\u4EF6 | ||
| 56 | table=\u8868 | ||
| 57 | text=\u6587\u672C | ||
| 58 | tree=\u6811 | ||
| 59 | togglebutton=\u5207\u6362\u6309\u94AE | ||
| 60 | toolbar=\u5DE5\u5177\u680F | ||
| 61 | tooltip=\u5DE5\u5177\u63D0\u793A | ||
| 62 | unknown=\u672A\u77E5 | ||
| 63 | viewport=\u89C6\u7A97 | ||
| 64 | window=\u7A97\u53E3 | ||
| 65 | # | ||
| 66 | # accessible relations | ||
| 67 | # | ||
| 68 | labelFor=\u6807\u7B7E\u5C5E\u4E8E | ||
| 69 | labeledBy=\u6807\u7B7E\u5236\u4F5C\u8005 | ||
| 70 | memberOf=\u5C5E\u4E8E | ||
| 71 | controlledBy=controlledBy | ||
| 72 | controllerFor=controllerFor | ||
| 73 | # | ||
| 74 | # accessible states | ||
| 75 | # | ||
| 76 | active=\u6D3B\u52A8 | ||
| 77 | armed=\u5F85\u547D | ||
| 78 | busy=\u5FD9 | ||
| 79 | checked=\u5DF2\u9009\u4E2D | ||
| 80 | collapsed=\u5DF2\u6536\u7F29 | ||
| 81 | editable=\u53EF\u7F16\u8F91 | ||
| 82 | expandable=\u53EF\u5C55\u5F00 | ||
| 83 | expanded=\u5DF2\u5C55\u5F00 | ||
| 84 | enabled=\u542F\u7528 | ||
| 85 | focusable=\u53EF\u96C6\u4E2D | ||
| 86 | focused=\u5DF2\u96C6\u4E2D | ||
| 87 | iconified=\u56FE\u6807\u5F0F | ||
| 88 | modal=\u6A21\u6001 | ||
| 89 | multiline=\u591A\u884C | ||
| 90 | multiselectable=\u591A\u9009\u62E9 | ||
| 91 | opaque=\u4E0D\u900F\u660E | ||
| 92 | pressed=\u5DF2\u6309\u4E0B | ||
| 93 | resizable=\u53EF\u8C03\u6574\u5927\u5C0F | ||
| 94 | selectable=\u53EF\u9009\u62E9 | ||
| 95 | selected=\u6240\u9009 | ||
| 96 | showing=\u6B63\u5728\u663E\u793A | ||
| 97 | singleline=\u5355\u884C | ||
| 98 | transient=\u77AC\u65F6 | ||
| 99 | visible=\u53EF\u89C1 | ||
| 100 | vertical=\u5782\u76F4 | ||
| 101 | horizontal=\u6C34\u5E73 | ||
| 102 | # | ||
| 103 | # accessible actions | ||
| 104 | # | ||
| 105 | toggle expand=\u5207\u6362\u5C55\u5F00 | ||
| 106 | |||
| 107 | # new relations, roles and states for J2SE 1.5.0 | ||
| 108 | |||
| 109 | # | ||
| 110 | # accessible relations | ||
| 111 | # | ||
| 112 | flowsTo=\u6D41\u5411 | ||
| 113 | flowsFrom=\u6D41\u81EA | ||
| 114 | subwindowOf=\u5B50\u7A97\u53E3 | ||
| 115 | parentWindowOf=\u7236\u7A97\u53E3 | ||
| 116 | embeds=\u5D4C\u5165\u9879 | ||
| 117 | embeddedBy=\u5D4C\u5165\u8005 | ||
| 118 | childNodeOf=\u5B50\u8282\u70B9 | ||
| 119 | |||
| 120 | # | ||
| 121 | # accessible roles | ||
| 122 | # | ||
| 123 | header=\u9875\u7709 | ||
| 124 | footer=\u9875\u811A | ||
| 125 | paragraph=\u6BB5\u843D | ||
| 126 | ruler=\u6807\u5C3A | ||
| 127 | editbar=\u7F16\u8F91\u680F | ||
| 128 | progressMonitor=\u8FDB\u5EA6\u76D1\u89C6\u5668 | ||
| 129 | |||
| 130 | # | ||
| 131 | # accessible states | ||
| 132 | # | ||
| 133 | managesDescendants=\u7BA1\u7406\u5B50\u9879 | ||
| 134 | indeterminate=\u4E0D\u786E\u5B9A | ||
| 135 | truncated=\u5DF2\u622A\u65AD | ||
| 136 | |||
| 137 | # new for J2SE 1.6.0 | ||
| 138 | |||
| 139 | # | ||
| 140 | # accessible roles | ||
| 141 | # | ||
| 142 | htmlcontainer=HTML \u5BB9\u5668 | ||
| 143 | |||
| 144 | # | ||
| 145 | # END OF MATERIAL TO LOCALIZE | ||
| 146 | # | ||
| @@ -0,0 +1,146 @@ | |||
| 1 | # | ||
| 2 | # This properties file is used to create a PropertyResourceBundle | ||
| 3 | # It contains Locale specific strings used be the Accessibility package. | ||
| 4 | # | ||
| 5 | # When this file is read in, the strings are put into the | ||
| 6 | # defaults table. This is an implementation detail of the current | ||
| 7 | # workings of Accessibility. DO NOT DEPEND ON THIS. | ||
| 8 | # This may change in future versions of Accessibility as we improve | ||
| 9 | # localization support. | ||
| 10 | # | ||
| 11 | # @author Lynn Monsanto | ||
| 12 | |||
| 13 | # | ||
| 14 | # accessible roles | ||
| 15 | # | ||
| 16 | alert=\u8B66\u793A | ||
| 17 | awtcomponent=AWT \u5143\u4EF6 | ||
| 18 | checkbox=\u6838\u53D6\u65B9\u584A | ||
| 19 | colorchooser=\u8272\u5F69\u9078\u64C7\u5668 | ||
| 20 | columnheader=\u76F4\u6B04\u6A19\u984C | ||
| 21 | combobox=\u4E0B\u62C9\u5F0F\u6E05\u55AE\u65B9\u584A | ||
| 22 | canvas=\u756B\u5E03 | ||
| 23 | desktopicon=\u684C\u9762\u5716\u793A | ||
| 24 | desktoppane=\u684C\u9762\u7A97\u683C | ||
| 25 | dialog=\u5C0D\u8A71\u65B9\u584A | ||
| 26 | directorypane=\u76EE\u9304\u7A97\u683C | ||
| 27 | glasspane=\u6AA2\u8996\u7A97\u683C | ||
| 28 | filechooser=\u6A94\u6848\u9078\u64C7\u5668 | ||
| 29 | filler=\u586B\u5145\u7269 | ||
| 30 | frame=\u6846\u67B6 | ||
| 31 | internalframe=\u5167\u90E8\u6846\u67B6 | ||
| 32 | label=\u6A19\u7C64 | ||
| 33 | layeredpane=\u5206\u5C64\u7A97\u683C | ||
| 34 | list=\u6E05\u55AE | ||
| 35 | listitem=\u6E05\u55AE\u9805\u76EE | ||
| 36 | menubar=\u529F\u80FD\u8868\u5217 | ||
| 37 | menu=\u529F\u80FD\u8868 | ||
| 38 | menuitem=\u529F\u80FD\u8868\u9805\u76EE | ||
| 39 | optionpane=\u9078\u9805\u7A97\u683C | ||
| 40 | pagetab=\u9801\u9762\u9801\u7C64 | ||
| 41 | pagetablist=\u9801\u9762\u9801\u7C64\u6E05\u55AE | ||
| 42 | panel=\u9762\u677F | ||
| 43 | passwordtext=\u5BC6\u78BC\u6587\u5B57 | ||
| 44 | popupmenu=\u5373\u73FE\u5F0F\u529F\u80FD\u8868 | ||
| 45 | progressbar=\u9032\u5EA6\u5217 | ||
| 46 | pushbutton=\u4E0B\u58D3\u6309\u9215 | ||
| 47 | radiobutton=\u55AE\u9078\u9215 | ||
| 48 | rootpane=root \u7A97\u683C | ||
| 49 | rowheader=\u5217\u6A19\u984C | ||
| 50 | scrollbar=\u6372\u8EF8 | ||
| 51 | scrollpane=\u6372\u52D5\u7A97\u683C | ||
| 52 | separator=\u5206\u9694\u5143 | ||
| 53 | slider=\u6ED1\u52D5\u8EF8 | ||
| 54 | splitpane=\u5206\u5272\u7A97\u683C | ||
| 55 | swingcomponent=Swing \u5143\u4EF6 | ||
| 56 | table=\u8868\u683C | ||
| 57 | text=\u6587\u5B57 | ||
| 58 | tree=\u6A39\u72C0\u7D50\u69CB | ||
| 59 | togglebutton=\u5207\u63DB\u6309\u9215 | ||
| 60 | toolbar=\u5DE5\u5177\u5217 | ||
| 61 | tooltip=\u5DE5\u5177\u63D0\u793A | ||
| 62 | unknown=\u4E0D\u660E\u7684 | ||
| 63 | viewport=\u6AA2\u8996\u5340 | ||
| 64 | window=\u8996\u7A97 | ||
| 65 | # | ||
| 66 | # accessible relations | ||
| 67 | # | ||
| 68 | labelFor=\u6A19\u793A\u5C0D\u8C61 | ||
| 69 | labeledBy=\u6A19\u793A\u8005 | ||
| 70 | memberOf=\u6240\u5C6C\u6210\u54E1 | ||
| 71 | controlledBy=\u63A7\u5236\u8005 | ||
| 72 | controllerFor=\u63A7\u5236\u5C0D\u8C61 | ||
| 73 | # | ||
| 74 | # accessible states | ||
| 75 | # | ||
| 76 | active=\u4F5C\u7528\u4E2D | ||
| 77 | armed=\u5DF2\u914D\u5099 | ||
| 78 | busy=\u5FD9\u788C\u4E2D | ||
| 79 | checked=\u5DF2\u6838\u9078 | ||
| 80 | collapsed=\u5DF2\u6536\u7E2E | ||
| 81 | editable=\u53EF\u7DE8\u8F2F | ||
| 82 | expandable=\u53EF\u64F4\u5C55 | ||
| 83 | expanded=\u5DF2\u64F4\u5C55 | ||
| 84 | enabled=\u5DF2\u555F\u7528 | ||
| 85 | focusable=\u53EF\u805A\u7126 | ||
| 86 | focused=\u5DF2\u805A\u7126 | ||
| 87 | iconified=\u5DF2\u5716\u793A\u5316 | ||
| 88 | modal=\u6A21\u614B | ||
| 89 | multiline=\u591A\u884C | ||
| 90 | multiselectable=\u53EF\u591A\u91CD\u9078\u53D6 | ||
| 91 | opaque=\u4E0D\u900F\u660E | ||
| 92 | pressed=\u5DF2\u6309\u4E0B | ||
| 93 | resizable=\u53EF\u8ABF\u6574\u5927\u5C0F | ||
| 94 | selectable=\u53EF\u9078\u53D6 | ||
| 95 | selected=\u5DF2\u9078\u53D6 | ||
| 96 | showing=\u986F\u793A | ||
| 97 | singleline=\u55AE\u884C | ||
| 98 | transient=\u66AB\u6642\u7684 | ||
| 99 | visible=\u53EF\u898B\u7684 | ||
| 100 | vertical=\u5782\u76F4 | ||
| 101 | horizontal=\u6C34\u5E73 | ||
| 102 | # | ||
| 103 | # accessible actions | ||
| 104 | # | ||
| 105 | toggle expand=\u5207\u63DB\u64F4\u5C55 | ||
| 106 | |||
| 107 | # new relations, roles and states for J2SE 1.5.0 | ||
| 108 | |||
| 109 | # | ||
| 110 | # accessible relations | ||
| 111 | # | ||
| 112 | flowsTo=\u6D41\u52D5\u81F3 | ||
| 113 | flowsFrom=\u6D41\u52D5\u81EA | ||
| 114 | subwindowOf=\u5B50\u8996\u7A97 | ||
| 115 | parentWindowOf=\u7236\u7CFB\u8996\u7A97 | ||
| 116 | embeds=\u5167\u5D4C | ||
| 117 | embeddedBy=\u5167\u5D4C\u8005 | ||
| 118 | childNodeOf=\u5B50\u7BC0\u9EDE | ||
| 119 | |||
| 120 | # | ||
| 121 | # accessible roles | ||
| 122 | # | ||
| 123 | header=\u9801\u9996 | ||
| 124 | footer=\u9801\u5C3E | ||
| 125 | paragraph=\u6BB5\u843D | ||
| 126 | ruler=\u5C3A\u898F | ||
| 127 | editbar=\u7DE8\u8F2F\u5217 | ||
| 128 | progressMonitor=\u9032\u5EA6\u76E3\u8996\u5668 | ||
| 129 | |||
| 130 | # | ||
| 131 | # accessible states | ||
| 132 | # | ||
| 133 | managesDescendants=\u7BA1\u7406\u5B50\u4EE3 | ||
| 134 | indeterminate=\u4E0D\u78BA\u5B9A | ||
| 135 | truncated=\u5DF2\u622A\u65B7 | ||
| 136 | |||
| 137 | # new for J2SE 1.6.0 | ||
| 138 | |||
| 139 | # | ||
| 140 | # accessible roles | ||
| 141 | # | ||
| 142 | htmlcontainer=HTML \u5BB9\u5668 | ||
| 143 | |||
| 144 | # | ||
| 145 | # END OF MATERIAL TO LOCALIZE | ||
| 146 | # | ||
| @@ -0,0 +1,2 @@ | |||
| 1 | <../../../../../../../mkconfig | ||
| 2 | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | <../../../../../mkconfig | ||
| 2 | |||
| 3 | DIRS=\ | ||
| 4 | internal\ | ||
| 5 | |||
| 6 | <$ROOT/mkfiles/mksubdirs | ||
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,462 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.awt; | ||
| 27 | |||
| 28 | import java.awt.*; | ||
| 29 | |||
| 30 | import sun.awt.AWTAccessor; | ||
| 31 | import sun.awt.SunToolkit; | ||
| 32 | |||
| 33 | /** | ||
| 34 | * A collection of utility methods for AWT. | ||
| 35 | * | ||
| 36 | * The functionality provided by the static methods of the class includes: | ||
| 37 | * <ul> | ||
| 38 | * <li>Setting shapes on top-level windows | ||
| 39 | * <li>Setting a constant alpha value for each pixel of a top-level window | ||
| 40 | * <li>Making a window non-opaque, after that it paints only explicitly | ||
| 41 | * painted pixels on the screen, with arbitrary alpha values for every pixel. | ||
| 42 | * <li>Setting a 'mixing-cutout' shape for a component. | ||
| 43 | * </ul> | ||
| 44 | * <p> | ||
| 45 | * A "top-level window" is an instance of the {@code Window} class (or its | ||
| 46 | * descendant, such as {@code JFrame}). | ||
| 47 | * <p> | ||
| 48 | * Some of the mentioned features may not be supported by the native platform. | ||
| 49 | * To determine whether a particular feature is supported, the user must use | ||
| 50 | * the {@code isTranslucencySupported()} method of the class passing a desired | ||
| 51 | * translucency kind (a member of the {@code Translucency} enum) as an | ||
| 52 | * argument. | ||
| 53 | * <p> | ||
| 54 | * The per-pixel alpha feature also requires the user to create her/his | ||
| 55 | * windows using a translucency-capable graphics configuration. | ||
| 56 | * The {@code isTranslucencyCapable()} method must | ||
| 57 | * be used to verify whether any given GraphicsConfiguration supports | ||
| 58 | * the trasnlcency effects. | ||
| 59 | * <p> | ||
| 60 | * <b>WARNING</b>: This class is an implementation detail and only meant | ||
| 61 | * for limited use outside of the core platform. This API may change | ||
| 62 | * drastically between update release, and it may even be | ||
| 63 | * removed or be moved in some other package(s)/class(es). | ||
| 64 | */ | ||
| 65 | public final class AWTUtilities { | ||
| 66 | |||
| 67 | /** | ||
| 68 | * The AWTUtilities class should not be instantiated | ||
| 69 | */ | ||
| 70 | private AWTUtilities() { | ||
| 71 | } | ||
| 72 | |||
| 73 | /** Kinds of translucency supported by the underlying system. | ||
| 74 | * @see #isTranslucencySupported | ||
| 75 | */ | ||
| 76 | public static enum Translucency { | ||
| 77 | /** | ||
| 78 | * Represents support in the underlying system for windows each pixel | ||
| 79 | * of which is guaranteed to be either completely opaque, with | ||
| 80 | * an alpha value of 1.0, or completely transparent, with an alpha | ||
| 81 | * value of 0.0. | ||
| 82 | */ | ||
| 83 | PERPIXEL_TRANSPARENT, | ||
| 84 | |||
| 85 | /** | ||
| 86 | * Represents support in the underlying system for windows all of | ||
| 87 | * the pixels of which have the same alpha value between or including | ||
| 88 | * 0.0 and 1.0. | ||
| 89 | */ | ||
| 90 | TRANSLUCENT, | ||
| 91 | |||
| 92 | /** | ||
| 93 | * Represents support in the underlying system for windows that | ||
| 94 | * contain or might contain pixels with arbitrary alpha values | ||
| 95 | * between and including 0.0 and 1.0. | ||
| 96 | */ | ||
| 97 | PERPIXEL_TRANSLUCENT; | ||
| 98 | } | ||
| 99 | |||
| 100 | |||
| 101 | /** | ||
| 102 | * Returns whether the given level of translucency is supported by | ||
| 103 | * the underlying system. | ||
| 104 | * | ||
| 105 | * Note that this method may sometimes return the value | ||
| 106 | * indicating that the particular level is supported, but | ||
| 107 | * the native windowing system may still not support the | ||
| 108 | * given level of translucency (due to the bugs in | ||
| 109 | * the windowing system). | ||
| 110 | * | ||
| 111 | * @param translucencyKind a kind of translucency support | ||
| 112 | * (either PERPIXEL_TRANSPARENT, | ||
| 113 | * TRANSLUCENT, or PERPIXEL_TRANSLUCENT) | ||
| 114 | * @return whether the given translucency kind is supported | ||
| 115 | */ | ||
| 116 | public static boolean isTranslucencySupported(Translucency translucencyKind) { | ||
| 117 | switch (translucencyKind) { | ||
| 118 | case PERPIXEL_TRANSPARENT: | ||
| 119 | return isWindowShapingSupported(); | ||
| 120 | case TRANSLUCENT: | ||
| 121 | return isWindowOpacitySupported(); | ||
| 122 | case PERPIXEL_TRANSLUCENT: | ||
| 123 | return isWindowTranslucencySupported(); | ||
| 124 | } | ||
| 125 | return false; | ||
| 126 | } | ||
| 127 | |||
| 128 | |||
| 129 | /** | ||
| 130 | * Returns whether the windowing system supports changing the opacity | ||
| 131 | * value of top-level windows. | ||
| 132 | * Note that this method may sometimes return true, but the native | ||
| 133 | * windowing system may still not support the concept of | ||
| 134 | * translucency (due to the bugs in the windowing system). | ||
| 135 | */ | ||
| 136 | private static boolean isWindowOpacitySupported() { | ||
| 137 | Toolkit curToolkit = Toolkit.getDefaultToolkit(); | ||
| 138 | if (!(curToolkit instanceof SunToolkit)) { | ||
| 139 | return false; | ||
| 140 | } | ||
| 141 | return ((SunToolkit)curToolkit).isWindowOpacitySupported(); | ||
| 142 | } | ||
| 143 | |||
| 144 | /** | ||
| 145 | * Set the opacity of the window. The opacity is at the range [0..1]. | ||
| 146 | * Note that setting the opacity level of 0 may or may not disable | ||
| 147 | * the mouse event handling on this window. This is | ||
| 148 | * a platform-dependent behavior. | ||
| 149 | * | ||
| 150 | * In order for this method to enable the translucency effect, | ||
| 151 | * the isTranslucencySupported() method should indicate that the | ||
| 152 | * TRANSLUCENT level of translucency is supported. | ||
| 153 | * | ||
| 154 | * <p>Also note that the window must not be in the full-screen mode | ||
| 155 | * when setting the opacity value < 1.0f. Otherwise | ||
| 156 | * the IllegalArgumentException is thrown. | ||
| 157 | * | ||
| 158 | * @param window the window to set the opacity level to | ||
| 159 | * @param opacity the opacity level to set to the window | ||
| 160 | * @throws NullPointerException if the window argument is null | ||
| 161 | * @throws IllegalArgumentException if the opacity is out of | ||
| 162 | * the range [0..1] | ||
| 163 | * @throws IllegalArgumentException if the window is in full screen mode, | ||
| 164 | * and the opacity is less than 1.0f | ||
| 165 | * @throws UnsupportedOperationException if the TRANSLUCENT translucency | ||
| 166 | * kind is not supported | ||
| 167 | */ | ||
| 168 | public static void setWindowOpacity(Window window, float opacity) { | ||
| 169 | if (window == null) { | ||
| 170 | throw new NullPointerException( | ||
| 171 | "The window argument should not be null."); | ||
| 172 | } | ||
| 173 | |||
| 174 | AWTAccessor.getWindowAccessor().setOpacity(window, opacity); | ||
| 175 | } | ||
| 176 | |||
| 177 | /** | ||
| 178 | * Get the opacity of the window. If the opacity has not | ||
| 179 | * yet being set, this method returns 1.0. | ||
| 180 | * | ||
| 181 | * @param window the window to get the opacity level from | ||
| 182 | * @throws NullPointerException if the window argument is null | ||
| 183 | */ | ||
| 184 | public static float getWindowOpacity(Window window) { | ||
| 185 | if (window == null) { | ||
| 186 | throw new NullPointerException( | ||
| 187 | "The window argument should not be null."); | ||
| 188 | } | ||
| 189 | |||
| 190 | return AWTAccessor.getWindowAccessor().getOpacity(window); | ||
| 191 | } | ||
| 192 | |||
| 193 | /** | ||
| 194 | * Returns whether the windowing system supports changing the shape | ||
| 195 | * of top-level windows. | ||
| 196 | * Note that this method may sometimes return true, but the native | ||
| 197 | * windowing system may still not support the concept of | ||
| 198 | * shaping (due to the bugs in the windowing system). | ||
| 199 | */ | ||
| 200 | public static boolean isWindowShapingSupported() { | ||
| 201 | Toolkit curToolkit = Toolkit.getDefaultToolkit(); | ||
| 202 | if (!(curToolkit instanceof SunToolkit)) { | ||
| 203 | return false; | ||
| 204 | } | ||
| 205 | return ((SunToolkit)curToolkit).isWindowShapingSupported(); | ||
| 206 | } | ||
| 207 | |||
| 208 | /** | ||
| 209 | * Returns an object that implements the Shape interface and represents | ||
| 210 | * the shape previously set with the call to the setWindowShape() method. | ||
| 211 | * If no shape has been set yet, or the shape has been reset to null, | ||
| 212 | * this method returns null. | ||
| 213 | * | ||
| 214 | * @param window the window to get the shape from | ||
| 215 | * @return the current shape of the window | ||
| 216 | * @throws NullPointerException if the window argument is null | ||
| 217 | */ | ||
| 218 | public static Shape getWindowShape(Window window) { | ||
| 219 | if (window == null) { | ||
| 220 | throw new NullPointerException( | ||
| 221 | "The window argument should not be null."); | ||
| 222 | } | ||
| 223 | return AWTAccessor.getWindowAccessor().getShape(window); | ||
| 224 | } | ||
| 225 | |||
| 226 | /** | ||
| 227 | * Sets a shape for the given window. | ||
| 228 | * If the shape argument is null, this methods restores | ||
| 229 | * the default shape making the window rectangular. | ||
| 230 | * <p>Note that in order to set a shape, the window must be undecorated. | ||
| 231 | * If the window is decorated, this method ignores the {@code shape} | ||
| 232 | * argument and resets the shape to null. | ||
| 233 | * <p>Also note that the window must not be in the full-screen mode | ||
| 234 | * when setting a non-null shape. Otherwise the IllegalArgumentException | ||
| 235 | * is thrown. | ||
| 236 | * <p>Depending on the platform, the method may return without | ||
| 237 | * effecting the shape of the window if the window has a non-null warning | ||
| 238 | * string ({@link Window#getWarningString()}). In this case the passed | ||
| 239 | * shape object is ignored. | ||
| 240 | * | ||
| 241 | * @param window the window to set the shape to | ||
| 242 | * @param shape the shape to set to the window | ||
| 243 | * @throws NullPointerException if the window argument is null | ||
| 244 | * @throws IllegalArgumentException if the window is in full screen mode, | ||
| 245 | * and the shape is not null | ||
| 246 | * @throws UnsupportedOperationException if the PERPIXEL_TRANSPARENT | ||
| 247 | * translucency kind is not supported | ||
| 248 | */ | ||
| 249 | public static void setWindowShape(Window window, Shape shape) { | ||
| 250 | if (window == null) { | ||
| 251 | throw new NullPointerException( | ||
| 252 | "The window argument should not be null."); | ||
| 253 | } | ||
| 254 | AWTAccessor.getWindowAccessor().setShape(window, shape); | ||
| 255 | } | ||
| 256 | |||
| 257 | private static boolean isWindowTranslucencySupported() { | ||
| 258 | /* | ||
| 259 | * Per-pixel alpha is supported if all the conditions are TRUE: | ||
| 260 | * 1. The toolkit is a sort of SunToolkit | ||
| 261 | * 2. The toolkit supports translucency in general | ||
| 262 | * (isWindowTranslucencySupported()) | ||
| 263 | * 3. There's at least one translucency-capable | ||
| 264 | * GraphicsConfiguration | ||
| 265 | */ | ||
| 266 | |||
| 267 | Toolkit curToolkit = Toolkit.getDefaultToolkit(); | ||
| 268 | if (!(curToolkit instanceof SunToolkit)) { | ||
| 269 | return false; | ||
| 270 | } | ||
| 271 | |||
| 272 | if (!((SunToolkit)curToolkit).isWindowTranslucencySupported()) { | ||
| 273 | return false; | ||
| 274 | } | ||
| 275 | |||
| 276 | GraphicsEnvironment env = | ||
| 277 | GraphicsEnvironment.getLocalGraphicsEnvironment(); | ||
| 278 | |||
| 279 | // If the default GC supports translucency return true. | ||
| 280 | // It is important to optimize the verification this way, | ||
| 281 | // see CR 6661196 for more details. | ||
| 282 | if (isTranslucencyCapable(env.getDefaultScreenDevice() | ||
| 283 | .getDefaultConfiguration())) | ||
| 284 | { | ||
| 285 | return true; | ||
| 286 | } | ||
| 287 | |||
| 288 | // ... otherwise iterate through all the GCs. | ||
| 289 | GraphicsDevice[] devices = env.getScreenDevices(); | ||
| 290 | |||
| 291 | for (int i = 0; i < devices.length; i++) { | ||
| 292 | GraphicsConfiguration[] configs = devices[i].getConfigurations(); | ||
| 293 | for (int j = 0; j < configs.length; j++) { | ||
| 294 | if (isTranslucencyCapable(configs[j])) { | ||
| 295 | return true; | ||
| 296 | } | ||
| 297 | } | ||
| 298 | } | ||
| 299 | |||
| 300 | return false; | ||
| 301 | } | ||
| 302 | |||
| 303 | /** | ||
| 304 | * Enables the per-pixel alpha support for the given window. | ||
| 305 | * Once the window becomes non-opaque (the isOpaque is set to false), | ||
| 306 | * the drawing sub-system is starting to respect the alpha value of each | ||
| 307 | * separate pixel. If a pixel gets painted with alpha color component | ||
| 308 | * equal to zero, it becomes visually transparent, if the alpha of the | ||
| 309 | * pixel is equal to 255, the pixel is fully opaque. Interim values | ||
| 310 | * of the alpha color component make the pixel semi-transparent (i.e. | ||
| 311 | * translucent). | ||
| 312 | * <p>Note that in order for the window to support the per-pixel alpha | ||
| 313 | * mode, the window must be created using the GraphicsConfiguration | ||
| 314 | * for which the {@link #isTranslucencyCapable} | ||
| 315 | * method returns true. | ||
| 316 | * <p>Also note that some native systems enable the per-pixel translucency | ||
| 317 | * mode for any window created using the translucency-compatible | ||
| 318 | * graphics configuration. However, it is highly recommended to always | ||
| 319 | * invoke the setWindowOpaque() method for these windows, at least for | ||
| 320 | * the sake of cross-platform compatibility reasons. | ||
| 321 | * <p>Also note that the window must not be in the full-screen mode | ||
| 322 | * when making it non-opaque. Otherwise the IllegalArgumentException | ||
| 323 | * is thrown. | ||
| 324 | * <p>If the window is a {@code Frame} or a {@code Dialog}, the window must | ||
| 325 | * be undecorated prior to enabling the per-pixel translucency effect (see | ||
| 326 | * {@link Frame#setUndecorated()} and/or {@link Dialog#setUndecorated()}). | ||
| 327 | * If the window becomes decorated through a subsequent call to the | ||
| 328 | * corresponding {@code setUndecorated()} method, the per-pixel | ||
| 329 | * translucency effect will be disabled and the opaque property reset to | ||
| 330 | * {@code true}. | ||
| 331 | * <p>Depending on the platform, the method may return without | ||
| 332 | * effecting the opaque property of the window if the window has a non-null | ||
| 333 | * warning string ({@link Window#getWarningString()}). In this case | ||
| 334 | * the passed 'isOpaque' value is ignored. | ||
| 335 | * | ||
| 336 | * @param window the window to set the shape to | ||
| 337 | * @param isOpaque whether the window must be opaque (true), | ||
| 338 | * or translucent (false) | ||
| 339 | * @throws NullPointerException if the window argument is null | ||
| 340 | * @throws IllegalArgumentException if the window uses | ||
| 341 | * a GraphicsConfiguration for which the | ||
| 342 | * {@code isTranslucencyCapable()} | ||
| 343 | * method returns false | ||
| 344 | * @throws IllegalArgumentException if the window is in full screen mode, | ||
| 345 | * and the isOpaque is false | ||
| 346 | * @throws IllegalArgumentException if the window is decorated and the | ||
| 347 | * isOpaque argument is {@code false}. | ||
| 348 | * @throws UnsupportedOperationException if the PERPIXEL_TRANSLUCENT | ||
| 349 | * translucency kind is not supported | ||
| 350 | */ | ||
| 351 | public static void setWindowOpaque(Window window, boolean isOpaque) { | ||
| 352 | if (window == null) { | ||
| 353 | throw new NullPointerException( | ||
| 354 | "The window argument should not be null."); | ||
| 355 | } | ||
| 356 | if (!isOpaque && !isTranslucencySupported(Translucency.PERPIXEL_TRANSLUCENT)) { | ||
| 357 | throw new UnsupportedOperationException( | ||
| 358 | "The PERPIXEL_TRANSLUCENT translucency kind is not supported"); | ||
| 359 | } | ||
| 360 | AWTAccessor.getWindowAccessor().setOpaque(window, isOpaque); | ||
| 361 | } | ||
| 362 | |||
| 363 | /** | ||
| 364 | * Returns whether the window is opaque or translucent. | ||
| 365 | * | ||
| 366 | * @param window the window to set the shape to | ||
| 367 | * @return whether the window is currently opaque (true) | ||
| 368 | * or translucent (false) | ||
| 369 | * @throws NullPointerException if the window argument is null | ||
| 370 | */ | ||
| 371 | public static boolean isWindowOpaque(Window window) { | ||
| 372 | if (window == null) { | ||
| 373 | throw new NullPointerException( | ||
| 374 | "The window argument should not be null."); | ||
| 375 | } | ||
| 376 | |||
| 377 | return window.isOpaque(); | ||
| 378 | } | ||
| 379 | |||
| 380 | /** | ||
| 381 | * Verifies whether a given GraphicsConfiguration supports | ||
| 382 | * the PERPIXEL_TRANSLUCENT kind of translucency. | ||
| 383 | * All windows that are intended to be used with the {@link #setWindowOpaque} | ||
| 384 | * method must be created using a GraphicsConfiguration for which this method | ||
| 385 | * returns true. | ||
| 386 | * <p>Note that some native systems enable the per-pixel translucency | ||
| 387 | * mode for any window created using a translucency-capable | ||
| 388 | * graphics configuration. However, it is highly recommended to always | ||
| 389 | * invoke the setWindowOpaque() method for these windows, at least | ||
| 390 | * for the sake of cross-platform compatibility reasons. | ||
| 391 | * | ||
| 392 | * @param gc GraphicsConfiguration | ||
| 393 | * @throws NullPointerException if the gc argument is null | ||
| 394 | * @return whether the given GraphicsConfiguration supports | ||
| 395 | * the translucency effects. | ||
| 396 | */ | ||
| 397 | public static boolean isTranslucencyCapable(GraphicsConfiguration gc) { | ||
| 398 | if (gc == null) { | ||
| 399 | throw new NullPointerException("The gc argument should not be null"); | ||
| 400 | } | ||
| 401 | /* | ||
| 402 | return gc.isTranslucencyCapable(); | ||
| 403 | */ | ||
| 404 | Toolkit curToolkit = Toolkit.getDefaultToolkit(); | ||
| 405 | if (!(curToolkit instanceof SunToolkit)) { | ||
| 406 | return false; | ||
| 407 | } | ||
| 408 | return ((SunToolkit)curToolkit).isTranslucencyCapable(gc); | ||
| 409 | } | ||
| 410 | |||
| 411 | /** | ||
| 412 | * Sets a 'mixing-cutout' shape for the given component. | ||
| 413 | * | ||
| 414 | * By default a lightweight component is treated as an opaque rectangle for | ||
| 415 | * the purposes of the Heavyweight/Lightweight Components Mixing feature. | ||
| 416 | * This method enables developers to set an arbitrary shape to be cut out | ||
| 417 | * from heavyweight components positioned underneath the lightweight | ||
| 418 | * component in the z-order. | ||
| 419 | * <p> | ||
| 420 | * The {@code shape} argument may have the following values: | ||
| 421 | * <ul> | ||
| 422 | * <li>{@code null} - reverts the default cutout shape (the rectangle equal | ||
| 423 | * to the component's {@code getBounds()}) | ||
| 424 | * <li><i>empty-shape</i> - does not cut out anything from heavyweight | ||
| 425 | * components. This makes the given lightweight component effectively | ||
| 426 | * transparent. Note that descendants of the lightweight component still | ||
| 427 | * affect the shapes of heavyweight components. An example of an | ||
| 428 | * <i>empty-shape</i> is {@code new Rectangle()}. | ||
| 429 | * <li><i>non-empty-shape</i> - the given shape will be cut out from | ||
| 430 | * heavyweight components. | ||
| 431 | * </ul> | ||
| 432 | * <p> | ||
| 433 | * The most common example when the 'mixing-cutout' shape is needed is a | ||
| 434 | * glass pane component. The {@link JRootPane#setGlassPane()} method | ||
| 435 | * automatically sets the <i>empty-shape</i> as the 'mixing-cutout' shape | ||
| 436 | * for the given glass pane component. If a developer needs some other | ||
| 437 | * 'mixing-cutout' shape for the glass pane (which is rare), this must be | ||
| 438 | * changed manually after installing the glass pane to the root pane. | ||
| 439 | * <p> | ||
| 440 | * Note that the 'mixing-cutout' shape neither affects painting, nor the | ||
| 441 | * mouse events handling for the given component. It is used exclusively | ||
| 442 | * for the purposes of the Heavyweight/Lightweight Components Mixing | ||
| 443 | * feature. | ||
| 444 | * | ||
| 445 | * @param component the component that needs non-default | ||
| 446 | * 'mixing-cutout' shape | ||
| 447 | * @param shape the new 'mixing-cutout' shape | ||
| 448 | * @throws NullPointerException if the component argument is {@code null} | ||
| 449 | */ | ||
| 450 | public static void setComponentMixingCutoutShape(Component component, | ||
| 451 | Shape shape) | ||
| 452 | { | ||
| 453 | if (component == null) { | ||
| 454 | throw new NullPointerException( | ||
| 455 | "The component argument should not be null."); | ||
| 456 | } | ||
| 457 | |||
| 458 | AWTAccessor.getComponentAccessor().setMixingCutoutShape(component, | ||
| 459 | shape); | ||
| 460 | } | ||
| 461 | } | ||
| 462 | |||
| @@ -0,0 +1,169 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.awt; | ||
| 27 | |||
| 28 | import java.awt.*; | ||
| 29 | import java.awt.geom.*; | ||
| 30 | |||
| 31 | import sun.awt.AWTAccessor; | ||
| 32 | |||
| 33 | |||
| 34 | /** | ||
| 35 | * Security Warning control interface. | ||
| 36 | * | ||
| 37 | * This class provides a couple of methods that help a developer relocate | ||
| 38 | * the AWT security warning to an appropriate position relative to the current | ||
| 39 | * window size. A "top-level window" is an instance of the {@code Window} | ||
| 40 | * class (or its descendant, such as {@code JFrame}). The security warning | ||
| 41 | * is applied to all windows created by an untrusted code. All such windows | ||
| 42 | * have a non-null "warning string" (see {@link Window#getWarningString()}). | ||
| 43 | * <p> | ||
| 44 | * <b>WARNING</b>: This class is an implementation detail and only meant | ||
| 45 | * for limited use outside of the core platform. This API may change | ||
| 46 | * drastically between update release, and it may even be | ||
| 47 | * removed or be moved to some other packages or classes. | ||
| 48 | */ | ||
| 49 | public final class SecurityWarning { | ||
| 50 | |||
| 51 | /** | ||
| 52 | * The SecurityWarning class should not be instantiated | ||
| 53 | */ | ||
| 54 | private SecurityWarning() { | ||
| 55 | } | ||
| 56 | |||
| 57 | /** | ||
| 58 | * Gets the size of the security warning. | ||
| 59 | * | ||
| 60 | * The returned value is not valid until the peer has been created. Before | ||
| 61 | * invoking this method a developer must call the {@link Window#pack()}, | ||
| 62 | * {@link Window#setVisible()}, or some other method that creates the peer. | ||
| 63 | * | ||
| 64 | * @param window the window to get the security warning size for | ||
| 65 | * | ||
| 66 | * @throws NullPointerException if the window argument is null | ||
| 67 | * @throws IllegalArgumentException if the window is trusted (i.e. | ||
| 68 | * the {@code getWarningString()} returns null) | ||
| 69 | */ | ||
| 70 | public static Dimension getSize(Window window) { | ||
| 71 | if (window == null) { | ||
| 72 | throw new NullPointerException( | ||
| 73 | "The window argument should not be null."); | ||
| 74 | } | ||
| 75 | if (window.getWarningString() == null) { | ||
| 76 | throw new IllegalArgumentException( | ||
| 77 | "The window must have a non-null warning string."); | ||
| 78 | } | ||
| 79 | // We don't check for a non-null peer since it may be destroyed | ||
| 80 | // after assigning a valid value to the security warning size. | ||
| 81 | |||
| 82 | return AWTAccessor.getWindowAccessor().getSecurityWarningSize(window); | ||
| 83 | } | ||
| 84 | |||
| 85 | /** | ||
| 86 | * Sets the position of the security warning. | ||
| 87 | * <p> | ||
| 88 | * The {@code alignmentX} and {@code alignmentY} arguments specify the | ||
| 89 | * origin of the coordinate system used to calculate the position of the | ||
| 90 | * security warning. The values must be in the range [0.0f...1.0f]. The | ||
| 91 | * {@code 0.0f} value represents the left (top) edge of the rectangular | ||
| 92 | * bounds of the window. The {@code 1.0f} value represents the right | ||
| 93 | * (bottom) edge of the bounds. Whenever the size of the window changes, | ||
| 94 | * the origin of the coordinate system gets relocated accordingly. For | ||
| 95 | * convenience a developer may use the {@code Component.*_ALIGNMENT} | ||
| 96 | * constants to pass predefined values for these arguments. | ||
| 97 | * <p> | ||
| 98 | * The {@code point} argument specifies the location of the security | ||
| 99 | * warning in the coordinate system described above. If both {@code x} and | ||
| 100 | * {@code y} coordinates of the point are equal to zero, the warning will | ||
| 101 | * be located right in the origin of the coordinate system. On the other | ||
| 102 | * hand, if both {@code alignmentX} and {@code alignmentY} are equal to | ||
| 103 | * zero (i.e. the origin of the coordinate system is placed at the top-left | ||
| 104 | * corner of the window), then the {@code point} argument represents the | ||
| 105 | * absolute location of the security warning relative to the location of | ||
| 106 | * the window. The "absolute" in this case means that the position of the | ||
| 107 | * security warning is not effected by resizing of the window. | ||
| 108 | * <p> | ||
| 109 | * Note that the security warning managment code guarantees that: | ||
| 110 | * <ul> | ||
| 111 | * <li>The security warning cannot be located farther than two pixels from | ||
| 112 | * the rectangular bounds of the window (see {@link Window#getBounds}), and | ||
| 113 | * <li>The security warning is always visible on the screen. | ||
| 114 | * </ul> | ||
| 115 | * If either of the conditions is violated, the calculated position of the | ||
| 116 | * security warning is adjusted by the system to meet both these | ||
| 117 | * conditions. | ||
| 118 | * <p> | ||
| 119 | * The default position of the security warning is in the upper-right | ||
| 120 | * corner of the window, two pixels to the right from the right edge. This | ||
| 121 | * corresponds to the following arguments passed to this method: | ||
| 122 | * <ul> | ||
| 123 | * <li>{@code alignmentX = Component.RIGHT_ALIGNMENT} | ||
| 124 | * <li>{@code alignmentY = Component.TOP_ALIGNMENT} | ||
| 125 | * <li>{@code point = (2, 0)} | ||
| 126 | * </ul> | ||
| 127 | * | ||
| 128 | * @param window the window to set the position of the security warning for | ||
| 129 | * @param alignmentX the horizontal origin of the coordinate system | ||
| 130 | * @param alignmentY the vertical origin of the coordinate system | ||
| 131 | * @param point the position of the security warning in the specified | ||
| 132 | * coordinate system | ||
| 133 | * | ||
| 134 | * @throws NullPointerException if the window argument is null | ||
| 135 | * @throws NullPointerException if the point argument is null | ||
| 136 | * @throws IllegalArgumentException if the window is trusted (i.e. | ||
| 137 | * the {@code getWarningString()} returns null | ||
| 138 | * @throws IllegalArgumentException if the alignmentX or alignmentY | ||
| 139 | * arguments are not within the range [0.0f ... 1.0f] | ||
| 140 | */ | ||
| 141 | public static void setPosition(Window window, Point2D point, | ||
| 142 | float alignmentX, float alignmentY) | ||
| 143 | { | ||
| 144 | if (window == null) { | ||
| 145 | throw new NullPointerException( | ||
| 146 | "The window argument should not be null."); | ||
| 147 | } | ||
| 148 | if (window.getWarningString() == null) { | ||
| 149 | throw new IllegalArgumentException( | ||
| 150 | "The window must have a non-null warning string."); | ||
| 151 | } | ||
| 152 | if (point == null) { | ||
| 153 | throw new NullPointerException( | ||
| 154 | "The point argument must not be null"); | ||
| 155 | } | ||
| 156 | if (alignmentX < 0.0f || alignmentX > 1.0f) { | ||
| 157 | throw new IllegalArgumentException( | ||
| 158 | "alignmentX must be in the range [0.0f ... 1.0f]."); | ||
| 159 | } | ||
| 160 | if (alignmentY < 0.0f || alignmentY > 1.0f) { | ||
| 161 | throw new IllegalArgumentException( | ||
| 162 | "alignmentY must be in the range [0.0f ... 1.0f]."); | ||
| 163 | } | ||
| 164 | |||
| 165 | AWTAccessor.getWindowAccessor().setSecurityWarningPosition(window, | ||
| 166 | point, alignmentX, alignmentY); | ||
| 167 | } | ||
| 168 | } | ||
| 169 | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | <../../../../../mkconfig | ||
| 2 | |||
| 3 | TARG=\ | ||
| 4 | AWTUtilities.dis\ | ||
| 5 | SecurityWarning.dis\ | ||
| 6 | |||
| 7 | DISBIN=$ROOT/java/dis/java/java/com/sun/awt | ||
| 8 | |||
| 9 | <$ROOT/mkfiles/mkjava | ||
Binary file not shown.
| @@ -0,0 +1,410 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans; | ||
| 26 | |||
| 27 | import java.lang.reflect.Array; | ||
| 28 | import java.lang.reflect.GenericArrayType; | ||
| 29 | import java.lang.reflect.ParameterizedType; | ||
| 30 | import java.lang.reflect.Type; | ||
| 31 | import java.lang.reflect.TypeVariable; | ||
| 32 | import java.lang.reflect.WildcardType; | ||
| 33 | import java.util.HashMap; | ||
| 34 | import java.util.Map; | ||
| 35 | |||
| 36 | import sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl; | ||
| 37 | import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl; | ||
| 38 | |||
| 39 | /** | ||
| 40 | * This is utility class to resolve types. | ||
| 41 | * | ||
| 42 | * @since 1.7 | ||
| 43 | * | ||
| 44 | * @author Eamonn McManus | ||
| 45 | * @author Sergey Malenkov | ||
| 46 | */ | ||
| 47 | public final class TypeResolver { | ||
| 48 | /** | ||
| 49 | * Replaces the given {@code type} in an inherited method | ||
| 50 | * with the actual type it has in the given {@code inClass}. | ||
| 51 | * | ||
| 52 | * <p>Although type parameters are not inherited by subclasses in the Java | ||
| 53 | * language, they <em>are</em> effectively inherited when using reflection. | ||
| 54 | * For example, if you declare an interface like this...</p> | ||
| 55 | * | ||
| 56 | * <pre> | ||
| 57 | * public interface StringToIntMap extends Map<String,Integer> {} | ||
| 58 | * </pre> | ||
| 59 | * | ||
| 60 | * <p>...then StringToIntMap.class.getMethods() will show that it has methods | ||
| 61 | * like put(K,V) even though StringToIntMap has no type parameters. The K | ||
| 62 | * and V variables are the ones declared by Map, so | ||
| 63 | * {@link TypeVariable#getGenericDeclaration()} will return Map.class.</p> | ||
| 64 | * | ||
| 65 | * <p>The purpose of this method is to take a Type from a possibly-inherited | ||
| 66 | * method and replace it with the correct Type for the inheriting class. | ||
| 67 | * So given parameters of K and StringToIntMap.class in the above example, | ||
| 68 | * this method will return String.</p> | ||
| 69 | * | ||
| 70 | * @param inClass the base class used to resolve | ||
| 71 | * @param type the type to resolve | ||
| 72 | * @return a resolved type | ||
| 73 | * | ||
| 74 | * @see #getActualType(Class) | ||
| 75 | * @see #resolve(Type,Type) | ||
| 76 | */ | ||
| 77 | public static Type resolveInClass(Class<?> inClass, Type type) { | ||
| 78 | return resolve(getActualType(inClass), type); | ||
| 79 | } | ||
| 80 | |||
| 81 | /** | ||
| 82 | * Replaces all {@code types} in the given array | ||
| 83 | * with the actual types they have in the given {@code inClass}. | ||
| 84 | * | ||
| 85 | * @param inClass the base class used to resolve | ||
| 86 | * @param types the array of types to resolve | ||
| 87 | * @return an array of resolved types | ||
| 88 | * | ||
| 89 | * @see #getActualType(Class) | ||
| 90 | * @see #resolve(Type,Type[]) | ||
| 91 | */ | ||
| 92 | public static Type[] resolveInClass(Class<?> inClass, Type[] types) { | ||
| 93 | return resolve(getActualType(inClass), types); | ||
| 94 | } | ||
| 95 | |||
| 96 | /** | ||
| 97 | * Replaces type variables of the given {@code formal} type | ||
| 98 | * with the types they stand for in the given {@code actual} type. | ||
| 99 | * | ||
| 100 | * <p>A ParameterizedType is a class with type parameters, and the values | ||
| 101 | * of those parameters. For example, Map<K,V> is a generic class, and | ||
| 102 | * a corresponding ParameterizedType might look like | ||
| 103 | * Map<K=String,V=Integer>. Given such a ParameterizedType, this method | ||
| 104 | * will replace K with String, or List<K> with List<String;, or | ||
| 105 | * List<? super K> with List<? super String>.</p> | ||
| 106 | * | ||
| 107 | * <p>The {@code actual} argument to this method can also be a Class. | ||
| 108 | * In this case, either it is equivalent to a ParameterizedType with | ||
| 109 | * no parameters (for example, Integer.class), or it is equivalent to | ||
| 110 | * a "raw" ParameterizedType (for example, Map.class). In the latter | ||
| 111 | * case, every type parameter declared or inherited by the class is replaced | ||
| 112 | * by its "erasure". For a type parameter declared as <T>, the erasure | ||
| 113 | * is Object. For a type parameter declared as <T extends Number>, | ||
| 114 | * the erasure is Number.</p> | ||
| 115 | * | ||
| 116 | * <p>Although type parameters are not inherited by subclasses in the Java | ||
| 117 | * language, they <em>are</em> effectively inherited when using reflection. | ||
| 118 | * For example, if you declare an interface like this...</p> | ||
| 119 | * | ||
| 120 | * <pre> | ||
| 121 | * public interface StringToIntMap extends Map<String,Integer> {} | ||
| 122 | * </pre> | ||
| 123 | * | ||
| 124 | * <p>...then StringToIntMap.class.getMethods() will show that it has methods | ||
| 125 | * like put(K,V) even though StringToIntMap has no type parameters. The K | ||
| 126 | * and V variables are the ones declared by Map, so | ||
| 127 | * {@link TypeVariable#getGenericDeclaration()} will return {@link Map Map.class}.</p> | ||
| 128 | * | ||
| 129 | * <p>For this reason, this method replaces inherited type parameters too. | ||
| 130 | * Therefore if this method is called with {@code actual} being | ||
| 131 | * StringToIntMap.class and {@code formal} being the K from Map, | ||
| 132 | * it will return {@link String String.class}.</p> | ||
| 133 | * | ||
| 134 | * <p>In the case where {@code actual} is a "raw" ParameterizedType, the | ||
| 135 | * inherited type parameters will also be replaced by their erasures. | ||
| 136 | * The erasure of a Class is the Class itself, so a "raw" subinterface of | ||
| 137 | * StringToIntMap will still show the K from Map as String.class. But | ||
| 138 | * in a case like this... | ||
| 139 | * | ||
| 140 | * <pre> | ||
| 141 | * public interface StringToIntListMap extends Map<String,List<Integer>> {} | ||
| 142 | * public interface RawStringToIntListMap extends StringToIntListMap {} | ||
| 143 | * </pre> | ||
| 144 | * | ||
| 145 | * <p>...the V inherited from Map will show up as List<Integer> in | ||
| 146 | * StringToIntListMap, but as plain List in RawStringToIntListMap.</p> | ||
| 147 | * | ||
| 148 | * @param actual the type that supplies bindings for type variables | ||
| 149 | * @param formal the type where occurrences of the variables | ||
| 150 | * in {@code actual} will be replaced by the corresponding bound values | ||
| 151 | * @return a resolved type | ||
| 152 | * | ||
| 153 | * @see #TypeResolver(Type) | ||
| 154 | * @see #resolve(Type) | ||
| 155 | */ | ||
| 156 | public static Type resolve(Type actual, Type formal) { | ||
| 157 | return new TypeResolver(actual).resolve(formal); | ||
| 158 | } | ||
| 159 | |||
| 160 | /** | ||
| 161 | * Replaces type variables of all formal types in the given array | ||
| 162 | * with the types they stand for in the given {@code actual} type. | ||
| 163 | * | ||
| 164 | * @param actual the type that supplies bindings for type variables | ||
| 165 | * @param formals the array of types to resolve | ||
| 166 | * @return an array of resolved types | ||
| 167 | * | ||
| 168 | * @see #TypeResolver(Type) | ||
| 169 | * @see #resolve(Type[]) | ||
| 170 | */ | ||
| 171 | public static Type[] resolve(Type actual, Type[] formals) { | ||
| 172 | return new TypeResolver(actual).resolve(formals); | ||
| 173 | } | ||
| 174 | |||
| 175 | /** | ||
| 176 | * Converts the given {@code type} to the corresponding class. | ||
| 177 | * This method implements the concept of type erasure, | ||
| 178 | * that is described in section 4.6 of | ||
| 179 | * <cite>The Java™ Language Specification</cite>. | ||
| 180 | * | ||
| 181 | * @param type the array of types to convert | ||
| 182 | * @return a corresponding class | ||
| 183 | */ | ||
| 184 | public static Class<?> erase(Type type) { | ||
| 185 | if (type instanceof Class) { | ||
| 186 | return (Class<?>) type; | ||
| 187 | } | ||
| 188 | if (type instanceof ParameterizedType) { | ||
| 189 | ParameterizedType pt = (ParameterizedType) type; | ||
| 190 | return (Class<?>) pt.getRawType(); | ||
| 191 | } | ||
| 192 | if (type instanceof TypeVariable) { | ||
| 193 | TypeVariable tv = (TypeVariable)type; | ||
| 194 | Type[] bounds = tv.getBounds(); | ||
| 195 | return (0 < bounds.length) | ||
| 196 | ? erase(bounds[0]) | ||
| 197 | : Object.class; | ||
| 198 | } | ||
| 199 | if (type instanceof WildcardType) { | ||
| 200 | WildcardType wt = (WildcardType)type; | ||
| 201 | Type[] bounds = wt.getUpperBounds(); | ||
| 202 | return (0 < bounds.length) | ||
| 203 | ? erase(bounds[0]) | ||
| 204 | : Object.class; | ||
| 205 | } | ||
| 206 | if (type instanceof GenericArrayType) { | ||
| 207 | GenericArrayType gat = (GenericArrayType)type; | ||
| 208 | return Array.newInstance(erase(gat.getGenericComponentType()), 0).getClass(); | ||
| 209 | } | ||
| 210 | throw new IllegalArgumentException("Unknown Type kind: " + type.getClass()); | ||
| 211 | } | ||
| 212 | |||
| 213 | /** | ||
| 214 | * Converts all {@code types} in the given array | ||
| 215 | * to the corresponding classes. | ||
| 216 | * | ||
| 217 | * @param types the array of types to convert | ||
| 218 | * @return an array of corresponding classes | ||
| 219 | * | ||
| 220 | * @see #erase(Type) | ||
| 221 | */ | ||
| 222 | public static Class[] erase(Type[] types) { | ||
| 223 | int length = types.length; | ||
| 224 | Class[] classes = new Class[length]; | ||
| 225 | for (int i = 0; i < length; i++) { | ||
| 226 | classes[i] = TypeResolver.erase(types[i]); | ||
| 227 | } | ||
| 228 | return classes; | ||
| 229 | } | ||
| 230 | |||
| 231 | |||
| 232 | private final Map<TypeVariable<?>, Type> map | ||
| 233 | = new HashMap<TypeVariable<?>, Type>(); | ||
| 234 | |||
| 235 | /** | ||
| 236 | * Constructs the type resolver for the given actual type. | ||
| 237 | * | ||
| 238 | * @param actual the type that supplies bindings for type variables | ||
| 239 | * | ||
| 240 | * @see #prepare(Type) | ||
| 241 | */ | ||
| 242 | private TypeResolver(Type actual) { | ||
| 243 | prepare(actual); | ||
| 244 | } | ||
| 245 | |||
| 246 | /** | ||
| 247 | * Fills the map from type parameters | ||
| 248 | * to types as seen by the given {@code type}. | ||
| 249 | * The method is recursive because the {@code type} | ||
| 250 | * inherits mappings from its parent classes and interfaces. | ||
| 251 | * The {@code type} can be either a {@link Class Class} | ||
| 252 | * or a {@link ParameterizedType ParameterizedType}. | ||
| 253 | * If it is a {@link Class Class}, it is either equivalent | ||
| 254 | * to a {@link ParameterizedType ParameterizedType} with no parameters, | ||
| 255 | * or it represents the erasure of a {@link ParameterizedType ParameterizedType}. | ||
| 256 | * | ||
| 257 | * @param type the next type in the hierarchy | ||
| 258 | */ | ||
| 259 | private void prepare(Type type) { | ||
| 260 | Class<?> raw = (Class<?>)((type instanceof Class<?>) | ||
| 261 | ? type | ||
| 262 | : ((ParameterizedType)type).getRawType()); | ||
| 263 | |||
| 264 | TypeVariable<?>[] formals = raw.getTypeParameters(); | ||
| 265 | |||
| 266 | Type[] actuals = (type instanceof Class<?>) | ||
| 267 | ? formals | ||
| 268 | : ((ParameterizedType)type).getActualTypeArguments(); | ||
| 269 | |||
| 270 | assert formals.length == actuals.length; | ||
| 271 | for (int i = 0; i < formals.length; i++) { | ||
| 272 | this.map.put(formals[i], actuals[i]); | ||
| 273 | } | ||
| 274 | Type gSuperclass = raw.getGenericSuperclass(); | ||
| 275 | if (gSuperclass != null) { | ||
| 276 | prepare(gSuperclass); | ||
| 277 | } | ||
| 278 | for (Type gInterface : raw.getGenericInterfaces()) { | ||
| 279 | prepare(gInterface); | ||
| 280 | } | ||
| 281 | // If type is the raw version of a parameterized class, we type-erase | ||
| 282 | // all of its type variables, including inherited ones. | ||
| 283 | if (type instanceof Class<?> && formals.length > 0) { | ||
| 284 | for (Map.Entry<TypeVariable<?>, Type> entry : this.map.entrySet()) { | ||
| 285 | entry.setValue(erase(entry.getValue())); | ||
| 286 | } | ||
| 287 | } | ||
| 288 | } | ||
| 289 | |||
| 290 | /** | ||
| 291 | * Replaces the given {@code formal} type | ||
| 292 | * with the type it stand for in this type resolver. | ||
| 293 | * | ||
| 294 | * @param formal the array of types to resolve | ||
| 295 | * @return a resolved type | ||
| 296 | */ | ||
| 297 | private Type resolve(Type formal) { | ||
| 298 | if (formal instanceof Class) { | ||
| 299 | return formal; | ||
| 300 | } | ||
| 301 | if (formal instanceof GenericArrayType) { | ||
| 302 | Type comp = ((GenericArrayType)formal).getGenericComponentType(); | ||
| 303 | comp = resolve(comp); | ||
| 304 | return (comp instanceof Class) | ||
| 305 | ? Array.newInstance((Class<?>)comp, 0).getClass() | ||
| 306 | : GenericArrayTypeImpl.make(comp); | ||
| 307 | } | ||
| 308 | if (formal instanceof ParameterizedType) { | ||
| 309 | ParameterizedType fpt = (ParameterizedType)formal; | ||
| 310 | Type[] actuals = resolve(fpt.getActualTypeArguments()); | ||
| 311 | return ParameterizedTypeImpl.make( | ||
| 312 | (Class<?>)fpt.getRawType(), actuals, fpt.getOwnerType()); | ||
| 313 | } | ||
| 314 | if (formal instanceof WildcardType) { | ||
| 315 | WildcardType fwt = (WildcardType)formal; | ||
| 316 | Type[] upper = resolve(fwt.getUpperBounds()); | ||
| 317 | Type[] lower = resolve(fwt.getLowerBounds()); | ||
| 318 | return new WildcardTypeImpl(upper, lower); | ||
| 319 | } | ||
| 320 | if (!(formal instanceof TypeVariable)) { | ||
| 321 | throw new IllegalArgumentException("Bad Type kind: " + formal.getClass()); | ||
| 322 | } | ||
| 323 | Type actual = this.map.get((TypeVariable) formal); | ||
| 324 | if (actual == null || actual.equals(formal)) { | ||
| 325 | return formal; | ||
| 326 | } | ||
| 327 | actual = fixGenericArray(actual); | ||
| 328 | return resolve(actual); | ||
| 329 | // A variable can be bound to another variable that is itself bound | ||
| 330 | // to something. For example, given: | ||
| 331 | // class Super<T> {...} | ||
| 332 | // class Mid<X> extends Super<T> {...} | ||
| 333 | // class Sub extends Mid<String> | ||
| 334 | // the variable T is bound to X, which is in turn bound to String. | ||
| 335 | // So if we have to resolve T, we need the tail recursion here. | ||
| 336 | } | ||
| 337 | |||
| 338 | /** | ||
| 339 | * Replaces all formal types in the given array | ||
| 340 | * with the types they stand for in this type resolver. | ||
| 341 | * | ||
| 342 | * @param formals the array of types to resolve | ||
| 343 | * @return an array of resolved types | ||
| 344 | * | ||
| 345 | * @see #resolve(Type) | ||
| 346 | */ | ||
| 347 | private Type[] resolve(Type[] formals) { | ||
| 348 | int length = formals.length; | ||
| 349 | Type[] actuals = new Type[length]; | ||
| 350 | for (int i = 0; i < length; i++) { | ||
| 351 | actuals[i] = resolve(formals[i]); | ||
| 352 | } | ||
| 353 | return actuals; | ||
| 354 | } | ||
| 355 | |||
| 356 | /** | ||
| 357 | * Replaces a {@link GenericArrayType GenericArrayType} | ||
| 358 | * with plain array class where it is possible. | ||
| 359 | * Bug <a href="http://bugs.sun.com/view_bug.do?bug_id=5041784">5041784</a> | ||
| 360 | * is that arrays of non-generic type sometimes show up | ||
| 361 | * as {@link GenericArrayType GenericArrayType} when using reflection. | ||
| 362 | * For example, a {@code String[]} might show up | ||
| 363 | * as a {@link GenericArrayType GenericArrayType} | ||
| 364 | * where {@link GenericArrayType#getGenericComponentType getGenericComponentType} | ||
| 365 | * is {@code String.class}. This violates the specification, | ||
| 366 | * which says that {@link GenericArrayType GenericArrayType} | ||
| 367 | * is used when the component type is a type variable or parameterized type. | ||
| 368 | * We fit the specification here. | ||
| 369 | * | ||
| 370 | * @param type the type to fix | ||
| 371 | * @return a corresponding type for the generic array type, | ||
| 372 | * or the same type as {@code type} | ||
| 373 | */ | ||
| 374 | private static Type fixGenericArray(Type type) { | ||
| 375 | if (type instanceof GenericArrayType) { | ||
| 376 | Type comp = ((GenericArrayType)type).getGenericComponentType(); | ||
| 377 | comp = fixGenericArray(comp); | ||
| 378 | if (comp instanceof Class) { | ||
| 379 | return Array.newInstance((Class<?>)comp, 0).getClass(); | ||
| 380 | } | ||
| 381 | } | ||
| 382 | return type; | ||
| 383 | } | ||
| 384 | |||
| 385 | /** | ||
| 386 | * Replaces a {@link Class Class} with type parameters | ||
| 387 | * with a {@link ParameterizedType ParameterizedType} | ||
| 388 | * where every parameter is bound to itself. | ||
| 389 | * When calling {@link #resolveInClass} in the context of {@code inClass}, | ||
| 390 | * we can't just pass {@code inClass} as the {@code actual} parameter, | ||
| 391 | * because if {@code inClass} has type parameters | ||
| 392 | * that would be interpreted as accessing the raw type, | ||
| 393 | * so we would get unwanted erasure. | ||
| 394 | * This is why we bind each parameter to itself. | ||
| 395 | * If {@code inClass} does have type parameters and has methods | ||
| 396 | * where those parameters appear in the return type or argument types, | ||
| 397 | * we will correctly leave those types alone. | ||
| 398 | * | ||
| 399 | * @param inClass the base class used to resolve | ||
| 400 | * @return a parameterized type for the class, | ||
| 401 | * or the same class as {@code inClass} | ||
| 402 | */ | ||
| 403 | private static Type getActualType(Class<?> inClass) { | ||
| 404 | Type[] params = inClass.getTypeParameters(); | ||
| 405 | return (params.length == 0) | ||
| 406 | ? inClass | ||
| 407 | : ParameterizedTypeImpl.make( | ||
| 408 | inClass, params, inClass.getEnclosingClass()); | ||
| 409 | } | ||
| 410 | } | ||
Binary file not shown.
| @@ -0,0 +1,91 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans; | ||
| 26 | |||
| 27 | import java.lang.ref.Reference; | ||
| 28 | import java.lang.ref.WeakReference; | ||
| 29 | |||
| 30 | import java.util.Map; | ||
| 31 | import java.util.WeakHashMap; | ||
| 32 | |||
| 33 | /** | ||
| 34 | * A hashtable-based cache with weak keys and weak values. | ||
| 35 | * An entry in the map will be automatically removed | ||
| 36 | * when its key is no longer in the ordinary use. | ||
| 37 | * A value will be automatically removed as well | ||
| 38 | * when it is no longer in the ordinary use. | ||
| 39 | * | ||
| 40 | * @since 1.7 | ||
| 41 | * | ||
| 42 | * @author Sergey A. Malenkov | ||
| 43 | */ | ||
| 44 | public final class WeakCache<K, V> { | ||
| 45 | private final Map<K, Reference<V>> map = new WeakHashMap<K, Reference<V>>(); | ||
| 46 | |||
| 47 | /** | ||
| 48 | * Returns a value to which the specified {@code key} is mapped, | ||
| 49 | * or {@code null} if this map contains no mapping for the {@code key}. | ||
| 50 | * | ||
| 51 | * @param key the key whose associated value is returned | ||
| 52 | * @return a value to which the specified {@code key} is mapped | ||
| 53 | */ | ||
| 54 | public V get(K key) { | ||
| 55 | Reference<V> reference = this.map.get(key); | ||
| 56 | if (reference == null) { | ||
| 57 | return null; | ||
| 58 | } | ||
| 59 | V value = reference.get(); | ||
| 60 | if (value == null) { | ||
| 61 | this.map.remove(key); | ||
| 62 | } | ||
| 63 | return value; | ||
| 64 | } | ||
| 65 | |||
| 66 | /** | ||
| 67 | * Associates the specified {@code value} with the specified {@code key}. | ||
| 68 | * Removes the mapping for the specified {@code key} from this cache | ||
| 69 | * if it is present and the specified {@code value} is {@code null}. | ||
| 70 | * If the cache previously contained a mapping for the {@code key}, | ||
| 71 | * the old value is replaced by the specified {@code value}. | ||
| 72 | * | ||
| 73 | * @param key the key with which the specified value is associated | ||
| 74 | * @param value the value to be associated with the specified key | ||
| 75 | */ | ||
| 76 | public void put(K key, V value) { | ||
| 77 | if (value != null) { | ||
| 78 | this.map.put(key, new WeakReference<V>(value)); | ||
| 79 | } | ||
| 80 | else { | ||
| 81 | this.map.remove(key); | ||
| 82 | } | ||
| 83 | } | ||
| 84 | |||
| 85 | /** | ||
| 86 | * Removes all of the mappings from this cache. | ||
| 87 | */ | ||
| 88 | public void clear() { | ||
| 89 | this.map.clear(); | ||
| 90 | } | ||
| 91 | } | ||
Binary file not shown.
| @@ -0,0 +1,161 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans; | ||
| 26 | |||
| 27 | import java.lang.reflect.Type; | ||
| 28 | import java.lang.reflect.WildcardType; | ||
| 29 | import java.util.Arrays; | ||
| 30 | |||
| 31 | /** | ||
| 32 | * This class implements {@link WildcardType WildcardType} compatibly with the JDK's | ||
| 33 | * {@link sun.reflect.generics.reflectiveObjects.WildcardTypeImpl WildcardTypeImpl}. | ||
| 34 | * Unfortunately we can't use the JDK's | ||
| 35 | * {@link sun.reflect.generics.reflectiveObjects.WildcardTypeImpl WildcardTypeImpl} here as we do for | ||
| 36 | * {@link sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl ParameterizedTypeImpl} and | ||
| 37 | * {@link sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl GenericArrayTypeImpl}, | ||
| 38 | * because {@link sun.reflect.generics.reflectiveObjects.WildcardTypeImpl WildcardTypeImpl}'s | ||
| 39 | * constructor takes parameters representing intermediate structures obtained during class-file parsing. | ||
| 40 | * We could reconstruct versions of those structures but it would be more trouble than it's worth. | ||
| 41 | * | ||
| 42 | * @since 1.7 | ||
| 43 | * | ||
| 44 | * @author Eamonn McManus | ||
| 45 | * @author Sergey Malenkov | ||
| 46 | */ | ||
| 47 | final class WildcardTypeImpl implements WildcardType { | ||
| 48 | private final Type[] upperBounds; | ||
| 49 | private final Type[] lowerBounds; | ||
| 50 | |||
| 51 | /** | ||
| 52 | * Creates a wildcard type with the requested bounds. | ||
| 53 | * Note that the array arguments are not cloned | ||
| 54 | * because instances of this class are never constructed | ||
| 55 | * from outside the containing package. | ||
| 56 | * | ||
| 57 | * @param upperBounds the array of types representing | ||
| 58 | * the upper bound(s) of this type variable | ||
| 59 | * @param lowerBounds the array of types representing | ||
| 60 | * the lower bound(s) of this type variable | ||
| 61 | */ | ||
| 62 | WildcardTypeImpl(Type[] upperBounds, Type[] lowerBounds) { | ||
| 63 | this.upperBounds = upperBounds; | ||
| 64 | this.lowerBounds = lowerBounds; | ||
| 65 | } | ||
| 66 | |||
| 67 | /** | ||
| 68 | * Returns an array of {@link Type Type} objects | ||
| 69 | * representing the upper bound(s) of this type variable. | ||
| 70 | * Note that if no upper bound is explicitly declared, | ||
| 71 | * the upper bound is {@link Object Object}. | ||
| 72 | * | ||
| 73 | * @return an array of types representing | ||
| 74 | * the upper bound(s) of this type variable | ||
| 75 | */ | ||
| 76 | public Type[] getUpperBounds() { | ||
| 77 | return this.upperBounds.clone(); | ||
| 78 | } | ||
| 79 | |||
| 80 | /** | ||
| 81 | * Returns an array of {@link Type Type} objects | ||
| 82 | * representing the lower bound(s) of this type variable. | ||
| 83 | * Note that if no lower bound is explicitly declared, | ||
| 84 | * the lower bound is the type of {@code null}. | ||
| 85 | * In this case, a zero length array is returned. | ||
| 86 | * | ||
| 87 | * @return an array of types representing | ||
| 88 | * the lower bound(s) of this type variable | ||
| 89 | */ | ||
| 90 | public Type[] getLowerBounds() { | ||
| 91 | return this.lowerBounds.clone(); | ||
| 92 | } | ||
| 93 | |||
| 94 | /** | ||
| 95 | * Indicates whether some other object is "equal to" this one. | ||
| 96 | * It is implemented compatibly with the JDK's | ||
| 97 | * {@link sun.reflect.generics.reflectiveObjects.WildcardTypeImpl WildcardTypeImpl}. | ||
| 98 | * | ||
| 99 | * @param object the reference object with which to compare | ||
| 100 | * @return {@code true} if this object is the same as the object argument; | ||
| 101 | * {@code false} otherwise | ||
| 102 | * @see sun.reflect.generics.reflectiveObjects.WildcardTypeImpl#equals | ||
| 103 | */ | ||
| 104 | @Override | ||
| 105 | public boolean equals(Object object) { | ||
| 106 | if (object instanceof WildcardType) { | ||
| 107 | WildcardType type = (WildcardType) object; | ||
| 108 | return Arrays.equals(this.upperBounds, type.getUpperBounds()) | ||
| 109 | && Arrays.equals(this.lowerBounds, type.getLowerBounds()); | ||
| 110 | } | ||
| 111 | return false; | ||
| 112 | } | ||
| 113 | |||
| 114 | /** | ||
| 115 | * Returns a hash code value for the object. | ||
| 116 | * It is implemented compatibly with the JDK's | ||
| 117 | * {@link sun.reflect.generics.reflectiveObjects.WildcardTypeImpl WildcardTypeImpl}. | ||
| 118 | * | ||
| 119 | * @return a hash code value for this object | ||
| 120 | * @see sun.reflect.generics.reflectiveObjects.WildcardTypeImpl#hashCode | ||
| 121 | */ | ||
| 122 | @Override | ||
| 123 | public int hashCode() { | ||
| 124 | return Arrays.hashCode(this.upperBounds) | ||
| 125 | ^ Arrays.hashCode(this.lowerBounds); | ||
| 126 | } | ||
| 127 | |||
| 128 | /** | ||
| 129 | * Returns a string representation of the object. | ||
| 130 | * It is implemented compatibly with the JDK's | ||
| 131 | * {@link sun.reflect.generics.reflectiveObjects.WildcardTypeImpl WildcardTypeImpl}. | ||
| 132 | * | ||
| 133 | * @return a string representation of the object | ||
| 134 | * @see sun.reflect.generics.reflectiveObjects.WildcardTypeImpl#toString | ||
| 135 | */ | ||
| 136 | @Override | ||
| 137 | public String toString() { | ||
| 138 | StringBuilder sb; | ||
| 139 | Type[] bounds; | ||
| 140 | if (this.lowerBounds.length == 0) { | ||
| 141 | if (this.upperBounds.length == 0 || Object.class == this.upperBounds[0]) { | ||
| 142 | return "?"; | ||
| 143 | } | ||
| 144 | bounds = this.upperBounds; | ||
| 145 | sb = new StringBuilder("? extends "); | ||
| 146 | } | ||
| 147 | else { | ||
| 148 | bounds = this.lowerBounds; | ||
| 149 | sb = new StringBuilder("? super "); | ||
| 150 | } | ||
| 151 | for (int i = 0; i < bounds.length; i++) { | ||
| 152 | if (i > 0) { | ||
| 153 | sb.append(" & "); | ||
| 154 | } | ||
| 155 | sb.append((bounds[i] instanceof Class) | ||
| 156 | ? ((Class) bounds[i]).getName() | ||
| 157 | : bounds[i].toString()); | ||
| 158 | } | ||
| 159 | return sb.toString(); | ||
| 160 | } | ||
| 161 | } | ||
Binary file not shown.
| @@ -0,0 +1,105 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.decoder; | ||
| 26 | |||
| 27 | /** | ||
| 28 | * This is base class that simplifies access to entities (fields or properties). | ||
| 29 | * The {@code name} attribute specifies the name of the accessible entity. | ||
| 30 | * The element defines getter if it contains no argument | ||
| 31 | * or setter if it contains one argument. | ||
| 32 | * | ||
| 33 | * @since 1.7 | ||
| 34 | * | ||
| 35 | * @author Sergey A. Malenkov | ||
| 36 | */ | ||
| 37 | abstract class AccessorElementHandler extends ElementHandler { | ||
| 38 | private String name; | ||
| 39 | private ValueObject value; | ||
| 40 | |||
| 41 | /** | ||
| 42 | * Parses attributes of the element. | ||
| 43 | * The following atributes are supported: | ||
| 44 | * <dl> | ||
| 45 | * <dt>name | ||
| 46 | * <dd>the name of the accessible entity | ||
| 47 | * <dt>id | ||
| 48 | * <dd>the identifier of the variable that is intended to store the result | ||
| 49 | * </dl> | ||
| 50 | * | ||
| 51 | * @param name the attribute name | ||
| 52 | * @param value the attribute value | ||
| 53 | */ | ||
| 54 | @Override | ||
| 55 | public void addAttribute(String name, String value) { | ||
| 56 | if (name.equals("name")) { // NON-NLS: the attribute name | ||
| 57 | this.name = value; | ||
| 58 | } else { | ||
| 59 | super.addAttribute(name, value); | ||
| 60 | } | ||
| 61 | } | ||
| 62 | |||
| 63 | /** | ||
| 64 | * Adds the argument that is used to set the value of this element. | ||
| 65 | * | ||
| 66 | * @param argument the value of the element that contained in this one | ||
| 67 | */ | ||
| 68 | @Override | ||
| 69 | protected final void addArgument(Object argument) { | ||
| 70 | if (this.value != null) { | ||
| 71 | throw new IllegalStateException("Could not add argument to evaluated element"); | ||
| 72 | } | ||
| 73 | setValue(this.name, argument); | ||
| 74 | this.value = ValueObjectImpl.VOID; | ||
| 75 | } | ||
| 76 | |||
| 77 | /** | ||
| 78 | * Returns the value of this element. | ||
| 79 | * | ||
| 80 | * @return the value of this element | ||
| 81 | */ | ||
| 82 | @Override | ||
| 83 | protected final ValueObject getValueObject() { | ||
| 84 | if (this.value == null) { | ||
| 85 | this.value = ValueObjectImpl.create(getValue(this.name)); | ||
| 86 | } | ||
| 87 | return this.value; | ||
| 88 | } | ||
| 89 | |||
| 90 | /** | ||
| 91 | * Returns the value of the entity with specified {@code name}. | ||
| 92 | * | ||
| 93 | * @param name the name of the accessible entity | ||
| 94 | * @return the value of the specified entity | ||
| 95 | */ | ||
| 96 | protected abstract Object getValue(String name); | ||
| 97 | |||
| 98 | /** | ||
| 99 | * Sets the new value for the entity with specified {@code name}. | ||
| 100 | * | ||
| 101 | * @param name the name of the accessible entity | ||
| 102 | * @param value the new value for the specified entity | ||
| 103 | */ | ||
| 104 | protected abstract void setValue(String name, Object value); | ||
| 105 | } | ||
Binary file not shown.
| @@ -0,0 +1,133 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.decoder; | ||
| 26 | |||
| 27 | import java.lang.reflect.Array; | ||
| 28 | |||
| 29 | /** | ||
| 30 | * This class is intended to handle <array> element, | ||
| 31 | * that is used to array creation. | ||
| 32 | * The {@code length} attribute specifies the length of the array. | ||
| 33 | * The {@code class} attribute specifies the elements type. | ||
| 34 | * The {@link Object} type is used by default. | ||
| 35 | * For example:<pre> | ||
| 36 | * <array length="10"/></pre> | ||
| 37 | * is equivalent to {@code new Component[10]} in Java code. | ||
| 38 | * The {@code set} and {@code get} methods, | ||
| 39 | * as defined in the {@link java.util.List} interface, | ||
| 40 | * can be used as if they could be applied to array instances. | ||
| 41 | * The {@code index} attribute can thus be used with arrays. | ||
| 42 | * For example:<pre> | ||
| 43 | * <array length="3" class="java.lang.String"> | ||
| 44 | * <void index="1"> | ||
| 45 | * <string>Hello, world</string> | ||
| 46 | * </void> | ||
| 47 | * </array></pre> | ||
| 48 | * is equivalent to the following Java code:<pre> | ||
| 49 | * String[] s = new String[3]; | ||
| 50 | * s[1] = "Hello, world";</pre> | ||
| 51 | * It is possible to omit the {@code length} attribute and | ||
| 52 | * specify the values directly, without using {@code void} tags. | ||
| 53 | * The length of the array is equal to the number of values specified. | ||
| 54 | * For example:<pre> | ||
| 55 | * <array id="array" class="int"> | ||
| 56 | * <int>123</int> | ||
| 57 | * <int>456</int> | ||
| 58 | * </array></pre> | ||
| 59 | * is equivalent to {@code int[] array = {123, 456}} in Java code. | ||
| 60 | * <p>The following atributes are supported: | ||
| 61 | * <dl> | ||
| 62 | * <dt>length | ||
| 63 | * <dd>the array length | ||
| 64 | * <dt>class | ||
| 65 | * <dd>the type of object for instantiation | ||
| 66 | * <dt>id | ||
| 67 | * <dd>the identifier of the variable that is intended to store the result | ||
| 68 | * </dl> | ||
| 69 | * | ||
| 70 | * @since 1.7 | ||
| 71 | * | ||
| 72 | * @author Sergey A. Malenkov | ||
| 73 | */ | ||
| 74 | final class ArrayElementHandler extends NewElementHandler { | ||
| 75 | private Integer length; | ||
| 76 | |||
| 77 | /** | ||
| 78 | * Parses attributes of the element. | ||
| 79 | * The following atributes are supported: | ||
| 80 | * <dl> | ||
| 81 | * <dt>length | ||
| 82 | * <dd>the array length | ||
| 83 | * <dt>class | ||
| 84 | * <dd>the type of object for instantiation | ||
| 85 | * <dt>id | ||
| 86 | * <dd>the identifier of the variable that is intended to store the result | ||
| 87 | * </dl> | ||
| 88 | * | ||
| 89 | * @param name the attribute name | ||
| 90 | * @param value the attribute value | ||
| 91 | */ | ||
| 92 | @Override | ||
| 93 | public void addAttribute(String name, String value) { | ||
| 94 | if (name.equals("length")) { // NON-NLS: the attribute name | ||
| 95 | this.length = Integer.valueOf(value); | ||
| 96 | } else { | ||
| 97 | super.addAttribute(name, value); | ||
| 98 | } | ||
| 99 | } | ||
| 100 | |||
| 101 | /** | ||
| 102 | * Calculates the value of this element | ||
| 103 | * if the lentgh attribute is set. | ||
| 104 | */ | ||
| 105 | @Override | ||
| 106 | public void startElement() { | ||
| 107 | if (this.length != null) { | ||
| 108 | getValueObject(); | ||
| 109 | } | ||
| 110 | } | ||
| 111 | |||
| 112 | /** | ||
| 113 | * Creates an instance of the array. | ||
| 114 | * | ||
| 115 | * @param type the base class | ||
| 116 | * @param args the array of arguments | ||
| 117 | * @return the value of this element | ||
| 118 | */ | ||
| 119 | @Override | ||
| 120 | protected ValueObject getValueObject(Class<?> type, Object[] args) { | ||
| 121 | if (type == null) { | ||
| 122 | type = Object.class; | ||
| 123 | } | ||
| 124 | if (this.length != null) { | ||
| 125 | return ValueObjectImpl.create(Array.newInstance(type, this.length)); | ||
| 126 | } | ||
| 127 | Object array = Array.newInstance(type, args.length); | ||
| 128 | for (int i = 0; i < args.length; i++) { | ||
| 129 | Array.set(array, i, args[i]); | ||
| 130 | } | ||
| 131 | return ValueObjectImpl.create(array); | ||
| 132 | } | ||
| 133 | } | ||
Binary file not shown.
| @@ -0,0 +1,69 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.decoder; | ||
| 26 | |||
| 27 | /** | ||
| 28 | * This class is intended to handle <boolean> element. | ||
| 29 | * This element specifies {@code boolean} values. | ||
| 30 | * The class {@link Boolean} is used as wrapper for these values. | ||
| 31 | * The result value is created from text of the body of this element. | ||
| 32 | * The body parsing is described in the class {@link StringElementHandler}. | ||
| 33 | * For example:<pre> | ||
| 34 | * <boolean>true</boolean></pre> | ||
| 35 | * is shortcut to<pre> | ||
| 36 | * <method name="valueOf" class="java.lang.Boolean"> | ||
| 37 | * <string>true</string> | ||
| 38 | * </method></pre> | ||
| 39 | * which is equivalent to {@code Boolean.valueOf("true")} in Java code. | ||
| 40 | * <p>The following atribute is supported: | ||
| 41 | * <dl> | ||
| 42 | * <dt>id | ||
| 43 | * <dd>the identifier of the variable that is intended to store the result | ||
| 44 | * </dl> | ||
| 45 | * | ||
| 46 | * @since 1.7 | ||
| 47 | * | ||
| 48 | * @author Sergey A. Malenkov | ||
| 49 | */ | ||
| 50 | final class BooleanElementHandler extends StringElementHandler { | ||
| 51 | |||
| 52 | /** | ||
| 53 | * Creates {@code boolean} value from | ||
| 54 | * the text of the body of this element. | ||
| 55 | * | ||
| 56 | * @param argument the text of the body | ||
| 57 | * @return evaluated {@code boolean} value | ||
| 58 | */ | ||
| 59 | @Override | ||
| 60 | public Object getValue(String argument) { | ||
| 61 | if (Boolean.TRUE.toString().equalsIgnoreCase(argument)) { | ||
| 62 | return Boolean.TRUE; | ||
| 63 | } | ||
| 64 | if (Boolean.FALSE.toString().equalsIgnoreCase(argument)) { | ||
| 65 | return Boolean.FALSE; | ||
| 66 | } | ||
| 67 | throw new IllegalArgumentException("Unsupported boolean argument: " + argument); | ||
| 68 | } | ||
| 69 | } | ||
Binary file not shown.
| @@ -0,0 +1,63 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.decoder; | ||
| 26 | |||
| 27 | /** | ||
| 28 | * This class is intended to handle <byte> element. | ||
| 29 | * This element specifies {@code byte} values. | ||
| 30 | * The class {@link Byte} is used as wrapper for these values. | ||
| 31 | * The result value is created from text of the body of this element. | ||
| 32 | * The body parsing is described in the class {@link StringElementHandler}. | ||
| 33 | * For example:<pre> | ||
| 34 | * <byte>127</byte></pre> | ||
| 35 | * is shortcut to<pre> | ||
| 36 | * <method name="decode" class="java.lang.Byte"> | ||
| 37 | * <string>127</string> | ||
| 38 | * </method></pre> | ||
| 39 | * which is equivalent to {@code Byte.decode("127")} in Java code. | ||
| 40 | * <p>The following atribute is supported: | ||
| 41 | * <dl> | ||
| 42 | * <dt>id | ||
| 43 | * <dd>the identifier of the variable that is intended to store the result | ||
| 44 | * </dl> | ||
| 45 | * | ||
| 46 | * @since 1.7 | ||
| 47 | * | ||
| 48 | * @author Sergey A. Malenkov | ||
| 49 | */ | ||
| 50 | final class ByteElementHandler extends StringElementHandler { | ||
| 51 | |||
| 52 | /** | ||
| 53 | * Creates {@code byte} value from | ||
| 54 | * the text of the body of this element. | ||
| 55 | * | ||
| 56 | * @param argument the text of the body | ||
| 57 | * @return evaluated {@code byte} value | ||
| 58 | */ | ||
| 59 | @Override | ||
| 60 | public Object getValue(String argument) { | ||
| 61 | return Byte.decode(argument); | ||
| 62 | } | ||
| 63 | } | ||
Binary file not shown.
| @@ -0,0 +1,92 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.decoder; | ||
| 26 | |||
| 27 | /** | ||
| 28 | * This class is intended to handle <char> element. | ||
| 29 | * This element specifies {@code char} values. | ||
| 30 | * The class {@link Character} is used as wrapper for these values. | ||
| 31 | * The result value is created from text of the body of this element. | ||
| 32 | * The body parsing is described in the class {@link StringElementHandler}. | ||
| 33 | * For example:<pre> | ||
| 34 | * <char>X</char></pre> | ||
| 35 | * which is equivalent to {@code Character.valueOf('X')} in Java code. | ||
| 36 | * <p>The following atributes are supported: | ||
| 37 | * <dl> | ||
| 38 | * <dt>code | ||
| 39 | * <dd>this attribute specifies character code | ||
| 40 | * <dt>id | ||
| 41 | * <dd>the identifier of the variable that is intended to store the result | ||
| 42 | * </dl> | ||
| 43 | * The {@code code} attribute can be used for characters | ||
| 44 | * that are illegal in XML document, for example:<pre> | ||
| 45 | * <char code="0"/></pre> | ||
| 46 | * | ||
| 47 | * @since 1.7 | ||
| 48 | * | ||
| 49 | * @author Sergey A. Malenkov | ||
| 50 | */ | ||
| 51 | final class CharElementHandler extends StringElementHandler { | ||
| 52 | |||
| 53 | /** | ||
| 54 | * Parses attributes of the element. | ||
| 55 | * The following atributes are supported: | ||
| 56 | * <dl> | ||
| 57 | * <dt>code | ||
| 58 | * <dd>this attribute specifies character code | ||
| 59 | * <dt>id | ||
| 60 | * <dd>the identifier of the variable that is intended to store the result | ||
| 61 | * </dl> | ||
| 62 | * | ||
| 63 | * @param name the attribute name | ||
| 64 | * @param value the attribute value | ||
| 65 | */ | ||
| 66 | @Override | ||
| 67 | public void addAttribute(String name, String value) { | ||
| 68 | if (name.equals("code")) { // NON-NLS: the attribute name | ||
| 69 | int code = Integer.decode(value); | ||
| 70 | for (char ch : Character.toChars(code)) { | ||
| 71 | addCharacter(ch); | ||
| 72 | } | ||
| 73 | } else { | ||
| 74 | super.addAttribute(name, value); | ||
| 75 | } | ||
| 76 | } | ||
| 77 | |||
| 78 | /** | ||
| 79 | * Creates {@code char} value from | ||
| 80 | * the text of the body of this element. | ||
| 81 | * | ||
| 82 | * @param argument the text of the body | ||
| 83 | * @return evaluated {@code char} value | ||
| 84 | */ | ||
| 85 | @Override | ||
| 86 | public Object getValue(String argument) { | ||
| 87 | if (argument.length() != 1) { | ||
| 88 | throw new IllegalArgumentException("Wrong characters count"); | ||
| 89 | } | ||
| 90 | return Character.valueOf(argument.charAt(0)); | ||
| 91 | } | ||
| 92 | } | ||
Binary file not shown.
| @@ -0,0 +1,62 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.decoder; | ||
| 26 | |||
| 27 | /** | ||
| 28 | * This class is intended to handle <class> element. | ||
| 29 | * This element specifies {@link Class} values. | ||
| 30 | * The result value is created from text of the body of this element. | ||
| 31 | * The body parsing is described in the class {@link StringElementHandler}. | ||
| 32 | * For example:<pre> | ||
| 33 | * <class>java.lang.Class</class></pre> | ||
| 34 | * is shortcut to<pre> | ||
| 35 | * <method name="forName" class="java.lang.Class"> | ||
| 36 | * <string>java.lang.Class</string> | ||
| 37 | * </method></pre> | ||
| 38 | * which is equivalent to {@code Class.forName("java.lang.Class")} in Java code. | ||
| 39 | * <p>The following atribute is supported: | ||
| 40 | * <dl> | ||
| 41 | * <dt>id | ||
| 42 | * <dd>the identifier of the variable that is intended to store the result | ||
| 43 | * </dl> | ||
| 44 | * | ||
| 45 | * @since 1.7 | ||
| 46 | * | ||
| 47 | * @author Sergey A. Malenkov | ||
| 48 | */ | ||
| 49 | final class ClassElementHandler extends StringElementHandler { | ||
| 50 | |||
| 51 | /** | ||
| 52 | * Creates class by the name from | ||
| 53 | * the text of the body of this element. | ||
| 54 | * | ||
| 55 | * @param argument the text of the body | ||
| 56 | * @return evaluated {@code Class} value | ||
| 57 | */ | ||
| 58 | @Override | ||
| 59 | public Object getValue(String argument) { | ||
| 60 | return getOwner().findClass(argument); | ||
| 61 | } | ||
| 62 | } | ||
Binary file not shown.
| @@ -0,0 +1,389 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.decoder; | ||
| 26 | |||
| 27 | import com.sun.beans.finder.ClassFinder; | ||
| 28 | |||
| 29 | import java.beans.ExceptionListener; | ||
| 30 | |||
| 31 | import java.io.IOException; | ||
| 32 | |||
| 33 | import java.lang.ref.Reference; | ||
| 34 | import java.lang.ref.WeakReference; | ||
| 35 | |||
| 36 | import java.util.ArrayList; | ||
| 37 | import java.util.HashMap; | ||
| 38 | import java.util.List; | ||
| 39 | import java.util.Map; | ||
| 40 | |||
| 41 | import javax.xml.parsers.ParserConfigurationException; | ||
| 42 | import javax.xml.parsers.SAXParserFactory; | ||
| 43 | |||
| 44 | import org.xml.sax.Attributes; | ||
| 45 | import org.xml.sax.InputSource; | ||
| 46 | import org.xml.sax.SAXException; | ||
| 47 | import org.xml.sax.helpers.DefaultHandler; | ||
| 48 | |||
| 49 | /** | ||
| 50 | * The main class to parse JavaBeans XML archive. | ||
| 51 | * | ||
| 52 | * @since 1.7 | ||
| 53 | * | ||
| 54 | * @author Sergey A. Malenkov | ||
| 55 | * | ||
| 56 | * @see ElementHandler | ||
| 57 | */ | ||
| 58 | public final class DocumentHandler extends DefaultHandler { | ||
| 59 | private final Map<String, Class<? extends ElementHandler>> handlers = new HashMap<String, Class<? extends ElementHandler>>(); | ||
| 60 | |||
| 61 | private final Map<String, Object> environment = new HashMap<String, Object>(); | ||
| 62 | |||
| 63 | private final List<Object> objects = new ArrayList<Object>(); | ||
| 64 | |||
| 65 | private Reference<ClassLoader> loader; | ||
| 66 | private ExceptionListener listener; | ||
| 67 | private Object owner; | ||
| 68 | |||
| 69 | private ElementHandler handler; | ||
| 70 | |||
| 71 | /** | ||
| 72 | * Creates new instance of document handler. | ||
| 73 | */ | ||
| 74 | public DocumentHandler() { | ||
| 75 | setElementHandler("java", JavaElementHandler.class); // NON-NLS: the element name | ||
| 76 | setElementHandler("null", NullElementHandler.class); // NON-NLS: the element name | ||
| 77 | setElementHandler("array", ArrayElementHandler.class); // NON-NLS: the element name | ||
| 78 | setElementHandler("class", ClassElementHandler.class); // NON-NLS: the element name | ||
| 79 | setElementHandler("string", StringElementHandler.class); // NON-NLS: the element name | ||
| 80 | setElementHandler("object", ObjectElementHandler.class); // NON-NLS: the element name | ||
| 81 | |||
| 82 | setElementHandler("void", VoidElementHandler.class); // NON-NLS: the element name | ||
| 83 | setElementHandler("char", CharElementHandler.class); // NON-NLS: the element name | ||
| 84 | setElementHandler("byte", ByteElementHandler.class); // NON-NLS: the element name | ||
| 85 | setElementHandler("short", ShortElementHandler.class); // NON-NLS: the element name | ||
| 86 | setElementHandler("int", IntElementHandler.class); // NON-NLS: the element name | ||
| 87 | setElementHandler("long", LongElementHandler.class); // NON-NLS: the element name | ||
| 88 | setElementHandler("float", FloatElementHandler.class); // NON-NLS: the element name | ||
| 89 | setElementHandler("double", DoubleElementHandler.class); // NON-NLS: the element name | ||
| 90 | setElementHandler("boolean", BooleanElementHandler.class); // NON-NLS: the element name | ||
| 91 | |||
| 92 | // some handlers for new elements | ||
| 93 | setElementHandler("new", NewElementHandler.class); // NON-NLS: the element name | ||
| 94 | setElementHandler("var", VarElementHandler.class); // NON-NLS: the element name | ||
| 95 | setElementHandler("true", TrueElementHandler.class); // NON-NLS: the element name | ||
| 96 | setElementHandler("false", FalseElementHandler.class); // NON-NLS: the element name | ||
| 97 | setElementHandler("field", FieldElementHandler.class); // NON-NLS: the element name | ||
| 98 | setElementHandler("method", MethodElementHandler.class); // NON-NLS: the element name | ||
| 99 | setElementHandler("property", PropertyElementHandler.class); // NON-NLS: the element name | ||
| 100 | } | ||
| 101 | |||
| 102 | /** | ||
| 103 | * Returns the class loader used to instantiate objects. | ||
| 104 | * If the class loader has not been explicitly set | ||
| 105 | * then {@code null} is returned. | ||
| 106 | * | ||
| 107 | * @return the class loader used to instantiate objects | ||
| 108 | */ | ||
| 109 | public ClassLoader getClassLoader() { | ||
| 110 | return (this.loader != null) | ||
| 111 | ? this.loader.get() | ||
| 112 | : null; | ||
| 113 | } | ||
| 114 | |||
| 115 | /** | ||
| 116 | * Sets the class loader used to instantiate objects. | ||
| 117 | * If the class loader is not set | ||
| 118 | * then default class loader will be used. | ||
| 119 | * | ||
| 120 | * @param loader a classloader to use | ||
| 121 | */ | ||
| 122 | public void setClassLoader(ClassLoader loader) { | ||
| 123 | this.loader = new WeakReference<ClassLoader>(loader); | ||
| 124 | } | ||
| 125 | |||
| 126 | /** | ||
| 127 | * Returns the exception listener for parsing. | ||
| 128 | * The exception listener is notified | ||
| 129 | * when handler catches recoverable exceptions. | ||
| 130 | * If the exception listener has not been explicitly set | ||
| 131 | * then default exception listener is returned. | ||
| 132 | * | ||
| 133 | * @return the exception listener for parsing | ||
| 134 | */ | ||
| 135 | public ExceptionListener getExceptionListener() { | ||
| 136 | return this.listener; | ||
| 137 | } | ||
| 138 | |||
| 139 | /** | ||
| 140 | * Sets the exception listener for parsing. | ||
| 141 | * The exception listener is notified | ||
| 142 | * when handler catches recoverable exceptions. | ||
| 143 | * | ||
| 144 | * @param listener the exception listener for parsing | ||
| 145 | */ | ||
| 146 | public void setExceptionListener(ExceptionListener listener) { | ||
| 147 | this.listener = listener; | ||
| 148 | } | ||
| 149 | |||
| 150 | /** | ||
| 151 | * Returns the owner of this document handler. | ||
| 152 | * | ||
| 153 | * @return the owner of this document handler | ||
| 154 | */ | ||
| 155 | public Object getOwner() { | ||
| 156 | return this.owner; | ||
| 157 | } | ||
| 158 | |||
| 159 | /** | ||
| 160 | * Sets the owner of this document handler. | ||
| 161 | * | ||
| 162 | * @param owner the owner of this document handler | ||
| 163 | */ | ||
| 164 | public void setOwner(Object owner) { | ||
| 165 | this.owner = owner; | ||
| 166 | } | ||
| 167 | |||
| 168 | /** | ||
| 169 | * Returns the handler for the element with specified name. | ||
| 170 | * | ||
| 171 | * @param name the name of the element | ||
| 172 | * @return the corresponding element handler | ||
| 173 | */ | ||
| 174 | public Class<? extends ElementHandler> getElementHandler(String name) { | ||
| 175 | Class<? extends ElementHandler> type = this.handlers.get(name); | ||
| 176 | if (type == null) { | ||
| 177 | throw new IllegalArgumentException("Unsupported element: " + name); | ||
| 178 | } | ||
| 179 | return type; | ||
| 180 | } | ||
| 181 | |||
| 182 | /** | ||
| 183 | * Sets the handler for the element with specified name. | ||
| 184 | * | ||
| 185 | * @param name the name of the element | ||
| 186 | * @param handler the corresponding element handler | ||
| 187 | */ | ||
| 188 | public void setElementHandler(String name, Class<? extends ElementHandler> handler) { | ||
| 189 | this.handlers.put(name, handler); | ||
| 190 | } | ||
| 191 | |||
| 192 | /** | ||
| 193 | * Indicates whether the variable with specified identifier is defined. | ||
| 194 | * | ||
| 195 | * @param id the identifier | ||
| 196 | * @return @{code true} if the variable is defined; | ||
| 197 | * @{code false} otherwise | ||
| 198 | */ | ||
| 199 | public boolean hasVariable(String id) { | ||
| 200 | return this.environment.containsKey(id); | ||
| 201 | } | ||
| 202 | |||
| 203 | /** | ||
| 204 | * Returns the value of the variable with specified identifier. | ||
| 205 | * | ||
| 206 | * @param id the identifier | ||
| 207 | * @return the value of the variable | ||
| 208 | */ | ||
| 209 | public Object getVariable(String id) { | ||
| 210 | if (!this.environment.containsKey(id)) { | ||
| 211 | throw new IllegalArgumentException("Unbound variable: " + id); | ||
| 212 | } | ||
| 213 | return this.environment.get(id); | ||
| 214 | } | ||
| 215 | |||
| 216 | /** | ||
| 217 | * Sets new value of the variable with specified identifier. | ||
| 218 | * | ||
| 219 | * @param id the identifier | ||
| 220 | * @param value new value of the variable | ||
| 221 | */ | ||
| 222 | public void setVariable(String id, Object value) { | ||
| 223 | this.environment.put(id, value); | ||
| 224 | } | ||
| 225 | |||
| 226 | /** | ||
| 227 | * Returns the array of readed objects. | ||
| 228 | * | ||
| 229 | * @return the array of readed objects | ||
| 230 | */ | ||
| 231 | public Object[] getObjects() { | ||
| 232 | return this.objects.toArray(); | ||
| 233 | } | ||
| 234 | |||
| 235 | /** | ||
| 236 | * Adds the object to the list of readed objects. | ||
| 237 | * | ||
| 238 | * @param object the object that is readed from XML document | ||
| 239 | */ | ||
| 240 | void addObject(Object object) { | ||
| 241 | this.objects.add(object); | ||
| 242 | } | ||
| 243 | |||
| 244 | /** | ||
| 245 | * Prepares this handler to read objects from XML document. | ||
| 246 | */ | ||
| 247 | @Override | ||
| 248 | public void startDocument() { | ||
| 249 | this.objects.clear(); | ||
| 250 | this.handler = null; | ||
| 251 | } | ||
| 252 | |||
| 253 | /** | ||
| 254 | * Parses opening tag of XML element | ||
| 255 | * using corresponding element handler. | ||
| 256 | * | ||
| 257 | * @param uri the namespace URI, or the empty string | ||
| 258 | * if the element has no namespace URI or | ||
| 259 | * if namespace processing is not being performed | ||
| 260 | * @param localName the local name (without prefix), or the empty string | ||
| 261 | * if namespace processing is not being performed | ||
| 262 | * @param qName the qualified name (with prefix), or the empty string | ||
| 263 | * if qualified names are not available | ||
| 264 | * @param attributes the attributes attached to the element | ||
| 265 | */ | ||
| 266 | @Override | ||
| 267 | public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { | ||
| 268 | ElementHandler parent = this.handler; | ||
| 269 | try { | ||
| 270 | this.handler = getElementHandler(qName).newInstance(); | ||
| 271 | this.handler.setOwner(this); | ||
| 272 | this.handler.setParent(parent); | ||
| 273 | } | ||
| 274 | catch (Exception exception) { | ||
| 275 | throw new SAXException(exception); | ||
| 276 | } | ||
| 277 | for (int i = 0; i < attributes.getLength(); i++) | ||
| 278 | try { | ||
| 279 | String name = attributes.getQName(i); | ||
| 280 | String value = attributes.getValue(i); | ||
| 281 | this.handler.addAttribute(name, value); | ||
| 282 | } | ||
| 283 | catch (RuntimeException exception) { | ||
| 284 | handleException(exception); | ||
| 285 | } | ||
| 286 | |||
| 287 | this.handler.startElement(); | ||
| 288 | } | ||
| 289 | |||
| 290 | /** | ||
| 291 | * Parses closing tag of XML element | ||
| 292 | * using corresponding element handler. | ||
| 293 | * | ||
| 294 | * @param uri the namespace URI, or the empty string | ||
| 295 | * if the element has no namespace URI or | ||
| 296 | * if namespace processing is not being performed | ||
| 297 | * @param localName the local name (without prefix), or the empty string | ||
| 298 | * if namespace processing is not being performed | ||
| 299 | * @param qName the qualified name (with prefix), or the empty string | ||
| 300 | * if qualified names are not available | ||
| 301 | */ | ||
| 302 | @Override | ||
| 303 | public void endElement(String uri, String localName, String qName) { | ||
| 304 | try { | ||
| 305 | this.handler.endElement(); | ||
| 306 | } | ||
| 307 | catch (RuntimeException exception) { | ||
| 308 | handleException(exception); | ||
| 309 | } | ||
| 310 | finally { | ||
| 311 | this.handler = this.handler.getParent(); | ||
| 312 | } | ||
| 313 | } | ||
| 314 | |||
| 315 | /** | ||
| 316 | * Parses character data inside XML element. | ||
| 317 | * | ||
| 318 | * @param chars the array of characters | ||
| 319 | * @param start the start position in the character array | ||
| 320 | * @param length the number of characters to use | ||
| 321 | */ | ||
| 322 | @Override | ||
| 323 | public void characters(char[] chars, int start, int length) { | ||
| 324 | if (this.handler != null) { | ||
| 325 | try { | ||
| 326 | while (0 < length--) { | ||
| 327 | this.handler.addCharacter(chars[start++]); | ||
| 328 | } | ||
| 329 | } | ||
| 330 | catch (RuntimeException exception) { | ||
| 331 | handleException(exception); | ||
| 332 | } | ||
| 333 | } | ||
| 334 | } | ||
| 335 | |||
| 336 | /** | ||
| 337 | * Handles an exception using current exception listener. | ||
| 338 | * | ||
| 339 | * @param exception an exception to handle | ||
| 340 | * @see #setExceptionListener | ||
| 341 | */ | ||
| 342 | public void handleException(Exception exception) { | ||
| 343 | if (this.listener == null) { | ||
| 344 | throw new IllegalStateException(exception); | ||
| 345 | } | ||
| 346 | this.listener.exceptionThrown(exception); | ||
| 347 | } | ||
| 348 | |||
| 349 | /** | ||
| 350 | * Starts parsing of the specified input source. | ||
| 351 | * | ||
| 352 | * @param input the input source to parse | ||
| 353 | */ | ||
| 354 | public void parse(InputSource input) { | ||
| 355 | try { | ||
| 356 | SAXParserFactory.newInstance().newSAXParser().parse(input, this); | ||
| 357 | } | ||
| 358 | catch (ParserConfigurationException exception) { | ||
| 359 | handleException(exception); | ||
| 360 | } | ||
| 361 | catch (SAXException wrapper) { | ||
| 362 | Exception exception = wrapper.getException(); | ||
| 363 | if (exception == null) { | ||
| 364 | exception = wrapper; | ||
| 365 | } | ||
| 366 | handleException(exception); | ||
| 367 | } | ||
| 368 | catch (IOException exception) { | ||
| 369 | handleException(exception); | ||
| 370 | } | ||
| 371 | } | ||
| 372 | |||
| 373 | /** | ||
| 374 | * Resolves class by name using current class loader. | ||
| 375 | * This method handles exception using current exception listener. | ||
| 376 | * | ||
| 377 | * @param name the name of the class | ||
| 378 | * @return the object that represents the class | ||
| 379 | */ | ||
| 380 | public Class<?> findClass(String name) { | ||
| 381 | try { | ||
| 382 | return ClassFinder.resolveClass(name, getClassLoader()); | ||
| 383 | } | ||
| 384 | catch (ClassNotFoundException exception) { | ||
| 385 | handleException(exception); | ||
| 386 | return null; | ||
| 387 | } | ||
| 388 | } | ||
| 389 | } | ||
Binary file not shown.
| @@ -0,0 +1,63 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.decoder; | ||
| 26 | |||
| 27 | /** | ||
| 28 | * This class is intended to handle <double> element. | ||
| 29 | * This element specifies {@code double} values. | ||
| 30 | * The class {@link Double} is used as wrapper for these values. | ||
| 31 | * The result value is created from text of the body of this element. | ||
| 32 | * The body parsing is described in the class {@link StringElementHandler}. | ||
| 33 | * For example:<pre> | ||
| 34 | * <double>1.23e45</double></pre> | ||
| 35 | * is shortcut to<pre> | ||
| 36 | * <method name="valueOf" class="java.lang.Double"> | ||
| 37 | * <string>1.23e45</string> | ||
| 38 | * </method></pre> | ||
| 39 | * which is equivalent to {@code Double.valueOf("1.23e45")} in Java code. | ||
| 40 | * <p>The following atribute is supported: | ||
| 41 | * <dl> | ||
| 42 | * <dt>id | ||
| 43 | * <dd>the identifier of the variable that is intended to store the result | ||
| 44 | * </dl> | ||
| 45 | * | ||
| 46 | * @since 1.7 | ||
| 47 | * | ||
| 48 | * @author Sergey A. Malenkov | ||
| 49 | */ | ||
| 50 | final class DoubleElementHandler extends StringElementHandler { | ||
| 51 | |||
| 52 | /** | ||
| 53 | * Creates {@code double} value from | ||
| 54 | * the text of the body of this element. | ||
| 55 | * | ||
| 56 | * @param argument the text of the body | ||
| 57 | * @return evaluated {@code double} value | ||
| 58 | */ | ||
| 59 | @Override | ||
| 60 | public Object getValue(String argument) { | ||
| 61 | return Double.valueOf(argument); | ||
| 62 | } | ||
| 63 | } | ||
Binary file not shown.
| @@ -0,0 +1,224 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.decoder; | ||
| 26 | |||
| 27 | /** | ||
| 28 | * The base class for element handlers. | ||
| 29 | * | ||
| 30 | * @since 1.7 | ||
| 31 | * | ||
| 32 | * @author Sergey A. Malenkov | ||
| 33 | * | ||
| 34 | * @see DocumentHandler | ||
| 35 | */ | ||
| 36 | public abstract class ElementHandler { | ||
| 37 | private DocumentHandler owner; | ||
| 38 | private ElementHandler parent; | ||
| 39 | |||
| 40 | private String id; | ||
| 41 | |||
| 42 | /** | ||
| 43 | * Returns the document handler that creates this element handler. | ||
| 44 | * | ||
| 45 | * @return the owner document handler | ||
| 46 | */ | ||
| 47 | public final DocumentHandler getOwner() { | ||
| 48 | return this.owner; | ||
| 49 | } | ||
| 50 | |||
| 51 | /** | ||
| 52 | * Sets the document handler that creates this element handler. | ||
| 53 | * The owner document handler should be set after instantiation. | ||
| 54 | * Such approach is used to simplify the extensibility. | ||
| 55 | * | ||
| 56 | * @param owner the owner document handler | ||
| 57 | * @see DocumentHandler#startElement | ||
| 58 | */ | ||
| 59 | final void setOwner(DocumentHandler owner) { | ||
| 60 | if (owner == null) { | ||
| 61 | throw new IllegalArgumentException("Every element should have owner"); | ||
| 62 | } | ||
| 63 | this.owner = owner; | ||
| 64 | } | ||
| 65 | |||
| 66 | /** | ||
| 67 | * Returns the element handler that contains this one. | ||
| 68 | * | ||
| 69 | * @return the parent element handler | ||
| 70 | */ | ||
| 71 | public final ElementHandler getParent() { | ||
| 72 | return this.parent; | ||
| 73 | } | ||
| 74 | |||
| 75 | /** | ||
| 76 | * Sets the element handler that contains this one. | ||
| 77 | * The parent element handler should be set after instantiation. | ||
| 78 | * Such approach is used to simplify the extensibility. | ||
| 79 | * | ||
| 80 | * @param parent the parent element handler | ||
| 81 | * @see DocumentHandler#startElement | ||
| 82 | */ | ||
| 83 | final void setParent(ElementHandler parent) { | ||
| 84 | this.parent = parent; | ||
| 85 | } | ||
| 86 | |||
| 87 | /** | ||
| 88 | * Returns the value of the variable with specified identifier. | ||
| 89 | * | ||
| 90 | * @param id the identifier | ||
| 91 | * @return the value of the variable | ||
| 92 | */ | ||
| 93 | protected final Object getVariable(String id) { | ||
| 94 | if (id.equals(this.id)) { | ||
| 95 | ValueObject value = getValueObject(); | ||
| 96 | if (value.isVoid()) { | ||
| 97 | throw new IllegalStateException("The element does not return value"); | ||
| 98 | } | ||
| 99 | return value.getValue(); | ||
| 100 | } | ||
| 101 | return (this.parent != null) | ||
| 102 | ? this.parent.getVariable(id) | ||
| 103 | : this.owner.getVariable(id); | ||
| 104 | } | ||
| 105 | |||
| 106 | /** | ||
| 107 | * Returns the value of the parent element. | ||
| 108 | * | ||
| 109 | * @return the value of the parent element | ||
| 110 | */ | ||
| 111 | protected Object getContextBean() { | ||
| 112 | if (this.parent != null) { | ||
| 113 | ValueObject value = this.parent.getValueObject(); | ||
| 114 | if (!value.isVoid()) { | ||
| 115 | return value.getValue(); | ||
| 116 | } | ||
| 117 | throw new IllegalStateException("The outer element does not return value"); | ||
| 118 | } else { | ||
| 119 | Object value = this.owner.getOwner(); | ||
| 120 | if (value != null) { | ||
| 121 | return value; | ||
| 122 | } | ||
| 123 | throw new IllegalStateException("The topmost element does not have context"); | ||
| 124 | } | ||
| 125 | } | ||
| 126 | |||
| 127 | /** | ||
| 128 | * Parses attributes of the element. | ||
| 129 | * By default, the following atribute is supported: | ||
| 130 | * <dl> | ||
| 131 | * <dt>id | ||
| 132 | * <dd>the identifier of the variable that is intended to store the result | ||
| 133 | * </dl> | ||
| 134 | * | ||
| 135 | * @param name the attribute name | ||
| 136 | * @param value the attribute value | ||
| 137 | */ | ||
| 138 | public void addAttribute(String name, String value) { | ||
| 139 | if (name.equals("id")) { // NON-NLS: the attribute name | ||
| 140 | this.id = value; | ||
| 141 | } else { | ||
| 142 | throw new IllegalArgumentException("Unsupported attribute: " + name); | ||
| 143 | } | ||
| 144 | } | ||
| 145 | |||
| 146 | /** | ||
| 147 | * This method is called before parsing of the element's body. | ||
| 148 | * All attributes are parsed at this point. | ||
| 149 | * By default, do nothing. | ||
| 150 | */ | ||
| 151 | public void startElement() { | ||
| 152 | } | ||
| 153 | |||
| 154 | /** | ||
| 155 | * This method is called after parsing of the element's body. | ||
| 156 | * By default, it calculates the value of this element. | ||
| 157 | * The following tasks are executing for any non-void value: | ||
| 158 | * <ol> | ||
| 159 | * <li>If the {@code id} attribute is set | ||
| 160 | * the value of the variable with the specified identifier | ||
| 161 | * is set to the value of this element.</li> | ||
| 162 | * <li>This element is used as an argument of parent element if it is possible.</li> | ||
| 163 | * </ol> | ||
| 164 | * | ||
| 165 | * @see #isArgument | ||
| 166 | */ | ||
| 167 | public void endElement() { | ||
| 168 | // do nothing if no value returned | ||
| 169 | ValueObject value = getValueObject(); | ||
| 170 | if (!value.isVoid()) { | ||
| 171 | if (this.id != null) { | ||
| 172 | this.owner.setVariable(this.id, value.getValue()); | ||
| 173 | } | ||
| 174 | if (isArgument()) { | ||
| 175 | if (this.parent != null) { | ||
| 176 | this.parent.addArgument(value.getValue()); | ||
| 177 | } else { | ||
| 178 | this.owner.addObject(value.getValue()); | ||
| 179 | } | ||
| 180 | } | ||
| 181 | } | ||
| 182 | } | ||
| 183 | |||
| 184 | /** | ||
| 185 | * Adds the character that contained in this element. | ||
| 186 | * By default, only whitespaces are acceptable. | ||
| 187 | * | ||
| 188 | * @param ch the character | ||
| 189 | */ | ||
| 190 | public void addCharacter(char ch) { | ||
| 191 | if ((ch != ' ') && (ch != '\n') && (ch != '\t') && (ch != '\r')) { | ||
| 192 | throw new IllegalStateException("Illegal character with code " + (int) ch); | ||
| 193 | } | ||
| 194 | } | ||
| 195 | |||
| 196 | /** | ||
| 197 | * Adds the argument that is used to calculate the value of this element. | ||
| 198 | * By default, no arguments are acceptable. | ||
| 199 | * | ||
| 200 | * @param argument the value of the element that contained in this one | ||
| 201 | */ | ||
| 202 | protected void addArgument(Object argument) { | ||
| 203 | throw new IllegalStateException("Could not add argument to simple element"); | ||
| 204 | } | ||
| 205 | |||
| 206 | /** | ||
| 207 | * Tests whether the value of this element can be used | ||
| 208 | * as an argument of the element that contained in this one. | ||
| 209 | * | ||
| 210 | * @return {@code true} if the value of this element can be used | ||
| 211 | * as an argument of the element that contained in this one, | ||
| 212 | * {@code false} otherwise | ||
| 213 | */ | ||
| 214 | protected boolean isArgument() { | ||
| 215 | return this.id == null; | ||
| 216 | } | ||
| 217 | |||
| 218 | /** | ||
| 219 | * Returns the value of this element. | ||
| 220 | * | ||
| 221 | * @return the value of this element | ||
| 222 | */ | ||
| 223 | protected abstract ValueObject getValueObject(); | ||
| 224 | } | ||
Binary file not shown.
| @@ -0,0 +1,56 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.decoder; | ||
| 26 | |||
| 27 | /** | ||
| 28 | * This class is intended to handle <false> element. | ||
| 29 | * This element specifies {@code false} value. | ||
| 30 | * It should not contain body or inner elements. | ||
| 31 | * For example:<pre> | ||
| 32 | * <false/></pre> | ||
| 33 | * is equivalent to {@code false} in Java code. | ||
| 34 | * <p>The following atribute is supported: | ||
| 35 | * <dl> | ||
| 36 | * <dt>id | ||
| 37 | * <dd>the identifier of the variable that is intended to store the result | ||
| 38 | * </dl> | ||
| 39 | * | ||
| 40 | * @since 1.7 | ||
| 41 | * | ||
| 42 | * @author Sergey A. Malenkov | ||
| 43 | */ | ||
| 44 | final class FalseElementHandler extends NullElementHandler { | ||
| 45 | |||
| 46 | /** | ||
| 47 | * Returns {@code Boolean.FALSE} | ||
| 48 | * as a value of <false> element. | ||
| 49 | * | ||
| 50 | * @return {@code Boolean.FALSE} by default | ||
| 51 | */ | ||
| 52 | @Override | ||
| 53 | public Object getValue() { | ||
| 54 | return Boolean.FALSE; | ||
| 55 | } | ||
| 56 | } | ||
Binary file not shown.
| @@ -0,0 +1,189 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.decoder; | ||
| 26 | |||
| 27 | import com.sun.beans.finder.FieldFinder; | ||
| 28 | |||
| 29 | import java.lang.reflect.Field; | ||
| 30 | |||
| 31 | /** | ||
| 32 | * This class is intended to handle <field> element. | ||
| 33 | * This element simplifies access to the fields. | ||
| 34 | * If the {@code class} attribute is specified | ||
| 35 | * this element accesses static field of specified class. | ||
| 36 | * This element defines getter if it contains no argument. | ||
| 37 | * It returns the value of the field in this case. | ||
| 38 | * For example:<pre> | ||
| 39 | * <field name="TYPE" class="java.lang.Long"/></pre> | ||
| 40 | * is equivalent to {@code Long.TYPE} in Java code. | ||
| 41 | * This element defines setter if it contains one argument. | ||
| 42 | * It does not return the value of the field in this case. | ||
| 43 | * For example:<pre> | ||
| 44 | * <field name="id"><int>0</int></field></pre> | ||
| 45 | * is equivalent to {@code id = 0} in Java code. | ||
| 46 | * <p>The following atributes are supported: | ||
| 47 | * <dl> | ||
| 48 | * <dt>name | ||
| 49 | * <dd>the field name | ||
| 50 | * <dt>class | ||
| 51 | * <dd>the type is used for static fields only | ||
| 52 | * <dt>id | ||
| 53 | * <dd>the identifier of the variable that is intended to store the result | ||
| 54 | * </dl> | ||
| 55 | * | ||
| 56 | * @since 1.7 | ||
| 57 | * | ||
| 58 | * @author Sergey A. Malenkov | ||
| 59 | */ | ||
| 60 | final class FieldElementHandler extends AccessorElementHandler { | ||
| 61 | private Class<?> type; | ||
| 62 | |||
| 63 | /** | ||
| 64 | * Parses attributes of the element. | ||
| 65 | * The following atributes are supported: | ||
| 66 | * <dl> | ||
| 67 | * <dt>name | ||
| 68 | * <dd>the field name | ||
| 69 | * <dt>class | ||
| 70 | * <dd>the type is used for static fields only | ||
| 71 | * <dt>id | ||
| 72 | * <dd>the identifier of the variable that is intended to store the result | ||
| 73 | * </dl> | ||
| 74 | * | ||
| 75 | * @param name the attribute name | ||
| 76 | * @param value the attribute value | ||
| 77 | */ | ||
| 78 | @Override | ||
| 79 | public void addAttribute(String name, String value) { | ||
| 80 | if (name.equals("class")) { // NON-NLS: the attribute name | ||
| 81 | this.type = getOwner().findClass(value); | ||
| 82 | } else { | ||
| 83 | super.addAttribute(name, value); | ||
| 84 | } | ||
| 85 | } | ||
| 86 | |||
| 87 | /** | ||
| 88 | * Tests whether the value of this element can be used | ||
| 89 | * as an argument of the element that contained in this one. | ||
| 90 | * | ||
| 91 | * @return {@code true} if the value of this element should be used | ||
| 92 | * as an argument of the element that contained in this one, | ||
| 93 | * {@code false} otherwise | ||
| 94 | */ | ||
| 95 | @Override | ||
| 96 | protected boolean isArgument() { | ||
| 97 | return super.isArgument() && (this.type != null); // only static accessor can be used an argument | ||
| 98 | } | ||
| 99 | |||
| 100 | /** | ||
| 101 | * Returns the context of the field. | ||
| 102 | * The context of the static field is the class object. | ||
| 103 | * The context of the non-static field is the value of the parent element. | ||
| 104 | * | ||
| 105 | * @return the context of the field | ||
| 106 | */ | ||
| 107 | @Override | ||
| 108 | protected Object getContextBean() { | ||
| 109 | return (this.type != null) | ||
| 110 | ? this.type | ||
| 111 | : super.getContextBean(); | ||
| 112 | } | ||
| 113 | |||
| 114 | /** | ||
| 115 | * Returns the value of the field with specified {@code name}. | ||
| 116 | * | ||
| 117 | * @param name the name of the field | ||
| 118 | * @return the value of the specified field | ||
| 119 | */ | ||
| 120 | @Override | ||
| 121 | protected Object getValue(String name) { | ||
| 122 | try { | ||
| 123 | return getFieldValue(getContextBean(), name); | ||
| 124 | } | ||
| 125 | catch (Exception exception) { | ||
| 126 | getOwner().handleException(exception); | ||
| 127 | } | ||
| 128 | return null; | ||
| 129 | } | ||
| 130 | |||
| 131 | /** | ||
| 132 | * Sets the new value for the field with specified {@code name}. | ||
| 133 | * | ||
| 134 | * @param name the name of the field | ||
| 135 | * @param value the new value for the specified field | ||
| 136 | */ | ||
| 137 | @Override | ||
| 138 | protected void setValue(String name, Object value) { | ||
| 139 | try { | ||
| 140 | setFieldValue(getContextBean(), name, value); | ||
| 141 | } | ||
| 142 | catch (Exception exception) { | ||
| 143 | getOwner().handleException(exception); | ||
| 144 | } | ||
| 145 | } | ||
| 146 | |||
| 147 | /** | ||
| 148 | * Performs the search of the field with specified {@code name} | ||
| 149 | * in specified context and returns its value. | ||
| 150 | * | ||
| 151 | * @param bean the context bean that contains field | ||
| 152 | * @param name the name of the field | ||
| 153 | * @return the value of the field | ||
| 154 | * @throws IllegalAccessException if the field is not accesible | ||
| 155 | * @throws NoSuchFieldException if the field is not found | ||
| 156 | */ | ||
| 157 | static Object getFieldValue(Object bean, String name) throws IllegalAccessException, NoSuchFieldException { | ||
| 158 | return findField(bean, name).get(bean); | ||
| 159 | } | ||
| 160 | |||
| 161 | /** | ||
| 162 | * Performs the search of the field with specified {@code name} | ||
| 163 | * in specified context and updates its value. | ||
| 164 | * | ||
| 165 | * @param bean the context bean that contains field | ||
| 166 | * @param name the name of the field | ||
| 167 | * @param value the new value for the field | ||
| 168 | * @throws IllegalAccessException if the field is not accesible | ||
| 169 | * @throws NoSuchFieldException if the field is not found | ||
| 170 | */ | ||
| 171 | private static void setFieldValue(Object bean, String name, Object value) throws IllegalAccessException, NoSuchFieldException { | ||
| 172 | findField(bean, name).set(bean, value); | ||
| 173 | } | ||
| 174 | |||
| 175 | /** | ||
| 176 | * Performs the search of the field | ||
| 177 | * with specified {@code name} in specified context. | ||
| 178 | * | ||
| 179 | * @param bean the context bean that contains field | ||
| 180 | * @param name the name of the field | ||
| 181 | * @return field object that represents found field | ||
| 182 | * @throws NoSuchFieldException if the field is not found | ||
| 183 | */ | ||
| 184 | private static Field findField(Object bean, String name) throws NoSuchFieldException { | ||
| 185 | return (bean instanceof Class<?>) | ||
| 186 | ? FieldFinder.findStaticField((Class<?>) bean, name) | ||
| 187 | : FieldFinder.findField(bean.getClass(), name); | ||
| 188 | } | ||
| 189 | } | ||
Binary file not shown.
| @@ -0,0 +1,63 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.decoder; | ||
| 26 | |||
| 27 | /** | ||
| 28 | * This class is intended to handle <float> element. | ||
| 29 | * This element specifies {@code float} values. | ||
| 30 | * The class {@link Float} is used as wrapper for these values. | ||
| 31 | * The result value is created from text of the body of this element. | ||
| 32 | * The body parsing is described in the class {@link StringElementHandler}. | ||
| 33 | * For example:<pre> | ||
| 34 | * <float>-1.23</float></pre> | ||
| 35 | * is shortcut to<pre> | ||
| 36 | * <method name="valueOf" class="java.lang.Float"> | ||
| 37 | * <string>-1.23</string> | ||
| 38 | * </method></pre> | ||
| 39 | * which is equivalent to {@code Float.valueOf("-1.23")} in Java code. | ||
| 40 | * <p>The following atribute is supported: | ||
| 41 | * <dl> | ||
| 42 | * <dt>id | ||
| 43 | * <dd>the identifier of the variable that is intended to store the result | ||
| 44 | * </dl> | ||
| 45 | * | ||
| 46 | * @since 1.7 | ||
| 47 | * | ||
| 48 | * @author Sergey A. Malenkov | ||
| 49 | */ | ||
| 50 | final class FloatElementHandler extends StringElementHandler { | ||
| 51 | |||
| 52 | /** | ||
| 53 | * Creates {@code float} value from | ||
| 54 | * the text of the body of this element. | ||
| 55 | * | ||
| 56 | * @param argument the text of the body | ||
| 57 | * @return evaluated {@code float} value | ||
| 58 | */ | ||
| 59 | @Override | ||
| 60 | public Object getValue(String argument) { | ||
| 61 | return Float.valueOf(argument); | ||
| 62 | } | ||
| 63 | } | ||
Binary file not shown.
| @@ -0,0 +1,63 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.decoder; | ||
| 26 | |||
| 27 | /** | ||
| 28 | * This class is intended to handle <int> element. | ||
| 29 | * This element specifies {@code int} values. | ||
| 30 | * The class {@link Integer} is used as wrapper for these values. | ||
| 31 | * The result value is created from text of the body of this element. | ||
| 32 | * The body parsing is described in the class {@link StringElementHandler}. | ||
| 33 | * For example:<pre> | ||
| 34 | * <int>-1</int></pre> | ||
| 35 | * is shortcut to<pre> | ||
| 36 | * <method name="decode" class="java.lang.Integer"> | ||
| 37 | * <string>-1</string> | ||
| 38 | * </method></pre> | ||
| 39 | * which is equivalent to {@code Integer.decode("-1")} in Java code. | ||
| 40 | * <p>The following atribute is supported: | ||
| 41 | * <dl> | ||
| 42 | * <dt>id | ||
| 43 | * <dd>the identifier of the variable that is intended to store the result | ||
| 44 | * </dl> | ||
| 45 | * | ||
| 46 | * @since 1.7 | ||
| 47 | * | ||
| 48 | * @author Sergey A. Malenkov | ||
| 49 | */ | ||
| 50 | final class IntElementHandler extends StringElementHandler { | ||
| 51 | |||
| 52 | /** | ||
| 53 | * Creates {@code int} value from | ||
| 54 | * the text of the body of this element. | ||
| 55 | * | ||
| 56 | * @param argument the text of the body | ||
| 57 | * @return evaluated {@code int} value | ||
| 58 | */ | ||
| 59 | @Override | ||
| 60 | public Object getValue(String argument) { | ||
| 61 | return Integer.decode(argument); | ||
| 62 | } | ||
| 63 | } | ||
Binary file not shown.
| @@ -0,0 +1,151 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.decoder; | ||
| 26 | |||
| 27 | import java.beans.XMLDecoder; | ||
| 28 | |||
| 29 | /** | ||
| 30 | * This class is intended to handle <java> element. | ||
| 31 | * Each element that appears in the body of this element | ||
| 32 | * is evaluated in the context of the decoder itself. | ||
| 33 | * Typically this outer context is used to retrieve the owner of the decoder, | ||
| 34 | * which can be set before reading the archive. | ||
| 35 | * <p>The following atributes are supported: | ||
| 36 | * <dl> | ||
| 37 | * <dt>version | ||
| 38 | * <dd>the Java version (not supported) | ||
| 39 | * <dt>class | ||
| 40 | * <dd>the type of preferable parser (not supported) | ||
| 41 | * <dt>id | ||
| 42 | * <dd>the identifier of the variable that is intended to store the result | ||
| 43 | * </dl> | ||
| 44 | * | ||
| 45 | * @see DocumentHandler#getOwner | ||
| 46 | * @see DocumentHandler#setOwner | ||
| 47 | * @since 1.7 | ||
| 48 | * | ||
| 49 | * @author Sergey A. Malenkov | ||
| 50 | */ | ||
| 51 | final class JavaElementHandler extends ElementHandler { | ||
| 52 | private Class<?> type; | ||
| 53 | private ValueObject value; | ||
| 54 | |||
| 55 | /** | ||
| 56 | * Parses attributes of the element. | ||
| 57 | * The following atributes are supported: | ||
| 58 | * <dl> | ||
| 59 | * <dt>version | ||
| 60 | * <dd>the Java version (not supported) | ||
| 61 | * <dt>class | ||
| 62 | * <dd>the type of preferable parser (not supported) | ||
| 63 | * <dt>id | ||
| 64 | * <dd>the identifier of the variable that is intended to store the result | ||
| 65 | * </dl> | ||
| 66 | * | ||
| 67 | * @param name the attribute name | ||
| 68 | * @param value the attribute value | ||
| 69 | */ | ||
| 70 | @Override | ||
| 71 | public void addAttribute(String name, String value) { | ||
| 72 | if (name.equals("version")) { // NON-NLS: the attribute name | ||
| 73 | // unsupported attribute | ||
| 74 | } else if (name.equals("class")) { // NON-NLS: the attribute name | ||
| 75 | // check class for owner | ||
| 76 | this.type = getOwner().findClass(value); | ||
| 77 | } else { | ||
| 78 | super.addAttribute(name, value); | ||
| 79 | } | ||
| 80 | } | ||
| 81 | |||
| 82 | /** | ||
| 83 | * Adds the argument to the list of readed objects. | ||
| 84 | * | ||
| 85 | * @param argument the value of the element that contained in this one | ||
| 86 | */ | ||
| 87 | @Override | ||
| 88 | protected void addArgument(Object argument) { | ||
| 89 | getOwner().addObject(argument); | ||
| 90 | } | ||
| 91 | |||
| 92 | /** | ||
| 93 | * Tests whether the value of this element can be used | ||
| 94 | * as an argument of the element that contained in this one. | ||
| 95 | * | ||
| 96 | * @return {@code true} if the value of this element should be used | ||
| 97 | * as an argument of the element that contained in this one, | ||
| 98 | * {@code false} otherwise | ||
| 99 | */ | ||
| 100 | @Override | ||
| 101 | protected boolean isArgument() { | ||
| 102 | return false; // do not use owner as object | ||
| 103 | } | ||
| 104 | |||
| 105 | /** | ||
| 106 | * Returns the value of this element. | ||
| 107 | * | ||
| 108 | * @return the value of this element | ||
| 109 | */ | ||
| 110 | @Override | ||
| 111 | protected ValueObject getValueObject() { | ||
| 112 | if (this.value == null) { | ||
| 113 | this.value = ValueObjectImpl.create(getValue()); | ||
| 114 | } | ||
| 115 | return this.value; | ||
| 116 | } | ||
| 117 | |||
| 118 | /** | ||
| 119 | * Returns the owner of the owner document handler | ||
| 120 | * as a value of <java> element. | ||
| 121 | * | ||
| 122 | * @return the owner of the owner document handler | ||
| 123 | */ | ||
| 124 | private Object getValue() { | ||
| 125 | Object owner = getOwner().getOwner(); | ||
| 126 | if ((this.type == null) || isValid(owner)) { | ||
| 127 | return owner; | ||
| 128 | } | ||
| 129 | if (owner instanceof XMLDecoder) { | ||
| 130 | XMLDecoder decoder = (XMLDecoder) owner; | ||
| 131 | owner = decoder.getOwner(); | ||
| 132 | if (isValid(owner)) { | ||
| 133 | return owner; | ||
| 134 | } | ||
| 135 | } | ||
| 136 | throw new IllegalStateException("Unexpected owner class: " + owner.getClass().getName()); | ||
| 137 | } | ||
| 138 | |||
| 139 | /** | ||
| 140 | * Validates the owner of the <java> element. | ||
| 141 | * The owner is valid if it is {@code null} or an instance | ||
| 142 | * of the class specified by the {@code class} attribute. | ||
| 143 | * | ||
| 144 | * @param owner the owner of the <java> element | ||
| 145 | * @return {@code true} if the {@code owner} is valid; | ||
| 146 | * {@code false} otherwise | ||
| 147 | */ | ||
| 148 | private boolean isValid(Object owner) { | ||
| 149 | return (owner == null) || this.type.isInstance(owner); | ||
| 150 | } | ||
| 151 | } | ||
Binary file not shown.
| @@ -0,0 +1,63 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.decoder; | ||
| 26 | |||
| 27 | /** | ||
| 28 | * This class is intended to handle <long> element. | ||
| 29 | * This element specifies {@code long} values. | ||
| 30 | * The class {@link Long} is used as wrapper for these values. | ||
| 31 | * The result value is created from text of the body of this element. | ||
| 32 | * The body parsing is described in the class {@link StringElementHandler}. | ||
| 33 | * For example:<pre> | ||
| 34 | * <long>0xFFFF</long></pre> | ||
| 35 | * is shortcut to<pre> | ||
| 36 | * <method name="decode" class="java.lang.Long"> | ||
| 37 | * <string>0xFFFF</string> | ||
| 38 | * </method></pre> | ||
| 39 | * which is equivalent to {@code Long.decode("0xFFFF")} in Java code. | ||
| 40 | * <p>The following atribute is supported: | ||
| 41 | * <dl> | ||
| 42 | * <dt>id | ||
| 43 | * <dd>the identifier of the variable that is intended to store the result | ||
| 44 | * </dl> | ||
| 45 | * | ||
| 46 | * @since 1.7 | ||
| 47 | * | ||
| 48 | * @author Sergey A. Malenkov | ||
| 49 | */ | ||
| 50 | final class LongElementHandler extends StringElementHandler { | ||
| 51 | |||
| 52 | /** | ||
| 53 | * Creates {@code long} value from | ||
| 54 | * the text of the body of this element. | ||
| 55 | * | ||
| 56 | * @param argument the text of the body | ||
| 57 | * @return evaluated {@code long} value | ||
| 58 | */ | ||
| 59 | @Override | ||
| 60 | public Object getValue(String argument) { | ||
| 61 | return Long.decode(argument); | ||
| 62 | } | ||
| 63 | } | ||
Binary file not shown.
| @@ -0,0 +1,109 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.decoder; | ||
| 26 | |||
| 27 | import com.sun.beans.finder.MethodFinder; | ||
| 28 | |||
| 29 | import java.lang.reflect.Method; | ||
| 30 | |||
| 31 | /** | ||
| 32 | * This class is intended to handle <method> element. | ||
| 33 | * It describes invocation of the method. | ||
| 34 | * The {@code name} attribute denotes | ||
| 35 | * the name of the method to invoke. | ||
| 36 | * If the {@code class} attribute is specified | ||
| 37 | * this element invokes static method of specified class. | ||
| 38 | * The inner elements specifies the arguments of the method. | ||
| 39 | * For example:<pre> | ||
| 40 | * <method name="valueOf" class="java.lang.Long"> | ||
| 41 | * <string>10</string> | ||
| 42 | * </method></pre> | ||
| 43 | * is equivalent to {@code Long.valueOf("10")} in Java code. | ||
| 44 | * <p>The following atributes are supported: | ||
| 45 | * <dl> | ||
| 46 | * <dt>name | ||
| 47 | * <dd>the method name | ||
| 48 | * <dt>class | ||
| 49 | * <dd>the type of object for instantiation | ||
| 50 | * <dt>id | ||
| 51 | * <dd>the identifier of the variable that is intended to store the result | ||
| 52 | * </dl> | ||
| 53 | * | ||
| 54 | * @since 1.7 | ||
| 55 | * | ||
| 56 | * @author Sergey A. Malenkov | ||
| 57 | */ | ||
| 58 | final class MethodElementHandler extends NewElementHandler { | ||
| 59 | private String name; | ||
| 60 | |||
| 61 | /** | ||
| 62 | * Parses attributes of the element. | ||
| 63 | * The following atributes are supported: | ||
| 64 | * <dl> | ||
| 65 | * <dt>name | ||
| 66 | * <dd>the method name | ||
| 67 | * <dt>class | ||
| 68 | * <dd>the type of object for instantiation | ||
| 69 | * <dt>id | ||
| 70 | * <dd>the identifier of the variable that is intended to store the result | ||
| 71 | * </dl> | ||
| 72 | * | ||
| 73 | * @param name the attribute name | ||
| 74 | * @param value the attribute value | ||
| 75 | */ | ||
| 76 | @Override | ||
| 77 | public void addAttribute(String name, String value) { | ||
| 78 | if (name.equals("name")) { // NON-NLS: the attribute name | ||
| 79 | this.name = value; | ||
| 80 | } else { | ||
| 81 | super.addAttribute(name, value); | ||
| 82 | } | ||
| 83 | } | ||
| 84 | |||
| 85 | /** | ||
| 86 | * Returns the result of method execution. | ||
| 87 | * | ||
| 88 | * @param type the base class | ||
| 89 | * @param args the array of arguments | ||
| 90 | * @return the value of this element | ||
| 91 | * @throws Exception if calculation is failed | ||
| 92 | */ | ||
| 93 | @Override | ||
| 94 | protected ValueObject getValueObject(Class<?> type, Object[] args) throws Exception { | ||
| 95 | Object bean = getContextBean(); | ||
| 96 | Class<?>[] types = getArgumentTypes(args); | ||
| 97 | Method method = (type != null) | ||
| 98 | ? MethodFinder.findStaticMethod(type, this.name, types) | ||
| 99 | : MethodFinder.findMethod(bean.getClass(), this.name, types); | ||
| 100 | |||
| 101 | if (method.isVarArgs()) { | ||
| 102 | args = getArguments(args, method.getParameterTypes()); | ||
| 103 | } | ||
| 104 | Object value = method.invoke(bean, args); | ||
| 105 | return method.getReturnType().equals(void.class) | ||
| 106 | ? ValueObjectImpl.VOID | ||
| 107 | : ValueObjectImpl.create(value); | ||
| 108 | } | ||
| 109 | } | ||
Binary file not shown.
| @@ -0,0 +1,205 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.decoder; | ||
| 26 | |||
| 27 | import com.sun.beans.finder.ConstructorFinder; | ||
| 28 | |||
| 29 | import java.lang.reflect.Array; | ||
| 30 | import java.lang.reflect.Constructor; | ||
| 31 | |||
| 32 | import java.util.ArrayList; | ||
| 33 | import java.util.List; | ||
| 34 | |||
| 35 | /** | ||
| 36 | * This class is intended to handle <new> element. | ||
| 37 | * It describes instantiation of the object. | ||
| 38 | * The {@code class} attribute denotes | ||
| 39 | * the name of the class to instantiate. | ||
| 40 | * The inner elements specifies the arguments of the constructor. | ||
| 41 | * For example:<pre> | ||
| 42 | * <new class="java.lang.Long"> | ||
| 43 | * <string>10</string> | ||
| 44 | * </new></pre> | ||
| 45 | * is equivalent to {@code new Long("10")} in Java code. | ||
| 46 | * <p>The following atributes are supported: | ||
| 47 | * <dl> | ||
| 48 | * <dt>class | ||
| 49 | * <dd>the type of object for instantiation | ||
| 50 | * <dt>id | ||
| 51 | * <dd>the identifier of the variable that is intended to store the result | ||
| 52 | * </dl> | ||
| 53 | * | ||
| 54 | * @since 1.7 | ||
| 55 | * | ||
| 56 | * @author Sergey A. Malenkov | ||
| 57 | */ | ||
| 58 | class NewElementHandler extends ElementHandler { | ||
| 59 | private List<Object> arguments = new ArrayList<Object>(); | ||
| 60 | private ValueObject value = ValueObjectImpl.VOID; | ||
| 61 | |||
| 62 | private Class<?> type; | ||
| 63 | |||
| 64 | /** | ||
| 65 | * Parses attributes of the element. | ||
| 66 | * The following atributes are supported: | ||
| 67 | * <dl> | ||
| 68 | * <dt>class | ||
| 69 | * <dd>the type of object for instantiation | ||
| 70 | * <dt>id | ||
| 71 | * <dd>the identifier of the variable that is intended to store the result | ||
| 72 | * </dl> | ||
| 73 | * | ||
| 74 | * @param name the attribute name | ||
| 75 | * @param value the attribute value | ||
| 76 | */ | ||
| 77 | @Override | ||
| 78 | public void addAttribute(String name, String value) { | ||
| 79 | if (name.equals("class")) { // NON-NLS: the attribute name | ||
| 80 | this.type = getOwner().findClass(value); | ||
| 81 | } else { | ||
| 82 | super.addAttribute(name, value); | ||
| 83 | } | ||
| 84 | } | ||
| 85 | |||
| 86 | /** | ||
| 87 | * Adds the argument to the list of arguments | ||
| 88 | * that is used to calculate the value of this element. | ||
| 89 | * | ||
| 90 | * @param argument the value of the element that contained in this one | ||
| 91 | */ | ||
| 92 | @Override | ||
| 93 | protected final void addArgument(Object argument) { | ||
| 94 | if (this.arguments == null) { | ||
| 95 | throw new IllegalStateException("Could not add argument to evaluated element"); | ||
| 96 | } | ||
| 97 | this.arguments.add(argument); | ||
| 98 | } | ||
| 99 | |||
| 100 | /** | ||
| 101 | * Returns the context of the method. | ||
| 102 | * The context of the static method is the class object. | ||
| 103 | * The context of the non-static method is the value of the parent element. | ||
| 104 | * | ||
| 105 | * @return the context of the method | ||
| 106 | */ | ||
| 107 | @Override | ||
| 108 | protected final Object getContextBean() { | ||
| 109 | return (this.type != null) | ||
| 110 | ? this.type | ||
| 111 | : super.getContextBean(); | ||
| 112 | } | ||
| 113 | |||
| 114 | /** | ||
| 115 | * Returns the value of this element. | ||
| 116 | * | ||
| 117 | * @return the value of this element | ||
| 118 | */ | ||
| 119 | @Override | ||
| 120 | protected final ValueObject getValueObject() { | ||
| 121 | if (this.arguments != null) { | ||
| 122 | try { | ||
| 123 | this.value = getValueObject(this.type, this.arguments.toArray()); | ||
| 124 | } | ||
| 125 | catch (Exception exception) { | ||
| 126 | getOwner().handleException(exception); | ||
| 127 | } | ||
| 128 | finally { | ||
| 129 | this.arguments = null; | ||
| 130 | } | ||
| 131 | } | ||
| 132 | return this.value; | ||
| 133 | } | ||
| 134 | |||
| 135 | /** | ||
| 136 | * Calculates the value of this element | ||
| 137 | * using the base class and the array of arguments. | ||
| 138 | * By default, it creates an instance of the base class. | ||
| 139 | * This method should be overridden in those handlers | ||
| 140 | * that extend behavior of this element. | ||
| 141 | * | ||
| 142 | * @param type the base class | ||
| 143 | * @param args the array of arguments | ||
| 144 | * @return the value of this element | ||
| 145 | * @throws Exception if calculation is failed | ||
| 146 | */ | ||
| 147 | ValueObject getValueObject(Class<?> type, Object[] args) throws Exception { | ||
| 148 | if (type == null) { | ||
| 149 | throw new IllegalArgumentException("Class name is not set"); | ||
| 150 | } | ||
| 151 | Class<?>[] types = getArgumentTypes(args); | ||
| 152 | Constructor<?> constructor = ConstructorFinder.findConstructor(type, types); | ||
| 153 | if (constructor.isVarArgs()) { | ||
| 154 | args = getArguments(args, constructor.getParameterTypes()); | ||
| 155 | } | ||
| 156 | return ValueObjectImpl.create(constructor.newInstance(args)); | ||
| 157 | } | ||
| 158 | |||
| 159 | /** | ||
| 160 | * Converts the array of arguments to the array of corresponding classes. | ||
| 161 | * If argument is {@code null} the class is {@code null} too. | ||
| 162 | * | ||
| 163 | * @param arguments the array of arguments | ||
| 164 | * @return the array of corresponding classes | ||
| 165 | */ | ||
| 166 | static Class<?>[] getArgumentTypes(Object[] arguments) { | ||
| 167 | Class<?>[] types = new Class<?>[arguments.length]; | ||
| 168 | for (int i = 0; i < arguments.length; i++) { | ||
| 169 | if (arguments[i] != null) { | ||
| 170 | types[i] = arguments[i].getClass(); | ||
| 171 | } | ||
| 172 | } | ||
| 173 | return types; | ||
| 174 | } | ||
| 175 | |||
| 176 | /** | ||
| 177 | * Resolves variable arguments. | ||
| 178 | * | ||
| 179 | * @param arguments the array of arguments | ||
| 180 | * @param types the array of parameter types | ||
| 181 | * @return the resolved array of arguments | ||
| 182 | */ | ||
| 183 | static Object[] getArguments(Object[] arguments, Class<?>[] types) { | ||
| 184 | int index = types.length - 1; | ||
| 185 | if (types.length == arguments.length) { | ||
| 186 | Object argument = arguments[index]; | ||
| 187 | if (argument == null) { | ||
| 188 | return arguments; | ||
| 189 | } | ||
| 190 | Class<?> type = types[index]; | ||
| 191 | if (type.isAssignableFrom(argument.getClass())) { | ||
| 192 | return arguments; | ||
| 193 | } | ||
| 194 | } | ||
| 195 | int length = arguments.length - index; | ||
| 196 | Class<?> type = types[index].getComponentType(); | ||
| 197 | Object array = Array.newInstance(type, length); | ||
| 198 | System.arraycopy(arguments, index, array, 0, length); | ||
| 199 | |||
| 200 | Object[] args = new Object[types.length]; | ||
| 201 | System.arraycopy(arguments, 0, args, 0, index); | ||
| 202 | args[index] = array; | ||
| 203 | return args; | ||
| 204 | } | ||
| 205 | } | ||
Binary file not shown.
| @@ -0,0 +1,76 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.decoder; | ||
| 26 | |||
| 27 | /** | ||
| 28 | * This class is intended to handle <null> element. | ||
| 29 | * This element specifies {@code null} value. | ||
| 30 | * It should not contain body or inner elements. | ||
| 31 | * For example:<pre> | ||
| 32 | * <null/></pre> | ||
| 33 | * is equivalent to {@code null} in Java code. | ||
| 34 | * <p>The following atribute is supported: | ||
| 35 | * <dl> | ||
| 36 | * <dt>id | ||
| 37 | * <dd>the identifier of the variable that is intended to store the result | ||
| 38 | * </dl> | ||
| 39 | * | ||
| 40 | * @since 1.7 | ||
| 41 | * | ||
| 42 | * @author Sergey A. Malenkov | ||
| 43 | */ | ||
| 44 | class NullElementHandler extends ElementHandler implements ValueObject { | ||
| 45 | |||
| 46 | /** | ||
| 47 | * Returns the value of this element. | ||
| 48 | * | ||
| 49 | * @return the value of this element | ||
| 50 | */ | ||
| 51 | @Override | ||
| 52 | protected final ValueObject getValueObject() { | ||
| 53 | return this; | ||
| 54 | } | ||
| 55 | |||
| 56 | /** | ||
| 57 | * Returns {@code null} | ||
| 58 | * as a value of <null> element. | ||
| 59 | * This method should be overridden in those handlers | ||
| 60 | * that extend behavior of this element. | ||
| 61 | * | ||
| 62 | * @return {@code null} by default | ||
| 63 | */ | ||
| 64 | public Object getValue() { | ||
| 65 | return null; | ||
| 66 | } | ||
| 67 | |||
| 68 | /** | ||
| 69 | * Returns {@code void} state of this value object. | ||
| 70 | * | ||
| 71 | * @return {@code false} always | ||
| 72 | */ | ||
| 73 | public final boolean isVoid() { | ||
| 74 | return false; | ||
| 75 | } | ||
| 76 | } | ||
Binary file not shown.
| @@ -0,0 +1,168 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.decoder; | ||
| 26 | |||
| 27 | import java.beans.Expression; | ||
| 28 | |||
| 29 | import static java.util.Locale.ENGLISH; | ||
| 30 | |||
| 31 | /** | ||
| 32 | * This class is intended to handle <object> element. | ||
| 33 | * This element looks like <void> element, | ||
| 34 | * but its value is always used as an argument for element | ||
| 35 | * that contains this one. | ||
| 36 | * <p>The following atributes are supported: | ||
| 37 | * <dl> | ||
| 38 | * <dt>class | ||
| 39 | * <dd>the type is used for static methods and fields | ||
| 40 | * <dt>method | ||
| 41 | * <dd>the method name | ||
| 42 | * <dt>property | ||
| 43 | * <dd>the property name | ||
| 44 | * <dt>index | ||
| 45 | * <dd>the property index | ||
| 46 | * <dt>field | ||
| 47 | * <dd>the field name | ||
| 48 | * <dt>idref | ||
| 49 | * <dd>the identifier to refer to the variable | ||
| 50 | * <dt>id | ||
| 51 | * <dd>the identifier of the variable that is intended to store the result | ||
| 52 | * </dl> | ||
| 53 | * | ||
| 54 | * @since 1.7 | ||
| 55 | * | ||
| 56 | * @author Sergey A. Malenkov | ||
| 57 | */ | ||
| 58 | class ObjectElementHandler extends NewElementHandler { | ||
| 59 | private String idref; | ||
| 60 | private String field; | ||
| 61 | private Integer index; | ||
| 62 | private String property; | ||
| 63 | private String method; | ||
| 64 | |||
| 65 | /** | ||
| 66 | * Parses attributes of the element. | ||
| 67 | * The following atributes are supported: | ||
| 68 | * <dl> | ||
| 69 | * <dt>class | ||
| 70 | * <dd>the type is used for static methods and fields | ||
| 71 | * <dt>method | ||
| 72 | * <dd>the method name | ||
| 73 | * <dt>property | ||
| 74 | * <dd>the property name | ||
| 75 | * <dt>index | ||
| 76 | * <dd>the property index | ||
| 77 | * <dt>field | ||
| 78 | * <dd>the field name | ||
| 79 | * <dt>idref | ||
| 80 | * <dd>the identifier to refer to the variable | ||
| 81 | * <dt>id | ||
| 82 | * <dd>the identifier of the variable that is intended to store the result | ||
| 83 | * </dl> | ||
| 84 | * | ||
| 85 | * @param name the attribute name | ||
| 86 | * @param value the attribute value | ||
| 87 | */ | ||
| 88 | @Override | ||
| 89 | public final void addAttribute(String name, String value) { | ||
| 90 | if (name.equals("idref")) { // NON-NLS: the attribute name | ||
| 91 | this.idref = value; | ||
| 92 | } else if (name.equals("field")) { // NON-NLS: the attribute name | ||
| 93 | this.field = value; | ||
| 94 | } else if (name.equals("index")) { // NON-NLS: the attribute name | ||
| 95 | this.index = Integer.valueOf(value); | ||
| 96 | addArgument(this.index); // hack for compatibility | ||
| 97 | } else if (name.equals("property")) { // NON-NLS: the attribute name | ||
| 98 | this.property = value; | ||
| 99 | } else if (name.equals("method")) { // NON-NLS: the attribute name | ||
| 100 | this.method = value; | ||
| 101 | } else { | ||
| 102 | super.addAttribute(name, value); | ||
| 103 | } | ||
| 104 | } | ||
| 105 | |||
| 106 | /** | ||
| 107 | * Calculates the value of this element | ||
| 108 | * if the field attribute or the idref attribute is set. | ||
| 109 | */ | ||
| 110 | @Override | ||
| 111 | public final void startElement() { | ||
| 112 | if ((this.field != null) || (this.idref != null)) { | ||
| 113 | getValueObject(); | ||
| 114 | } | ||
| 115 | } | ||
| 116 | |||
| 117 | /** | ||
| 118 | * Tests whether the value of this element can be used | ||
| 119 | * as an argument of the element that contained in this one. | ||
| 120 | * | ||
| 121 | * @return {@code true} if the value of this element can be used | ||
| 122 | * as an argument of the element that contained in this one, | ||
| 123 | * {@code false} otherwise | ||
| 124 | */ | ||
| 125 | @Override | ||
| 126 | protected boolean isArgument() { | ||
| 127 | return true; // hack for compatibility | ||
| 128 | } | ||
| 129 | |||
| 130 | /** | ||
| 131 | * Creates the value of this element. | ||
| 132 | * | ||
| 133 | * @param type the base class | ||
| 134 | * @param args the array of arguments | ||
| 135 | * @return the value of this element | ||
| 136 | * @throws Exception if calculation is failed | ||
| 137 | */ | ||
| 138 | @Override | ||
| 139 | protected final ValueObject getValueObject(Class<?> type, Object[] args) throws Exception { | ||
| 140 | if (this.field != null) { | ||
| 141 | return ValueObjectImpl.create(FieldElementHandler.getFieldValue(getContextBean(), this.field)); | ||
| 142 | } | ||
| 143 | if (this.idref != null) { | ||
| 144 | return ValueObjectImpl.create(getVariable(this.idref)); | ||
| 145 | } | ||
| 146 | Object bean = getContextBean(); | ||
| 147 | String name; | ||
| 148 | if (this.index != null) { | ||
| 149 | name = (args.length == 2) | ||
| 150 | ? PropertyElementHandler.SETTER | ||
| 151 | : PropertyElementHandler.GETTER; | ||
| 152 | } else if (this.property != null) { | ||
| 153 | name = (args.length == 1) | ||
| 154 | ? PropertyElementHandler.SETTER | ||
| 155 | : PropertyElementHandler.GETTER; | ||
| 156 | |||
| 157 | if (0 < this.property.length()) { | ||
| 158 | name += this.property.substring(0, 1).toUpperCase(ENGLISH) + this.property.substring(1); | ||
| 159 | } | ||
| 160 | } else { | ||
| 161 | name = (this.method != null) && (0 < this.method.length()) | ||
| 162 | ? this.method | ||
| 163 | : "new"; // NON-NLS: the constructor marker | ||
| 164 | } | ||
| 165 | Expression expression = new Expression(bean, name, args); | ||
| 166 | return ValueObjectImpl.create(expression.getValue()); | ||
| 167 | } | ||
| 168 | } | ||
Binary file not shown.
| @@ -0,0 +1,287 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.decoder; | ||
| 26 | |||
| 27 | import com.sun.beans.finder.MethodFinder; | ||
| 28 | |||
| 29 | import java.beans.IndexedPropertyDescriptor; | ||
| 30 | import java.beans.IntrospectionException; | ||
| 31 | import java.beans.Introspector; | ||
| 32 | import java.beans.PropertyDescriptor; | ||
| 33 | |||
| 34 | import java.lang.reflect.Array; | ||
| 35 | import java.lang.reflect.InvocationTargetException; | ||
| 36 | import java.lang.reflect.Method; | ||
| 37 | |||
| 38 | /** | ||
| 39 | * This class is intended to handle <property> element. | ||
| 40 | * This element simplifies access to the properties. | ||
| 41 | * If the {@code index} attribute is specified | ||
| 42 | * this element uses additional {@code int} parameter. | ||
| 43 | * If the {@code name} attribute is not specified | ||
| 44 | * this element uses method "get" as getter | ||
| 45 | * and method "set" as setter. | ||
| 46 | * This element defines getter if it contains no argument. | ||
| 47 | * It returns the value of the property in this case. | ||
| 48 | * For example:<pre> | ||
| 49 | * <property name="object" index="10"/></pre> | ||
| 50 | * is shortcut to<pre> | ||
| 51 | * <method name="getObject"> | ||
| 52 | * <int>10</int> | ||
| 53 | * </method></pre> | ||
| 54 | * which is equivalent to {@code getObject(10)} in Java code. | ||
| 55 | * This element defines setter if it contains one argument. | ||
| 56 | * It does not return the value of the property in this case. | ||
| 57 | * For example:<pre> | ||
| 58 | * <property><int>0</int></property></pre> | ||
| 59 | * is shortcut to<pre> | ||
| 60 | * <method name="set"> | ||
| 61 | * <int>0</int> | ||
| 62 | * </method></pre> | ||
| 63 | * which is equivalent to {@code set(0)} in Java code. | ||
| 64 | * <p>The following atributes are supported: | ||
| 65 | * <dl> | ||
| 66 | * <dt>name | ||
| 67 | * <dd>the property name | ||
| 68 | * <dt>index | ||
| 69 | * <dd>the property index | ||
| 70 | * <dt>id | ||
| 71 | * <dd>the identifier of the variable that is intended to store the result | ||
| 72 | * </dl> | ||
| 73 | * | ||
| 74 | * @since 1.7 | ||
| 75 | * | ||
| 76 | * @author Sergey A. Malenkov | ||
| 77 | */ | ||
| 78 | final class PropertyElementHandler extends AccessorElementHandler { | ||
| 79 | static final String GETTER = "get"; // NON-NLS: the getter prefix | ||
| 80 | static final String SETTER = "set"; // NON-NLS: the setter prefix | ||
| 81 | |||
| 82 | private Integer index; | ||
| 83 | |||
| 84 | /** | ||
| 85 | * Parses attributes of the element. | ||
| 86 | * The following atributes are supported: | ||
| 87 | * <dl> | ||
| 88 | * <dt>name | ||
| 89 | * <dd>the property name | ||
| 90 | * <dt>index | ||
| 91 | * <dd>the property index | ||
| 92 | * <dt>id | ||
| 93 | * <dd>the identifier of the variable that is intended to store the result | ||
| 94 | * </dl> | ||
| 95 | * | ||
| 96 | * @param name the attribute name | ||
| 97 | * @param value the attribute value | ||
| 98 | */ | ||
| 99 | @Override | ||
| 100 | public void addAttribute(String name, String value) { | ||
| 101 | if (name.equals("index")) { // NON-NLS: the attribute name | ||
| 102 | this.index = Integer.valueOf(value); | ||
| 103 | } else { | ||
| 104 | super.addAttribute(name, value); | ||
| 105 | } | ||
| 106 | } | ||
| 107 | |||
| 108 | /** | ||
| 109 | * Tests whether the value of this element can be used | ||
| 110 | * as an argument of the element that contained in this one. | ||
| 111 | * | ||
| 112 | * @return {@code true} if the value of this element should be used | ||
| 113 | * as an argument of the element that contained in this one, | ||
| 114 | * {@code false} otherwise | ||
| 115 | */ | ||
| 116 | @Override | ||
| 117 | protected boolean isArgument() { | ||
| 118 | return false; // non-static accessor cannot be used an argument | ||
| 119 | } | ||
| 120 | |||
| 121 | /** | ||
| 122 | * Returns the value of the property with specified {@code name}. | ||
| 123 | * | ||
| 124 | * @param name the name of the property | ||
| 125 | * @return the value of the specified property | ||
| 126 | */ | ||
| 127 | @Override | ||
| 128 | protected Object getValue(String name) { | ||
| 129 | try { | ||
| 130 | return getPropertyValue(getContextBean(), name, this.index); | ||
| 131 | } | ||
| 132 | catch (Exception exception) { | ||
| 133 | getOwner().handleException(exception); | ||
| 134 | } | ||
| 135 | return null; | ||
| 136 | } | ||
| 137 | |||
| 138 | /** | ||
| 139 | * Sets the new value for the property with specified {@code name}. | ||
| 140 | * | ||
| 141 | * @param name the name of the property | ||
| 142 | * @param value the new value for the specified property | ||
| 143 | */ | ||
| 144 | @Override | ||
| 145 | protected void setValue(String name, Object value) { | ||
| 146 | try { | ||
| 147 | setPropertyValue(getContextBean(), name, this.index, value); | ||
| 148 | } | ||
| 149 | catch (Exception exception) { | ||
| 150 | getOwner().handleException(exception); | ||
| 151 | } | ||
| 152 | } | ||
| 153 | |||
| 154 | /** | ||
| 155 | * Performs the search of the getter for the property | ||
| 156 | * with specified {@code name} in specified class | ||
| 157 | * and returns value of the property. | ||
| 158 | * | ||
| 159 | * @param bean the context bean that contains property | ||
| 160 | * @param name the name of the property | ||
| 161 | * @param index the index of the indexed property | ||
| 162 | * @return the value of the property | ||
| 163 | * @throws IllegalAccessException if the property is not accesible | ||
| 164 | * @throws IntrospectionException if the bean introspection is failed | ||
| 165 | * @throws InvocationTargetException if the getter cannot be invoked | ||
| 166 | * @throws NoSuchMethodException if the getter is not found | ||
| 167 | */ | ||
| 168 | private static Object getPropertyValue(Object bean, String name, Integer index) throws IllegalAccessException, IntrospectionException, InvocationTargetException, NoSuchMethodException { | ||
| 169 | Class<?> type = bean.getClass(); | ||
| 170 | if (index == null) { | ||
| 171 | return findGetter(type, name).invoke(bean); | ||
| 172 | } else if (type.isArray() && (name == null)) { | ||
| 173 | return Array.get(bean, index); | ||
| 174 | } else { | ||
| 175 | return findGetter(type, name, int.class).invoke(bean, index); | ||
| 176 | } | ||
| 177 | } | ||
| 178 | |||
| 179 | /** | ||
| 180 | * Performs the search of the setter for the property | ||
| 181 | * with specified {@code name} in specified class | ||
| 182 | * and updates value of the property. | ||
| 183 | * | ||
| 184 | * @param bean the context bean that contains property | ||
| 185 | * @param name the name of the property | ||
| 186 | * @param index the index of the indexed property | ||
| 187 | * @param value the new value for the property | ||
| 188 | * @throws IllegalAccessException if the property is not accesible | ||
| 189 | * @throws IntrospectionException if the bean introspection is failed | ||
| 190 | * @throws InvocationTargetException if the setter cannot be invoked | ||
| 191 | * @throws NoSuchMethodException if the setter is not found | ||
| 192 | */ | ||
| 193 | private static void setPropertyValue(Object bean, String name, Integer index, Object value) throws IllegalAccessException, IntrospectionException, InvocationTargetException, NoSuchMethodException { | ||
| 194 | Class<?> type = bean.getClass(); | ||
| 195 | Class<?> param = (value != null) | ||
| 196 | ? value.getClass() | ||
| 197 | : null; | ||
| 198 | |||
| 199 | if (index == null) { | ||
| 200 | findSetter(type, name, param).invoke(bean, value); | ||
| 201 | } else if (type.isArray() && (name == null)) { | ||
| 202 | Array.set(bean, index, value); | ||
| 203 | } else { | ||
| 204 | findSetter(type, name, int.class, param).invoke(bean, index, value); | ||
| 205 | } | ||
| 206 | } | ||
| 207 | |||
| 208 | /** | ||
| 209 | * Performs the search of the getter for the property | ||
| 210 | * with specified {@code name} in specified class. | ||
| 211 | * | ||
| 212 | * @param type the class that contains method | ||
| 213 | * @param name the name of the property | ||
| 214 | * @param args the method arguments | ||
| 215 | * @return method object that represents found getter | ||
| 216 | * @throws IntrospectionException if the bean introspection is failed | ||
| 217 | * @throws NoSuchMethodException if method is not found | ||
| 218 | */ | ||
| 219 | private static Method findGetter(Class<?> type, String name, Class<?>...args) throws IntrospectionException, NoSuchMethodException { | ||
| 220 | if (name == null) { | ||
| 221 | return MethodFinder.findInstanceMethod(type, GETTER, args); | ||
| 222 | } | ||
| 223 | PropertyDescriptor pd = getProperty(type, name); | ||
| 224 | if (args.length == 0) { | ||
| 225 | Method method = pd.getReadMethod(); | ||
| 226 | if (method != null) { | ||
| 227 | return method; | ||
| 228 | } | ||
| 229 | } else if (pd instanceof IndexedPropertyDescriptor) { | ||
| 230 | IndexedPropertyDescriptor ipd = (IndexedPropertyDescriptor) pd; | ||
| 231 | Method method = ipd.getIndexedReadMethod(); | ||
| 232 | if (method != null) { | ||
| 233 | return method; | ||
| 234 | } | ||
| 235 | } | ||
| 236 | throw new IntrospectionException("Could not find getter for the " + name + " property"); | ||
| 237 | } | ||
| 238 | |||
| 239 | /** | ||
| 240 | * Performs the search of the setter for the property | ||
| 241 | * with specified {@code name} in specified class. | ||
| 242 | * | ||
| 243 | * @param type the class that contains method | ||
| 244 | * @param name the name of the property | ||
| 245 | * @param args the method arguments | ||
| 246 | * @return method object that represents found setter | ||
| 247 | * @throws IntrospectionException if the bean introspection is failed | ||
| 248 | * @throws NoSuchMethodException if method is not found | ||
| 249 | */ | ||
| 250 | private static Method findSetter(Class<?> type, String name, Class<?>...args) throws IntrospectionException, NoSuchMethodException { | ||
| 251 | if (name == null) { | ||
| 252 | return MethodFinder.findInstanceMethod(type, SETTER, args); | ||
| 253 | } | ||
| 254 | PropertyDescriptor pd = getProperty(type, name); | ||
| 255 | if (args.length == 1) { | ||
| 256 | Method method = pd.getWriteMethod(); | ||
| 257 | if (method != null) { | ||
| 258 | return method; | ||
| 259 | } | ||
| 260 | } else if (pd instanceof IndexedPropertyDescriptor) { | ||
| 261 | IndexedPropertyDescriptor ipd = (IndexedPropertyDescriptor) pd; | ||
| 262 | Method method = ipd.getIndexedWriteMethod(); | ||
| 263 | if (method != null) { | ||
| 264 | return method; | ||
| 265 | } | ||
| 266 | } | ||
| 267 | throw new IntrospectionException("Could not find setter for the " + name + " property"); | ||
| 268 | } | ||
| 269 | |||
| 270 | /** | ||
| 271 | * Performs the search of the descriptor for the property | ||
| 272 | * with specified {@code name} in specified class. | ||
| 273 | * | ||
| 274 | * @param type the class to introspect | ||
| 275 | * @param name the property name | ||
| 276 | * @return descriptor for the named property | ||
| 277 | * @throws IntrospectionException if property descriptor is not found | ||
| 278 | */ | ||
| 279 | private static PropertyDescriptor getProperty(Class<?> type, String name) throws IntrospectionException { | ||
| 280 | for (PropertyDescriptor pd : Introspector.getBeanInfo(type).getPropertyDescriptors()) { | ||
| 281 | if (name.equals(pd.getName())) { | ||
| 282 | return pd; | ||
| 283 | } | ||
| 284 | } | ||
| 285 | throw new IntrospectionException("Could not find the " + name + " property descriptor"); | ||
| 286 | } | ||
| 287 | } | ||
Binary file not shown.
| @@ -0,0 +1,63 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.decoder; | ||
| 26 | |||
| 27 | /** | ||
| 28 | * This class is intended to handle <short> element. | ||
| 29 | * This element specifies {@code short} values. | ||
| 30 | * The class {@link Short} is used as wrapper for these values. | ||
| 31 | * The result value is created from text of the body of this element. | ||
| 32 | * The body parsing is described in the class {@link StringElementHandler}. | ||
| 33 | * For example:<pre> | ||
| 34 | * <short>200</short></pre> | ||
| 35 | * is shortcut to<pre> | ||
| 36 | * <method name="decode" class="java.lang.Short"> | ||
| 37 | * <string>200</string> | ||
| 38 | * </method></pre> | ||
| 39 | * which is equivalent to {@code Short.decode("200")} in Java code. | ||
| 40 | * <p>The following atribute is supported: | ||
| 41 | * <dl> | ||
| 42 | * <dt>id | ||
| 43 | * <dd>the identifier of the variable that is intended to store the result | ||
| 44 | * </dl> | ||
| 45 | * | ||
| 46 | * @since 1.7 | ||
| 47 | * | ||
| 48 | * @author Sergey A. Malenkov | ||
| 49 | */ | ||
| 50 | final class ShortElementHandler extends StringElementHandler { | ||
| 51 | |||
| 52 | /** | ||
| 53 | * Creates {@code short} value from | ||
| 54 | * the text of the body of this element. | ||
| 55 | * | ||
| 56 | * @param argument the text of the body | ||
| 57 | * @return evaluated {@code short} value | ||
| 58 | */ | ||
| 59 | @Override | ||
| 60 | public Object getValue(String argument) { | ||
| 61 | return Short.decode(argument); | ||
| 62 | } | ||
| 63 | } | ||
Binary file not shown.
| @@ -0,0 +1,116 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.decoder; | ||
| 26 | |||
| 27 | /** | ||
| 28 | * This class is intended to handle <string> element. | ||
| 29 | * This element specifies {@link String} values. | ||
| 30 | * The result value is created from text of the body of this element. | ||
| 31 | * For example:<pre> | ||
| 32 | * <string>description</string></pre> | ||
| 33 | * is equivalent to {@code "description"} in Java code. | ||
| 34 | * The value of inner element is calculated | ||
| 35 | * before adding to the string using {@link String#valueOf(Object)}. | ||
| 36 | * Note that all characters are used including whitespaces (' ', '\t', '\n', '\r'). | ||
| 37 | * So the value of the element<pre> | ||
| 38 | * <string><true></string></pre> | ||
| 39 | * is not equal to the value of the element<pre> | ||
| 40 | * <string> | ||
| 41 | * <true> | ||
| 42 | * </string></pre> | ||
| 43 | * <p>The following atribute is supported: | ||
| 44 | * <dl> | ||
| 45 | * <dt>id | ||
| 46 | * <dd>the identifier of the variable that is intended to store the result | ||
| 47 | * </dl> | ||
| 48 | * | ||
| 49 | * @since 1.7 | ||
| 50 | * | ||
| 51 | * @author Sergey A. Malenkov | ||
| 52 | */ | ||
| 53 | public class StringElementHandler extends ElementHandler { | ||
| 54 | private StringBuilder sb = new StringBuilder(); | ||
| 55 | private ValueObject value = ValueObjectImpl.NULL; | ||
| 56 | |||
| 57 | /** | ||
| 58 | * Adds the character that contained in this element. | ||
| 59 | * | ||
| 60 | * @param ch the character | ||
| 61 | */ | ||
| 62 | @Override | ||
| 63 | public final void addCharacter(char ch) { | ||
| 64 | if (this.sb == null) { | ||
| 65 | throw new IllegalStateException("Could not add chararcter to evaluated string element"); | ||
| 66 | } | ||
| 67 | this.sb.append(ch); | ||
| 68 | } | ||
| 69 | |||
| 70 | /** | ||
| 71 | * Adds the string value of the argument to the string value of this element. | ||
| 72 | * | ||
| 73 | * @param argument the value of the element that contained in this one | ||
| 74 | */ | ||
| 75 | @Override | ||
| 76 | protected final void addArgument(Object argument) { | ||
| 77 | if (this.sb == null) { | ||
| 78 | throw new IllegalStateException("Could not add argument to evaluated string element"); | ||
| 79 | } | ||
| 80 | this.sb.append(argument); | ||
| 81 | } | ||
| 82 | |||
| 83 | /** | ||
| 84 | * Returns the value of this element. | ||
| 85 | * | ||
| 86 | * @return the value of this element | ||
| 87 | */ | ||
| 88 | @Override | ||
| 89 | protected final ValueObject getValueObject() { | ||
| 90 | if (this.sb != null) { | ||
| 91 | try { | ||
| 92 | this.value = ValueObjectImpl.create(getValue(this.sb.toString())); | ||
| 93 | } | ||
| 94 | catch (RuntimeException exception) { | ||
| 95 | getOwner().handleException(exception); | ||
| 96 | } | ||
| 97 | finally { | ||
| 98 | this.sb = null; | ||
| 99 | } | ||
| 100 | } | ||
| 101 | return this.value; | ||
| 102 | } | ||
| 103 | |||
| 104 | /** | ||
| 105 | * Returns the text of the body of this element. | ||
| 106 | * This method evaluates value from text of the body, | ||
| 107 | * and should be overridden in those handlers | ||
| 108 | * that extend behavior of this element. | ||
| 109 | * | ||
| 110 | * @param argument the text of the body | ||
| 111 | * @return evaluated value | ||
| 112 | */ | ||
| 113 | protected Object getValue(String argument) { | ||
| 114 | return argument; | ||
| 115 | } | ||
| 116 | } | ||
Binary file not shown.
| @@ -0,0 +1,56 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.decoder; | ||
| 26 | |||
| 27 | /** | ||
| 28 | * This class is intended to handle <true> element. | ||
| 29 | * This element specifies {@code true} value. | ||
| 30 | * It should not contain body or inner elements. | ||
| 31 | * For example:<pre> | ||
| 32 | * <true/></pre> | ||
| 33 | * is equivalent to {@code true} in Java code. | ||
| 34 | * <p>The following atribute is supported: | ||
| 35 | * <dl> | ||
| 36 | * <dt>id | ||
| 37 | * <dd>the identifier of the variable that is intended to store the result | ||
| 38 | * </dl> | ||
| 39 | * | ||
| 40 | * @since 1.7 | ||
| 41 | * | ||
| 42 | * @author Sergey A. Malenkov | ||
| 43 | */ | ||
| 44 | final class TrueElementHandler extends NullElementHandler { | ||
| 45 | |||
| 46 | /** | ||
| 47 | * Returns {@code Boolean.TRUE} | ||
| 48 | * as a value of <true> element. | ||
| 49 | * | ||
| 50 | * @return {@code Boolean.TRUE} by default | ||
| 51 | */ | ||
| 52 | @Override | ||
| 53 | public Object getValue() { | ||
| 54 | return Boolean.TRUE; | ||
| 55 | } | ||
| 56 | } | ||
Binary file not shown.
| @@ -0,0 +1,50 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.decoder; | ||
| 26 | |||
| 27 | /** | ||
| 28 | * This interface represents the result of method execution. | ||
| 29 | * | ||
| 30 | * @since 1.7 | ||
| 31 | * | ||
| 32 | * @author Sergey A. Malenkov | ||
| 33 | */ | ||
| 34 | public interface ValueObject { | ||
| 35 | |||
| 36 | /** | ||
| 37 | * Returns the result of method execution. | ||
| 38 | * | ||
| 39 | * @return the result of method execution | ||
| 40 | */ | ||
| 41 | Object getValue(); | ||
| 42 | |||
| 43 | /** | ||
| 44 | * Returns {@code void} state of this value object. | ||
| 45 | * | ||
| 46 | * @return {@code true} if value can be ignored, | ||
| 47 | * {@code false} otherwise | ||
| 48 | */ | ||
| 49 | boolean isVoid(); | ||
| 50 | } | ||
Binary file not shown.
| @@ -0,0 +1,88 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.decoder; | ||
| 26 | |||
| 27 | /** | ||
| 28 | * This utility class provides {@code static} method | ||
| 29 | * to create the object that contains the result of method execution. | ||
| 30 | * | ||
| 31 | * @since 1.7 | ||
| 32 | * | ||
| 33 | * @author Sergey A. Malenkov | ||
| 34 | */ | ||
| 35 | final class ValueObjectImpl implements ValueObject { | ||
| 36 | static final ValueObject NULL = new ValueObjectImpl(null); | ||
| 37 | static final ValueObject VOID = new ValueObjectImpl(); | ||
| 38 | |||
| 39 | /** | ||
| 40 | * Returns the object that describes returning value. | ||
| 41 | * | ||
| 42 | * @param value the result of method execution | ||
| 43 | * @return the object that describes value | ||
| 44 | */ | ||
| 45 | static ValueObject create(Object value) { | ||
| 46 | return (value != null) | ||
| 47 | ? new ValueObjectImpl(value) | ||
| 48 | : NULL; | ||
| 49 | } | ||
| 50 | |||
| 51 | private Object value; | ||
| 52 | private boolean isVoid; | ||
| 53 | |||
| 54 | /** | ||
| 55 | * Creates the object that describes returning void value. | ||
| 56 | */ | ||
| 57 | private ValueObjectImpl() { | ||
| 58 | this.isVoid = true; | ||
| 59 | } | ||
| 60 | |||
| 61 | /** | ||
| 62 | * Creates the object that describes returning non-void value. | ||
| 63 | * | ||
| 64 | * @param value the result of method execution | ||
| 65 | */ | ||
| 66 | private ValueObjectImpl(Object value) { | ||
| 67 | this.value = value; | ||
| 68 | } | ||
| 69 | |||
| 70 | /** | ||
| 71 | * Returns the result of method execution. | ||
| 72 | * | ||
| 73 | * @return the result of method execution | ||
| 74 | */ | ||
| 75 | public Object getValue() { | ||
| 76 | return this.value; | ||
| 77 | } | ||
| 78 | |||
| 79 | /** | ||
| 80 | * Returns {@code void} state of this value object. | ||
| 81 | * | ||
| 82 | * @return {@code true} if value should be ignored, | ||
| 83 | * {@code false} otherwise | ||
| 84 | */ | ||
| 85 | public boolean isVoid() { | ||
| 86 | return this.isVoid; | ||
| 87 | } | ||
| 88 | } | ||
Binary file not shown.
| @@ -0,0 +1,82 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.decoder; | ||
| 26 | |||
| 27 | /** | ||
| 28 | * This class is intended to handle <var> element. | ||
| 29 | * This element retrieves the value of specified variable. | ||
| 30 | * For example:<pre> | ||
| 31 | * <var id="id1" idref="id2"/></pre> | ||
| 32 | * is equivalent to {@code id1 = id2} in Java code. | ||
| 33 | * <p>The following atributes are supported: | ||
| 34 | * <dl> | ||
| 35 | * <dt>idref | ||
| 36 | * <dd>the identifier to refer to the variable | ||
| 37 | * <dt>id | ||
| 38 | * <dd>the identifier of the variable that is intended to store the result | ||
| 39 | * </dl> | ||
| 40 | * | ||
| 41 | * @since 1.7 | ||
| 42 | * | ||
| 43 | * @author Sergey A. Malenkov | ||
| 44 | */ | ||
| 45 | final class VarElementHandler extends ElementHandler { | ||
| 46 | private ValueObject value; | ||
| 47 | |||
| 48 | /** | ||
| 49 | * Parses attributes of the element. | ||
| 50 | * The following atributes are supported: | ||
| 51 | * <dl> | ||
| 52 | * <dt>idref | ||
| 53 | * <dd>the identifier to refer to the variable | ||
| 54 | * <dt>id | ||
| 55 | * <dd>the identifier of the variable that is intended to store the result | ||
| 56 | * </dl> | ||
| 57 | * | ||
| 58 | * @param name the attribute name | ||
| 59 | * @param value the attribute value | ||
| 60 | */ | ||
| 61 | @Override | ||
| 62 | public void addAttribute(String name, String value) { | ||
| 63 | if (name.equals("idref")) { // NON-NLS: the attribute name | ||
| 64 | this.value = ValueObjectImpl.create(getVariable(value)); | ||
| 65 | } else { | ||
| 66 | super.addAttribute(name, value); | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 70 | /** | ||
| 71 | * Returns the value of this element. | ||
| 72 | * | ||
| 73 | * @return the value of this element | ||
| 74 | */ | ||
| 75 | @Override | ||
| 76 | protected ValueObject getValueObject() { | ||
| 77 | if (this.value == null) { | ||
| 78 | throw new IllegalArgumentException("Variable name is not set"); | ||
| 79 | } | ||
| 80 | return this.value; | ||
| 81 | } | ||
| 82 | } | ||
Binary file not shown.
| @@ -0,0 +1,68 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.decoder; | ||
| 26 | |||
| 27 | /** | ||
| 28 | * This class is intended to handle <void> element. | ||
| 29 | * This element looks like <object> element, | ||
| 30 | * but its value is not used as an argument for element | ||
| 31 | * that contains this one. | ||
| 32 | * <p>The following atributes are supported: | ||
| 33 | * <dl> | ||
| 34 | * <dt>class | ||
| 35 | * <dd>the type is used for static methods and fields | ||
| 36 | * <dt>method | ||
| 37 | * <dd>the method name | ||
| 38 | * <dt>property | ||
| 39 | * <dd>the property name | ||
| 40 | * <dt>index | ||
| 41 | * <dd>the property index | ||
| 42 | * <dt>field | ||
| 43 | * <dd>the field name | ||
| 44 | * <dt>idref | ||
| 45 | * <dd>the identifier to refer to the variable | ||
| 46 | * <dt>id | ||
| 47 | * <dd>the identifier of the variable that is intended to store the result | ||
| 48 | * </dl> | ||
| 49 | * | ||
| 50 | * @since 1.7 | ||
| 51 | * | ||
| 52 | * @author Sergey A. Malenkov | ||
| 53 | */ | ||
| 54 | final class VoidElementHandler extends ObjectElementHandler { | ||
| 55 | |||
| 56 | /** | ||
| 57 | * Tests whether the value of this element can be used | ||
| 58 | * as an argument of the element that contained in this one. | ||
| 59 | * | ||
| 60 | * @return {@code true} if the value of this element should be used | ||
| 61 | * as an argument of the element that contained in this one, | ||
| 62 | * {@code false} otherwise | ||
| 63 | */ | ||
| 64 | @Override | ||
| 65 | protected boolean isArgument() { | ||
| 66 | return false; // hack for compatibility | ||
| 67 | } | ||
| 68 | } | ||
| @@ -0,0 +1,34 @@ | |||
| 1 | <../../../../../../mkconfig | ||
| 2 | |||
| 3 | TARG=\ | ||
| 4 | AccessorElementHandler.dis\ | ||
| 5 | ArrayElementHandler.dis\ | ||
| 6 | BooleanElementHandler.dis\ | ||
| 7 | ByteElementHandler.dis\ | ||
| 8 | CharElementHandler.dis\ | ||
| 9 | ClassElementHandler.dis\ | ||
| 10 | DocumentHandler.dis\ | ||
| 11 | DoubleElementHandler.dis\ | ||
| 12 | ElementHandler.dis\ | ||
| 13 | FalseElementHandler.dis\ | ||
| 14 | FieldElementHandler.dis\ | ||
| 15 | FloatElementHandler.dis\ | ||
| 16 | IntElementHandler.dis\ | ||
| 17 | JavaElementHandler.dis\ | ||
| 18 | LongElementHandler.dis\ | ||
| 19 | MethodElementHandler.dis\ | ||
| 20 | NewElementHandler.dis\ | ||
| 21 | NullElementHandler.dis\ | ||
| 22 | ObjectElementHandler.dis\ | ||
| 23 | PropertyElementHandler.dis\ | ||
| 24 | ShortElementHandler.dis\ | ||
| 25 | StringElementHandler.dis\ | ||
| 26 | TrueElementHandler.dis\ | ||
| 27 | ValueObject.dis\ | ||
| 28 | ValueObjectImpl.dis\ | ||
| 29 | VarElementHandler.dis\ | ||
| 30 | VoidElementHandler.dis\ | ||
| 31 | |||
| 32 | DISBIN=$ROOT/java/dis/java/java/com/sun/beans/decoder | ||
| 33 | |||
| 34 | <$ROOT/mkfiles/mkjava | ||
Binary file not shown.
| @@ -0,0 +1,213 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.finder; | ||
| 26 | |||
| 27 | import java.util.HashMap; | ||
| 28 | import java.util.Map; | ||
| 29 | |||
| 30 | /** | ||
| 31 | * This abstract class provides functionality | ||
| 32 | * to find a public method or constructor | ||
| 33 | * with specified parameter types. | ||
| 34 | * It supports a variable number of parameters. | ||
| 35 | * | ||
| 36 | * @since 1.7 | ||
| 37 | * | ||
| 38 | * @author Sergey A. Malenkov | ||
| 39 | */ | ||
| 40 | abstract class AbstractFinder<T> { | ||
| 41 | private final Class<?>[] args; | ||
| 42 | |||
| 43 | /** | ||
| 44 | * Creates finder for array of classes of arguments. | ||
| 45 | * If a particular element of array equals {@code null}, | ||
| 46 | * than the appropriate pair of classes | ||
| 47 | * does not take into consideration. | ||
| 48 | * | ||
| 49 | * @param args array of classes of arguments | ||
| 50 | */ | ||
| 51 | protected AbstractFinder(Class<?>[] args) { | ||
| 52 | this.args = args; | ||
| 53 | } | ||
| 54 | |||
| 55 | /** | ||
| 56 | * Returns an array of {@code Class} objects | ||
| 57 | * that represent the formal parameter types of the method | ||
| 58 | * Returns an empty array if the method takes no parameters. | ||
| 59 | * | ||
| 60 | * @param method the object that represents method | ||
| 61 | * @return the parameter types of the method | ||
| 62 | */ | ||
| 63 | protected abstract Class<?>[] getParameters(T method); | ||
| 64 | |||
| 65 | /** | ||
| 66 | * Returns {@code true} if and only if the method | ||
| 67 | * was declared to take a variable number of arguments. | ||
| 68 | * | ||
| 69 | * @param method the object that represents method | ||
| 70 | * @return {@code true} if the method was declared | ||
| 71 | * to take a variable number of arguments; | ||
| 72 | * {@code false} otherwise | ||
| 73 | */ | ||
| 74 | protected abstract boolean isVarArgs(T method); | ||
| 75 | |||
| 76 | /** | ||
| 77 | * Checks validness of the method. | ||
| 78 | * At least the valid method should be public. | ||
| 79 | * | ||
| 80 | * @param method the object that represents method | ||
| 81 | * @return {@code true} if the method is valid, | ||
| 82 | * {@code false} otherwise | ||
| 83 | */ | ||
| 84 | protected abstract boolean isValid(T method); | ||
| 85 | |||
| 86 | /** | ||
| 87 | * Performs a search in the {@code methods} array. | ||
| 88 | * The one method is selected from the array of the valid methods. | ||
| 89 | * The list of parameters of the selected method shows | ||
| 90 | * the best correlation with the list of arguments | ||
| 91 | * specified at class initialization. | ||
| 92 | * If more than one method is both accessible and applicable | ||
| 93 | * to a method invocation, it is necessary to choose one | ||
| 94 | * to provide the descriptor for the run-time method dispatch. | ||
| 95 | * The most specific method should be chosen. | ||
| 96 | * | ||
| 97 | * @param methods the array of methods to search within | ||
| 98 | * @return the object that represents found method | ||
| 99 | * @throws NoSuchMethodException if no method was found or several | ||
| 100 | * methods meet the search criteria | ||
| 101 | * @see #isAssignable | ||
| 102 | */ | ||
| 103 | final T find(T[] methods) throws NoSuchMethodException { | ||
| 104 | Map<T, Class<?>[]> map = new HashMap<T, Class<?>[]>(); | ||
| 105 | |||
| 106 | T oldMethod = null; | ||
| 107 | Class<?>[] oldParams = null; | ||
| 108 | boolean ambiguous = false; | ||
| 109 | |||
| 110 | for (T newMethod : methods) { | ||
| 111 | if (isValid(newMethod)) { | ||
| 112 | Class<?>[] newParams = getParameters(newMethod); | ||
| 113 | if (newParams.length == this.args.length) { | ||
| 114 | PrimitiveWrapperMap.replacePrimitivesWithWrappers(newParams); | ||
| 115 | if (isAssignable(newParams, this.args)) { | ||
| 116 | if (oldMethod == null) { | ||
| 117 | oldMethod = newMethod; | ||
| 118 | oldParams = newParams; | ||
| 119 | } else { | ||
| 120 | boolean useNew = isAssignable(oldParams, newParams); | ||
| 121 | boolean useOld = isAssignable(newParams, oldParams); | ||
| 122 | |||
| 123 | if (useOld == useNew) { | ||
| 124 | ambiguous = true; | ||
| 125 | } else if (useNew) { | ||
| 126 | oldMethod = newMethod; | ||
| 127 | oldParams = newParams; | ||
| 128 | ambiguous = false; | ||
| 129 | } | ||
| 130 | } | ||
| 131 | } | ||
| 132 | } | ||
| 133 | if (isVarArgs(newMethod)) { | ||
| 134 | int length = newParams.length - 1; | ||
| 135 | if (length <= this.args.length) { | ||
| 136 | Class<?>[] array = new Class<?>[this.args.length]; | ||
| 137 | System.arraycopy(newParams, 0, array, 0, length); | ||
| 138 | if (length < this.args.length) { | ||
| 139 | Class<?> type = newParams[length].getComponentType(); | ||
| 140 | if (type.isPrimitive()) { | ||
| 141 | type = PrimitiveWrapperMap.getType(type.getName()); | ||
| 142 | } | ||
| 143 | for (int i = length; i < this.args.length; i++) { | ||
| 144 | array[i] = type; | ||
| 145 | } | ||
| 146 | } | ||
| 147 | map.put(newMethod, array); | ||
| 148 | } | ||
| 149 | } | ||
| 150 | } | ||
| 151 | } | ||
| 152 | for (T newMethod : methods) { | ||
| 153 | Class<?>[] newParams = map.get(newMethod); | ||
| 154 | if (newParams != null) { | ||
| 155 | if (isAssignable(newParams, this.args)) { | ||
| 156 | if (oldMethod == null) { | ||
| 157 | oldMethod = newMethod; | ||
| 158 | oldParams = newParams; | ||
| 159 | } else { | ||
| 160 | boolean useNew = isAssignable(oldParams, newParams); | ||
| 161 | boolean useOld = isAssignable(newParams, oldParams); | ||
| 162 | |||
| 163 | if (useOld == useNew) { | ||
| 164 | if (oldParams == map.get(oldMethod)) { | ||
| 165 | ambiguous = true; | ||
| 166 | } | ||
| 167 | } else if (useNew) { | ||
| 168 | oldMethod = newMethod; | ||
| 169 | oldParams = newParams; | ||
| 170 | ambiguous = false; | ||
| 171 | } | ||
| 172 | } | ||
| 173 | } | ||
| 174 | } | ||
| 175 | } | ||
| 176 | |||
| 177 | if (ambiguous) { | ||
| 178 | throw new NoSuchMethodException("Ambiguous methods are found"); | ||
| 179 | } | ||
| 180 | if (oldMethod == null) { | ||
| 181 | throw new NoSuchMethodException("Method is not found"); | ||
| 182 | } | ||
| 183 | return oldMethod; | ||
| 184 | } | ||
| 185 | |||
| 186 | /** | ||
| 187 | * Determines if every class in {@code min} array is either the same as, | ||
| 188 | * or is a superclass of, the corresponding class in {@code max} array. | ||
| 189 | * The length of every array must equal the number of arguments. | ||
| 190 | * This comparison is performed in the {@link #find} method | ||
| 191 | * before the first call of the isAssignable method. | ||
| 192 | * If an argument equals {@code null} | ||
| 193 | * the appropriate pair of classes does not take into consideration. | ||
| 194 | * | ||
| 195 | * @param min the array of classes to be checked | ||
| 196 | * @param max the array of classes that is used to check | ||
| 197 | * @return {@code true} if all classes in {@code min} array | ||
| 198 | * are assignable from corresponding classes in {@code max} array, | ||
| 199 | * {@code false} otherwise | ||
| 200 | * | ||
| 201 | * @see Class#isAssignableFrom | ||
| 202 | */ | ||
| 203 | private boolean isAssignable(Class<?>[] min, Class<?>[] max) { | ||
| 204 | for (int i = 0; i < this.args.length; i++) { | ||
| 205 | if (null != this.args[i]) { | ||
| 206 | if (!min[i].isAssignableFrom(max[i])) { | ||
| 207 | return false; | ||
| 208 | } | ||
| 209 | } | ||
| 210 | } | ||
| 211 | return true; | ||
| 212 | } | ||
| 213 | } | ||
Binary file not shown.
| @@ -0,0 +1,98 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.finder; | ||
| 26 | |||
| 27 | import java.beans.BeanDescriptor; | ||
| 28 | import java.beans.BeanInfo; | ||
| 29 | import java.beans.MethodDescriptor; | ||
| 30 | import java.beans.PropertyDescriptor; | ||
| 31 | import java.lang.reflect.Method; | ||
| 32 | |||
| 33 | /** | ||
| 34 | * This is utility class that provides functionality | ||
| 35 | * to find a {@link BeanInfo} for a JavaBean specified by its type. | ||
| 36 | * | ||
| 37 | * @since 1.7 | ||
| 38 | * | ||
| 39 | * @author Sergey A. Malenkov | ||
| 40 | */ | ||
| 41 | public final class BeanInfoFinder | ||
| 42 | extends InstanceFinder<BeanInfo> { | ||
| 43 | |||
| 44 | private static final String DEFAULT = "sun.beans.infos"; | ||
| 45 | |||
| 46 | public BeanInfoFinder() { | ||
| 47 | super(BeanInfo.class, true, "BeanInfo", DEFAULT); | ||
| 48 | } | ||
| 49 | |||
| 50 | private static boolean isValid(Class<?> type, Method method) { | ||
| 51 | return (method != null) && method.getDeclaringClass().isAssignableFrom(type); | ||
| 52 | } | ||
| 53 | |||
| 54 | @Override | ||
| 55 | protected BeanInfo instantiate(Class<?> type, String prefix, String name) { | ||
| 56 | // this optimization will only use the BeanInfo search path | ||
| 57 | // if is has changed from the original | ||
| 58 | // or trying to get the ComponentBeanInfo | ||
| 59 | BeanInfo info = !DEFAULT.equals(prefix) || "ComponentBeanInfo".equals(name) | ||
| 60 | ? super.instantiate(type, prefix, name) | ||
| 61 | : null; | ||
| 62 | |||
| 63 | if (info != null) { | ||
| 64 | // make sure that the returned BeanInfo matches the class | ||
| 65 | BeanDescriptor bd = info.getBeanDescriptor(); | ||
| 66 | if (bd != null) { | ||
| 67 | if (type.equals(bd.getBeanClass())) { | ||
| 68 | return info; | ||
| 69 | } | ||
| 70 | } | ||
| 71 | else { | ||
| 72 | PropertyDescriptor[] pds = info.getPropertyDescriptors(); | ||
| 73 | if (pds != null) { | ||
| 74 | for (PropertyDescriptor pd : pds) { | ||
| 75 | Method method = pd.getReadMethod(); | ||
| 76 | if (method == null) { | ||
| 77 | method = pd.getWriteMethod(); | ||
| 78 | } | ||
| 79 | if (isValid(type, method)) { | ||
| 80 | return info; | ||
| 81 | } | ||
| 82 | } | ||
| 83 | } | ||
| 84 | else { | ||
| 85 | MethodDescriptor[] mds = info.getMethodDescriptors(); | ||
| 86 | if (mds != null) { | ||
| 87 | for (MethodDescriptor md : mds) { | ||
| 88 | if (isValid(type, md.getMethod())) { | ||
| 89 | return info; | ||
| 90 | } | ||
| 91 | } | ||
| 92 | } | ||
| 93 | } | ||
| 94 | } | ||
| 95 | } | ||
| 96 | return null; | ||
| 97 | } | ||
| 98 | } | ||
Binary file not shown.
| @@ -0,0 +1,176 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2006, 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.finder; | ||
| 26 | |||
| 27 | /** | ||
| 28 | * This is utility class that provides {@code static} methods | ||
| 29 | * to find a class with the specified name using the specified class loader. | ||
| 30 | * | ||
| 31 | * @since 1.7 | ||
| 32 | * | ||
| 33 | * @author Sergey A. Malenkov | ||
| 34 | */ | ||
| 35 | public final class ClassFinder { | ||
| 36 | |||
| 37 | /** | ||
| 38 | * Returns the {@code Class} object associated | ||
| 39 | * with the class or interface with the given string name, | ||
| 40 | * using the default class loader. | ||
| 41 | * <p> | ||
| 42 | * The {@code name} can denote an array class | ||
| 43 | * (see {@link Class#getName} for details). | ||
| 44 | * | ||
| 45 | * @param name fully qualified name of the desired class | ||
| 46 | * @return class object representing the desired class | ||
| 47 | * | ||
| 48 | * @throws ClassNotFoundException if the class cannot be located | ||
| 49 | * by the specified class loader | ||
| 50 | * | ||
| 51 | * @see Class#forName(String) | ||
| 52 | * @see Class#forName(String,boolean,ClassLoader) | ||
| 53 | * @see ClassLoader#getSystemClassLoader() | ||
| 54 | * @see Thread#getContextClassLoader() | ||
| 55 | */ | ||
| 56 | public static Class<?> findClass(String name) throws ClassNotFoundException { | ||
| 57 | try { | ||
| 58 | ClassLoader loader = Thread.currentThread().getContextClassLoader(); | ||
| 59 | if (loader == null) { | ||
| 60 | // can be null in IE (see 6204697) | ||
| 61 | loader = ClassLoader.getSystemClassLoader(); | ||
| 62 | } | ||
| 63 | if (loader != null) { | ||
| 64 | return Class.forName(name, false, loader); | ||
| 65 | } | ||
| 66 | |||
| 67 | } catch (ClassNotFoundException exception) { | ||
| 68 | // use current class loader instead | ||
| 69 | } catch (SecurityException exception) { | ||
| 70 | // use current class loader instead | ||
| 71 | } | ||
| 72 | return Class.forName(name); | ||
| 73 | } | ||
| 74 | |||
| 75 | /** | ||
| 76 | * Returns the {@code Class} object associated with | ||
| 77 | * the class or interface with the given string name, | ||
| 78 | * using the given class loader. | ||
| 79 | * <p> | ||
| 80 | * The {@code name} can denote an array class | ||
| 81 | * (see {@link Class#getName} for details). | ||
| 82 | * <p> | ||
| 83 | * If the parameter {@code loader} is null, | ||
| 84 | * the class is loaded through the default class loader. | ||
| 85 | * | ||
| 86 | * @param name fully qualified name of the desired class | ||
| 87 | * @param loader class loader from which the class must be loaded | ||
| 88 | * @return class object representing the desired class | ||
| 89 | * | ||
| 90 | * @throws ClassNotFoundException if the class cannot be located | ||
| 91 | * by the specified class loader | ||
| 92 | * | ||
| 93 | * @see #findClass(String,ClassLoader) | ||
| 94 | * @see Class#forName(String,boolean,ClassLoader) | ||
| 95 | */ | ||
| 96 | public static Class<?> findClass(String name, ClassLoader loader) throws ClassNotFoundException { | ||
| 97 | if (loader != null) { | ||
| 98 | try { | ||
| 99 | return Class.forName(name, false, loader); | ||
| 100 | } catch (ClassNotFoundException exception) { | ||
| 101 | // use default class loader instead | ||
| 102 | } catch (SecurityException exception) { | ||
| 103 | // use default class loader instead | ||
| 104 | } | ||
| 105 | } | ||
| 106 | return findClass(name); | ||
| 107 | } | ||
| 108 | |||
| 109 | /** | ||
| 110 | * Returns the {@code Class} object associated | ||
| 111 | * with the class or interface with the given string name, | ||
| 112 | * using the default class loader. | ||
| 113 | * <p> | ||
| 114 | * The {@code name} can denote an array class | ||
| 115 | * (see {@link Class#getName} for details). | ||
| 116 | * <p> | ||
| 117 | * This method can be used to obtain | ||
| 118 | * any of the {@code Class} objects | ||
| 119 | * representing {@code void} or primitive Java types: | ||
| 120 | * {@code char}, {@code byte}, {@code short}, | ||
| 121 | * {@code int}, {@code long}, {@code float}, | ||
| 122 | * {@code double} and {@code boolean}. | ||
| 123 | * | ||
| 124 | * @param name fully qualified name of the desired class | ||
| 125 | * @return class object representing the desired class | ||
| 126 | * | ||
| 127 | * @throws ClassNotFoundException if the class cannot be located | ||
| 128 | * by the specified class loader | ||
| 129 | * | ||
| 130 | * @see #resolveClass(String,ClassLoader) | ||
| 131 | */ | ||
| 132 | public static Class<?> resolveClass(String name) throws ClassNotFoundException { | ||
| 133 | return resolveClass(name, null); | ||
| 134 | } | ||
| 135 | |||
| 136 | /** | ||
| 137 | * Returns the {@code Class} object associated with | ||
| 138 | * the class or interface with the given string name, | ||
| 139 | * using the given class loader. | ||
| 140 | * <p> | ||
| 141 | * The {@code name} can denote an array class | ||
| 142 | * (see {@link Class#getName} for details). | ||
| 143 | * <p> | ||
| 144 | * If the parameter {@code loader} is null, | ||
| 145 | * the class is loaded through the default class loader. | ||
| 146 | * <p> | ||
| 147 | * This method can be used to obtain | ||
| 148 | * any of the {@code Class} objects | ||
| 149 | * representing {@code void} or primitive Java types: | ||
| 150 | * {@code char}, {@code byte}, {@code short}, | ||
| 151 | * {@code int}, {@code long}, {@code float}, | ||
| 152 | * {@code double} and {@code boolean}. | ||
| 153 | * | ||
| 154 | * @param name fully qualified name of the desired class | ||
| 155 | * @param loader class loader from which the class must be loaded | ||
| 156 | * @return class object representing the desired class | ||
| 157 | * | ||
| 158 | * @throws ClassNotFoundException if the class cannot be located | ||
| 159 | * by the specified class loader | ||
| 160 | * | ||
| 161 | * @see #findClass(String,ClassLoader) | ||
| 162 | * @see PrimitiveTypeMap#getType(String) | ||
| 163 | */ | ||
| 164 | public static Class<?> resolveClass(String name, ClassLoader loader) throws ClassNotFoundException { | ||
| 165 | Class<?> type = PrimitiveTypeMap.getType(name); | ||
| 166 | return (type == null) | ||
| 167 | ? findClass(name, loader) | ||
| 168 | : type; | ||
| 169 | } | ||
| 170 | |||
| 171 | /** | ||
| 172 | * Disable instantiation. | ||
| 173 | */ | ||
| 174 | private ClassFinder() { | ||
| 175 | } | ||
| 176 | } | ||
Binary file not shown.
| @@ -0,0 +1,127 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.finder; | ||
| 26 | |||
| 27 | import com.sun.beans.WeakCache; | ||
| 28 | |||
| 29 | import java.lang.reflect.Constructor; | ||
| 30 | import java.lang.reflect.Modifier; | ||
| 31 | |||
| 32 | /** | ||
| 33 | * This utility class provides {@code static} methods | ||
| 34 | * to find a public constructor with specified parameter types | ||
| 35 | * in specified class. | ||
| 36 | * | ||
| 37 | * @since 1.7 | ||
| 38 | * | ||
| 39 | * @author Sergey A. Malenkov | ||
| 40 | */ | ||
| 41 | public final class ConstructorFinder extends AbstractFinder<Constructor<?>> { | ||
| 42 | private static final WeakCache<Signature, Constructor<?>> CACHE = new WeakCache<Signature, Constructor<?>>(); | ||
| 43 | |||
| 44 | /** | ||
| 45 | * Finds public constructor | ||
| 46 | * that is declared in public class. | ||
| 47 | * | ||
| 48 | * @param type the class that can have constructor | ||
| 49 | * @param args parameter types that is used to find constructor | ||
| 50 | * @return object that represents found constructor | ||
| 51 | * @throws NoSuchMethodException if constructor could not be found | ||
| 52 | * or some constructors are found | ||
| 53 | */ | ||
| 54 | public static Constructor<?> findConstructor(Class<?> type, Class<?>...args) throws NoSuchMethodException { | ||
| 55 | if (type.isPrimitive()) { | ||
| 56 | throw new NoSuchMethodException("Primitive wrapper does not contain constructors"); | ||
| 57 | } | ||
| 58 | if (type.isInterface()) { | ||
| 59 | throw new NoSuchMethodException("Interface does not contain constructors"); | ||
| 60 | } | ||
| 61 | if (Modifier.isAbstract(type.getModifiers())) { | ||
| 62 | throw new NoSuchMethodException("Abstract class cannot be instantiated"); | ||
| 63 | } | ||
| 64 | if (!Modifier.isPublic(type.getModifiers())) { | ||
| 65 | throw new NoSuchMethodException("Class is not accessible"); | ||
| 66 | } | ||
| 67 | PrimitiveWrapperMap.replacePrimitivesWithWrappers(args); | ||
| 68 | Signature signature = new Signature(type, args); | ||
| 69 | |||
| 70 | Constructor<?> constructor = CACHE.get(signature); | ||
| 71 | if (constructor != null) { | ||
| 72 | return constructor; | ||
| 73 | } | ||
| 74 | constructor = new ConstructorFinder(args).find(type.getConstructors()); | ||
| 75 | CACHE.put(signature, constructor); | ||
| 76 | return constructor; | ||
| 77 | } | ||
| 78 | |||
| 79 | /** | ||
| 80 | * Creates constructor finder with specified array of parameter types. | ||
| 81 | * | ||
| 82 | * @param args the array of parameter types | ||
| 83 | */ | ||
| 84 | private ConstructorFinder(Class<?>[] args) { | ||
| 85 | super(args); | ||
| 86 | } | ||
| 87 | |||
| 88 | /** | ||
| 89 | * Returns an array of {@code Class} objects | ||
| 90 | * that represent the formal parameter types of the constructor | ||
| 91 | * Returns an empty array if the constructor takes no parameters. | ||
| 92 | * | ||
| 93 | * @param constructor the object that represents constructor | ||
| 94 | * @return the parameter types of the constructor | ||
| 95 | */ | ||
| 96 | @Override | ||
| 97 | protected Class<?>[] getParameters(Constructor<?> constructor) { | ||
| 98 | return constructor.getParameterTypes(); | ||
| 99 | } | ||
| 100 | |||
| 101 | /** | ||
| 102 | * Returns {@code true} if and only if the constructor | ||
| 103 | * was declared to take a variable number of arguments. | ||
| 104 | * | ||
| 105 | * @param constructor the object that represents constructor | ||
| 106 | * @return {@code true} if the constructor was declared | ||
| 107 | * to take a variable number of arguments; | ||
| 108 | * {@code false} otherwise | ||
| 109 | */ | ||
| 110 | @Override | ||
| 111 | protected boolean isVarArgs(Constructor<?> constructor) { | ||
| 112 | return constructor.isVarArgs(); | ||
| 113 | } | ||
| 114 | |||
| 115 | /** | ||
| 116 | * Checks validness of the constructor. | ||
| 117 | * The valid constructor should be public. | ||
| 118 | * | ||
| 119 | * @param constructor the object that represents constructor | ||
| 120 | * @return {@code true} if the constructor is valid, | ||
| 121 | * {@code false} otherwise | ||
| 122 | */ | ||
| 123 | @Override | ||
| 124 | protected boolean isValid(Constructor<?> constructor) { | ||
| 125 | return Modifier.isPublic(constructor.getModifiers()); | ||
| 126 | } | ||
| 127 | } | ||
Binary file not shown.
| @@ -0,0 +1,106 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.finder; | ||
| 26 | |||
| 27 | import java.lang.reflect.Field; | ||
| 28 | import java.lang.reflect.Modifier; | ||
| 29 | |||
| 30 | /** | ||
| 31 | * This utility class provides {@code static} methods | ||
| 32 | * to find a public field with specified name | ||
| 33 | * in specified class. | ||
| 34 | * | ||
| 35 | * @since 1.7 | ||
| 36 | * | ||
| 37 | * @author Sergey A. Malenkov | ||
| 38 | */ | ||
| 39 | public final class FieldFinder { | ||
| 40 | |||
| 41 | /** | ||
| 42 | * Finds public field (static or non-static) | ||
| 43 | * that is declared in public class. | ||
| 44 | * | ||
| 45 | * @param type the class that can have field | ||
| 46 | * @param name the name of field to find | ||
| 47 | * @return object that represents found field | ||
| 48 | * @throws NoSuchFieldException if field is not found | ||
| 49 | * @see Class#getField | ||
| 50 | */ | ||
| 51 | public static Field findField(Class<?> type, String name) throws NoSuchFieldException { | ||
| 52 | if (name == null) { | ||
| 53 | throw new IllegalArgumentException("Field name is not set"); | ||
| 54 | } | ||
| 55 | Field field = type.getField(name); | ||
| 56 | if (!Modifier.isPublic(field.getModifiers())) { | ||
| 57 | throw new NoSuchFieldException("Field '" + name + "' is not public"); | ||
| 58 | } | ||
| 59 | if (!Modifier.isPublic(field.getDeclaringClass().getModifiers())) { | ||
| 60 | throw new NoSuchFieldException("Field '" + name + "' is not accessible"); | ||
| 61 | } | ||
| 62 | return field; | ||
| 63 | } | ||
| 64 | |||
| 65 | /** | ||
| 66 | * Finds public non-static field | ||
| 67 | * that is declared in public class. | ||
| 68 | * | ||
| 69 | * @param type the class that can have field | ||
| 70 | * @param name the name of field to find | ||
| 71 | * @return object that represents found field | ||
| 72 | * @throws NoSuchFieldException if field is not found | ||
| 73 | * @see Class#getField | ||
| 74 | */ | ||
| 75 | public static Field findInstanceField(Class<?> type, String name) throws NoSuchFieldException { | ||
| 76 | Field field = findField(type, name); | ||
| 77 | if (Modifier.isStatic(field.getModifiers())) { | ||
| 78 | throw new NoSuchFieldException("Field '" + name + "' is static"); | ||
| 79 | } | ||
| 80 | return field; | ||
| 81 | } | ||
| 82 | |||
| 83 | /** | ||
| 84 | * Finds public static field | ||
| 85 | * that is declared in public class. | ||
| 86 | * | ||
| 87 | * @param type the class that can have field | ||
| 88 | * @param name the name of field to find | ||
| 89 | * @return object that represents found field | ||
| 90 | * @throws NoSuchFieldException if field is not found | ||
| 91 | * @see Class#getField | ||
| 92 | */ | ||
| 93 | public static Field findStaticField(Class<?> type, String name) throws NoSuchFieldException { | ||
| 94 | Field field = findField(type, name); | ||
| 95 | if (!Modifier.isStatic(field.getModifiers())) { | ||
| 96 | throw new NoSuchFieldException("Field '" + name + "' is not static"); | ||
| 97 | } | ||
| 98 | return field; | ||
| 99 | } | ||
| 100 | |||
| 101 | /** | ||
| 102 | * Disable instantiation. | ||
| 103 | */ | ||
| 104 | private FieldFinder() { | ||
| 105 | } | ||
| 106 | } | ||
Binary file not shown.
| @@ -0,0 +1,109 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.finder; | ||
| 26 | |||
| 27 | /** | ||
| 28 | * This is utility class that provides basic functionality | ||
| 29 | * to find an auxiliary class for a JavaBean specified by its type. | ||
| 30 | * | ||
| 31 | * @since 1.7 | ||
| 32 | * | ||
| 33 | * @author Sergey A. Malenkov | ||
| 34 | */ | ||
| 35 | class InstanceFinder<T> { | ||
| 36 | |||
| 37 | private static final String[] EMPTY = { }; | ||
| 38 | |||
| 39 | private final Class<? extends T> type; | ||
| 40 | private final boolean allow; | ||
| 41 | private final String suffix; | ||
| 42 | private volatile String[] packages; | ||
| 43 | |||
| 44 | InstanceFinder(Class<? extends T> type, boolean allow, String suffix, String... packages) { | ||
| 45 | this.type = type; | ||
| 46 | this.allow = allow; | ||
| 47 | this.suffix = suffix; | ||
| 48 | this.packages = packages.clone(); | ||
| 49 | } | ||
| 50 | |||
| 51 | public String[] getPackages() { | ||
| 52 | return this.packages.clone(); | ||
| 53 | } | ||
| 54 | |||
| 55 | public void setPackages(String... packages) { | ||
| 56 | this.packages = (packages != null) && (packages.length > 0) | ||
| 57 | ? packages.clone() | ||
| 58 | : EMPTY; | ||
| 59 | } | ||
| 60 | |||
| 61 | public T find(Class<?> type) { | ||
| 62 | if (type == null) { | ||
| 63 | return null; | ||
| 64 | } | ||
| 65 | String name = type.getName() + this.suffix; | ||
| 66 | T object = instantiate(type, name); | ||
| 67 | if (object != null) { | ||
| 68 | return object; | ||
| 69 | } | ||
| 70 | if (this.allow) { | ||
| 71 | object = instantiate(type, null); | ||
| 72 | if (object != null) { | ||
| 73 | return object; | ||
| 74 | } | ||
| 75 | } | ||
| 76 | int index = name.lastIndexOf('.') + 1; | ||
| 77 | if (index > 0) { | ||
| 78 | name = name.substring(index); | ||
| 79 | } | ||
| 80 | for (String prefix : this.packages) { | ||
| 81 | object = instantiate(type, prefix, name); | ||
| 82 | if (object != null) { | ||
| 83 | return object; | ||
| 84 | } | ||
| 85 | } | ||
| 86 | return null; | ||
| 87 | } | ||
| 88 | |||
| 89 | protected T instantiate(Class<?> type, String name) { | ||
| 90 | if (type != null) { | ||
| 91 | try { | ||
| 92 | if (name != null) { | ||
| 93 | type = ClassFinder.findClass(name, type.getClassLoader()); | ||
| 94 | } | ||
| 95 | if (this.type.isAssignableFrom(type)) { | ||
| 96 | return (T) type.newInstance(); | ||
| 97 | } | ||
| 98 | } | ||
| 99 | catch (Exception exception) { | ||
| 100 | // ignore any exceptions | ||
| 101 | } | ||
| 102 | } | ||
| 103 | return null; | ||
| 104 | } | ||
| 105 | |||
| 106 | protected T instantiate(Class<?> type, String prefix, String name) { | ||
| 107 | return instantiate(type, prefix + '.' + name); | ||
| 108 | } | ||
| 109 | } | ||
Binary file not shown.
| @@ -0,0 +1,231 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.finder; | ||
| 26 | |||
| 27 | import com.sun.beans.TypeResolver; | ||
| 28 | import com.sun.beans.WeakCache; | ||
| 29 | |||
| 30 | import java.lang.reflect.Method; | ||
| 31 | import java.lang.reflect.Modifier; | ||
| 32 | import java.lang.reflect.ParameterizedType; | ||
| 33 | import java.lang.reflect.Type; | ||
| 34 | import java.util.Arrays; | ||
| 35 | |||
| 36 | /** | ||
| 37 | * This utility class provides {@code static} methods | ||
| 38 | * to find a public method with specified name and parameter types | ||
| 39 | * in specified class. | ||
| 40 | * | ||
| 41 | * @since 1.7 | ||
| 42 | * | ||
| 43 | * @author Sergey A. Malenkov | ||
| 44 | */ | ||
| 45 | public final class MethodFinder extends AbstractFinder<Method> { | ||
| 46 | private static final WeakCache<Signature, Method> CACHE = new WeakCache<Signature, Method>(); | ||
| 47 | |||
| 48 | /** | ||
| 49 | * Finds public method (static or non-static) | ||
| 50 | * that is accessible from public class. | ||
| 51 | * | ||
| 52 | * @param type the class that can have method | ||
| 53 | * @param name the name of method to find | ||
| 54 | * @param args parameter types that is used to find method | ||
| 55 | * @return object that represents found method | ||
| 56 | * @throws NoSuchMethodException if method could not be found | ||
| 57 | * or some methods are found | ||
| 58 | */ | ||
| 59 | public static Method findMethod(Class<?> type, String name, Class<?>...args) throws NoSuchMethodException { | ||
| 60 | if (name == null) { | ||
| 61 | throw new IllegalArgumentException("Method name is not set"); | ||
| 62 | } | ||
| 63 | PrimitiveWrapperMap.replacePrimitivesWithWrappers(args); | ||
| 64 | Signature signature = new Signature(type, name, args); | ||
| 65 | |||
| 66 | Method method = CACHE.get(signature); | ||
| 67 | if (method != null) { | ||
| 68 | return method; | ||
| 69 | } | ||
| 70 | method = findAccessibleMethod(new MethodFinder(name, args).find(type.getMethods())); | ||
| 71 | CACHE.put(signature, method); | ||
| 72 | return method; | ||
| 73 | } | ||
| 74 | |||
| 75 | /** | ||
| 76 | * Finds public non-static method | ||
| 77 | * that is accessible from public class. | ||
| 78 | * | ||
| 79 | * @param type the class that can have method | ||
| 80 | * @param name the name of method to find | ||
| 81 | * @param args parameter types that is used to find method | ||
| 82 | * @return object that represents found method | ||
| 83 | * @throws NoSuchMethodException if method could not be found | ||
| 84 | * or some methods are found | ||
| 85 | */ | ||
| 86 | public static Method findInstanceMethod(Class<?> type, String name, Class<?>... args) throws NoSuchMethodException { | ||
| 87 | Method method = findMethod(type, name, args); | ||
| 88 | if (Modifier.isStatic(method.getModifiers())) { | ||
| 89 | throw new NoSuchMethodException("Method '" + name + "' is static"); | ||
| 90 | } | ||
| 91 | return method; | ||
| 92 | } | ||
| 93 | |||
| 94 | /** | ||
| 95 | * Finds public static method | ||
| 96 | * that is accessible from public class. | ||
| 97 | * | ||
| 98 | * @param type the class that can have method | ||
| 99 | * @param name the name of method to find | ||
| 100 | * @param args parameter types that is used to find method | ||
| 101 | * @return object that represents found method | ||
| 102 | * @throws NoSuchMethodException if method could not be found | ||
| 103 | * or some methods are found | ||
| 104 | */ | ||
| 105 | public static Method findStaticMethod(Class<?> type, String name, Class<?>...args) throws NoSuchMethodException { | ||
| 106 | Method method = findMethod(type, name, args); | ||
| 107 | if (!Modifier.isStatic(method.getModifiers())) { | ||
| 108 | throw new NoSuchMethodException("Method '" + name + "' is not static"); | ||
| 109 | } | ||
| 110 | return method; | ||
| 111 | } | ||
| 112 | |||
| 113 | /** | ||
| 114 | * Finds method that is accessible from public class or interface through class hierarchy. | ||
| 115 | * | ||
| 116 | * @param method object that represents found method | ||
| 117 | * @return object that represents accessible method | ||
| 118 | * @throws NoSuchMethodException if method is not accessible or is not found | ||
| 119 | * in specified superclass or interface | ||
| 120 | */ | ||
| 121 | public static Method findAccessibleMethod(Method method) throws NoSuchMethodException { | ||
| 122 | Class<?> type = method.getDeclaringClass(); | ||
| 123 | if (Modifier.isPublic(type.getModifiers())) { | ||
| 124 | return method; | ||
| 125 | } | ||
| 126 | if (Modifier.isStatic(method.getModifiers())) { | ||
| 127 | throw new NoSuchMethodException("Method '" + method.getName() + "' is not accessible"); | ||
| 128 | } | ||
| 129 | for (Type generic : type.getGenericInterfaces()) { | ||
| 130 | try { | ||
| 131 | return findAccessibleMethod(method, generic); | ||
| 132 | } | ||
| 133 | catch (NoSuchMethodException exception) { | ||
| 134 | // try to find in superclass or another interface | ||
| 135 | } | ||
| 136 | } | ||
| 137 | return findAccessibleMethod(method, type.getGenericSuperclass()); | ||
| 138 | } | ||
| 139 | |||
| 140 | /** | ||
| 141 | * Finds method that accessible from specified class. | ||
| 142 | * | ||
| 143 | * @param method object that represents found method | ||
| 144 | * @param generic generic type that is used to find accessible method | ||
| 145 | * @return object that represents accessible method | ||
| 146 | * @throws NoSuchMethodException if method is not accessible or is not found | ||
| 147 | * in specified superclass or interface | ||
| 148 | */ | ||
| 149 | private static Method findAccessibleMethod(Method method, Type generic) throws NoSuchMethodException { | ||
| 150 | String name = method.getName(); | ||
| 151 | Class<?>[] params = method.getParameterTypes(); | ||
| 152 | if (generic instanceof Class) { | ||
| 153 | Class<?> type = (Class<?>) generic; | ||
| 154 | return findAccessibleMethod(type.getMethod(name, params)); | ||
| 155 | } | ||
| 156 | if (generic instanceof ParameterizedType) { | ||
| 157 | ParameterizedType pt = (ParameterizedType) generic; | ||
| 158 | Class<?> type = (Class<?>) pt.getRawType(); | ||
| 159 | for (Method m : type.getMethods()) { | ||
| 160 | if (m.getName().equals(name)) { | ||
| 161 | Class<?>[] pts = m.getParameterTypes(); | ||
| 162 | if (pts.length == params.length) { | ||
| 163 | if (Arrays.equals(params, pts)) { | ||
| 164 | return findAccessibleMethod(m); | ||
| 165 | } | ||
| 166 | Type[] gpts = m.getGenericParameterTypes(); | ||
| 167 | if (Arrays.equals(params, TypeResolver.erase(TypeResolver.resolve(pt, gpts)))) { | ||
| 168 | return findAccessibleMethod(m); | ||
| 169 | } | ||
| 170 | } | ||
| 171 | } | ||
| 172 | } | ||
| 173 | } | ||
| 174 | throw new NoSuchMethodException("Method '" + name + "' is not accessible"); | ||
| 175 | } | ||
| 176 | |||
| 177 | |||
| 178 | private final String name; | ||
| 179 | |||
| 180 | /** | ||
| 181 | * Creates method finder with specified array of parameter types. | ||
| 182 | * | ||
| 183 | * @param name the name of method to find | ||
| 184 | * @param args the array of parameter types | ||
| 185 | */ | ||
| 186 | private MethodFinder(String name, Class<?>[] args) { | ||
| 187 | super(args); | ||
| 188 | this.name = name; | ||
| 189 | } | ||
| 190 | |||
| 191 | /** | ||
| 192 | * Returns an array of {@code Class} objects | ||
| 193 | * that represent the formal parameter types of the method | ||
| 194 | * Returns an empty array if the method takes no parameters. | ||
| 195 | * | ||
| 196 | * @param method the object that represents method | ||
| 197 | * @return the parameter types of the method | ||
| 198 | */ | ||
| 199 | @Override | ||
| 200 | protected Class<?>[] getParameters(Method method) { | ||
| 201 | return method.getParameterTypes(); | ||
| 202 | } | ||
| 203 | |||
| 204 | /** | ||
| 205 | * Returns {@code true} if and only if the method | ||
| 206 | * was declared to take a variable number of arguments. | ||
| 207 | * | ||
| 208 | * @param method the object that represents method | ||
| 209 | * @return {@code true} if the method was declared | ||
| 210 | * to take a variable number of arguments; | ||
| 211 | * {@code false} otherwise | ||
| 212 | */ | ||
| 213 | @Override | ||
| 214 | protected boolean isVarArgs(Method method) { | ||
| 215 | return method.isVarArgs(); | ||
| 216 | } | ||
| 217 | |||
| 218 | /** | ||
| 219 | * Checks validness of the method. | ||
| 220 | * The valid method should be public and | ||
| 221 | * should have the specified name. | ||
| 222 | * | ||
| 223 | * @param method the object that represents method | ||
| 224 | * @return {@code true} if the method is valid, | ||
| 225 | * {@code false} otherwise | ||
| 226 | */ | ||
| 227 | @Override | ||
| 228 | protected boolean isValid(Method method) { | ||
| 229 | return Modifier.isPublic(method.getModifiers()) && method.getName().equals(this.name); | ||
| 230 | } | ||
| 231 | } | ||
Binary file not shown.
| @@ -0,0 +1,68 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.finder; | ||
| 26 | |||
| 27 | import java.beans.PersistenceDelegate; | ||
| 28 | import java.util.HashMap; | ||
| 29 | import java.util.Map; | ||
| 30 | |||
| 31 | /** | ||
| 32 | * This is utility class that provides functionality | ||
| 33 | * to find a {@link PersistenceDelegate} for a JavaBean specified by its type. | ||
| 34 | * | ||
| 35 | * @since 1.7 | ||
| 36 | * | ||
| 37 | * @author Sergey A. Malenkov | ||
| 38 | */ | ||
| 39 | public final class PersistenceDelegateFinder | ||
| 40 | extends InstanceFinder<PersistenceDelegate> { | ||
| 41 | |||
| 42 | private final Map<Class<?>, PersistenceDelegate> registry; | ||
| 43 | |||
| 44 | public PersistenceDelegateFinder() { | ||
| 45 | super(PersistenceDelegate.class, true, "PersistenceDelegate"); | ||
| 46 | this.registry = new HashMap<Class<?>, PersistenceDelegate>(); | ||
| 47 | } | ||
| 48 | |||
| 49 | public void register(Class<?> type, PersistenceDelegate delegate) { | ||
| 50 | synchronized (this.registry) { | ||
| 51 | if (delegate != null) { | ||
| 52 | this.registry.put(type, delegate); | ||
| 53 | } | ||
| 54 | else { | ||
| 55 | this.registry.remove(type); | ||
| 56 | } | ||
| 57 | } | ||
| 58 | } | ||
| 59 | |||
| 60 | @Override | ||
| 61 | public PersistenceDelegate find(Class<?> type) { | ||
| 62 | PersistenceDelegate delegate; | ||
| 63 | synchronized (this.registry) { | ||
| 64 | delegate = this.registry.get(type); | ||
| 65 | } | ||
| 66 | return (delegate != null) ? delegate : super.find(type); | ||
| 67 | } | ||
| 68 | } | ||
Binary file not shown.
| @@ -0,0 +1,70 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2006, 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.finder; | ||
| 26 | |||
| 27 | import java.util.HashMap; | ||
| 28 | import java.util.Map; | ||
| 29 | |||
| 30 | /** | ||
| 31 | * This utility class associates | ||
| 32 | * name of primitive type with appropriate class. | ||
| 33 | * | ||
| 34 | * @since 1.7 | ||
| 35 | * | ||
| 36 | * @author Sergey A. Malenkov | ||
| 37 | */ | ||
| 38 | final class PrimitiveTypeMap { | ||
| 39 | |||
| 40 | /** | ||
| 41 | * Returns primitive type class by its name. | ||
| 42 | * | ||
| 43 | * @param name the name of primitive type | ||
| 44 | * @return found primitive type class, | ||
| 45 | * or {@code null} if not found | ||
| 46 | */ | ||
| 47 | static Class<?> getType(String name) { | ||
| 48 | return map.get(name); | ||
| 49 | } | ||
| 50 | |||
| 51 | private static final Map<String, Class<?>> map = new HashMap<String, Class<?>>(9); | ||
| 52 | |||
| 53 | static { | ||
| 54 | map.put(boolean.class.getName(), boolean.class); | ||
| 55 | map.put(char.class.getName(), char.class); | ||
| 56 | map.put(byte.class.getName(), byte.class); | ||
| 57 | map.put(short.class.getName(), short.class); | ||
| 58 | map.put(int.class.getName(), int.class); | ||
| 59 | map.put(long.class.getName(), long.class); | ||
| 60 | map.put(float.class.getName(), float.class); | ||
| 61 | map.put(double.class.getName(), double.class); | ||
| 62 | map.put(void.class.getName(), void.class); | ||
| 63 | } | ||
| 64 | |||
| 65 | /** | ||
| 66 | * Disable instantiation. | ||
| 67 | */ | ||
| 68 | private PrimitiveTypeMap() { | ||
| 69 | } | ||
| 70 | } | ||
Binary file not shown.
| @@ -0,0 +1,86 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.finder; | ||
| 26 | |||
| 27 | import java.util.HashMap; | ||
| 28 | import java.util.Map; | ||
| 29 | |||
| 30 | /** | ||
| 31 | * This utility class associates | ||
| 32 | * name of primitive type with appropriate wrapper. | ||
| 33 | * | ||
| 34 | * @since 1.7 | ||
| 35 | * | ||
| 36 | * @author Sergey A. Malenkov | ||
| 37 | */ | ||
| 38 | public final class PrimitiveWrapperMap { | ||
| 39 | |||
| 40 | /** | ||
| 41 | * Replaces all primitive types in specified array with wrappers. | ||
| 42 | * | ||
| 43 | * @param types array of classes where all primitive types | ||
| 44 | * will be replaced by appropriate wrappers | ||
| 45 | */ | ||
| 46 | static void replacePrimitivesWithWrappers(Class<?>[] types) { | ||
| 47 | for (int i = 0; i < types.length; i++) { | ||
| 48 | if (types[i] != null) { | ||
| 49 | if (types[i].isPrimitive()) { | ||
| 50 | types[i] = getType(types[i].getName()); | ||
| 51 | } | ||
| 52 | } | ||
| 53 | } | ||
| 54 | } | ||
| 55 | |||
| 56 | /** | ||
| 57 | * Returns wrapper for primitive type by its name. | ||
| 58 | * | ||
| 59 | * @param name the name of primitive type | ||
| 60 | * @return found wrapper for primitive type, | ||
| 61 | * or {@code null} if not found | ||
| 62 | */ | ||
| 63 | public static Class<?> getType(String name) { | ||
| 64 | return map.get(name); | ||
| 65 | } | ||
| 66 | |||
| 67 | private static final Map<String, Class<?>> map = new HashMap<String, Class<?>>(9); | ||
| 68 | |||
| 69 | static { | ||
| 70 | map.put(Boolean.TYPE.getName(), Boolean.class); | ||
| 71 | map.put(Character.TYPE.getName(), Character.class); | ||
| 72 | map.put(Byte.TYPE.getName(), Byte.class); | ||
| 73 | map.put(Short.TYPE.getName(), Short.class); | ||
| 74 | map.put(Integer.TYPE.getName(), Integer.class); | ||
| 75 | map.put(Long.TYPE.getName(), Long.class); | ||
| 76 | map.put(Float.TYPE.getName(), Float.class); | ||
| 77 | map.put(Double.TYPE.getName(), Double.class); | ||
| 78 | map.put(Void.TYPE.getName(), Void.class); | ||
| 79 | } | ||
| 80 | |||
| 81 | /** | ||
| 82 | * Disable instantiation. | ||
| 83 | */ | ||
| 84 | private PrimitiveWrapperMap() { | ||
| 85 | } | ||
| 86 | } | ||
Binary file not shown.
| @@ -0,0 +1,87 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.finder; | ||
| 26 | |||
| 27 | import com.sun.beans.WeakCache; | ||
| 28 | |||
| 29 | import java.beans.PropertyEditor; | ||
| 30 | |||
| 31 | import sun.beans.editors.BooleanEditor; | ||
| 32 | import sun.beans.editors.ByteEditor; | ||
| 33 | import sun.beans.editors.DoubleEditor; | ||
| 34 | import sun.beans.editors.EnumEditor; | ||
| 35 | import sun.beans.editors.FloatEditor; | ||
| 36 | import sun.beans.editors.IntegerEditor; | ||
| 37 | import sun.beans.editors.LongEditor; | ||
| 38 | import sun.beans.editors.ShortEditor; | ||
| 39 | |||
| 40 | /** | ||
| 41 | * This is utility class that provides functionality | ||
| 42 | * to find a {@link PropertyEditor} for a JavaBean specified by its type. | ||
| 43 | * | ||
| 44 | * @since 1.7 | ||
| 45 | * | ||
| 46 | * @author Sergey A. Malenkov | ||
| 47 | */ | ||
| 48 | public final class PropertyEditorFinder | ||
| 49 | extends InstanceFinder<PropertyEditor> { | ||
| 50 | |||
| 51 | private final WeakCache<Class<?>, Class<?>> registry; | ||
| 52 | |||
| 53 | public PropertyEditorFinder() { | ||
| 54 | super(PropertyEditor.class, false, "Editor", "sun.beans.editors"); | ||
| 55 | |||
| 56 | this.registry = new WeakCache<Class<?>, Class<?>>(); | ||
| 57 | this.registry.put(Byte.TYPE, ByteEditor.class); | ||
| 58 | this.registry.put(Short.TYPE, ShortEditor.class); | ||
| 59 | this.registry.put(Integer.TYPE, IntegerEditor.class); | ||
| 60 | this.registry.put(Long.TYPE, LongEditor.class); | ||
| 61 | this.registry.put(Boolean.TYPE, BooleanEditor.class); | ||
| 62 | this.registry.put(Float.TYPE, FloatEditor.class); | ||
| 63 | this.registry.put(Double.TYPE, DoubleEditor.class); | ||
| 64 | } | ||
| 65 | |||
| 66 | public void register(Class<?> type, Class<?> editor) { | ||
| 67 | synchronized (this.registry) { | ||
| 68 | this.registry.put(type, editor); | ||
| 69 | } | ||
| 70 | } | ||
| 71 | |||
| 72 | @Override | ||
| 73 | public PropertyEditor find(Class<?> type) { | ||
| 74 | Class<?> predefined; | ||
| 75 | synchronized (this.registry) { | ||
| 76 | predefined = this.registry.get(type); | ||
| 77 | } | ||
| 78 | PropertyEditor editor = instantiate(predefined, null); | ||
| 79 | if (editor == null) { | ||
| 80 | editor = super.find(type); | ||
| 81 | if ((editor == null) && (null != type.getEnumConstants())) { | ||
| 82 | editor = new EnumEditor(type); | ||
| 83 | } | ||
| 84 | } | ||
| 85 | return editor; | ||
| 86 | } | ||
| 87 | } | ||
Binary file not shown.
| @@ -0,0 +1,169 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | package com.sun.beans.finder; | ||
| 26 | |||
| 27 | /** | ||
| 28 | * This class is designed to be a key of a cache | ||
| 29 | * of constructors or methods. | ||
| 30 | * | ||
| 31 | * @since 1.7 | ||
| 32 | * | ||
| 33 | * @author Sergey A. Malenkov | ||
| 34 | */ | ||
| 35 | final class Signature { | ||
| 36 | private final Class<?> type; | ||
| 37 | private final String name; | ||
| 38 | private final Class<?>[] args; | ||
| 39 | |||
| 40 | private volatile int code; | ||
| 41 | |||
| 42 | /** | ||
| 43 | * Constructs signature for constructor. | ||
| 44 | * | ||
| 45 | * @param type the class that contains constructor | ||
| 46 | * @param args the types of constructor's parameters | ||
| 47 | */ | ||
| 48 | Signature(Class<?> type, Class<?>[] args) { | ||
| 49 | this(type, null, args); | ||
| 50 | } | ||
| 51 | |||
| 52 | /** | ||
| 53 | * Constructs signature for method. | ||
| 54 | * | ||
| 55 | * @param type the class that contains method | ||
| 56 | * @param name the name of the method | ||
| 57 | * @param args the types of method's parameters | ||
| 58 | */ | ||
| 59 | Signature(Class<?> type, String name, Class<?>[] args) { | ||
| 60 | this.type = type; | ||
| 61 | this.name = name; | ||
| 62 | this.args = args; | ||
| 63 | } | ||
| 64 | |||
| 65 | /** | ||
| 66 | * Indicates whether some other object is "equal to" this one. | ||
| 67 | * | ||
| 68 | * @param object the reference object with which to compare | ||
| 69 | * @return {@code true} if this object is the same as the | ||
| 70 | * {@code object} argument, {@code false} otherwise | ||
| 71 | * @see #hashCode() | ||
| 72 | */ | ||
| 73 | @Override | ||
| 74 | public boolean equals(Object object) { | ||
| 75 | if (this == object) { | ||
| 76 | return true; | ||
| 77 | } | ||
| 78 | if (object instanceof Signature) { | ||
| 79 | Signature signature = (Signature) object; | ||
| 80 | return isEqual(signature.type, this.type) | ||
| 81 | && isEqual(signature.name, this.name) | ||
| 82 | && isEqual(signature.args, this.args); | ||
| 83 | } | ||
| 84 | return false; | ||
| 85 | } | ||
| 86 | |||
| 87 | /** | ||
| 88 | * Indicates whether some object is "equal to" another one. | ||
| 89 | * This method supports {@code null} values. | ||
| 90 | * | ||
| 91 | * @param obj1 the first reference object that will compared | ||
| 92 | * @param obj2 the second reference object that will compared | ||
| 93 | * @return {@code true} if first object is the same as the second object, | ||
| 94 | * {@code false} otherwise | ||
| 95 | */ | ||
| 96 | private static boolean isEqual(Object obj1, Object obj2) { | ||
| 97 | return (obj1 == null) | ||
| 98 | ? obj2 == null | ||
| 99 | : obj1.equals(obj2); | ||
| 100 | } | ||
| 101 | |||
| 102 | /** | ||
| 103 | * Indicates whether some array is "equal to" another one. | ||
| 104 | * This method supports {@code null} values. | ||
| 105 | * | ||
| 106 | * @param args1 the first reference array that will compared | ||
| 107 | * @param args2 the second reference array that will compared | ||
| 108 | * @return {@code true} if first array is the same as the second array, | ||
| 109 | * {@code false} otherwise | ||
| 110 | */ | ||
| 111 | private static boolean isEqual(Class<?>[] args1, Class<?>[] args2) { | ||
| 112 | if ((args1 == null) || (args2 == null)) { | ||
| 113 | return args1 == args2; | ||
| 114 | } | ||
| 115 | if (args1.length != args2.length) { | ||
| 116 | return false; | ||
| 117 | } | ||
| 118 | for (int i = 0; i < args1.length; i++) { | ||
| 119 | if (!isEqual(args1[i], args2[i])) { | ||
| 120 | return false; | ||
| 121 | } | ||
| 122 | } | ||
| 123 | return true; | ||
| 124 | } | ||
| 125 | |||
| 126 | /** | ||
| 127 | * Returns a hash code value for the object. | ||
| 128 | * This method is supported for the benefit of hashtables | ||
| 129 | * such as {@link java.util.HashMap} or {@link java.util.HashSet}. | ||
| 130 | * Hash code computed using algorithm | ||
| 131 | * suggested in Effective Java, Item 8. | ||
| 132 | * | ||
| 133 | * @return a hash code value for this object | ||
| 134 | * @see #equals(Object) | ||
| 135 | */ | ||
| 136 | @Override | ||
| 137 | public int hashCode() { | ||
| 138 | if (this.code == 0) { | ||
| 139 | int code = 17; | ||
| 140 | code = addHashCode(code, this.type); | ||
| 141 | code = addHashCode(code, this.name); | ||
| 142 | |||
| 143 | if (this.args != null) { | ||
| 144 | for (Class<?> arg : this.args) { | ||
| 145 | code = addHashCode(code, arg); | ||
| 146 | } | ||
| 147 | } | ||
| 148 | this.code = code; | ||
| 149 | } | ||
| 150 | return this.code; | ||
| 151 | } | ||
| 152 | |||
| 153 | /** | ||
| 154 | * Adds hash code value if specified object. | ||
| 155 | * This is a part of the algorithm | ||
| 156 | * suggested in Effective Java, Item 8. | ||
| 157 | * | ||
| 158 | * @param code current hash code value | ||
| 159 | * @param object object that updates hash code value | ||
| 160 | * @return updated hash code value | ||
| 161 | * @see #hashCode() | ||
| 162 | */ | ||
| 163 | private static int addHashCode(int code, Object object) { | ||
| 164 | code *= 37; | ||
| 165 | return (object != null) | ||
| 166 | ? code + object.hashCode() | ||
| 167 | : code; | ||
| 168 | } | ||
| 169 | } | ||
| @@ -0,0 +1,19 @@ | |||
| 1 | <../../../../../../mkconfig | ||
| 2 | |||
| 3 | TARG=\ | ||
| 4 | AbstractFinder.dis\ | ||
| 5 | BeanInfoFinder.dis\ | ||
| 6 | ClassFinder.dis\ | ||
| 7 | ConstructorFinder.dis\ | ||
| 8 | FieldFinder.dis\ | ||
| 9 | InstanceFinder.dis\ | ||
| 10 | MethodFinder.dis\ | ||
| 11 | PersistenceDelegateFinder.dis\ | ||
| 12 | PrimitiveTypeMap.dis\ | ||
| 13 | PrimitiveWrapperMap.dis\ | ||
| 14 | PropertyEditorFinder.dis\ | ||
| 15 | Signature.dis\ | ||
| 16 | |||
| 17 | DISBIN=$ROOT/java/dis/java/java/com/sun/beans/finder | ||
| 18 | |||
| 19 | <$ROOT/mkfiles/mkjava | ||
| @@ -0,0 +1,15 @@ | |||
| 1 | <../../../../../mkconfig | ||
| 2 | |||
| 3 | DIRS=\ | ||
| 4 | decoder\ | ||
| 5 | finder\ | ||
| 6 | |||
| 7 | TARG=\ | ||
| 8 | TypeResolver.dis\ | ||
| 9 | WeakCache.dis\ | ||
| 10 | WildcardTypeImpl.dis\ | ||
| 11 | |||
| 12 | DISBIN=$ROOT/java/dis/java/java/com/sun/beans | ||
| 13 | |||
| 14 | <$ROOT/mkfiles/mkjava | ||
| 15 | <$ROOT/mkfiles/mksubdirs | ||
| @@ -0,0 +1,6 @@ | |||
| 1 | <../../../../../mkconfig | ||
| 2 | |||
| 3 | DIRS=\ | ||
| 4 | provider\ | ||
| 5 | |||
| 6 | <$ROOT/mkfiles/mksubdirs | ||
| @@ -0,0 +1,427 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.security.*; | ||
| 29 | import java.security.spec.*; | ||
| 30 | import javax.crypto.*; | ||
| 31 | import javax.crypto.spec.*; | ||
| 32 | import javax.crypto.BadPaddingException; | ||
| 33 | |||
| 34 | /** | ||
| 35 | * This class implements the AES algorithm in its various modes | ||
| 36 | * (<code>ECB</code>, <code>CFB</code>, <code>OFB</code>, <code>CBC</code>, | ||
| 37 | * <code>PCBC</code>) and padding schemes (<code>PKCS5Padding</code>, | ||
| 38 | * <code>NoPadding</code>, <code>ISO10126Padding</code>). | ||
| 39 | * | ||
| 40 | * @author Valerie Peng | ||
| 41 | * | ||
| 42 | * | ||
| 43 | * @see AESCrypt | ||
| 44 | * @see CipherBlockChaining | ||
| 45 | * @see ElectronicCodeBook | ||
| 46 | * @see CipherFeedback | ||
| 47 | * @see OutputFeedback | ||
| 48 | */ | ||
| 49 | |||
| 50 | public final class AESCipher extends CipherSpi { | ||
| 51 | /* | ||
| 52 | * internal CipherCore object which does the real work. | ||
| 53 | */ | ||
| 54 | private CipherCore core = null; | ||
| 55 | |||
| 56 | /** | ||
| 57 | * Creates an instance of AES cipher with default ECB mode and | ||
| 58 | * PKCS5Padding. | ||
| 59 | */ | ||
| 60 | public AESCipher() { | ||
| 61 | core = new CipherCore(new AESCrypt(), AESConstants.AES_BLOCK_SIZE); | ||
| 62 | } | ||
| 63 | |||
| 64 | /** | ||
| 65 | * Sets the mode of this cipher. | ||
| 66 | * | ||
| 67 | * @param mode the cipher mode | ||
| 68 | * | ||
| 69 | * @exception NoSuchAlgorithmException if the requested cipher mode does | ||
| 70 | * not exist | ||
| 71 | */ | ||
| 72 | protected void engineSetMode(String mode) | ||
| 73 | throws NoSuchAlgorithmException { | ||
| 74 | core.setMode(mode); | ||
| 75 | } | ||
| 76 | |||
| 77 | /** | ||
| 78 | * Sets the padding mechanism of this cipher. | ||
| 79 | * | ||
| 80 | * @param padding the padding mechanism | ||
| 81 | * | ||
| 82 | * @exception NoSuchPaddingException if the requested padding mechanism | ||
| 83 | * does not exist | ||
| 84 | */ | ||
| 85 | protected void engineSetPadding(String paddingScheme) | ||
| 86 | throws NoSuchPaddingException { | ||
| 87 | core.setPadding(paddingScheme); | ||
| 88 | } | ||
| 89 | |||
| 90 | /** | ||
| 91 | * Returns the block size (in bytes). | ||
| 92 | * | ||
| 93 | * @return the block size (in bytes), or 0 if the underlying algorithm is | ||
| 94 | * not a block cipher | ||
| 95 | */ | ||
| 96 | protected int engineGetBlockSize() { | ||
| 97 | return AESConstants.AES_BLOCK_SIZE; | ||
| 98 | } | ||
| 99 | |||
| 100 | /** | ||
| 101 | * Returns the length in bytes that an output buffer would need to be in | ||
| 102 | * order to hold the result of the next <code>update</code> or | ||
| 103 | * <code>doFinal</code> operation, given the input length | ||
| 104 | * <code>inputLen</code> (in bytes). | ||
| 105 | * | ||
| 106 | * <p>This call takes into account any unprocessed (buffered) data from a | ||
| 107 | * previous <code>update</code> call, and padding. | ||
| 108 | * | ||
| 109 | * <p>The actual output length of the next <code>update</code> or | ||
| 110 | * <code>doFinal</code> call may be smaller than the length returned by | ||
| 111 | * this method. | ||
| 112 | * | ||
| 113 | * @param inputLen the input length (in bytes) | ||
| 114 | * | ||
| 115 | * @return the required output buffer size (in bytes) | ||
| 116 | */ | ||
| 117 | protected int engineGetOutputSize(int inputLen) { | ||
| 118 | return core.getOutputSize(inputLen); | ||
| 119 | } | ||
| 120 | |||
| 121 | /** | ||
| 122 | * Returns the initialization vector (IV) in a new buffer. | ||
| 123 | * | ||
| 124 | * <p>This is useful in the case where a random IV has been created | ||
| 125 | * (see <a href = "#init">init</a>), | ||
| 126 | * or in the context of password-based encryption or | ||
| 127 | * decryption, where the IV is derived from a user-provided password. | ||
| 128 | * | ||
| 129 | * @return the initialization vector in a new buffer, or null if the | ||
| 130 | * underlying algorithm does not use an IV, or if the IV has not yet | ||
| 131 | * been set. | ||
| 132 | */ | ||
| 133 | protected byte[] engineGetIV() { | ||
| 134 | return core.getIV(); | ||
| 135 | } | ||
| 136 | |||
| 137 | /** | ||
| 138 | * Returns the parameters used with this cipher. | ||
| 139 | * | ||
| 140 | * <p>The returned parameters may be the same that were used to initialize | ||
| 141 | * this cipher, or may contain the default set of parameters or a set of | ||
| 142 | * randomly generated parameters used by the underlying cipher | ||
| 143 | * implementation (provided that the underlying cipher implementation | ||
| 144 | * uses a default set of parameters or creates new parameters if it needs | ||
| 145 | * parameters but was not initialized with any). | ||
| 146 | * | ||
| 147 | * @return the parameters used with this cipher, or null if this cipher | ||
| 148 | * does not use any parameters. | ||
| 149 | */ | ||
| 150 | protected AlgorithmParameters engineGetParameters() { | ||
| 151 | return core.getParameters("AES"); | ||
| 152 | } | ||
| 153 | |||
| 154 | /** | ||
| 155 | * Initializes this cipher with a key and a source of randomness. | ||
| 156 | * | ||
| 157 | * <p>The cipher is initialized for one of the following four operations: | ||
| 158 | * encryption, decryption, key wrapping or key unwrapping, depending on | ||
| 159 | * the value of <code>opmode</code>. | ||
| 160 | * | ||
| 161 | * <p>If this cipher requires an initialization vector (IV), it will get | ||
| 162 | * it from <code>random</code>. | ||
| 163 | * This behaviour should only be used in encryption or key wrapping | ||
| 164 | * mode, however. | ||
| 165 | * When initializing a cipher that requires an IV for decryption or | ||
| 166 | * key unwrapping, the IV | ||
| 167 | * (same IV that was used for encryption or key wrapping) must be provided | ||
| 168 | * explicitly as a | ||
| 169 | * parameter, in order to get the correct result. | ||
| 170 | * | ||
| 171 | * <p>This method also cleans existing buffer and other related state | ||
| 172 | * information. | ||
| 173 | * | ||
| 174 | * @param opmode the operation mode of this cipher (this is one of | ||
| 175 | * the following: | ||
| 176 | * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, | ||
| 177 | * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) | ||
| 178 | * @param key the secret key | ||
| 179 | * @param random the source of randomness | ||
| 180 | * | ||
| 181 | * @exception InvalidKeyException if the given key is inappropriate for | ||
| 182 | * initializing this cipher | ||
| 183 | */ | ||
| 184 | protected void engineInit(int opmode, Key key, SecureRandom random) | ||
| 185 | throws InvalidKeyException { | ||
| 186 | core.init(opmode, key, random); | ||
| 187 | } | ||
| 188 | |||
| 189 | /** | ||
| 190 | * Initializes this cipher with a key, a set of | ||
| 191 | * algorithm parameters, and a source of randomness. | ||
| 192 | * | ||
| 193 | * <p>The cipher is initialized for one of the following four operations: | ||
| 194 | * encryption, decryption, key wrapping or key unwrapping, depending on | ||
| 195 | * the value of <code>opmode</code>. | ||
| 196 | * | ||
| 197 | * <p>If this cipher (including its underlying feedback or padding scheme) | ||
| 198 | * requires any random bytes, it will get them from <code>random</code>. | ||
| 199 | * | ||
| 200 | * @param opmode the operation mode of this cipher (this is one of | ||
| 201 | * the following: | ||
| 202 | * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, | ||
| 203 | * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) | ||
| 204 | * @param key the encryption key | ||
| 205 | * @param params the algorithm parameters | ||
| 206 | * @param random the source of randomness | ||
| 207 | * | ||
| 208 | * @exception InvalidKeyException if the given key is inappropriate for | ||
| 209 | * initializing this cipher | ||
| 210 | * @exception InvalidAlgorithmParameterException if the given algorithm | ||
| 211 | * parameters are inappropriate for this cipher | ||
| 212 | */ | ||
| 213 | protected void engineInit(int opmode, Key key, | ||
| 214 | AlgorithmParameterSpec params, | ||
| 215 | SecureRandom random) | ||
| 216 | throws InvalidKeyException, InvalidAlgorithmParameterException { | ||
| 217 | core.init(opmode, key, params, random); | ||
| 218 | } | ||
| 219 | |||
| 220 | protected void engineInit(int opmode, Key key, | ||
| 221 | AlgorithmParameters params, | ||
| 222 | SecureRandom random) | ||
| 223 | throws InvalidKeyException, InvalidAlgorithmParameterException { | ||
| 224 | core.init(opmode, key, params, random); | ||
| 225 | } | ||
| 226 | |||
| 227 | /** | ||
| 228 | * Continues a multiple-part encryption or decryption operation | ||
| 229 | * (depending on how this cipher was initialized), processing another data | ||
| 230 | * part. | ||
| 231 | * | ||
| 232 | * <p>The first <code>inputLen</code> bytes in the <code>input</code> | ||
| 233 | * buffer, starting at <code>inputOffset</code>, are processed, and the | ||
| 234 | * result is stored in a new buffer. | ||
| 235 | * | ||
| 236 | * @param input the input buffer | ||
| 237 | * @param inputOffset the offset in <code>input</code> where the input | ||
| 238 | * starts | ||
| 239 | * @param inputLen the input length | ||
| 240 | * | ||
| 241 | * @return the new buffer with the result | ||
| 242 | * | ||
| 243 | * @exception IllegalStateException if this cipher is in a wrong state | ||
| 244 | * (e.g., has not been initialized) | ||
| 245 | */ | ||
| 246 | protected byte[] engineUpdate(byte[] input, int inputOffset, | ||
| 247 | int inputLen) { | ||
| 248 | return core.update(input, inputOffset, inputLen); | ||
| 249 | } | ||
| 250 | |||
| 251 | /** | ||
| 252 | * Continues a multiple-part encryption or decryption operation | ||
| 253 | * (depending on how this cipher was initialized), processing another data | ||
| 254 | * part. | ||
| 255 | * | ||
| 256 | * <p>The first <code>inputLen</code> bytes in the <code>input</code> | ||
| 257 | * buffer, starting at <code>inputOffset</code>, are processed, and the | ||
| 258 | * result is stored in the <code>output</code> buffer, starting at | ||
| 259 | * <code>outputOffset</code>. | ||
| 260 | * | ||
| 261 | * @param input the input buffer | ||
| 262 | * @param inputOffset the offset in <code>input</code> where the input | ||
| 263 | * starts | ||
| 264 | * @param inputLen the input length | ||
| 265 | * @param output the buffer for the result | ||
| 266 | * @param outputOffset the offset in <code>output</code> where the result | ||
| 267 | * is stored | ||
| 268 | * | ||
| 269 | * @return the number of bytes stored in <code>output</code> | ||
| 270 | * | ||
| 271 | * @exception ShortBufferException if the given output buffer is too small | ||
| 272 | * to hold the result | ||
| 273 | */ | ||
| 274 | protected int engineUpdate(byte[] input, int inputOffset, int inputLen, | ||
| 275 | byte[] output, int outputOffset) | ||
| 276 | throws ShortBufferException { | ||
| 277 | return core.update(input, inputOffset, inputLen, output, | ||
| 278 | outputOffset); | ||
| 279 | } | ||
| 280 | |||
| 281 | /** | ||
| 282 | * Encrypts or decrypts data in a single-part operation, | ||
| 283 | * or finishes a multiple-part operation. | ||
| 284 | * The data is encrypted or decrypted, depending on how this cipher was | ||
| 285 | * initialized. | ||
| 286 | * | ||
| 287 | * <p>The first <code>inputLen</code> bytes in the <code>input</code> | ||
| 288 | * buffer, starting at <code>inputOffset</code>, and any input bytes that | ||
| 289 | * may have been buffered during a previous <code>update</code> operation, | ||
| 290 | * are processed, with padding (if requested) being applied. | ||
| 291 | * The result is stored in a new buffer. | ||
| 292 | * | ||
| 293 | * <p>The cipher is reset to its initial state (uninitialized) after this | ||
| 294 | * call. | ||
| 295 | * | ||
| 296 | * @param input the input buffer | ||
| 297 | * @param inputOffset the offset in <code>input</code> where the input | ||
| 298 | * starts | ||
| 299 | * @param inputLen the input length | ||
| 300 | * | ||
| 301 | * @return the new buffer with the result | ||
| 302 | * | ||
| 303 | * @exception IllegalBlockSizeException if this cipher is a block cipher, | ||
| 304 | * no padding has been requested (only in encryption mode), and the total | ||
| 305 | * input length of the data processed by this cipher is not a multiple of | ||
| 306 | * block size | ||
| 307 | * @exception BadPaddingException if this cipher is in decryption mode, | ||
| 308 | * and (un)padding has been requested, but the decrypted data is not | ||
| 309 | * bounded by the appropriate padding bytes | ||
| 310 | */ | ||
| 311 | protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen) | ||
| 312 | throws IllegalBlockSizeException, BadPaddingException { | ||
| 313 | return core.doFinal(input, inputOffset, inputLen); | ||
| 314 | } | ||
| 315 | |||
| 316 | /** | ||
| 317 | * Encrypts or decrypts data in a single-part operation, | ||
| 318 | * or finishes a multiple-part operation. | ||
| 319 | * The data is encrypted or decrypted, depending on how this cipher was | ||
| 320 | * initialized. | ||
| 321 | * | ||
| 322 | * <p>The first <code>inputLen</code> bytes in the <code>input</code> | ||
| 323 | * buffer, starting at <code>inputOffset</code>, and any input bytes that | ||
| 324 | * may have been buffered during a previous <code>update</code> operation, | ||
| 325 | * are processed, with padding (if requested) being applied. | ||
| 326 | * The result is stored in the <code>output</code> buffer, starting at | ||
| 327 | * <code>outputOffset</code>. | ||
| 328 | * | ||
| 329 | * <p>The cipher is reset to its initial state (uninitialized) after this | ||
| 330 | * call. | ||
| 331 | * | ||
| 332 | * @param input the input buffer | ||
| 333 | * @param inputOffset the offset in <code>input</code> where the input | ||
| 334 | * starts | ||
| 335 | * @param inputLen the input length | ||
| 336 | * @param output the buffer for the result | ||
| 337 | * @param outputOffset the offset in <code>output</code> where the result | ||
| 338 | * is stored | ||
| 339 | * | ||
| 340 | * @return the number of bytes stored in <code>output</code> | ||
| 341 | * | ||
| 342 | * @exception IllegalBlockSizeException if this cipher is a block cipher, | ||
| 343 | * no padding has been requested (only in encryption mode), and the total | ||
| 344 | * input length of the data processed by this cipher is not a multiple of | ||
| 345 | * block size | ||
| 346 | * @exception ShortBufferException if the given output buffer is too small | ||
| 347 | * to hold the result | ||
| 348 | * @exception BadPaddingException if this cipher is in decryption mode, | ||
| 349 | * and (un)padding has been requested, but the decrypted data is not | ||
| 350 | * bounded by the appropriate padding bytes | ||
| 351 | */ | ||
| 352 | protected int engineDoFinal(byte[] input, int inputOffset, int inputLen, | ||
| 353 | byte[] output, int outputOffset) | ||
| 354 | throws IllegalBlockSizeException, ShortBufferException, | ||
| 355 | BadPaddingException { | ||
| 356 | return core.doFinal(input, inputOffset, inputLen, output, | ||
| 357 | outputOffset); | ||
| 358 | } | ||
| 359 | |||
| 360 | /** | ||
| 361 | * Returns the key size of the given key object. | ||
| 362 | * | ||
| 363 | * @param key the key object. | ||
| 364 | * | ||
| 365 | * @return the key size of the given key object. | ||
| 366 | * | ||
| 367 | * @exception InvalidKeyException if <code>key</code> is invalid. | ||
| 368 | */ | ||
| 369 | protected int engineGetKeySize(Key key) throws InvalidKeyException { | ||
| 370 | byte[] encoded = key.getEncoded(); | ||
| 371 | if (!AESCrypt.isKeySizeValid(encoded.length)) { | ||
| 372 | throw new InvalidKeyException("Invalid AES key length: " + | ||
| 373 | encoded.length + " bytes"); | ||
| 374 | } | ||
| 375 | return encoded.length * 8; | ||
| 376 | } | ||
| 377 | |||
| 378 | /** | ||
| 379 | * Wrap a key. | ||
| 380 | * | ||
| 381 | * @param key the key to be wrapped. | ||
| 382 | * | ||
| 383 | * @return the wrapped key. | ||
| 384 | * | ||
| 385 | * @exception IllegalBlockSizeException if this cipher is a block | ||
| 386 | * cipher, no padding has been requested, and the length of the | ||
| 387 | * encoding of the key to be wrapped is not a | ||
| 388 | * multiple of the block size. | ||
| 389 | * | ||
| 390 | * @exception InvalidKeyException if it is impossible or unsafe to | ||
| 391 | * wrap the key with this cipher (e.g., a hardware protected key is | ||
| 392 | * being passed to a software only cipher). | ||
| 393 | */ | ||
| 394 | protected byte[] engineWrap(Key key) | ||
| 395 | throws IllegalBlockSizeException, InvalidKeyException { | ||
| 396 | return core.wrap(key); | ||
| 397 | } | ||
| 398 | |||
| 399 | /** | ||
| 400 | * Unwrap a previously wrapped key. | ||
| 401 | * | ||
| 402 | * @param wrappedKey the key to be unwrapped. | ||
| 403 | * | ||
| 404 | * @param wrappedKeyAlgorithm the algorithm the wrapped key is for. | ||
| 405 | * | ||
| 406 | * @param wrappedKeyType the type of the wrapped key. | ||
| 407 | * This is one of <code>Cipher.SECRET_KEY</code>, | ||
| 408 | * <code>Cipher.PRIVATE_KEY</code>, or <code>Cipher.PUBLIC_KEY</code>. | ||
| 409 | * | ||
| 410 | * @return the unwrapped key. | ||
| 411 | * | ||
| 412 | * @exception NoSuchAlgorithmException if no installed providers | ||
| 413 | * can create keys of type <code>wrappedKeyType</code> for the | ||
| 414 | * <code>wrappedKeyAlgorithm</code>. | ||
| 415 | * | ||
| 416 | * @exception InvalidKeyException if <code>wrappedKey</code> does not | ||
| 417 | * represent a wrapped key of type <code>wrappedKeyType</code> for | ||
| 418 | * the <code>wrappedKeyAlgorithm</code>. | ||
| 419 | */ | ||
| 420 | protected Key engineUnwrap(byte[] wrappedKey, | ||
| 421 | String wrappedKeyAlgorithm, | ||
| 422 | int wrappedKeyType) | ||
| 423 | throws InvalidKeyException, NoSuchAlgorithmException { | ||
| 424 | return core.unwrap(wrappedKey, wrappedKeyAlgorithm, | ||
| 425 | wrappedKeyType); | ||
| 426 | } | ||
| 427 | } | ||
| @@ -0,0 +1,46 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | /** | ||
| 29 | * This class defines the constants used by the AES implementation. | ||
| 30 | * | ||
| 31 | * @author Valerie Peng | ||
| 32 | * | ||
| 33 | * | ||
| 34 | * @see AESCipher | ||
| 35 | */ | ||
| 36 | |||
| 37 | interface AESConstants { | ||
| 38 | |||
| 39 | // AES block size in bytes. | ||
| 40 | int AES_BLOCK_SIZE = 16; | ||
| 41 | |||
| 42 | // Valid AES key sizes in bytes. | ||
| 43 | // NOTE: The values need to be listed in an *increasing* order | ||
| 44 | // since DHKeyAgreement depends on this fact. | ||
| 45 | int[] AES_KEYSIZES = { 16, 24, 32 }; | ||
| 46 | } | ||
| @@ -0,0 +1,659 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | /* $Id: Rijndael.java,v 1.6 2000/02/10 01:31:41 gelderen Exp $ | ||
| 27 | * | ||
| 28 | * Copyright (C) 1995-2000 The Cryptix Foundation Limited. | ||
| 29 | * All rights reserved. | ||
| 30 | * | ||
| 31 | * Use, modification, copying and distribution of this softwareas is subject | ||
| 32 | * the terms and conditions of the Cryptix General Licence. You should have | ||
| 33 | * received a copy of the Cryptix General Licence along with this library; | ||
| 34 | * if not, you can download a copy from http://www.cryptix.org/ . | ||
| 35 | */ | ||
| 36 | |||
| 37 | package com.sun.crypto.provider; | ||
| 38 | |||
| 39 | import java.security.InvalidKeyException; | ||
| 40 | |||
| 41 | /** | ||
| 42 | * Rijndael --pronounced Reindaal-- is a symmetric cipher with a 128-bit | ||
| 43 | * block size and variable key-size (128-, 192- and 256-bit). | ||
| 44 | * <p> | ||
| 45 | * Rijndael was designed by <a href="mailto:rijmen@esat.kuleuven.ac.be">Vincent | ||
| 46 | * Rijmen</a> and <a href="mailto:Joan.Daemen@village.uunet.be">Joan Daemen</a>. | ||
| 47 | */ | ||
| 48 | final class AESCrypt extends SymmetricCipher implements AESConstants | ||
| 49 | { | ||
| 50 | private boolean ROUNDS_12 = false; | ||
| 51 | private boolean ROUNDS_14 = false; | ||
| 52 | |||
| 53 | /** Session and Sub keys */ | ||
| 54 | private Object[] sessionK = null; | ||
| 55 | private int[] K = null; | ||
| 56 | |||
| 57 | /** (ROUNDS-1) * 4 */ | ||
| 58 | private int limit = 0; | ||
| 59 | |||
| 60 | AESCrypt() { | ||
| 61 | // empty | ||
| 62 | } | ||
| 63 | |||
| 64 | /** | ||
| 65 | * Returns this cipher's block size. | ||
| 66 | * | ||
| 67 | * @return this cipher's block size | ||
| 68 | */ | ||
| 69 | int getBlockSize() { | ||
| 70 | return AES_BLOCK_SIZE; | ||
| 71 | } | ||
| 72 | |||
| 73 | void init(boolean decrypting, String algorithm, byte[] key) | ||
| 74 | throws InvalidKeyException { | ||
| 75 | if (!algorithm.equalsIgnoreCase("AES") | ||
| 76 | && !algorithm.equalsIgnoreCase("Rijndael")) { | ||
| 77 | throw new InvalidKeyException | ||
| 78 | ("Wrong algorithm: AES or Rijndael required"); | ||
| 79 | } | ||
| 80 | if (!isKeySizeValid(key.length)) { | ||
| 81 | throw new InvalidKeyException("Invalid AES key length: " + | ||
| 82 | key.length + " bytes"); | ||
| 83 | } | ||
| 84 | |||
| 85 | // generate session key and reset sub key. | ||
| 86 | sessionK = makeKey(key); | ||
| 87 | setSubKey(decrypting); | ||
| 88 | } | ||
| 89 | |||
| 90 | private void setSubKey(boolean decrypting) { | ||
| 91 | int[][] Kd = (int[][]) sessionK[decrypting ? 1 : 0]; | ||
| 92 | int rounds = Kd.length; | ||
| 93 | this.K = new int[rounds*4]; | ||
| 94 | for(int i=0; i<rounds; i++) { | ||
| 95 | for(int j=0; j<4; j++) { | ||
| 96 | K[i*4 + j] = Kd[i][j]; | ||
| 97 | } | ||
| 98 | } | ||
| 99 | |||
| 100 | if (decrypting) { | ||
| 101 | int j0 = K[K.length-4]; | ||
| 102 | int j1 = K[K.length-3]; | ||
| 103 | int j2 = K[K.length-2]; | ||
| 104 | int j3 = K[K.length-1]; | ||
| 105 | |||
| 106 | for (int i=this.K.length-1; i>3; i--) { | ||
| 107 | this.K[i] = this.K[i-4]; | ||
| 108 | } | ||
| 109 | K[0] = j0; | ||
| 110 | K[1] = j1; | ||
| 111 | K[2] = j2; | ||
| 112 | K[3] = j3; | ||
| 113 | } | ||
| 114 | |||
| 115 | ROUNDS_12 = (rounds>=13); | ||
| 116 | ROUNDS_14 = (rounds==15); | ||
| 117 | |||
| 118 | rounds--; | ||
| 119 | limit=rounds*4; | ||
| 120 | } | ||
| 121 | |||
| 122 | private static int[] | ||
| 123 | alog = new int[256], | ||
| 124 | log = new int[256]; | ||
| 125 | |||
| 126 | private static final byte[] | ||
| 127 | S = new byte[256], | ||
| 128 | Si = new byte[256]; | ||
| 129 | |||
| 130 | private static final int[] | ||
| 131 | T1 = new int[256], | ||
| 132 | T2 = new int[256], | ||
| 133 | T3 = new int[256], | ||
| 134 | T4 = new int[256], | ||
| 135 | T5 = new int[256], | ||
| 136 | T6 = new int[256], | ||
| 137 | T7 = new int[256], | ||
| 138 | T8 = new int[256]; | ||
| 139 | |||
| 140 | private static final int[] | ||
| 141 | U1 = new int[256], | ||
| 142 | U2 = new int[256], | ||
| 143 | U3 = new int[256], | ||
| 144 | U4 = new int[256]; | ||
| 145 | |||
| 146 | private static final byte[] rcon = new byte[30]; | ||
| 147 | |||
| 148 | |||
| 149 | // Static code - to intialise S-boxes and T-boxes | ||
| 150 | static | ||
| 151 | { | ||
| 152 | int ROOT = 0x11B; | ||
| 153 | int i, j = 0; | ||
| 154 | |||
| 155 | // | ||
| 156 | // produce log and alog tables, needed for multiplying in the | ||
| 157 | // field GF(2^m) (generator = 3) | ||
| 158 | // | ||
| 159 | alog[0] = 1; | ||
| 160 | for (i = 1; i < 256; i++) | ||
| 161 | { | ||
| 162 | j = (alog[i-1] << 1) ^ alog[i-1]; | ||
| 163 | if ((j & 0x100) != 0) { | ||
| 164 | j ^= ROOT; | ||
| 165 | } | ||
| 166 | alog[i] = j; | ||
| 167 | } | ||
| 168 | for (i = 1; i < 255; i++) { | ||
| 169 | log[alog[i]] = i; | ||
| 170 | } | ||
| 171 | byte[][] A = new byte[][] | ||
| 172 | { | ||
| 173 | {1, 1, 1, 1, 1, 0, 0, 0}, | ||
| 174 | {0, 1, 1, 1, 1, 1, 0, 0}, | ||
| 175 | {0, 0, 1, 1, 1, 1, 1, 0}, | ||
| 176 | {0, 0, 0, 1, 1, 1, 1, 1}, | ||
| 177 | {1, 0, 0, 0, 1, 1, 1, 1}, | ||
| 178 | {1, 1, 0, 0, 0, 1, 1, 1}, | ||
| 179 | {1, 1, 1, 0, 0, 0, 1, 1}, | ||
| 180 | {1, 1, 1, 1, 0, 0, 0, 1} | ||
| 181 | }; | ||
| 182 | byte[] B = new byte[] { 0, 1, 1, 0, 0, 0, 1, 1}; | ||
| 183 | |||
| 184 | // | ||
| 185 | // substitution box based on F^{-1}(x) | ||
| 186 | // | ||
| 187 | int t; | ||
| 188 | byte[][] box = new byte[256][8]; | ||
| 189 | box[1][7] = 1; | ||
| 190 | for (i = 2; i < 256; i++) { | ||
| 191 | j = alog[255 - log[i]]; | ||
| 192 | for (t = 0; t < 8; t++) { | ||
| 193 | box[i][t] = (byte)((j >>> (7 - t)) & 0x01); | ||
| 194 | } | ||
| 195 | } | ||
| 196 | // | ||
| 197 | // affine transform: box[i] <- B + A*box[i] | ||
| 198 | // | ||
| 199 | byte[][] cox = new byte[256][8]; | ||
| 200 | for (i = 0; i < 256; i++) { | ||
| 201 | for (t = 0; t < 8; t++) { | ||
| 202 | cox[i][t] = B[t]; | ||
| 203 | for (j = 0; j < 8; j++) { | ||
| 204 | cox[i][t] ^= A[t][j] * box[i][j]; | ||
| 205 | } | ||
| 206 | } | ||
| 207 | } | ||
| 208 | // | ||
| 209 | // S-boxes and inverse S-boxes | ||
| 210 | // | ||
| 211 | for (i = 0; i < 256; i++) { | ||
| 212 | S[i] = (byte)(cox[i][0] << 7); | ||
| 213 | for (t = 1; t < 8; t++) { | ||
| 214 | S[i] ^= cox[i][t] << (7-t); | ||
| 215 | } | ||
| 216 | Si[S[i] & 0xFF] = (byte) i; | ||
| 217 | } | ||
| 218 | // | ||
| 219 | // T-boxes | ||
| 220 | // | ||
| 221 | byte[][] G = new byte[][] { | ||
| 222 | {2, 1, 1, 3}, | ||
| 223 | {3, 2, 1, 1}, | ||
| 224 | {1, 3, 2, 1}, | ||
| 225 | {1, 1, 3, 2} | ||
| 226 | }; | ||
| 227 | byte[][] AA = new byte[4][8]; | ||
| 228 | for (i = 0; i < 4; i++) { | ||
| 229 | for (j = 0; j < 4; j++) AA[i][j] = G[i][j]; | ||
| 230 | AA[i][i+4] = 1; | ||
| 231 | } | ||
| 232 | byte pivot, tmp; | ||
| 233 | byte[][] iG = new byte[4][4]; | ||
| 234 | for (i = 0; i < 4; i++) { | ||
| 235 | pivot = AA[i][i]; | ||
| 236 | if (pivot == 0) { | ||
| 237 | t = i + 1; | ||
| 238 | while ((AA[t][i] == 0) && (t < 4)) { | ||
| 239 | t++; | ||
| 240 | } | ||
| 241 | if (t == 4) { | ||
| 242 | throw new RuntimeException("G matrix is not invertible"); | ||
| 243 | } | ||
| 244 | else { | ||
| 245 | for (j = 0; j < 8; j++) { | ||
| 246 | tmp = AA[i][j]; | ||
| 247 | AA[i][j] = AA[t][j]; | ||
| 248 | AA[t][j] = (byte) tmp; | ||
| 249 | } | ||
| 250 | pivot = AA[i][i]; | ||
| 251 | } | ||
| 252 | } | ||
| 253 | for (j = 0; j < 8; j++) { | ||
| 254 | if (AA[i][j] != 0) { | ||
| 255 | AA[i][j] = (byte) | ||
| 256 | alog[(255 + log[AA[i][j] & 0xFF] - log[pivot & 0xFF]) | ||
| 257 | % 255]; | ||
| 258 | } | ||
| 259 | } | ||
| 260 | for (t = 0; t < 4; t++) { | ||
| 261 | if (i != t) { | ||
| 262 | for (j = i+1; j < 8; j++) { | ||
| 263 | AA[t][j] ^= mul(AA[i][j], AA[t][i]); | ||
| 264 | } | ||
| 265 | AA[t][i] = 0; | ||
| 266 | } | ||
| 267 | } | ||
| 268 | } | ||
| 269 | for (i = 0; i < 4; i++) { | ||
| 270 | for (j = 0; j < 4; j++) { | ||
| 271 | iG[i][j] = AA[i][j + 4]; | ||
| 272 | } | ||
| 273 | } | ||
| 274 | |||
| 275 | int s; | ||
| 276 | for (t = 0; t < 256; t++) { | ||
| 277 | s = S[t]; | ||
| 278 | T1[t] = mul4(s, G[0]); | ||
| 279 | T2[t] = mul4(s, G[1]); | ||
| 280 | T3[t] = mul4(s, G[2]); | ||
| 281 | T4[t] = mul4(s, G[3]); | ||
| 282 | |||
| 283 | s = Si[t]; | ||
| 284 | T5[t] = mul4(s, iG[0]); | ||
| 285 | T6[t] = mul4(s, iG[1]); | ||
| 286 | T7[t] = mul4(s, iG[2]); | ||
| 287 | T8[t] = mul4(s, iG[3]); | ||
| 288 | |||
| 289 | U1[t] = mul4(t, iG[0]); | ||
| 290 | U2[t] = mul4(t, iG[1]); | ||
| 291 | U3[t] = mul4(t, iG[2]); | ||
| 292 | U4[t] = mul4(t, iG[3]); | ||
| 293 | } | ||
| 294 | // | ||
| 295 | // round constants | ||
| 296 | // | ||
| 297 | rcon[0] = 1; | ||
| 298 | int r = 1; | ||
| 299 | for (t = 1; t < 30; t++) { | ||
| 300 | r = mul(2, r); | ||
| 301 | rcon[t] = (byte) r; | ||
| 302 | } | ||
| 303 | log = null; | ||
| 304 | alog = null; | ||
| 305 | } | ||
| 306 | |||
| 307 | // multiply two elements of GF(2^m) | ||
| 308 | private static final int mul (int a, int b) { | ||
| 309 | return (a != 0 && b != 0) ? | ||
| 310 | alog[(log[a & 0xFF] + log[b & 0xFF]) % 255] : | ||
| 311 | 0; | ||
| 312 | } | ||
| 313 | |||
| 314 | // convenience method used in generating Transposition boxes | ||
| 315 | private static final int mul4 (int a, byte[] b) { | ||
| 316 | if (a == 0) return 0; | ||
| 317 | a = log[a & 0xFF]; | ||
| 318 | int a0 = (b[0] != 0) ? alog[(a + log[b[0] & 0xFF]) % 255] & 0xFF : 0; | ||
| 319 | int a1 = (b[1] != 0) ? alog[(a + log[b[1] & 0xFF]) % 255] & 0xFF : 0; | ||
| 320 | int a2 = (b[2] != 0) ? alog[(a + log[b[2] & 0xFF]) % 255] & 0xFF : 0; | ||
| 321 | int a3 = (b[3] != 0) ? alog[(a + log[b[3] & 0xFF]) % 255] & 0xFF : 0; | ||
| 322 | return a0 << 24 | a1 << 16 | a2 << 8 | a3; | ||
| 323 | } | ||
| 324 | |||
| 325 | // check if the specified length (in bytes) is a valid keysize for AES | ||
| 326 | static final boolean isKeySizeValid(int len) { | ||
| 327 | for (int i = 0; i < AES_KEYSIZES.length; i++) { | ||
| 328 | if (len == AES_KEYSIZES[i]) { | ||
| 329 | return true; | ||
| 330 | } | ||
| 331 | } | ||
| 332 | return false; | ||
| 333 | } | ||
| 334 | |||
| 335 | /** | ||
| 336 | * Encrypt exactly one block of plaintext. | ||
| 337 | */ | ||
| 338 | void encryptBlock(byte[] in, int inOffset, | ||
| 339 | byte[] out, int outOffset) | ||
| 340 | { | ||
| 341 | int keyOffset = 0; | ||
| 342 | int t0 = ((in[inOffset++] ) << 24 | | ||
| 343 | (in[inOffset++] & 0xFF) << 16 | | ||
| 344 | (in[inOffset++] & 0xFF) << 8 | | ||
| 345 | (in[inOffset++] & 0xFF) ) ^ K[keyOffset++]; | ||
| 346 | int t1 = ((in[inOffset++] ) << 24 | | ||
| 347 | (in[inOffset++] & 0xFF) << 16 | | ||
| 348 | (in[inOffset++] & 0xFF) << 8 | | ||
| 349 | (in[inOffset++] & 0xFF) ) ^ K[keyOffset++]; | ||
| 350 | int t2 = ((in[inOffset++] ) << 24 | | ||
| 351 | (in[inOffset++] & 0xFF) << 16 | | ||
| 352 | (in[inOffset++] & 0xFF) << 8 | | ||
| 353 | (in[inOffset++] & 0xFF) ) ^ K[keyOffset++]; | ||
| 354 | int t3 = ((in[inOffset++] ) << 24 | | ||
| 355 | (in[inOffset++] & 0xFF) << 16 | | ||
| 356 | (in[inOffset++] & 0xFF) << 8 | | ||
| 357 | (in[inOffset++] & 0xFF) ) ^ K[keyOffset++]; | ||
| 358 | |||
| 359 | // apply round transforms | ||
| 360 | while( keyOffset < limit ) | ||
| 361 | { | ||
| 362 | int a0, a1, a2; | ||
| 363 | a0 = T1[(t0 >>> 24) ] ^ | ||
| 364 | T2[(t1 >>> 16) & 0xFF] ^ | ||
| 365 | T3[(t2 >>> 8) & 0xFF] ^ | ||
| 366 | T4[(t3 ) & 0xFF] ^ K[keyOffset++]; | ||
| 367 | a1 = T1[(t1 >>> 24) ] ^ | ||
| 368 | T2[(t2 >>> 16) & 0xFF] ^ | ||
| 369 | T3[(t3 >>> 8) & 0xFF] ^ | ||
| 370 | T4[(t0 ) & 0xFF] ^ K[keyOffset++]; | ||
| 371 | a2 = T1[(t2 >>> 24) ] ^ | ||
| 372 | T2[(t3 >>> 16) & 0xFF] ^ | ||
| 373 | T3[(t0 >>> 8) & 0xFF] ^ | ||
| 374 | T4[(t1 ) & 0xFF] ^ K[keyOffset++]; | ||
| 375 | t3 = T1[(t3 >>> 24) ] ^ | ||
| 376 | T2[(t0 >>> 16) & 0xFF] ^ | ||
| 377 | T3[(t1 >>> 8) & 0xFF] ^ | ||
| 378 | T4[(t2 ) & 0xFF] ^ K[keyOffset++]; | ||
| 379 | t0 = a0; t1 = a1; t2 = a2; | ||
| 380 | } | ||
| 381 | |||
| 382 | // last round is special | ||
| 383 | int tt = K[keyOffset++]; | ||
| 384 | out[outOffset++] = (byte)(S[(t0 >>> 24) ] ^ (tt >>> 24)); | ||
| 385 | out[outOffset++] = (byte)(S[(t1 >>> 16) & 0xFF] ^ (tt >>> 16)); | ||
| 386 | out[outOffset++] = (byte)(S[(t2 >>> 8) & 0xFF] ^ (tt >>> 8)); | ||
| 387 | out[outOffset++] = (byte)(S[(t3 ) & 0xFF] ^ (tt )); | ||
| 388 | tt = K[keyOffset++]; | ||
| 389 | out[outOffset++] = (byte)(S[(t1 >>> 24) ] ^ (tt >>> 24)); | ||
| 390 | out[outOffset++] = (byte)(S[(t2 >>> 16) & 0xFF] ^ (tt >>> 16)); | ||
| 391 | out[outOffset++] = (byte)(S[(t3 >>> 8) & 0xFF] ^ (tt >>> 8)); | ||
| 392 | out[outOffset++] = (byte)(S[(t0 ) & 0xFF] ^ (tt )); | ||
| 393 | tt = K[keyOffset++]; | ||
| 394 | out[outOffset++] = (byte)(S[(t2 >>> 24) ] ^ (tt >>> 24)); | ||
| 395 | out[outOffset++] = (byte)(S[(t3 >>> 16) & 0xFF] ^ (tt >>> 16)); | ||
| 396 | out[outOffset++] = (byte)(S[(t0 >>> 8) & 0xFF] ^ (tt >>> 8)); | ||
| 397 | out[outOffset++] = (byte)(S[(t1 ) & 0xFF] ^ (tt )); | ||
| 398 | tt = K[keyOffset++]; | ||
| 399 | out[outOffset++] = (byte)(S[(t3 >>> 24) ] ^ (tt >>> 24)); | ||
| 400 | out[outOffset++] = (byte)(S[(t0 >>> 16) & 0xFF] ^ (tt >>> 16)); | ||
| 401 | out[outOffset++] = (byte)(S[(t1 >>> 8) & 0xFF] ^ (tt >>> 8)); | ||
| 402 | out[outOffset ] = (byte)(S[(t2 ) & 0xFF] ^ (tt )); | ||
| 403 | } | ||
| 404 | |||
| 405 | |||
| 406 | /** | ||
| 407 | * Decrypt exactly one block of plaintext. | ||
| 408 | */ | ||
| 409 | void decryptBlock(byte[] in, int inOffset, | ||
| 410 | byte[] out, int outOffset) | ||
| 411 | { | ||
| 412 | int keyOffset = 4; | ||
| 413 | int t0 = ((in[inOffset++] ) << 24 | | ||
| 414 | (in[inOffset++] & 0xFF) << 16 | | ||
| 415 | (in[inOffset++] & 0xFF) << 8 | | ||
| 416 | (in[inOffset++] & 0xFF) ) ^ K[keyOffset++]; | ||
| 417 | int t1 = ((in[inOffset++] ) << 24 | | ||
| 418 | (in[inOffset++] & 0xFF) << 16 | | ||
| 419 | (in[inOffset++] & 0xFF) << 8 | | ||
| 420 | (in[inOffset++] & 0xFF) ) ^ K[keyOffset++]; | ||
| 421 | int t2 = ((in[inOffset++] ) << 24 | | ||
| 422 | (in[inOffset++] & 0xFF) << 16 | | ||
| 423 | (in[inOffset++] & 0xFF) << 8 | | ||
| 424 | (in[inOffset++] & 0xFF) ) ^ K[keyOffset++]; | ||
| 425 | int t3 = ((in[inOffset++] ) << 24 | | ||
| 426 | (in[inOffset++] & 0xFF) << 16 | | ||
| 427 | (in[inOffset++] & 0xFF) << 8 | | ||
| 428 | (in[inOffset ] & 0xFF) ) ^ K[keyOffset++]; | ||
| 429 | |||
| 430 | int a0, a1, a2; | ||
| 431 | if(ROUNDS_12) | ||
| 432 | { | ||
| 433 | a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ | ||
| 434 | T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++]; | ||
| 435 | a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^ | ||
| 436 | T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++]; | ||
| 437 | a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^ | ||
| 438 | T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; | ||
| 439 | t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^ | ||
| 440 | T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++]; | ||
| 441 | t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ | ||
| 442 | T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++]; | ||
| 443 | t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^ | ||
| 444 | T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++]; | ||
| 445 | t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^ | ||
| 446 | T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; | ||
| 447 | t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^ | ||
| 448 | T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++]; | ||
| 449 | |||
| 450 | if(ROUNDS_14) | ||
| 451 | { | ||
| 452 | a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ | ||
| 453 | T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++]; | ||
| 454 | a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^ | ||
| 455 | T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++]; | ||
| 456 | a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^ | ||
| 457 | T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; | ||
| 458 | t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^ | ||
| 459 | T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++]; | ||
| 460 | t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ | ||
| 461 | T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++]; | ||
| 462 | t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^ | ||
| 463 | T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++]; | ||
| 464 | t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^ | ||
| 465 | T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; | ||
| 466 | t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^ | ||
| 467 | T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++]; | ||
| 468 | } | ||
| 469 | } | ||
| 470 | a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ | ||
| 471 | T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++]; | ||
| 472 | a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^ | ||
| 473 | T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++]; | ||
| 474 | a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^ | ||
| 475 | T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; | ||
| 476 | t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^ | ||
| 477 | T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++]; | ||
| 478 | t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ | ||
| 479 | T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++]; | ||
| 480 | t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^ | ||
| 481 | T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++]; | ||
| 482 | t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^ | ||
| 483 | T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; | ||
| 484 | t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^ | ||
| 485 | T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++]; | ||
| 486 | a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ | ||
| 487 | T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++]; | ||
| 488 | a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^ | ||
| 489 | T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++]; | ||
| 490 | a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^ | ||
| 491 | T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; | ||
| 492 | t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^ | ||
| 493 | T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++]; | ||
| 494 | t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ | ||
| 495 | T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++]; | ||
| 496 | t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^ | ||
| 497 | T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++]; | ||
| 498 | t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^ | ||
| 499 | T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; | ||
| 500 | t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^ | ||
| 501 | T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++]; | ||
| 502 | a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ | ||
| 503 | T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++]; | ||
| 504 | a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^ | ||
| 505 | T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++]; | ||
| 506 | a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^ | ||
| 507 | T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; | ||
| 508 | t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^ | ||
| 509 | T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++]; | ||
| 510 | t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ | ||
| 511 | T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++]; | ||
| 512 | t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^ | ||
| 513 | T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++]; | ||
| 514 | t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^ | ||
| 515 | T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; | ||
| 516 | t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^ | ||
| 517 | T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++]; | ||
| 518 | a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ | ||
| 519 | T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++]; | ||
| 520 | a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^ | ||
| 521 | T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++]; | ||
| 522 | a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^ | ||
| 523 | T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; | ||
| 524 | t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^ | ||
| 525 | T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++]; | ||
| 526 | t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ | ||
| 527 | T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++]; | ||
| 528 | t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^ | ||
| 529 | T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++]; | ||
| 530 | t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^ | ||
| 531 | T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; | ||
| 532 | t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^ | ||
| 533 | T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++]; | ||
| 534 | a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ | ||
| 535 | T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++]; | ||
| 536 | a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^ | ||
| 537 | T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++]; | ||
| 538 | a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^ | ||
| 539 | T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; | ||
| 540 | t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^ | ||
| 541 | T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++]; | ||
| 542 | |||
| 543 | t1 = K[0]; | ||
| 544 | out[outOffset++] = (byte)(Si[(a0 >>> 24) ] ^ (t1 >>> 24)); | ||
| 545 | out[outOffset++] = (byte)(Si[(t3 >>> 16) & 0xFF] ^ (t1 >>> 16)); | ||
| 546 | out[outOffset++] = (byte)(Si[(a2 >>> 8) & 0xFF] ^ (t1 >>> 8)); | ||
| 547 | out[outOffset++] = (byte)(Si[(a1 ) & 0xFF] ^ (t1 )); | ||
| 548 | t1 = K[1]; | ||
| 549 | out[outOffset++] = (byte)(Si[(a1 >>> 24) ] ^ (t1 >>> 24)); | ||
| 550 | out[outOffset++] = (byte)(Si[(a0 >>> 16) & 0xFF] ^ (t1 >>> 16)); | ||
| 551 | out[outOffset++] = (byte)(Si[(t3 >>> 8) & 0xFF] ^ (t1 >>> 8)); | ||
| 552 | out[outOffset++] = (byte)(Si[(a2 ) & 0xFF] ^ (t1 )); | ||
| 553 | t1 = K[2]; | ||
| 554 | out[outOffset++] = (byte)(Si[(a2 >>> 24) ] ^ (t1 >>> 24)); | ||
| 555 | out[outOffset++] = (byte)(Si[(a1 >>> 16) & 0xFF] ^ (t1 >>> 16)); | ||
| 556 | out[outOffset++] = (byte)(Si[(a0 >>> 8) & 0xFF] ^ (t1 >>> 8)); | ||
| 557 | out[outOffset++] = (byte)(Si[(t3 ) & 0xFF] ^ (t1 )); | ||
| 558 | t1 = K[3]; | ||
| 559 | out[outOffset++] = (byte)(Si[(t3 >>> 24) ] ^ (t1 >>> 24)); | ||
| 560 | out[outOffset++] = (byte)(Si[(a2 >>> 16) & 0xFF] ^ (t1 >>> 16)); | ||
| 561 | out[outOffset++] = (byte)(Si[(a1 >>> 8) & 0xFF] ^ (t1 >>> 8)); | ||
| 562 | out[outOffset ] = (byte)(Si[(a0 ) & 0xFF] ^ (t1 )); | ||
| 563 | } | ||
| 564 | |||
| 565 | |||
| 566 | /** | ||
| 567 | * Expand a user-supplied key material into a session key. | ||
| 568 | * | ||
| 569 | * @param key The 128/192/256-bit user-key to use. | ||
| 570 | * @exception InvalidKeyException If the key is invalid. | ||
| 571 | */ | ||
| 572 | private static Object[] makeKey(byte[] k) throws InvalidKeyException { | ||
| 573 | if (k == null) { | ||
| 574 | throw new InvalidKeyException("Empty key"); | ||
| 575 | } | ||
| 576 | if (!isKeySizeValid(k.length)) { | ||
| 577 | throw new InvalidKeyException("Invalid AES key length: " + | ||
| 578 | k.length + " bytes"); | ||
| 579 | } | ||
| 580 | int ROUNDS = getRounds(k.length); | ||
| 581 | int ROUND_KEY_COUNT = (ROUNDS + 1) * 4; | ||
| 582 | |||
| 583 | int BC = 4; | ||
| 584 | int[][] Ke = new int[ROUNDS + 1][4]; // encryption round keys | ||
| 585 | int[][] Kd = new int[ROUNDS + 1][4]; // decryption round keys | ||
| 586 | |||
| 587 | int KC = k.length/4; // keylen in 32-bit elements | ||
| 588 | |||
| 589 | int[] tk = new int[KC]; | ||
| 590 | int i, j; | ||
| 591 | |||
| 592 | // copy user material bytes into temporary ints | ||
| 593 | for (i = 0, j = 0; i < KC; i++, j+=4) { | ||
| 594 | tk[i] = (k[j] ) << 24 | | ||
| 595 | (k[j+1] & 0xFF) << 16 | | ||
| 596 | (k[j+2] & 0xFF) << 8 | | ||
| 597 | (k[j+3] & 0xFF); | ||
| 598 | } | ||
| 599 | |||
| 600 | // copy values into round key arrays | ||
| 601 | int t = 0; | ||
| 602 | for (j = 0; (j < KC) && (t < ROUND_KEY_COUNT); j++, t++) { | ||
| 603 | Ke[t / 4][t % 4] = tk[j]; | ||
| 604 | Kd[ROUNDS - (t / 4)][t % 4] = tk[j]; | ||
| 605 | } | ||
| 606 | int tt, rconpointer = 0; | ||
| 607 | while (t < ROUND_KEY_COUNT) { | ||
| 608 | // extrapolate using phi (the round key evolution function) | ||
| 609 | tt = tk[KC - 1]; | ||
| 610 | tk[0] ^= (S[(tt >>> 16) & 0xFF] ) << 24 ^ | ||
| 611 | (S[(tt >>> 8) & 0xFF] & 0xFF) << 16 ^ | ||
| 612 | (S[(tt ) & 0xFF] & 0xFF) << 8 ^ | ||
| 613 | (S[(tt >>> 24) ] & 0xFF) ^ | ||
| 614 | (rcon[rconpointer++] ) << 24; | ||
| 615 | if (KC != 8) | ||
| 616 | for (i = 1, j = 0; i < KC; i++, j++) tk[i] ^= tk[j]; | ||
| 617 | else { | ||
| 618 | for (i = 1, j = 0; i < KC / 2; i++, j++) tk[i] ^= tk[j]; | ||
| 619 | tt = tk[KC / 2 - 1]; | ||
| 620 | tk[KC / 2] ^= (S[(tt ) & 0xFF] & 0xFF) ^ | ||
| 621 | (S[(tt >>> 8) & 0xFF] & 0xFF) << 8 ^ | ||
| 622 | (S[(tt >>> 16) & 0xFF] & 0xFF) << 16 ^ | ||
| 623 | (S[(tt >>> 24) ] ) << 24; | ||
| 624 | for (j = KC / 2, i = j + 1; i < KC; i++, j++) tk[i] ^= tk[j]; | ||
| 625 | } | ||
| 626 | // copy values into round key arrays | ||
| 627 | for (j = 0; (j < KC) && (t < ROUND_KEY_COUNT); j++, t++) { | ||
| 628 | Ke[t / 4][t % 4] = tk[j]; | ||
| 629 | Kd[ROUNDS - (t / 4)][t % 4] = tk[j]; | ||
| 630 | } | ||
| 631 | } | ||
| 632 | for (int r = 1; r < ROUNDS; r++) { | ||
| 633 | // inverse MixColumn where needed | ||
| 634 | for (j = 0; j < BC; j++) { | ||
| 635 | tt = Kd[r][j]; | ||
| 636 | Kd[r][j] = U1[(tt >>> 24) & 0xFF] ^ | ||
| 637 | U2[(tt >>> 16) & 0xFF] ^ | ||
| 638 | U3[(tt >>> 8) & 0xFF] ^ | ||
| 639 | U4[ tt & 0xFF]; | ||
| 640 | } | ||
| 641 | } | ||
| 642 | // assemble the encryption (Ke) and decryption (Kd) round keys into | ||
| 643 | // one sessionKey object | ||
| 644 | Object[] result = new Object[] {Ke, Kd}; | ||
| 645 | return result; | ||
| 646 | } | ||
| 647 | |||
| 648 | |||
| 649 | /** | ||
| 650 | * Return The number of rounds for a given Rijndael keysize. | ||
| 651 | * | ||
| 652 | * @param keySize The size of the user key material in bytes. | ||
| 653 | * MUST be one of (16, 24, 32). | ||
| 654 | * @return The number of rounds. | ||
| 655 | */ | ||
| 656 | private static int getRounds(int keySize) { | ||
| 657 | return (keySize >> 2) + 6; | ||
| 658 | } | ||
| 659 | } | ||
| @@ -0,0 +1,117 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.security.SecureRandom; | ||
| 29 | import java.security.InvalidParameterException; | ||
| 30 | import java.security.InvalidAlgorithmParameterException; | ||
| 31 | import java.security.InvalidKeyException; | ||
| 32 | import java.security.spec.AlgorithmParameterSpec; | ||
| 33 | import javax.crypto.KeyGeneratorSpi; | ||
| 34 | import javax.crypto.SecretKey; | ||
| 35 | import javax.crypto.spec.SecretKeySpec; | ||
| 36 | |||
| 37 | |||
| 38 | /** | ||
| 39 | * This class generates a AES key. | ||
| 40 | * | ||
| 41 | * @author Valerie Peng | ||
| 42 | * | ||
| 43 | */ | ||
| 44 | |||
| 45 | public final class AESKeyGenerator extends KeyGeneratorSpi { | ||
| 46 | |||
| 47 | private SecureRandom random = null; | ||
| 48 | private int keySize = 16; // default keysize (in number of bytes) | ||
| 49 | |||
| 50 | /** | ||
| 51 | * Empty constructor. | ||
| 52 | */ | ||
| 53 | public AESKeyGenerator() { | ||
| 54 | } | ||
| 55 | |||
| 56 | /** | ||
| 57 | * Initializes this key generator. | ||
| 58 | * | ||
| 59 | * @param random the source of randomness for this generator | ||
| 60 | */ | ||
| 61 | protected void engineInit(SecureRandom random) { | ||
| 62 | this.random = random; | ||
| 63 | } | ||
| 64 | |||
| 65 | /** | ||
| 66 | * Initializes this key generator with the specified parameter | ||
| 67 | * set and a user-provided source of randomness. | ||
| 68 | * | ||
| 69 | * @param params the key generation parameters | ||
| 70 | * @param random the source of randomness for this key generator | ||
| 71 | * | ||
| 72 | * @exception InvalidAlgorithmParameterException if <code>params</code> is | ||
| 73 | * inappropriate for this key generator | ||
| 74 | */ | ||
| 75 | protected void engineInit(AlgorithmParameterSpec params, | ||
| 76 | SecureRandom random) | ||
| 77 | throws InvalidAlgorithmParameterException { | ||
| 78 | throw new InvalidAlgorithmParameterException | ||
| 79 | ("AES key generation does not take any parameters"); | ||
| 80 | } | ||
| 81 | |||
| 82 | /** | ||
| 83 | * Initializes this key generator for a certain keysize, using the given | ||
| 84 | * source of randomness. | ||
| 85 | * | ||
| 86 | * @param keysize the keysize. This is an algorithm-specific | ||
| 87 | * metric specified in number of bits. | ||
| 88 | * @param random the source of randomness for this key generator | ||
| 89 | */ | ||
| 90 | protected void engineInit(int keysize, SecureRandom random) { | ||
| 91 | if (((keysize % 8) != 0) || | ||
| 92 | (!AESCrypt.isKeySizeValid(keysize/8))) { | ||
| 93 | throw new InvalidParameterException | ||
| 94 | ("Wrong keysize: must be equal to 128, 192 or 256"); | ||
| 95 | } | ||
| 96 | this.keySize = keysize/8; | ||
| 97 | this.engineInit(random); | ||
| 98 | } | ||
| 99 | |||
| 100 | /** | ||
| 101 | * Generates the AES key. | ||
| 102 | * | ||
| 103 | * @return the new AES key | ||
| 104 | */ | ||
| 105 | protected SecretKey engineGenerateKey() { | ||
| 106 | SecretKeySpec aesKey = null; | ||
| 107 | |||
| 108 | if (this.random == null) { | ||
| 109 | this.random = SunJCE.RANDOM; | ||
| 110 | } | ||
| 111 | |||
| 112 | byte[] keyBytes = new byte[keySize]; | ||
| 113 | this.random.nextBytes(keyBytes); | ||
| 114 | aesKey = new SecretKeySpec(keyBytes, "AES"); | ||
| 115 | return aesKey; | ||
| 116 | } | ||
| 117 | } | ||
| @@ -0,0 +1,87 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.util.*; | ||
| 29 | import java.io.*; | ||
| 30 | import sun.security.util.*; | ||
| 31 | import java.security.AlgorithmParametersSpi; | ||
| 32 | import java.security.spec.AlgorithmParameterSpec; | ||
| 33 | import java.security.spec.InvalidParameterSpecException; | ||
| 34 | import javax.crypto.spec.IvParameterSpec; | ||
| 35 | |||
| 36 | /** | ||
| 37 | * This class implements the parameter (IV) used with the AES algorithm | ||
| 38 | * in feedback-mode. IV is defined in the standards as follows: | ||
| 39 | * | ||
| 40 | * <pre> | ||
| 41 | * IV ::= OCTET STRING -- 16 octets | ||
| 42 | * </pre> | ||
| 43 | * | ||
| 44 | * @author Valerie Peng | ||
| 45 | * | ||
| 46 | */ | ||
| 47 | public final class AESParameters extends AlgorithmParametersSpi { | ||
| 48 | |||
| 49 | private BlockCipherParamsCore core; | ||
| 50 | |||
| 51 | public AESParameters() { | ||
| 52 | core = new BlockCipherParamsCore(AESConstants.AES_BLOCK_SIZE); | ||
| 53 | } | ||
| 54 | |||
| 55 | protected void engineInit(AlgorithmParameterSpec paramSpec) | ||
| 56 | throws InvalidParameterSpecException { | ||
| 57 | core.init(paramSpec); | ||
| 58 | } | ||
| 59 | |||
| 60 | protected void engineInit(byte[] encoded) | ||
| 61 | throws IOException { | ||
| 62 | core.init(encoded); | ||
| 63 | } | ||
| 64 | |||
| 65 | protected void engineInit(byte[] encoded, String decodingMethod) | ||
| 66 | throws IOException { | ||
| 67 | core.init(encoded, decodingMethod); | ||
| 68 | } | ||
| 69 | |||
| 70 | protected AlgorithmParameterSpec engineGetParameterSpec(Class paramSpec) | ||
| 71 | throws InvalidParameterSpecException { | ||
| 72 | return core.getParameterSpec(paramSpec); | ||
| 73 | } | ||
| 74 | |||
| 75 | protected byte[] engineGetEncoded() throws IOException { | ||
| 76 | return core.getEncoded(); | ||
| 77 | } | ||
| 78 | |||
| 79 | protected byte[] engineGetEncoded(String encodingMethod) | ||
| 80 | throws IOException { | ||
| 81 | return core.getEncoded(); | ||
| 82 | } | ||
| 83 | |||
| 84 | protected String engineToString() { | ||
| 85 | return core.toString(); | ||
| 86 | } | ||
| 87 | } | ||
| @@ -0,0 +1,483 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2004, 2009, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.util.Arrays; | ||
| 29 | import java.security.*; | ||
| 30 | import java.security.spec.*; | ||
| 31 | import javax.crypto.*; | ||
| 32 | import javax.crypto.spec.*; | ||
| 33 | |||
| 34 | /** | ||
| 35 | * This class implements the AES KeyWrap algorithm as defined | ||
| 36 | * in <a href=http://www.w3.org/TR/xmlenc-core/#sec-Alg-SymmetricKeyWrap> | ||
| 37 | * "XML Encryption Syntax and Processing" section 5.6.3 "AES Key Wrap". | ||
| 38 | * Note: only <code>ECB</code> mode and <code>NoPadding</code> padding | ||
| 39 | * can be used for this algorithm. | ||
| 40 | * | ||
| 41 | * @author Valerie Peng | ||
| 42 | * | ||
| 43 | * | ||
| 44 | * @see AESCipher | ||
| 45 | */ | ||
| 46 | public final class AESWrapCipher extends CipherSpi { | ||
| 47 | |||
| 48 | private static final byte[] IV = { | ||
| 49 | (byte) 0xA6, (byte) 0xA6, (byte) 0xA6, (byte) 0xA6, | ||
| 50 | (byte) 0xA6, (byte) 0xA6, (byte) 0xA6, (byte) 0xA6 | ||
| 51 | }; | ||
| 52 | |||
| 53 | private static final int blksize = AESConstants.AES_BLOCK_SIZE; | ||
| 54 | |||
| 55 | /* | ||
| 56 | * internal cipher object which does the real work. | ||
| 57 | */ | ||
| 58 | private AESCrypt cipher; | ||
| 59 | |||
| 60 | /* | ||
| 61 | * are we encrypting or decrypting? | ||
| 62 | */ | ||
| 63 | private boolean decrypting = false; | ||
| 64 | |||
| 65 | /** | ||
| 66 | * Creates an instance of AES KeyWrap cipher with default | ||
| 67 | * mode, i.e. "ECB" and padding scheme, i.e. "NoPadding". | ||
| 68 | */ | ||
| 69 | public AESWrapCipher() { | ||
| 70 | cipher = new AESCrypt(); | ||
| 71 | } | ||
| 72 | |||
| 73 | /** | ||
| 74 | * Sets the mode of this cipher. Only "ECB" mode is accepted for this | ||
| 75 | * cipher. | ||
| 76 | * | ||
| 77 | * @param mode the cipher mode | ||
| 78 | * | ||
| 79 | * @exception NoSuchAlgorithmException if the requested cipher mode | ||
| 80 | * is not "ECB". | ||
| 81 | */ | ||
| 82 | protected void engineSetMode(String mode) | ||
| 83 | throws NoSuchAlgorithmException { | ||
| 84 | if (!mode.equalsIgnoreCase("ECB")) { | ||
| 85 | throw new NoSuchAlgorithmException(mode + " cannot be used"); | ||
| 86 | } | ||
| 87 | } | ||
| 88 | |||
| 89 | /** | ||
| 90 | * Sets the padding mechanism of this cipher. Only "NoPadding" schmem | ||
| 91 | * is accepted for this cipher. | ||
| 92 | * | ||
| 93 | * @param padding the padding mechanism | ||
| 94 | * | ||
| 95 | * @exception NoSuchPaddingException if the requested padding mechanism | ||
| 96 | * is not "NoPadding". | ||
| 97 | */ | ||
| 98 | protected void engineSetPadding(String padding) | ||
| 99 | throws NoSuchPaddingException { | ||
| 100 | if (!padding.equalsIgnoreCase("NoPadding")) { | ||
| 101 | throw new NoSuchPaddingException(padding + " cannot be used"); | ||
| 102 | } | ||
| 103 | } | ||
| 104 | |||
| 105 | /** | ||
| 106 | * Returns the block size (in bytes). i.e. 16 bytes. | ||
| 107 | * | ||
| 108 | * @return the block size (in bytes), i.e. 16 bytes. | ||
| 109 | */ | ||
| 110 | protected int engineGetBlockSize() { | ||
| 111 | return blksize; | ||
| 112 | } | ||
| 113 | |||
| 114 | /** | ||
| 115 | * Returns the length in bytes that an output buffer would need to be | ||
| 116 | * given the input length <code>inputLen</code> (in bytes). | ||
| 117 | * | ||
| 118 | * <p>The actual output length of the next <code>update</code> or | ||
| 119 | * <code>doFinal</code> call may be smaller than the length returned | ||
| 120 | * by this method. | ||
| 121 | * | ||
| 122 | * @param inputLen the input length (in bytes) | ||
| 123 | * | ||
| 124 | * @return the required output buffer size (in bytes) | ||
| 125 | */ | ||
| 126 | protected int engineGetOutputSize(int inputLen) { | ||
| 127 | // can only return an upper-limit if not initialized yet. | ||
| 128 | int result = 0; | ||
| 129 | if (decrypting) { | ||
| 130 | result = inputLen - 8; | ||
| 131 | } else { | ||
| 132 | result = inputLen + 8; | ||
| 133 | } | ||
| 134 | return (result < 0? 0:result); | ||
| 135 | } | ||
| 136 | |||
| 137 | /** | ||
| 138 | * Returns the initialization vector (IV) which is null for this cipher. | ||
| 139 | * | ||
| 140 | * @return null for this cipher. | ||
| 141 | */ | ||
| 142 | protected byte[] engineGetIV() { | ||
| 143 | return null; | ||
| 144 | } | ||
| 145 | |||
| 146 | /** | ||
| 147 | * Initializes this cipher with a key and a source of randomness. | ||
| 148 | * | ||
| 149 | * <p>The cipher only supports the following two operation modes:<b> | ||
| 150 | * Cipher.WRAP_MODE, and <b> | ||
| 151 | * Cipher.UNWRAP_MODE. | ||
| 152 | * <p>For modes other than the above two, UnsupportedOperationException | ||
| 153 | * will be thrown. | ||
| 154 | * | ||
| 155 | * @param opmode the operation mode of this cipher. Only | ||
| 156 | * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) are accepted. | ||
| 157 | * @param key the secret key. | ||
| 158 | * @param random the source of randomness. | ||
| 159 | * | ||
| 160 | * @exception InvalidKeyException if the given key is inappropriate for | ||
| 161 | * initializing this cipher. | ||
| 162 | */ | ||
| 163 | protected void engineInit(int opmode, Key key, SecureRandom random) | ||
| 164 | throws InvalidKeyException { | ||
| 165 | if (opmode == Cipher.WRAP_MODE) { | ||
| 166 | decrypting = false; | ||
| 167 | } else if (opmode == Cipher.UNWRAP_MODE) { | ||
| 168 | decrypting = true; | ||
| 169 | } else { | ||
| 170 | throw new UnsupportedOperationException("This cipher can " + | ||
| 171 | "only be used for key wrapping and unwrapping"); | ||
| 172 | } | ||
| 173 | cipher.init(decrypting, key.getAlgorithm(), key.getEncoded()); | ||
| 174 | } | ||
| 175 | |||
| 176 | /** | ||
| 177 | * Initializes this cipher with a key, a set of algorithm parameters, | ||
| 178 | * and a source of randomness. | ||
| 179 | * | ||
| 180 | * <p>The cipher only supports the following two operation modes:<b> | ||
| 181 | * Cipher.WRAP_MODE, and <b> | ||
| 182 | * Cipher.UNWRAP_MODE. | ||
| 183 | * <p>For modes other than the above two, UnsupportedOperationException | ||
| 184 | * will be thrown. | ||
| 185 | * | ||
| 186 | * @param opmode the operation mode of this cipher. Only | ||
| 187 | * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) are accepted. | ||
| 188 | * @param key the secret key. | ||
| 189 | * @param params the algorithm parameters; must be null for this cipher. | ||
| 190 | * @param random the source of randomness. | ||
| 191 | * | ||
| 192 | * @exception InvalidKeyException if the given key is inappropriate for | ||
| 193 | * initializing this cipher | ||
| 194 | * @exception InvalidAlgorithmParameterException if the given algorithm | ||
| 195 | * parameters is not null. | ||
| 196 | */ | ||
| 197 | protected void engineInit(int opmode, Key key, | ||
| 198 | AlgorithmParameterSpec params, | ||
| 199 | SecureRandom random) | ||
| 200 | throws InvalidKeyException, InvalidAlgorithmParameterException { | ||
| 201 | if (params != null) { | ||
| 202 | throw new InvalidAlgorithmParameterException("This cipher " + | ||
| 203 | "does not accept any parameters"); | ||
| 204 | } | ||
| 205 | engineInit(opmode, key, random); | ||
| 206 | } | ||
| 207 | |||
| 208 | /** | ||
| 209 | * Initializes this cipher with a key, a set of algorithm parameters, | ||
| 210 | * and a source of randomness. | ||
| 211 | * | ||
| 212 | * <p>The cipher only supports the following two operation modes:<b> | ||
| 213 | * Cipher.WRAP_MODE, and <b> | ||
| 214 | * Cipher.UNWRAP_MODE. | ||
| 215 | * <p>For modes other than the above two, UnsupportedOperationException | ||
| 216 | * will be thrown. | ||
| 217 | * | ||
| 218 | * @param opmode the operation mode of this cipher. Only | ||
| 219 | * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) are accepted. | ||
| 220 | * @param key the secret key. | ||
| 221 | * @param params the algorithm parameters; must be null for this cipher. | ||
| 222 | * @param random the source of randomness. | ||
| 223 | * | ||
| 224 | * @exception InvalidKeyException if the given key is inappropriate. | ||
| 225 | * @exception InvalidAlgorithmParameterException if the given algorithm | ||
| 226 | * parameters is not null. | ||
| 227 | */ | ||
| 228 | protected void engineInit(int opmode, Key key, | ||
| 229 | AlgorithmParameters params, | ||
| 230 | SecureRandom random) | ||
| 231 | throws InvalidKeyException, InvalidAlgorithmParameterException { | ||
| 232 | if (params != null) { | ||
| 233 | throw new InvalidAlgorithmParameterException("This cipher " + | ||
| 234 | "does not accept any parameters"); | ||
| 235 | } | ||
| 236 | engineInit(opmode, key, random); | ||
| 237 | } | ||
| 238 | |||
| 239 | /** | ||
| 240 | * This operation is not supported by this cipher. | ||
| 241 | * Since it's impossible to initialize this cipher given the | ||
| 242 | * current Cipher.engineInit(...) implementation, | ||
| 243 | * IllegalStateException will always be thrown upon invocation. | ||
| 244 | * | ||
| 245 | * @param in the input buffer. | ||
| 246 | * @param inOffset the offset in <code>in</code> where the input | ||
| 247 | * starts. | ||
| 248 | * @param inLen the input length. | ||
| 249 | * | ||
| 250 | * @return n/a. | ||
| 251 | * | ||
| 252 | * @exception IllegalStateException upon invocation of this method. | ||
| 253 | */ | ||
| 254 | protected byte[] engineUpdate(byte[] in, int inOffset, int inLen) { | ||
| 255 | throw new IllegalStateException("Cipher has not been initialized"); | ||
| 256 | } | ||
| 257 | |||
| 258 | /** | ||
| 259 | * This operation is not supported by this cipher. | ||
| 260 | * Since it's impossible to initialize this cipher given the | ||
| 261 | * current Cipher.engineInit(...) implementation, | ||
| 262 | * IllegalStateException will always be thrown upon invocation. | ||
| 263 | * | ||
| 264 | * @param in the input buffer. | ||
| 265 | * @param inOffset the offset in <code>in</code> where the input | ||
| 266 | * starts. | ||
| 267 | * @param inLen the input length. | ||
| 268 | * @param out the buffer for the result. | ||
| 269 | * @param outOffset the offset in <code>out</code> where the result | ||
| 270 | * is stored. | ||
| 271 | * | ||
| 272 | * @return n/a. | ||
| 273 | * | ||
| 274 | * @exception IllegalStateException upon invocation of this method. | ||
| 275 | */ | ||
| 276 | protected int engineUpdate(byte[] in, int inOffset, int inLen, | ||
| 277 | byte[] out, int outOffset) | ||
| 278 | throws ShortBufferException { | ||
| 279 | throw new IllegalStateException("Cipher has not been initialized"); | ||
| 280 | } | ||
| 281 | |||
| 282 | /** | ||
| 283 | * This operation is not supported by this cipher. | ||
| 284 | * Since it's impossible to initialize this cipher given the | ||
| 285 | * current Cipher.engineInit(...) implementation, | ||
| 286 | * IllegalStateException will always be thrown upon invocation. | ||
| 287 | * | ||
| 288 | * @param in the input buffer | ||
| 289 | * @param inOffset the offset in <code>in</code> where the input | ||
| 290 | * starts | ||
| 291 | * @param inLen the input length. | ||
| 292 | * | ||
| 293 | * @return n/a. | ||
| 294 | * | ||
| 295 | * @exception IllegalStateException upon invocation of this method. | ||
| 296 | */ | ||
| 297 | protected byte[] engineDoFinal(byte[] input, int inputOffset, | ||
| 298 | int inputLen) | ||
| 299 | throws IllegalBlockSizeException, BadPaddingException { | ||
| 300 | throw new IllegalStateException("Cipher has not been initialized"); | ||
| 301 | } | ||
| 302 | |||
| 303 | /** | ||
| 304 | * This operation is not supported by this cipher. | ||
| 305 | * Since it's impossible to initialize this cipher given the | ||
| 306 | * current Cipher.engineInit(...) implementation, | ||
| 307 | * IllegalStateException will always be thrown upon invocation. | ||
| 308 | * | ||
| 309 | * @param in the input buffer. | ||
| 310 | * @param inOffset the offset in <code>in</code> where the input | ||
| 311 | * starts. | ||
| 312 | * @param inLen the input length. | ||
| 313 | * @param out the buffer for the result. | ||
| 314 | * @param outOffset the ofset in <code>out</code> where the result | ||
| 315 | * is stored. | ||
| 316 | * | ||
| 317 | * @return n/a. | ||
| 318 | * | ||
| 319 | * @exception IllegalStateException upon invocation of this method. | ||
| 320 | */ | ||
| 321 | protected int engineDoFinal(byte[] in, int inOffset, int inLen, | ||
| 322 | byte[] out, int outOffset) | ||
| 323 | throws IllegalBlockSizeException, ShortBufferException, | ||
| 324 | BadPaddingException { | ||
| 325 | throw new IllegalStateException("Cipher has not been initialized"); | ||
| 326 | } | ||
| 327 | |||
| 328 | /** | ||
| 329 | * Returns the parameters used with this cipher which is always null | ||
| 330 | * for this cipher. | ||
| 331 | * | ||
| 332 | * @return null since this cipher does not use any parameters. | ||
| 333 | */ | ||
| 334 | protected AlgorithmParameters engineGetParameters() { | ||
| 335 | return null; | ||
| 336 | } | ||
| 337 | |||
| 338 | /** | ||
| 339 | * Returns the key size of the given key object in number of bits. | ||
| 340 | * | ||
| 341 | * @param key the key object. | ||
| 342 | * | ||
| 343 | * @return the "effective" key size of the given key object. | ||
| 344 | * | ||
| 345 | * @exception InvalidKeyException if <code>key</code> is invalid. | ||
| 346 | */ | ||
| 347 | protected int engineGetKeySize(Key key) throws InvalidKeyException { | ||
| 348 | byte[] encoded = key.getEncoded(); | ||
| 349 | if (!AESCrypt.isKeySizeValid(encoded.length)) { | ||
| 350 | throw new InvalidKeyException("Invalid key length: " + | ||
| 351 | encoded.length + " bytes"); | ||
| 352 | } | ||
| 353 | return encoded.length * 8; | ||
| 354 | } | ||
| 355 | |||
| 356 | /** | ||
| 357 | * Wrap a key. | ||
| 358 | * | ||
| 359 | * @param key the key to be wrapped. | ||
| 360 | * | ||
| 361 | * @return the wrapped key. | ||
| 362 | * | ||
| 363 | * @exception IllegalBlockSizeException if this cipher is a block | ||
| 364 | * cipher, no padding has been requested, and the length of the | ||
| 365 | * encoding of the key to be wrapped is not a | ||
| 366 | * multiple of the block size. | ||
| 367 | * | ||
| 368 | * @exception InvalidKeyException if it is impossible or unsafe to | ||
| 369 | * wrap the key with this cipher (e.g., a hardware protected key is | ||
| 370 | * being passed to a software only cipher). | ||
| 371 | */ | ||
| 372 | protected byte[] engineWrap(Key key) | ||
| 373 | throws IllegalBlockSizeException, InvalidKeyException { | ||
| 374 | byte[] keyVal = key.getEncoded(); | ||
| 375 | if ((keyVal == null) || (keyVal.length == 0)) { | ||
| 376 | throw new InvalidKeyException("Cannot get an encoding of " + | ||
| 377 | "the key to be wrapped"); | ||
| 378 | } | ||
| 379 | byte[] out = new byte[keyVal.length + 8]; | ||
| 380 | |||
| 381 | if (keyVal.length == 8) { | ||
| 382 | System.arraycopy(IV, 0, out, 0, IV.length); | ||
| 383 | System.arraycopy(keyVal, 0, out, IV.length, 8); | ||
| 384 | cipher.encryptBlock(out, 0, out, 0); | ||
| 385 | } else { | ||
| 386 | if (keyVal.length % 8 != 0) { | ||
| 387 | throw new IllegalBlockSizeException("length of the " + | ||
| 388 | "to be wrapped key should be multiples of 8 bytes"); | ||
| 389 | } | ||
| 390 | System.arraycopy(IV, 0, out, 0, IV.length); | ||
| 391 | System.arraycopy(keyVal, 0, out, IV.length, keyVal.length); | ||
| 392 | int N = keyVal.length/8; | ||
| 393 | byte[] buffer = new byte[blksize]; | ||
| 394 | for (int j = 0; j < 6; j++) { | ||
| 395 | for (int i = 1; i <= N; i++) { | ||
| 396 | int T = i + j*N; | ||
| 397 | System.arraycopy(out, 0, buffer, 0, IV.length); | ||
| 398 | System.arraycopy(out, i*8, buffer, IV.length, 8); | ||
| 399 | cipher.encryptBlock(buffer, 0, buffer, 0); | ||
| 400 | for (int k = 1; T != 0; k++) { | ||
| 401 | byte v = (byte) T; | ||
| 402 | buffer[IV.length - k] ^= v; | ||
| 403 | T >>>= 8; | ||
| 404 | } | ||
| 405 | System.arraycopy(buffer, 0, out, 0, IV.length); | ||
| 406 | System.arraycopy(buffer, 8, out, 8*i, 8); | ||
| 407 | } | ||
| 408 | } | ||
| 409 | } | ||
| 410 | return out; | ||
| 411 | } | ||
| 412 | |||
| 413 | /** | ||
| 414 | * Unwrap a previously wrapped key. | ||
| 415 | * | ||
| 416 | * @param wrappedKey the key to be unwrapped. | ||
| 417 | * | ||
| 418 | * @param wrappedKeyAlgorithm the algorithm the wrapped key is for. | ||
| 419 | * | ||
| 420 | * @param wrappedKeyType the type of the wrapped key. | ||
| 421 | * This is one of <code>Cipher.SECRET_KEY</code>, | ||
| 422 | * <code>Cipher.PRIVATE_KEY</code>, or <code>Cipher.PUBLIC_KEY</code>. | ||
| 423 | * | ||
| 424 | * @return the unwrapped key. | ||
| 425 | * | ||
| 426 | * @exception NoSuchAlgorithmException if no installed providers | ||
| 427 | * can create keys of type <code>wrappedKeyType</code> for the | ||
| 428 | * <code>wrappedKeyAlgorithm</code>. | ||
| 429 | * | ||
| 430 | * @exception InvalidKeyException if <code>wrappedKey</code> does not | ||
| 431 | * represent a wrapped key of type <code>wrappedKeyType</code> for | ||
| 432 | * the <code>wrappedKeyAlgorithm</code>. | ||
| 433 | */ | ||
| 434 | protected Key engineUnwrap(byte[] wrappedKey, | ||
| 435 | String wrappedKeyAlgorithm, | ||
| 436 | int wrappedKeyType) | ||
| 437 | throws InvalidKeyException, NoSuchAlgorithmException { | ||
| 438 | int wrappedKeyLen = wrappedKey.length; | ||
| 439 | // ensure the wrappedKey length is multiples of 8 bytes and non-zero | ||
| 440 | if (wrappedKeyLen == 0) { | ||
| 441 | throw new InvalidKeyException("The wrapped key is empty"); | ||
| 442 | } | ||
| 443 | if (wrappedKeyLen % 8 != 0) { | ||
| 444 | throw new InvalidKeyException | ||
| 445 | ("The wrapped key has invalid key length"); | ||
| 446 | } | ||
| 447 | byte[] out = new byte[wrappedKeyLen - 8]; | ||
| 448 | byte[] buffer = new byte[blksize]; | ||
| 449 | if (wrappedKeyLen == 16) { | ||
| 450 | cipher.decryptBlock(wrappedKey, 0, buffer, 0); | ||
| 451 | for (int i = 0; i < IV.length; i++) { | ||
| 452 | if (IV[i] != buffer[i]) { | ||
| 453 | throw new InvalidKeyException("Integrity check failed"); | ||
| 454 | } | ||
| 455 | } | ||
| 456 | System.arraycopy(buffer, IV.length, out, 0, out.length); | ||
| 457 | } else { | ||
| 458 | System.arraycopy(wrappedKey, 0, buffer, 0, IV.length); | ||
| 459 | System.arraycopy(wrappedKey, IV.length, out, 0, out.length); | ||
| 460 | int N = out.length/8; | ||
| 461 | for (int j = 5; j >= 0; j--) { | ||
| 462 | for (int i = N; i > 0; i--) { | ||
| 463 | int T = i + j*N; | ||
| 464 | System.arraycopy(out, 8*(i-1), buffer, IV.length, 8); | ||
| 465 | for (int k = 1; T != 0; k++) { | ||
| 466 | byte v = (byte) T; | ||
| 467 | buffer[IV.length - k] ^= v; | ||
| 468 | T >>>= 8; | ||
| 469 | } | ||
| 470 | cipher.decryptBlock(buffer, 0, buffer, 0); | ||
| 471 | System.arraycopy(buffer, IV.length, out, 8*(i-1), 8); | ||
| 472 | } | ||
| 473 | } | ||
| 474 | for (int i = 0; i < IV.length; i++) { | ||
| 475 | if (IV[i] != buffer[i]) { | ||
| 476 | throw new InvalidKeyException("Integrity check failed"); | ||
| 477 | } | ||
| 478 | } | ||
| 479 | } | ||
| 480 | return ConstructKeys.constructKey(out, wrappedKeyAlgorithm, | ||
| 481 | wrappedKeyType); | ||
| 482 | } | ||
| 483 | } | ||
| @@ -0,0 +1,263 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.security.*; | ||
| 29 | import java.security.spec.AlgorithmParameterSpec; | ||
| 30 | |||
| 31 | import javax.crypto.*; | ||
| 32 | |||
| 33 | /** | ||
| 34 | * Implementation of the ARCFOUR cipher, an algorithm apparently compatible | ||
| 35 | * with RSA Security's RC4(tm) cipher. The description of this algorithm was | ||
| 36 | * taken from Bruce Schneier's book Applied Cryptography, 2nd ed., | ||
| 37 | * section 17.1. | ||
| 38 | * | ||
| 39 | * We support keys from 40 to 1024 bits. ARCFOUR would allow for keys shorter | ||
| 40 | * than 40 bits, but that is too insecure for us to permit. | ||
| 41 | * | ||
| 42 | * Note that we subclass CipherSpi directly and do not use the CipherCore | ||
| 43 | * framework. That was designed to simplify implementation of block ciphers | ||
| 44 | * and does not offer any advantages for stream ciphers such as ARCFOUR. | ||
| 45 | * | ||
| 46 | * @since 1.5 | ||
| 47 | * @author Andreas Sterbenz | ||
| 48 | */ | ||
| 49 | public final class ARCFOURCipher extends CipherSpi { | ||
| 50 | |||
| 51 | // state array S, 256 entries. The entries are 8-bit, but we use an int[] | ||
| 52 | // because int arithmetic is much faster than in Java than bytes. | ||
| 53 | private final int[] S; | ||
| 54 | |||
| 55 | // state indices i and j. Called is and js to avoid collision with | ||
| 56 | // local variables. 'is' is set to -1 after a call to doFinal() | ||
| 57 | private int is, js; | ||
| 58 | |||
| 59 | // the bytes of the last key used (if any) | ||
| 60 | // we need this to re-initialize after a call to doFinal() | ||
| 61 | private byte[] lastKey; | ||
| 62 | |||
| 63 | // called by the JCE framework | ||
| 64 | public ARCFOURCipher() { | ||
| 65 | S = new int[256]; | ||
| 66 | } | ||
| 67 | |||
| 68 | // core key setup code. initializes S, is, and js | ||
| 69 | // assumes key is non-null and between 40 and 1024 bit | ||
| 70 | private void init(byte[] key) { | ||
| 71 | // initialize S[i] to i | ||
| 72 | for (int i = 0; i < 256; i++) { | ||
| 73 | S[i] = i; | ||
| 74 | } | ||
| 75 | |||
| 76 | // we avoid expanding key to 256 bytes and instead keep a separate | ||
| 77 | // counter ki = i mod key.length. | ||
| 78 | for (int i = 0, j = 0, ki = 0; i < 256; i++) { | ||
| 79 | int Si = S[i]; | ||
| 80 | j = (j + Si + key[ki]) & 0xff; | ||
| 81 | S[i] = S[j]; | ||
| 82 | S[j] = Si; | ||
| 83 | ki++; | ||
| 84 | if (ki == key.length) { | ||
| 85 | ki = 0; | ||
| 86 | } | ||
| 87 | } | ||
| 88 | |||
| 89 | // set indices to 0 | ||
| 90 | is = 0; | ||
| 91 | js = 0; | ||
| 92 | } | ||
| 93 | |||
| 94 | // core crypt code. OFB style, so works for both encryption and decryption | ||
| 95 | private void crypt(byte[] in, int inOfs, int inLen, byte[] out, | ||
| 96 | int outOfs) { | ||
| 97 | if (is < 0) { | ||
| 98 | // doFinal() was called, need to reset the cipher to initial state | ||
| 99 | init(lastKey); | ||
| 100 | } | ||
| 101 | while (inLen-- > 0) { | ||
| 102 | is = (is + 1) & 0xff; | ||
| 103 | int Si = S[is]; | ||
| 104 | js = (js + Si) & 0xff; | ||
| 105 | int Sj = S[js]; | ||
| 106 | S[is] = Sj; | ||
| 107 | S[js] = Si; | ||
| 108 | out[outOfs++] = (byte)(in[inOfs++] ^ S[(Si + Sj) & 0xff]); | ||
| 109 | } | ||
| 110 | } | ||
| 111 | |||
| 112 | // Modes do not make sense with stream ciphers, but allow ECB | ||
| 113 | // see JCE spec. | ||
| 114 | protected void engineSetMode(String mode) throws NoSuchAlgorithmException { | ||
| 115 | if (mode.equalsIgnoreCase("ECB") == false) { | ||
| 116 | throw new NoSuchAlgorithmException("Unsupported mode " + mode); | ||
| 117 | } | ||
| 118 | } | ||
| 119 | |||
| 120 | // Padding does not make sense with stream ciphers, but allow NoPadding | ||
| 121 | // see JCE spec. | ||
| 122 | protected void engineSetPadding(String padding) | ||
| 123 | throws NoSuchPaddingException { | ||
| 124 | if (padding.equalsIgnoreCase("NoPadding") == false) { | ||
| 125 | throw new NoSuchPaddingException("Padding must be NoPadding"); | ||
| 126 | } | ||
| 127 | } | ||
| 128 | |||
| 129 | // Return 0 to indicate stream cipher | ||
| 130 | // see JCE spec. | ||
| 131 | protected int engineGetBlockSize() { | ||
| 132 | return 0; | ||
| 133 | } | ||
| 134 | |||
| 135 | // output length is always the same as input length | ||
| 136 | // see JCE spec | ||
| 137 | protected int engineGetOutputSize(int inputLen) { | ||
| 138 | return inputLen; | ||
| 139 | } | ||
| 140 | |||
| 141 | // no IV, return null | ||
| 142 | // see JCE spec | ||
| 143 | protected byte[] engineGetIV() { | ||
| 144 | return null; | ||
| 145 | } | ||
| 146 | |||
| 147 | // no parameters | ||
| 148 | // see JCE spec | ||
| 149 | protected AlgorithmParameters engineGetParameters() { | ||
| 150 | return null; | ||
| 151 | } | ||
| 152 | |||
| 153 | // see JCE spec | ||
| 154 | protected void engineInit(int opmode, Key key, SecureRandom random) | ||
| 155 | throws InvalidKeyException { | ||
| 156 | init(opmode, key); | ||
| 157 | } | ||
| 158 | |||
| 159 | // see JCE spec | ||
| 160 | protected void engineInit(int opmode, Key key, | ||
| 161 | AlgorithmParameterSpec params, SecureRandom random) | ||
| 162 | throws InvalidKeyException, InvalidAlgorithmParameterException { | ||
| 163 | if (params != null) { | ||
| 164 | throw new InvalidAlgorithmParameterException | ||
| 165 | ("Parameters not supported"); | ||
| 166 | } | ||
| 167 | init(opmode, key); | ||
| 168 | } | ||
| 169 | |||
| 170 | // see JCE spec | ||
| 171 | protected void engineInit(int opmode, Key key, | ||
| 172 | AlgorithmParameters params, SecureRandom random) | ||
| 173 | throws InvalidKeyException, InvalidAlgorithmParameterException { | ||
| 174 | if (params != null) { | ||
| 175 | throw new InvalidAlgorithmParameterException | ||
| 176 | ("Parameters not supported"); | ||
| 177 | } | ||
| 178 | init(opmode, key); | ||
| 179 | } | ||
| 180 | |||
| 181 | // init method. Check opmode and key, then call init(byte[]). | ||
| 182 | private void init(int opmode, Key key) throws InvalidKeyException { | ||
| 183 | if ((opmode < Cipher.ENCRYPT_MODE) || (opmode > Cipher.UNWRAP_MODE)) { | ||
| 184 | throw new InvalidKeyException("Unknown opmode: " + opmode); | ||
| 185 | } | ||
| 186 | lastKey = getEncodedKey(key); | ||
| 187 | init(lastKey); | ||
| 188 | } | ||
| 189 | |||
| 190 | // return the encoding of key if key is a valid ARCFOUR key. | ||
| 191 | // otherwise, throw an InvalidKeyException | ||
| 192 | private static byte[] getEncodedKey(Key key) throws InvalidKeyException { | ||
| 193 | String keyAlg = key.getAlgorithm(); | ||
| 194 | if (!keyAlg.equals("RC4") && !keyAlg.equals("ARCFOUR")) { | ||
| 195 | throw new InvalidKeyException("Not an ARCFOUR key: " + keyAlg); | ||
| 196 | } | ||
| 197 | if ("RAW".equals(key.getFormat()) == false) { | ||
| 198 | throw new InvalidKeyException("Key encoding format must be RAW"); | ||
| 199 | } | ||
| 200 | byte[] encodedKey = key.getEncoded(); | ||
| 201 | if ((encodedKey.length < 5) || (encodedKey.length > 128)) { | ||
| 202 | throw new InvalidKeyException | ||
| 203 | ("Key length must be between 40 and 1024 bit"); | ||
| 204 | } | ||
| 205 | return encodedKey; | ||
| 206 | } | ||
| 207 | |||
| 208 | // see JCE spec | ||
| 209 | protected byte[] engineUpdate(byte[] in, int inOfs, int inLen) { | ||
| 210 | byte[] out = new byte[inLen]; | ||
| 211 | crypt(in, inOfs, inLen, out, 0); | ||
| 212 | return out; | ||
| 213 | } | ||
| 214 | |||
| 215 | // see JCE spec | ||
| 216 | protected int engineUpdate(byte[] in, int inOfs, int inLen, | ||
| 217 | byte[] out, int outOfs) throws ShortBufferException { | ||
| 218 | if (out.length - outOfs < inLen) { | ||
| 219 | throw new ShortBufferException("Output buffer too small"); | ||
| 220 | } | ||
| 221 | crypt(in, inOfs, inLen, out, outOfs); | ||
| 222 | return inLen; | ||
| 223 | } | ||
| 224 | |||
| 225 | // see JCE spec | ||
| 226 | protected byte[] engineDoFinal(byte[] in, int inOfs, int inLen) { | ||
| 227 | byte[] out = engineUpdate(in, inOfs, inLen); | ||
| 228 | is = -1; | ||
| 229 | return out; | ||
| 230 | } | ||
| 231 | |||
| 232 | // see JCE spec | ||
| 233 | protected int engineDoFinal(byte[] in, int inOfs, int inLen, | ||
| 234 | byte[] out, int outOfs) throws ShortBufferException { | ||
| 235 | int outLen = engineUpdate(in, inOfs, inLen, out, outOfs); | ||
| 236 | is = -1; | ||
| 237 | return outLen; | ||
| 238 | } | ||
| 239 | |||
| 240 | // see JCE spec | ||
| 241 | protected byte[] engineWrap(Key key) throws IllegalBlockSizeException, | ||
| 242 | InvalidKeyException { | ||
| 243 | byte[] encoded = key.getEncoded(); | ||
| 244 | if ((encoded == null) || (encoded.length == 0)) { | ||
| 245 | throw new InvalidKeyException("Could not obtain encoded key"); | ||
| 246 | } | ||
| 247 | return engineDoFinal(encoded, 0, encoded.length); | ||
| 248 | } | ||
| 249 | |||
| 250 | // see JCE spec | ||
| 251 | protected Key engineUnwrap(byte[] wrappedKey, String algorithm, | ||
| 252 | int type) throws InvalidKeyException, NoSuchAlgorithmException { | ||
| 253 | byte[] encoded = engineDoFinal(wrappedKey, 0, wrappedKey.length); | ||
| 254 | return ConstructKeys.constructKey(encoded, algorithm, type); | ||
| 255 | } | ||
| 256 | |||
| 257 | // see JCE spec | ||
| 258 | protected int engineGetKeySize(Key key) throws InvalidKeyException { | ||
| 259 | byte[] encodedKey = getEncodedKey(key); | ||
| 260 | return encodedKey.length << 3; | ||
| 261 | } | ||
| 262 | |||
| 263 | } | ||
| @@ -0,0 +1,127 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.util.*; | ||
| 29 | import java.io.*; | ||
| 30 | import sun.security.util.*; | ||
| 31 | import sun.misc.HexDumpEncoder; | ||
| 32 | import java.security.spec.AlgorithmParameterSpec; | ||
| 33 | import java.security.spec.InvalidParameterSpecException; | ||
| 34 | import javax.crypto.spec.IvParameterSpec; | ||
| 35 | |||
| 36 | /** | ||
| 37 | * This class implements the parameter (IV) used with Block Ciphers | ||
| 38 | * in feedback-mode. IV is defined in the standards as follows: | ||
| 39 | * | ||
| 40 | * <pre> | ||
| 41 | * IV ::= OCTET STRING -- length depends on the block size of the | ||
| 42 | * block ciphers | ||
| 43 | * </pre> | ||
| 44 | * | ||
| 45 | * @author Valerie Peng | ||
| 46 | * | ||
| 47 | */ | ||
| 48 | final class BlockCipherParamsCore { | ||
| 49 | private int block_size = 0; | ||
| 50 | private byte[] iv = null; | ||
| 51 | |||
| 52 | BlockCipherParamsCore(int blksize) { | ||
| 53 | block_size = blksize; | ||
| 54 | } | ||
| 55 | |||
| 56 | void init(AlgorithmParameterSpec paramSpec) | ||
| 57 | throws InvalidParameterSpecException { | ||
| 58 | if (!(paramSpec instanceof IvParameterSpec)) { | ||
| 59 | throw new InvalidParameterSpecException | ||
| 60 | ("Inappropriate parameter specification"); | ||
| 61 | } | ||
| 62 | byte[] tmpIv = ((IvParameterSpec)paramSpec).getIV(); | ||
| 63 | if (tmpIv.length != block_size) { | ||
| 64 | throw new InvalidParameterSpecException("IV not " + | ||
| 65 | block_size + " bytes long"); | ||
| 66 | } | ||
| 67 | iv = (byte[]) tmpIv.clone(); | ||
| 68 | } | ||
| 69 | |||
| 70 | void init(byte[] encoded) throws IOException { | ||
| 71 | DerInputStream der = new DerInputStream(encoded); | ||
| 72 | |||
| 73 | byte[] tmpIv = der.getOctetString(); | ||
| 74 | if (der.available() != 0) { | ||
| 75 | throw new IOException("IV parsing error: extra data"); | ||
| 76 | } | ||
| 77 | if (tmpIv.length != block_size) { | ||
| 78 | throw new IOException("IV not " + block_size + | ||
| 79 | " bytes long"); | ||
| 80 | } | ||
| 81 | iv = tmpIv; | ||
| 82 | } | ||
| 83 | |||
| 84 | void init(byte[] encoded, String decodingMethod) | ||
| 85 | throws IOException { | ||
| 86 | if ((decodingMethod != null) && | ||
| 87 | (!decodingMethod.equalsIgnoreCase("ASN.1"))) { | ||
| 88 | throw new IllegalArgumentException("Only support ASN.1 format"); | ||
| 89 | } | ||
| 90 | init(encoded); | ||
| 91 | } | ||
| 92 | |||
| 93 | AlgorithmParameterSpec getParameterSpec(Class paramSpec) | ||
| 94 | throws InvalidParameterSpecException | ||
| 95 | { | ||
| 96 | if (IvParameterSpec.class.isAssignableFrom(paramSpec)) { | ||
| 97 | return new IvParameterSpec(this.iv); | ||
| 98 | } else { | ||
| 99 | throw new InvalidParameterSpecException | ||
| 100 | ("Inappropriate parameter specification"); | ||
| 101 | } | ||
| 102 | } | ||
| 103 | |||
| 104 | byte[] getEncoded() throws IOException { | ||
| 105 | DerOutputStream out = new DerOutputStream(); | ||
| 106 | out.putOctetString(this.iv); | ||
| 107 | return out.toByteArray(); | ||
| 108 | } | ||
| 109 | |||
| 110 | byte[] getEncoded(String encodingMethod) | ||
| 111 | throws IOException { | ||
| 112 | return getEncoded(); | ||
| 113 | } | ||
| 114 | |||
| 115 | /* | ||
| 116 | * Returns a formatted string describing the parameters. | ||
| 117 | */ | ||
| 118 | public String toString() { | ||
| 119 | String LINE_SEP = System.getProperty("line.separator"); | ||
| 120 | |||
| 121 | String ivString = LINE_SEP + " iv:" + LINE_SEP + "["; | ||
| 122 | HexDumpEncoder encoder = new HexDumpEncoder(); | ||
| 123 | ivString += encoder.encodeBuffer(this.iv); | ||
| 124 | ivString += "]" + LINE_SEP; | ||
| 125 | return ivString; | ||
| 126 | } | ||
| 127 | } | ||
| @@ -0,0 +1,428 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.security.*; | ||
| 29 | import java.security.spec.*; | ||
| 30 | import sun.security.util.*; | ||
| 31 | import javax.crypto.*; | ||
| 32 | import javax.crypto.spec.*; | ||
| 33 | import javax.crypto.BadPaddingException; | ||
| 34 | |||
| 35 | /** | ||
| 36 | * This class implements the Blowfish algorithm in its various modes | ||
| 37 | * (<code>ECB</code>, <code>CFB</code>, <code>OFB</code>, <code>CBC</code>, | ||
| 38 | * <code>PCBC</code>) and padding schemes (<code>PKCS5Padding</code>, | ||
| 39 | * <code>NoPadding</code>, <code>ISO10126Padding</code>). | ||
| 40 | * | ||
| 41 | * <p> Blowfish is a 64-bit block cipher with a variable-length key. | ||
| 42 | * | ||
| 43 | * @author Jan Luehe | ||
| 44 | * | ||
| 45 | * | ||
| 46 | * @see BlowfishCrypt | ||
| 47 | * @see CipherBlockChaining | ||
| 48 | * @see ElectronicCodeBook | ||
| 49 | * @see CipherFeedback | ||
| 50 | * @see OutputFeedback | ||
| 51 | */ | ||
| 52 | |||
| 53 | public final class BlowfishCipher extends CipherSpi { | ||
| 54 | |||
| 55 | /* | ||
| 56 | * internal CipherCore object which does the real work. | ||
| 57 | */ | ||
| 58 | private CipherCore core = null; | ||
| 59 | |||
| 60 | /** | ||
| 61 | * Creates an instance of Blowfish cipher with default ECB mode and | ||
| 62 | * PKCS5Padding. | ||
| 63 | */ | ||
| 64 | public BlowfishCipher() { | ||
| 65 | core = new CipherCore(new BlowfishCrypt(), | ||
| 66 | BlowfishConstants.BLOWFISH_BLOCK_SIZE); | ||
| 67 | } | ||
| 68 | |||
| 69 | /** | ||
| 70 | * Sets the mode of this cipher. | ||
| 71 | * | ||
| 72 | * @param mode the cipher mode | ||
| 73 | * | ||
| 74 | * @exception NoSuchAlgorithmException if the requested cipher mode does | ||
| 75 | * not exist | ||
| 76 | */ | ||
| 77 | protected void engineSetMode(String mode) | ||
| 78 | throws NoSuchAlgorithmException { | ||
| 79 | core.setMode(mode); | ||
| 80 | } | ||
| 81 | |||
| 82 | /** | ||
| 83 | * Sets the padding mechanism of this cipher. | ||
| 84 | * | ||
| 85 | * @param padding the padding mechanism | ||
| 86 | * | ||
| 87 | * @exception NoSuchPaddingException if the requested padding mechanism | ||
| 88 | * does not exist | ||
| 89 | */ | ||
| 90 | protected void engineSetPadding(String paddingScheme) | ||
| 91 | throws NoSuchPaddingException { | ||
| 92 | core.setPadding(paddingScheme); | ||
| 93 | } | ||
| 94 | |||
| 95 | /** | ||
| 96 | * Returns the block size (in bytes). | ||
| 97 | * | ||
| 98 | * @return the block size (in bytes), or 0 if the underlying algorithm is | ||
| 99 | * not a block cipher | ||
| 100 | */ | ||
| 101 | protected int engineGetBlockSize() { | ||
| 102 | return BlowfishConstants.BLOWFISH_BLOCK_SIZE; | ||
| 103 | } | ||
| 104 | |||
| 105 | /** | ||
| 106 | * Returns the length in bytes that an output buffer would need to be in | ||
| 107 | * order to hold the result of the next <code>update</code> or | ||
| 108 | * <code>doFinal</code> operation, given the input length | ||
| 109 | * <code>inputLen</code> (in bytes). | ||
| 110 | * | ||
| 111 | * <p>This call takes into account any unprocessed (buffered) data from a | ||
| 112 | * previous <code>update</code> call, and padding. | ||
| 113 | * | ||
| 114 | * <p>The actual output length of the next <code>update</code> or | ||
| 115 | * <code>doFinal</code> call may be smaller than the length returned by | ||
| 116 | * this method. | ||
| 117 | * | ||
| 118 | * @param inputLen the input length (in bytes) | ||
| 119 | * | ||
| 120 | * @return the required output buffer size (in bytes) | ||
| 121 | */ | ||
| 122 | protected int engineGetOutputSize(int inputLen) { | ||
| 123 | return core.getOutputSize(inputLen); | ||
| 124 | } | ||
| 125 | |||
| 126 | /** | ||
| 127 | * Returns the initialization vector (IV) in a new buffer. | ||
| 128 | * | ||
| 129 | * <p>This is useful in the case where a random IV has been created | ||
| 130 | * (see <a href = "#init">init</a>), | ||
| 131 | * or in the context of password-based encryption or | ||
| 132 | * decryption, where the IV is derived from a user-supplied password. | ||
| 133 | * | ||
| 134 | * @return the initialization vector in a new buffer, or null if the | ||
| 135 | * underlying algorithm does not use an IV, or if the IV has not yet | ||
| 136 | * been set. | ||
| 137 | */ | ||
| 138 | protected byte[] engineGetIV() { | ||
| 139 | return core.getIV(); | ||
| 140 | } | ||
| 141 | |||
| 142 | /** | ||
| 143 | * Returns the parameters used with this cipher. | ||
| 144 | * | ||
| 145 | * <p>The returned parameters may be the same that were used to initialize | ||
| 146 | * this cipher, or may contain the default set of parameters or a set of | ||
| 147 | * randomly generated parameters used by the underlying cipher | ||
| 148 | * implementation (provided that the underlying cipher implementation | ||
| 149 | * uses a default set of parameters or creates new parameters if it needs | ||
| 150 | * parameters but was not initialized with any). | ||
| 151 | * | ||
| 152 | * @return the parameters used with this cipher, or null if this cipher | ||
| 153 | * does not use any parameters. | ||
| 154 | */ | ||
| 155 | protected AlgorithmParameters engineGetParameters() { | ||
| 156 | return core.getParameters("Blowfish"); | ||
| 157 | } | ||
| 158 | |||
| 159 | /** | ||
| 160 | * Initializes this cipher with a key and a source of randomness. | ||
| 161 | * | ||
| 162 | * <p>The cipher is initialized for one of the following four operations: | ||
| 163 | * encryption, decryption, key wrapping or key unwrapping, depending on | ||
| 164 | * the value of <code>opmode</code>. | ||
| 165 | * | ||
| 166 | * <p>If this cipher requires an initialization vector (IV), it will get | ||
| 167 | * it from <code>random</code>. | ||
| 168 | * This behaviour should only be used in encryption or key wrapping | ||
| 169 | * mode, however. | ||
| 170 | * When initializing a cipher that requires an IV for decryption or | ||
| 171 | * key unwrapping, the IV | ||
| 172 | * (same IV that was used for encryption or key wrapping) must be provided | ||
| 173 | * explicitly as a | ||
| 174 | * parameter, in order to get the correct result. | ||
| 175 | * | ||
| 176 | * <p>This method also cleans existing buffer and other related state | ||
| 177 | * information. | ||
| 178 | * | ||
| 179 | * @param opmode the operation mode of this cipher (this is one of | ||
| 180 | * the following: | ||
| 181 | * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, | ||
| 182 | * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) | ||
| 183 | * @param key the secret key | ||
| 184 | * @param random the source of randomness | ||
| 185 | * | ||
| 186 | * @exception InvalidKeyException if the given key is inappropriate for | ||
| 187 | * initializing this cipher | ||
| 188 | */ | ||
| 189 | protected void engineInit(int opmode, Key key, SecureRandom random) | ||
| 190 | throws InvalidKeyException { | ||
| 191 | core.init(opmode, key, random); | ||
| 192 | } | ||
| 193 | |||
| 194 | /** | ||
| 195 | * Initializes this cipher with a key, a set of | ||
| 196 | * algorithm parameters, and a source of randomness. | ||
| 197 | * | ||
| 198 | * <p>The cipher is initialized for one of the following four operations: | ||
| 199 | * encryption, decryption, key wrapping or key unwrapping, depending on | ||
| 200 | * the value of <code>opmode</code>. | ||
| 201 | * | ||
| 202 | * <p>If this cipher (including its underlying feedback or padding scheme) | ||
| 203 | * requires any random bytes, it will get them from <code>random</code>. | ||
| 204 | * | ||
| 205 | * @param opmode the operation mode of this cipher (this is one of | ||
| 206 | * the following: | ||
| 207 | * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, | ||
| 208 | * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) | ||
| 209 | * @param key the encryption key | ||
| 210 | * @param params the algorithm parameters | ||
| 211 | * @param random the source of randomness | ||
| 212 | * | ||
| 213 | * @exception InvalidKeyException if the given key is inappropriate for | ||
| 214 | * initializing this cipher | ||
| 215 | * @exception InvalidAlgorithmParameterException if the given algorithm | ||
| 216 | * parameters are inappropriate for this cipher | ||
| 217 | */ | ||
| 218 | protected void engineInit(int opmode, Key key, | ||
| 219 | AlgorithmParameterSpec params, | ||
| 220 | SecureRandom random) | ||
| 221 | throws InvalidKeyException, InvalidAlgorithmParameterException { | ||
| 222 | core.init(opmode, key, params, random); | ||
| 223 | } | ||
| 224 | |||
| 225 | protected void engineInit(int opmode, Key key, | ||
| 226 | AlgorithmParameters params, | ||
| 227 | SecureRandom random) | ||
| 228 | throws InvalidKeyException, InvalidAlgorithmParameterException { | ||
| 229 | core.init(opmode, key, params, random); | ||
| 230 | } | ||
| 231 | |||
| 232 | /** | ||
| 233 | * Continues a multiple-part encryption or decryption operation | ||
| 234 | * (depending on how this cipher was initialized), processing another data | ||
| 235 | * part. | ||
| 236 | * | ||
| 237 | * <p>The first <code>inputLen</code> bytes in the <code>input</code> | ||
| 238 | * buffer, starting at <code>inputOffset</code>, are processed, and the | ||
| 239 | * result is stored in a new buffer. | ||
| 240 | * | ||
| 241 | * @param input the input buffer | ||
| 242 | * @param inputOffset the offset in <code>input</code> where the input | ||
| 243 | * starts | ||
| 244 | * @param inputLen the input length | ||
| 245 | * | ||
| 246 | * @return the new buffer with the result | ||
| 247 | * | ||
| 248 | * @exception IllegalStateException if this cipher is in a wrong state | ||
| 249 | * (e.g., has not been initialized) | ||
| 250 | */ | ||
| 251 | protected byte[] engineUpdate(byte[] input, int inputOffset, | ||
| 252 | int inputLen) { | ||
| 253 | return core.update(input, inputOffset, inputLen); | ||
| 254 | } | ||
| 255 | |||
| 256 | /** | ||
| 257 | * Continues a multiple-part encryption or decryption operation | ||
| 258 | * (depending on how this cipher was initialized), processing another data | ||
| 259 | * part. | ||
| 260 | * | ||
| 261 | * <p>The first <code>inputLen</code> bytes in the <code>input</code> | ||
| 262 | * buffer, starting at <code>inputOffset</code>, are processed, and the | ||
| 263 | * result is stored in the <code>output</code> buffer, starting at | ||
| 264 | * <code>outputOffset</code>. | ||
| 265 | * | ||
| 266 | * @param input the input buffer | ||
| 267 | * @param inputOffset the offset in <code>input</code> where the input | ||
| 268 | * starts | ||
| 269 | * @param inputLen the input length | ||
| 270 | * @param output the buffer for the result | ||
| 271 | * @param outputOffset the offset in <code>output</code> where the result | ||
| 272 | * is stored | ||
| 273 | * | ||
| 274 | * @return the number of bytes stored in <code>output</code> | ||
| 275 | * | ||
| 276 | * @exception ShortBufferException if the given output buffer is too small | ||
| 277 | * to hold the result | ||
| 278 | */ | ||
| 279 | protected int engineUpdate(byte[] input, int inputOffset, int inputLen, | ||
| 280 | byte[] output, int outputOffset) | ||
| 281 | throws ShortBufferException { | ||
| 282 | return core.update(input, inputOffset, inputLen, output, | ||
| 283 | outputOffset); | ||
| 284 | } | ||
| 285 | |||
| 286 | /** | ||
| 287 | * Encrypts or decrypts data in a single-part operation, | ||
| 288 | * or finishes a multiple-part operation. | ||
| 289 | * The data is encrypted or decrypted, depending on how this cipher was | ||
| 290 | * initialized. | ||
| 291 | * | ||
| 292 | * <p>The first <code>inputLen</code> bytes in the <code>input</code> | ||
| 293 | * buffer, starting at <code>inputOffset</code>, and any input bytes that | ||
| 294 | * may have been buffered during a previous <code>update</code> operation, | ||
| 295 | * are processed, with padding (if requested) being applied. | ||
| 296 | * The result is stored in a new buffer. | ||
| 297 | * | ||
| 298 | * <p>The cipher is reset to its initial state (uninitialized) after this | ||
| 299 | * call. | ||
| 300 | * | ||
| 301 | * @param input the input buffer | ||
| 302 | * @param inputOffset the offset in <code>input</code> where the input | ||
| 303 | * starts | ||
| 304 | * @param inputLen the input length | ||
| 305 | * | ||
| 306 | * @return the new buffer with the result | ||
| 307 | * | ||
| 308 | * @exception IllegalBlockSizeException if this cipher is a block cipher, | ||
| 309 | * no padding has been requested (only in encryption mode), and the total | ||
| 310 | * input length of the data processed by this cipher is not a multiple of | ||
| 311 | * block size | ||
| 312 | * @exception BadPaddingException if this cipher is in decryption mode, | ||
| 313 | * and (un)padding has been requested, but the decrypted data is not | ||
| 314 | * bounded by the appropriate padding bytes | ||
| 315 | */ | ||
| 316 | protected byte[] engineDoFinal(byte[] input, int inputOffset, | ||
| 317 | int inputLen) | ||
| 318 | throws IllegalBlockSizeException, BadPaddingException { | ||
| 319 | return core.doFinal(input, inputOffset, inputLen); | ||
| 320 | } | ||
| 321 | |||
| 322 | /** | ||
| 323 | * Encrypts or decrypts data in a single-part operation, | ||
| 324 | * or finishes a multiple-part operation. | ||
| 325 | * The data is encrypted or decrypted, depending on how this cipher was | ||
| 326 | * initialized. | ||
| 327 | * | ||
| 328 | * <p>The first <code>inputLen</code> bytes in the <code>input</code> | ||
| 329 | * buffer, starting at <code>inputOffset</code>, and any input bytes that | ||
| 330 | * may have been buffered during a previous <code>update</code> operation, | ||
| 331 | * are processed, with padding (if requested) being applied. | ||
| 332 | * The result is stored in the <code>output</code> buffer, starting at | ||
| 333 | * <code>outputOffset</code>. | ||
| 334 | * | ||
| 335 | * <p>The cipher is reset to its initial state (uninitialized) after this | ||
| 336 | * call. | ||
| 337 | * | ||
| 338 | * @param input the input buffer | ||
| 339 | * @param inputOffset the offset in <code>input</code> where the input | ||
| 340 | * starts | ||
| 341 | * @param inputLen the input length | ||
| 342 | * @param output the buffer for the result | ||
| 343 | * @param outputOffset the offset in <code>output</code> where the result | ||
| 344 | * is stored | ||
| 345 | * | ||
| 346 | * @return the number of bytes stored in <code>output</code> | ||
| 347 | * | ||
| 348 | * @exception IllegalBlockSizeException if this cipher is a block cipher, | ||
| 349 | * no padding has been requested (only in encryption mode), and the total | ||
| 350 | * input length of the data processed by this cipher is not a multiple of | ||
| 351 | * block size | ||
| 352 | * @exception ShortBufferException if the given output buffer is too small | ||
| 353 | * to hold the result | ||
| 354 | * @exception BadPaddingException if this cipher is in decryption mode, | ||
| 355 | * and (un)padding has been requested, but the decrypted data is not | ||
| 356 | * bounded by the appropriate padding bytes | ||
| 357 | */ | ||
| 358 | protected int engineDoFinal(byte[] input, int inputOffset, int inputLen, | ||
| 359 | byte[] output, int outputOffset) | ||
| 360 | throws IllegalBlockSizeException, ShortBufferException, | ||
| 361 | BadPaddingException { | ||
| 362 | return core.doFinal(input, inputOffset, inputLen, output, | ||
| 363 | outputOffset); | ||
| 364 | } | ||
| 365 | |||
| 366 | /** | ||
| 367 | * Returns the key size of the given key object. | ||
| 368 | * | ||
| 369 | * @param key the key object. | ||
| 370 | * | ||
| 371 | * @return the key size of the given key object. | ||
| 372 | * | ||
| 373 | * @exception InvalidKeyException if <code>key</code> is invalid. | ||
| 374 | */ | ||
| 375 | protected int engineGetKeySize(Key key) throws InvalidKeyException { | ||
| 376 | return (key.getEncoded().length * 8); | ||
| 377 | } | ||
| 378 | |||
| 379 | /** | ||
| 380 | * Wrap a key. | ||
| 381 | * | ||
| 382 | * @param key the key to be wrapped. | ||
| 383 | * | ||
| 384 | * @return the wrapped key. | ||
| 385 | * | ||
| 386 | * @exception IllegalBlockSizeException if this cipher is a block | ||
| 387 | * cipher, no padding has been requested, and the length of the | ||
| 388 | * encoding of the key to be wrapped is not a | ||
| 389 | * multiple of the block size. | ||
| 390 | * | ||
| 391 | * @exception InvalidKeyException if it is impossible or unsafe to | ||
| 392 | * wrap the key with this cipher (e.g., a hardware protected key is | ||
| 393 | * being passed to a software only cipher). | ||
| 394 | */ | ||
| 395 | protected byte[] engineWrap(Key key) | ||
| 396 | throws IllegalBlockSizeException, InvalidKeyException { | ||
| 397 | return core.wrap(key); | ||
| 398 | } | ||
| 399 | |||
| 400 | /** | ||
| 401 | * Unwrap a previously wrapped key. | ||
| 402 | * | ||
| 403 | * @param wrappedKey the key to be unwrapped. | ||
| 404 | * | ||
| 405 | * @param wrappedKeyAlgorithm the algorithm the wrapped key is for. | ||
| 406 | * | ||
| 407 | * @param wrappedKeyType the type of the wrapped key. | ||
| 408 | * This is one of <code>Cipher.SECRET_KEY</code>, | ||
| 409 | * <code>Cipher.PRIVATE_KEY</code>, or <code>Cipher.PUBLIC_KEY</code>. | ||
| 410 | * | ||
| 411 | * @return the unwrapped key. | ||
| 412 | * | ||
| 413 | * @exception NoSuchAlgorithmException if no installed providers | ||
| 414 | * can create keys of type <code>wrappedKeyType</code> for the | ||
| 415 | * <code>wrappedKeyAlgorithm</code>. | ||
| 416 | * | ||
| 417 | * @exception InvalidKeyException if <code>wrappedKey</code> does not | ||
| 418 | * represent a wrapped key of type <code>wrappedKeyType</code> for | ||
| 419 | * the <code>wrappedKeyAlgorithm</code>. | ||
| 420 | */ | ||
| 421 | protected Key engineUnwrap(byte[] wrappedKey, | ||
| 422 | String wrappedKeyAlgorithm, | ||
| 423 | int wrappedKeyType) | ||
| 424 | throws InvalidKeyException, NoSuchAlgorithmException { | ||
| 425 | return core.unwrap(wrappedKey, wrappedKeyAlgorithm, | ||
| 426 | wrappedKeyType); | ||
| 427 | } | ||
| 428 | } | ||
| @@ -0,0 +1,41 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | /** | ||
| 29 | * This class defines the constants used by the Blowfish algorithm | ||
| 30 | * implementation. | ||
| 31 | * | ||
| 32 | * @author Jan Luehe | ||
| 33 | * | ||
| 34 | * @see BlowfishCipher | ||
| 35 | * @see BlowfishCrypt | ||
| 36 | */ | ||
| 37 | |||
| 38 | interface BlowfishConstants { | ||
| 39 | int BLOWFISH_BLOCK_SIZE = 8; // number of bytes | ||
| 40 | int BLOWFISH_MAX_KEYSIZE = 56; // number of bytes | ||
| 41 | } | ||
| @@ -0,0 +1,558 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.security.InvalidKeyException; | ||
| 29 | |||
| 30 | /** | ||
| 31 | * This is the internal Blowfish class responsible for encryption and | ||
| 32 | * decryption of a byte array of size <code>BLOWFISH_BLOCK_SIZE</code>. | ||
| 33 | * | ||
| 34 | * @author Jan Luehe | ||
| 35 | * @author David Brownell | ||
| 36 | * | ||
| 37 | * @see BlowfishCipher | ||
| 38 | */ | ||
| 39 | |||
| 40 | final class BlowfishCrypt extends SymmetricCipher | ||
| 41 | implements BlowfishConstants { | ||
| 42 | |||
| 43 | /* | ||
| 44 | * Are we encrypting or decrypting? | ||
| 45 | */ | ||
| 46 | private boolean decrypting = false; | ||
| 47 | |||
| 48 | /** | ||
| 49 | * Gets this cipher's block size. | ||
| 50 | * | ||
| 51 | * @return this cipher's block size | ||
| 52 | */ | ||
| 53 | int getBlockSize() { | ||
| 54 | return BLOWFISH_BLOCK_SIZE; | ||
| 55 | } | ||
| 56 | |||
| 57 | void init(boolean decrypting, String algorithm, byte[] rawKey) | ||
| 58 | throws InvalidKeyException { | ||
| 59 | this.decrypting = decrypting; | ||
| 60 | if (!algorithm.equalsIgnoreCase("Blowfish")) { | ||
| 61 | throw new InvalidKeyException("Wrong algorithm: Blowfish required"); | ||
| 62 | } | ||
| 63 | if (rawKey.length > BLOWFISH_MAX_KEYSIZE) { | ||
| 64 | throw new InvalidKeyException("Key too long (> 448 bits)"); | ||
| 65 | } | ||
| 66 | // Step 1: Init P and then S arrays from pi bytes | ||
| 67 | int i, j, count; | ||
| 68 | |||
| 69 | System.arraycopy(pi, 0, p, 0, 18); | ||
| 70 | System.arraycopy(pi, 18, s0, 0, 256); | ||
| 71 | System.arraycopy(pi, 18 + 256, s1, 0, 256); | ||
| 72 | System.arraycopy(pi, 18 + 512, s2, 0, 256); | ||
| 73 | System.arraycopy(pi, 18 + 768, s3, 0, 256); | ||
| 74 | |||
| 75 | // Step 2: XOR all parts of P with key data | ||
| 76 | int tmp = 0; | ||
| 77 | int nLen = rawKey.length; | ||
| 78 | int nKeyPos = 0; | ||
| 79 | for (i = 0; i < 18; i++) { | ||
| 80 | for (j = 0; j < 4; j++) { | ||
| 81 | tmp <<= 8; | ||
| 82 | tmp |= 0x0ff & rawKey[nKeyPos]; | ||
| 83 | if (++nKeyPos == nLen) nKeyPos = 0; | ||
| 84 | } | ||
| 85 | p[i] ^= tmp; | ||
| 86 | } | ||
| 87 | |||
| 88 | // Steps 3-7: Replace all P, S values with computed values | ||
| 89 | int[] data = new int[2]; | ||
| 90 | |||
| 91 | for (i = 0; i < 18; i+=2) { | ||
| 92 | encryptBlock(data); | ||
| 93 | p[i] = data[0]; | ||
| 94 | p[i+1] = data[1]; | ||
| 95 | } | ||
| 96 | |||
| 97 | for (j = 0; j < 256; j+=2) { | ||
| 98 | encryptBlock(data); | ||
| 99 | s0[j] = data[0]; | ||
| 100 | s0[j+1] = data[1]; | ||
| 101 | } | ||
| 102 | for (j = 0; j < 256; j+=2) { | ||
| 103 | encryptBlock(data); | ||
| 104 | s1[j] = data[0]; | ||
| 105 | s1[j+1] = data[1]; | ||
| 106 | } | ||
| 107 | for (j = 0; j < 256; j+=2) { | ||
| 108 | encryptBlock(data); | ||
| 109 | s2[j] = data[0]; | ||
| 110 | s2[j+1] = data[1]; | ||
| 111 | } | ||
| 112 | for (j = 0; j < 256; j+=2) { | ||
| 113 | encryptBlock(data); | ||
| 114 | s3[j] = data[0]; | ||
| 115 | s3[j+1] = data[1]; | ||
| 116 | } | ||
| 117 | } | ||
| 118 | |||
| 119 | /** | ||
| 120 | * Performs encryption operation. | ||
| 121 | * | ||
| 122 | * <p>The input plain text <code>plain</code>, starting at | ||
| 123 | * <code>plainOffset</code> and ending at | ||
| 124 | * <code>(plainOffset + len - 1)</code>, is encrypted. | ||
| 125 | * The result is stored in <code>cipher</code>, starting at | ||
| 126 | * <code>cipherOffset</code>. | ||
| 127 | * | ||
| 128 | * <p>The subclass that implements Cipher should ensure that | ||
| 129 | * <code>init</code> has been called before this method is called. | ||
| 130 | * | ||
| 131 | * @param plain the buffer with the input data to be encrypted | ||
| 132 | * @param plainOffset the offset in <code>plain</code> | ||
| 133 | * @param plainLen the length of the input data | ||
| 134 | * @param cipher the buffer for the result | ||
| 135 | * @param cipherOffset the offset in <code>cipher</code> | ||
| 136 | */ | ||
| 137 | void encryptBlock(byte[] plain, int plainOffset, | ||
| 138 | byte[] cipher, int cipherOffset) | ||
| 139 | { | ||
| 140 | cipherBlock(plain, plainOffset, cipher, cipherOffset); | ||
| 141 | } | ||
| 142 | |||
| 143 | /** | ||
| 144 | * Performs decryption operation. | ||
| 145 | * | ||
| 146 | * <p>The input cipher text <code>cipher</code>, starting at | ||
| 147 | * <code>cipherOffset</code> and ending at | ||
| 148 | * <code>(cipherOffset + len - 1)</code>, is decrypted. | ||
| 149 | * The result is stored in <code>plain</code>, starting at | ||
| 150 | * <code>plainOffset</code>. | ||
| 151 | * | ||
| 152 | * <p>The subclass that implements Cipher should ensure that | ||
| 153 | * <code>init</code> has been called before this method is called. | ||
| 154 | * | ||
| 155 | * @param cipher the buffer with the input data to be decrypted | ||
| 156 | * @param cipherOffset the offset in <code>cipherOffset</code> | ||
| 157 | * @param cipherLen the length of the input data | ||
| 158 | * @param plain the buffer for the result | ||
| 159 | * @param plainOffset the offset in <code>plain</code> | ||
| 160 | */ | ||
| 161 | void decryptBlock(byte[] cipher, int cipherOffset, | ||
| 162 | byte[] plain, int plainOffset) | ||
| 163 | { | ||
| 164 | cipherBlock(cipher, cipherOffset, plain, plainOffset); | ||
| 165 | } | ||
| 166 | |||
| 167 | /** | ||
| 168 | * Encrypts, or decrypts, the blocks of data passed in. | ||
| 169 | */ | ||
| 170 | private void cipherBlock(byte[] in, int inOffset, | ||
| 171 | byte[] out, int outOffset) { | ||
| 172 | temp[0] = ((in[inOffset ] ) << 24) | | ||
| 173 | ((in[inOffset + 1] & 0xff) << 16) | | ||
| 174 | ((in[inOffset + 2] & 0xff) << 8) | | ||
| 175 | ((in[inOffset + 3] & 0xff) ); | ||
| 176 | |||
| 177 | temp[1] = ((in[inOffset + 4] ) << 24) | | ||
| 178 | ((in[inOffset + 5] & 0xff) << 16) | | ||
| 179 | ((in[inOffset + 6] & 0xff) << 8) | | ||
| 180 | ((in[inOffset + 7] & 0xff) ); | ||
| 181 | |||
| 182 | if (decrypting) { | ||
| 183 | decryptBlock(temp); | ||
| 184 | } else { | ||
| 185 | encryptBlock(temp); | ||
| 186 | } | ||
| 187 | |||
| 188 | int t = temp[0]; | ||
| 189 | out[outOffset ] = (byte)(t >> 24); | ||
| 190 | out[outOffset + 1] = (byte)(t >> 16); | ||
| 191 | out[outOffset + 2] = (byte)(t >> 8); | ||
| 192 | out[outOffset + 3] = (byte)(t ); | ||
| 193 | |||
| 194 | t = temp[1]; | ||
| 195 | out[outOffset + 4] = (byte)(t >> 24); | ||
| 196 | out[outOffset + 5] = (byte)(t >> 16); | ||
| 197 | out[outOffset + 6] = (byte)(t >> 8); | ||
| 198 | out[outOffset + 7] = (byte)(t ); | ||
| 199 | } | ||
| 200 | |||
| 201 | /** | ||
| 202 | * Encrypts a single block, in place. | ||
| 203 | */ | ||
| 204 | private void encryptBlock(int[] value) { | ||
| 205 | int left = value[0]; | ||
| 206 | int right = value[1]; | ||
| 207 | |||
| 208 | left ^= p[0]; | ||
| 209 | |||
| 210 | right ^= F(left) ^ p[1]; | ||
| 211 | left ^= F(right) ^ p[2]; | ||
| 212 | right ^= F(left) ^ p[3]; | ||
| 213 | left ^= F(right) ^ p[4]; | ||
| 214 | |||
| 215 | right ^= F(left) ^ p[5]; | ||
| 216 | left ^= F(right) ^ p[6]; | ||
| 217 | right ^= F(left) ^ p[7]; | ||
| 218 | left ^= F(right) ^ p[8]; | ||
| 219 | |||
| 220 | right ^= F(left) ^ p[9]; | ||
| 221 | left ^= F(right) ^ p[10]; | ||
| 222 | right ^= F(left) ^ p[11]; | ||
| 223 | left ^= F(right) ^ p[12]; | ||
| 224 | |||
| 225 | right ^= F(left) ^ p[13]; | ||
| 226 | left ^= F(right) ^ p[14]; | ||
| 227 | right ^= F(left) ^ p[15]; | ||
| 228 | left ^= F(right) ^ p[16]; | ||
| 229 | |||
| 230 | right ^= p[17]; | ||
| 231 | |||
| 232 | value[0] = right; | ||
| 233 | value[1] = left; | ||
| 234 | } | ||
| 235 | |||
| 236 | /** | ||
| 237 | * Decrypts a single block, in place. | ||
| 238 | */ | ||
| 239 | private void decryptBlock(int[] value) { | ||
| 240 | int left = value[1]; | ||
| 241 | int right = value[0]; | ||
| 242 | |||
| 243 | right ^= p[17]; | ||
| 244 | |||
| 245 | left ^= p[16] ^ F(right); | ||
| 246 | right ^= p[15] ^ F(left); | ||
| 247 | left ^= p[14] ^ F(right); | ||
| 248 | right ^= p[13] ^ F(left); | ||
| 249 | |||
| 250 | left ^= p[12] ^ F(right); | ||
| 251 | right ^= p[11] ^ F(left); | ||
| 252 | left ^= p[10] ^ F(right); | ||
| 253 | right ^= p[9] ^ F(left); | ||
| 254 | |||
| 255 | left ^= p[8] ^ F(right); | ||
| 256 | right ^= p[7] ^ F(left); | ||
| 257 | left ^= p[6] ^ F(right); | ||
| 258 | right ^= p[5] ^ F(left); | ||
| 259 | |||
| 260 | left ^= p[4] ^ F(right); | ||
| 261 | right ^= p[3] ^ F(left); | ||
| 262 | left ^= p[2] ^ F(right); | ||
| 263 | right ^= p[1] ^ F(left); | ||
| 264 | |||
| 265 | left ^= p[0]; | ||
| 266 | |||
| 267 | value[0] = left; | ||
| 268 | value[1] = right; | ||
| 269 | } | ||
| 270 | |||
| 271 | /** | ||
| 272 | * Calculates the S-Box function F(). | ||
| 273 | * | ||
| 274 | * This gets used "rounds" times on each encryption/decryption. | ||
| 275 | */ | ||
| 276 | private int F(int v) { | ||
| 277 | return (( s0[ v >>> 24 ] | ||
| 278 | + s1[(v >> 16) & 0xff]) | ||
| 279 | ^ s2[(v >> 8) & 0xff]) | ||
| 280 | + s3[ v & 0xff]; | ||
| 281 | } | ||
| 282 | |||
| 283 | private final int[] p = new int[18]; // subkeys | ||
| 284 | private final int[] s0 = new int[256]; // s-boxes | ||
| 285 | private final int[] s1 = new int[256]; | ||
| 286 | private final int[] s2 = new int[256]; | ||
| 287 | private final int[] s3 = new int[256]; | ||
| 288 | private final int[] temp = new int[2]; // to avoid encrypt/decrypt mallocs | ||
| 289 | |||
| 290 | // many digits of pi, for initializing p and s | ||
| 291 | private static final int[] pi = { | ||
| 292 | |||
| 293 | // p [rounds + 2] | ||
| 294 | 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, | ||
| 295 | 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, | ||
| 296 | 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, | ||
| 297 | 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, | ||
| 298 | 0x9216d5d9, 0x8979fb1b, | ||
| 299 | |||
| 300 | // s [4][256] | ||
| 301 | 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, | ||
| 302 | 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, | ||
| 303 | 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, | ||
| 304 | 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, | ||
| 305 | 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, | ||
| 306 | 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, | ||
| 307 | 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, | ||
| 308 | 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, | ||
| 309 | 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, | ||
| 310 | 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, | ||
| 311 | 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, | ||
| 312 | 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, | ||
| 313 | 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, | ||
| 314 | 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, | ||
| 315 | 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, | ||
| 316 | 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, | ||
| 317 | 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, | ||
| 318 | 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, | ||
| 319 | 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, | ||
| 320 | 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, | ||
| 321 | 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, | ||
| 322 | 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, | ||
| 323 | 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, | ||
| 324 | 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, | ||
| 325 | 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, | ||
| 326 | 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, | ||
| 327 | 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, | ||
| 328 | 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, | ||
| 329 | 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, | ||
| 330 | 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, | ||
| 331 | 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, | ||
| 332 | 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, | ||
| 333 | 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, | ||
| 334 | 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, | ||
| 335 | 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, | ||
| 336 | 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, | ||
| 337 | 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, | ||
| 338 | 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, | ||
| 339 | 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, | ||
| 340 | 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, | ||
| 341 | 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, | ||
| 342 | 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, | ||
| 343 | 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, | ||
| 344 | 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, | ||
| 345 | 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, | ||
| 346 | 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, | ||
| 347 | 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, | ||
| 348 | 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, | ||
| 349 | 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, | ||
| 350 | 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, | ||
| 351 | 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, | ||
| 352 | 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, | ||
| 353 | 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, | ||
| 354 | 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, | ||
| 355 | 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, | ||
| 356 | 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, | ||
| 357 | 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, | ||
| 358 | 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, | ||
| 359 | 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, | ||
| 360 | 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, | ||
| 361 | 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, | ||
| 362 | 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, | ||
| 363 | 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, | ||
| 364 | 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a, | ||
| 365 | 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, | ||
| 366 | 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, | ||
| 367 | 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, | ||
| 368 | 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, | ||
| 369 | 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, | ||
| 370 | 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, | ||
| 371 | 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, | ||
| 372 | 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, | ||
| 373 | 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, | ||
| 374 | 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, | ||
| 375 | 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, | ||
| 376 | 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, | ||
| 377 | 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, | ||
| 378 | 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, | ||
| 379 | 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, | ||
| 380 | 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, | ||
| 381 | 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, | ||
| 382 | 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, | ||
| 383 | 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, | ||
| 384 | 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, | ||
| 385 | 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, | ||
| 386 | 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, | ||
| 387 | 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, | ||
| 388 | 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, | ||
| 389 | 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, | ||
| 390 | 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, | ||
| 391 | 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, | ||
| 392 | 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, | ||
| 393 | 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, | ||
| 394 | 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, | ||
| 395 | 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, | ||
| 396 | 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, | ||
| 397 | 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, | ||
| 398 | 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, | ||
| 399 | 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, | ||
| 400 | 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, | ||
| 401 | 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, | ||
| 402 | 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, | ||
| 403 | 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, | ||
| 404 | 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, | ||
| 405 | 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, | ||
| 406 | 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, | ||
| 407 | 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, | ||
| 408 | 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, | ||
| 409 | 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, | ||
| 410 | 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, | ||
| 411 | 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, | ||
| 412 | 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, | ||
| 413 | 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, | ||
| 414 | 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, | ||
| 415 | 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, | ||
| 416 | 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, | ||
| 417 | 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, | ||
| 418 | 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, | ||
| 419 | 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, | ||
| 420 | 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, | ||
| 421 | 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, | ||
| 422 | 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, | ||
| 423 | 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, | ||
| 424 | 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, | ||
| 425 | 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, | ||
| 426 | 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, | ||
| 427 | 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, | ||
| 428 | 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7, | ||
| 429 | 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, | ||
| 430 | 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, | ||
| 431 | 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, | ||
| 432 | 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, | ||
| 433 | 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, | ||
| 434 | 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, | ||
| 435 | 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, | ||
| 436 | 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, | ||
| 437 | 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, | ||
| 438 | 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, | ||
| 439 | 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, | ||
| 440 | 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, | ||
| 441 | 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, | ||
| 442 | 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, | ||
| 443 | 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, | ||
| 444 | 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, | ||
| 445 | 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, | ||
| 446 | 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, | ||
| 447 | 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, | ||
| 448 | 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, | ||
| 449 | 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, | ||
| 450 | 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, | ||
| 451 | 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, | ||
| 452 | 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, | ||
| 453 | 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, | ||
| 454 | 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, | ||
| 455 | 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, | ||
| 456 | 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, | ||
| 457 | 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, | ||
| 458 | 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, | ||
| 459 | 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, | ||
| 460 | 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, | ||
| 461 | 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, | ||
| 462 | 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, | ||
| 463 | 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, | ||
| 464 | 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, | ||
| 465 | 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, | ||
| 466 | 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, | ||
| 467 | 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, | ||
| 468 | 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, | ||
| 469 | 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, | ||
| 470 | 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, | ||
| 471 | 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, | ||
| 472 | 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, | ||
| 473 | 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, | ||
| 474 | 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, | ||
| 475 | 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, | ||
| 476 | 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, | ||
| 477 | 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, | ||
| 478 | 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, | ||
| 479 | 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, | ||
| 480 | 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, | ||
| 481 | 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, | ||
| 482 | 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, | ||
| 483 | 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, | ||
| 484 | 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, | ||
| 485 | 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, | ||
| 486 | 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, | ||
| 487 | 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, | ||
| 488 | 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, | ||
| 489 | 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, | ||
| 490 | 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, | ||
| 491 | 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, | ||
| 492 | 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0, | ||
| 493 | 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, | ||
| 494 | 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, | ||
| 495 | 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, | ||
| 496 | 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, | ||
| 497 | 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, | ||
| 498 | 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, | ||
| 499 | 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, | ||
| 500 | 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, | ||
| 501 | 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, | ||
| 502 | 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, | ||
| 503 | 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, | ||
| 504 | 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, | ||
| 505 | 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, | ||
| 506 | 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, | ||
| 507 | 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, | ||
| 508 | 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, | ||
| 509 | 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, | ||
| 510 | 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, | ||
| 511 | 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, | ||
| 512 | 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, | ||
| 513 | 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, | ||
| 514 | 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, | ||
| 515 | 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, | ||
| 516 | 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, | ||
| 517 | 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, | ||
| 518 | 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, | ||
| 519 | 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, | ||
| 520 | 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, | ||
| 521 | 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, | ||
| 522 | 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, | ||
| 523 | 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, | ||
| 524 | 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, | ||
| 525 | 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, | ||
| 526 | 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, | ||
| 527 | 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, | ||
| 528 | 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, | ||
| 529 | 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, | ||
| 530 | 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, | ||
| 531 | 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, | ||
| 532 | 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, | ||
| 533 | 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, | ||
| 534 | 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, | ||
| 535 | 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, | ||
| 536 | 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, | ||
| 537 | 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, | ||
| 538 | 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, | ||
| 539 | 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, | ||
| 540 | 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, | ||
| 541 | 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, | ||
| 542 | 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, | ||
| 543 | 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, | ||
| 544 | 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, | ||
| 545 | 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, | ||
| 546 | 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, | ||
| 547 | 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, | ||
| 548 | 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, | ||
| 549 | 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, | ||
| 550 | 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, | ||
| 551 | 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, | ||
| 552 | 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, | ||
| 553 | 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, | ||
| 554 | 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, | ||
| 555 | 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, | ||
| 556 | 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6, | ||
| 557 | }; | ||
| 558 | } | ||
| @@ -0,0 +1,115 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.security.SecureRandom; | ||
| 29 | import java.security.InvalidParameterException; | ||
| 30 | import java.security.InvalidAlgorithmParameterException; | ||
| 31 | import java.security.spec.AlgorithmParameterSpec; | ||
| 32 | import javax.crypto.KeyGeneratorSpi; | ||
| 33 | import javax.crypto.SecretKey; | ||
| 34 | import javax.crypto.spec.SecretKeySpec; | ||
| 35 | |||
| 36 | /** | ||
| 37 | * This class generates a secret key for use with the Blowfish algorithm. | ||
| 38 | * | ||
| 39 | * @author Jan Luehe | ||
| 40 | * | ||
| 41 | */ | ||
| 42 | |||
| 43 | public final class BlowfishKeyGenerator extends KeyGeneratorSpi { | ||
| 44 | |||
| 45 | private SecureRandom random = null; | ||
| 46 | private int keysize = 16; // default keysize (in number of bytes) | ||
| 47 | |||
| 48 | /** | ||
| 49 | * Empty constructor | ||
| 50 | */ | ||
| 51 | public BlowfishKeyGenerator() { | ||
| 52 | } | ||
| 53 | |||
| 54 | /** | ||
| 55 | * Initializes this key generator. | ||
| 56 | * | ||
| 57 | * @param random the source of randomness for this generator | ||
| 58 | */ | ||
| 59 | protected void engineInit(SecureRandom random) { | ||
| 60 | this.random = random; | ||
| 61 | } | ||
| 62 | |||
| 63 | /** | ||
| 64 | * Initializes this key generator with the specified parameter | ||
| 65 | * set and a user-provided source of randomness. | ||
| 66 | * | ||
| 67 | * @param params the key generation parameters | ||
| 68 | * @param random the source of randomness for this key generator | ||
| 69 | * | ||
| 70 | * @exception InvalidAlgorithmParameterException if <code>params</code> is | ||
| 71 | * inappropriate for this key generator | ||
| 72 | */ | ||
| 73 | protected void engineInit(AlgorithmParameterSpec params, | ||
| 74 | SecureRandom random) | ||
| 75 | throws InvalidAlgorithmParameterException | ||
| 76 | { | ||
| 77 | throw new InvalidAlgorithmParameterException | ||
| 78 | ("Blowfish key generation does not take any parameters"); | ||
| 79 | } | ||
| 80 | |||
| 81 | /** | ||
| 82 | * Initializes this key generator for a certain keysize, using the given | ||
| 83 | * source of randomness. | ||
| 84 | * | ||
| 85 | * @param keysize the keysize. This is an algorithm-specific | ||
| 86 | * metric specified in number of bits. | ||
| 87 | * @param random the source of randomness for this key generator | ||
| 88 | */ | ||
| 89 | protected void engineInit(int keysize, SecureRandom random) { | ||
| 90 | if (((keysize % 8) != 0) || (keysize < 32) || (keysize > 448)) { | ||
| 91 | throw new InvalidParameterException("Keysize must be " | ||
| 92 | + "multiple of 8, and can " | ||
| 93 | + "only range from 32 to 448 " | ||
| 94 | + "(inclusive)"); | ||
| 95 | } | ||
| 96 | this.keysize = keysize / 8; | ||
| 97 | this.engineInit(random); | ||
| 98 | } | ||
| 99 | |||
| 100 | /** | ||
| 101 | * Generates a Blowfish key. | ||
| 102 | * | ||
| 103 | * @return the new Blowfish key | ||
| 104 | */ | ||
| 105 | protected SecretKey engineGenerateKey() { | ||
| 106 | if (this.random == null) { | ||
| 107 | this.random = SunJCE.RANDOM; | ||
| 108 | } | ||
| 109 | |||
| 110 | byte[] keyBytes = new byte[this.keysize]; | ||
| 111 | this.random.nextBytes(keyBytes); | ||
| 112 | |||
| 113 | return new SecretKeySpec(keyBytes, "Blowfish"); | ||
| 114 | } | ||
| 115 | } | ||
| @@ -0,0 +1,88 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.util.*; | ||
| 29 | import java.io.*; | ||
| 30 | import sun.security.util.*; | ||
| 31 | import java.security.AlgorithmParametersSpi; | ||
| 32 | import java.security.spec.AlgorithmParameterSpec; | ||
| 33 | import java.security.spec.InvalidParameterSpecException; | ||
| 34 | import javax.crypto.spec.IvParameterSpec; | ||
| 35 | |||
| 36 | /** | ||
| 37 | * This class implements the parameter (IV) used with the Blowfish algorithm in | ||
| 38 | * feedback-mode. IV is defined in the standards as follows: | ||
| 39 | * | ||
| 40 | * <pre> | ||
| 41 | * IV ::= OCTET STRING -- 8 octets | ||
| 42 | * </pre> | ||
| 43 | * | ||
| 44 | * @author Jan Luehe | ||
| 45 | * | ||
| 46 | */ | ||
| 47 | |||
| 48 | public final class BlowfishParameters extends AlgorithmParametersSpi { | ||
| 49 | |||
| 50 | private BlockCipherParamsCore core; | ||
| 51 | |||
| 52 | public BlowfishParameters() { | ||
| 53 | core = new BlockCipherParamsCore | ||
| 54 | (BlowfishConstants.BLOWFISH_BLOCK_SIZE); | ||
| 55 | } | ||
| 56 | protected void engineInit(AlgorithmParameterSpec paramSpec) | ||
| 57 | throws InvalidParameterSpecException { | ||
| 58 | core.init(paramSpec); | ||
| 59 | } | ||
| 60 | |||
| 61 | protected void engineInit(byte[] encoded) | ||
| 62 | throws IOException { | ||
| 63 | core.init(encoded); | ||
| 64 | } | ||
| 65 | |||
| 66 | protected void engineInit(byte[] encoded, String decodingMethod) | ||
| 67 | throws IOException { | ||
| 68 | core.init(encoded, decodingMethod); | ||
| 69 | } | ||
| 70 | |||
| 71 | protected AlgorithmParameterSpec engineGetParameterSpec(Class paramSpec) | ||
| 72 | throws InvalidParameterSpecException { | ||
| 73 | return core.getParameterSpec(paramSpec); | ||
| 74 | } | ||
| 75 | |||
| 76 | protected byte[] engineGetEncoded() throws IOException { | ||
| 77 | return core.getEncoded(); | ||
| 78 | } | ||
| 79 | |||
| 80 | protected byte[] engineGetEncoded(String encodingMethod) | ||
| 81 | throws IOException { | ||
| 82 | return core.getEncoded(); | ||
| 83 | } | ||
| 84 | |||
| 85 | protected String engineToString() { | ||
| 86 | return core.toString(); | ||
| 87 | } | ||
| 88 | } | ||
| @@ -0,0 +1,212 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.security.InvalidKeyException; | ||
| 29 | |||
| 30 | /** | ||
| 31 | * This class represents ciphers in cipher block chaining (CBC) mode. | ||
| 32 | * | ||
| 33 | * <p>This mode is implemented independently of a particular cipher. | ||
| 34 | * Ciphers to which this mode should apply (e.g., DES) must be | ||
| 35 | * <i>plugged-in</i> using the constructor. | ||
| 36 | * | ||
| 37 | * <p>NOTE: This class does not deal with buffering or padding. | ||
| 38 | * | ||
| 39 | * @author Gigi Ankeny | ||
| 40 | */ | ||
| 41 | |||
| 42 | class CipherBlockChaining extends FeedbackCipher { | ||
| 43 | |||
| 44 | /* | ||
| 45 | * random bytes that are initialized with iv | ||
| 46 | */ | ||
| 47 | protected byte[] r; | ||
| 48 | |||
| 49 | /* | ||
| 50 | * output buffer | ||
| 51 | */ | ||
| 52 | private byte[] k; | ||
| 53 | |||
| 54 | // variables for save/restore calls | ||
| 55 | private byte[] rSave = null; | ||
| 56 | |||
| 57 | CipherBlockChaining(SymmetricCipher embeddedCipher) { | ||
| 58 | super(embeddedCipher); | ||
| 59 | k = new byte[blockSize]; | ||
| 60 | r = new byte[blockSize]; | ||
| 61 | } | ||
| 62 | |||
| 63 | /** | ||
| 64 | * Gets the name of this feedback mode. | ||
| 65 | * | ||
| 66 | * @return the string <code>CBC</code> | ||
| 67 | */ | ||
| 68 | String getFeedback() { | ||
| 69 | return "CBC"; | ||
| 70 | } | ||
| 71 | |||
| 72 | /** | ||
| 73 | * Initializes the cipher in the specified mode with the given key | ||
| 74 | * and iv. | ||
| 75 | * | ||
| 76 | * @param decrypting flag indicating encryption or decryption | ||
| 77 | * @param algorithm the algorithm name | ||
| 78 | * @param key the key | ||
| 79 | * @param iv the iv | ||
| 80 | * | ||
| 81 | * @exception InvalidKeyException if the given key is inappropriate for | ||
| 82 | * initializing this cipher | ||
| 83 | */ | ||
| 84 | void init(boolean decrypting, String algorithm, byte[] key, byte[] iv) | ||
| 85 | throws InvalidKeyException { | ||
| 86 | if ((key == null) || (iv == null) || (iv.length != blockSize)) { | ||
| 87 | throw new InvalidKeyException("Internal error"); | ||
| 88 | } | ||
| 89 | this.iv = iv; | ||
| 90 | reset(); | ||
| 91 | embeddedCipher.init(decrypting, algorithm, key); | ||
| 92 | } | ||
| 93 | |||
| 94 | /** | ||
| 95 | * Resets the iv to its original value. | ||
| 96 | * This is used when doFinal is called in the Cipher class, so that the | ||
| 97 | * cipher can be reused (with its original iv). | ||
| 98 | */ | ||
| 99 | void reset() { | ||
| 100 | System.arraycopy(iv, 0, r, 0, blockSize); | ||
| 101 | } | ||
| 102 | |||
| 103 | /** | ||
| 104 | * Save the current content of this cipher. | ||
| 105 | */ | ||
| 106 | void save() { | ||
| 107 | if (rSave == null) { | ||
| 108 | rSave = new byte[blockSize]; | ||
| 109 | } | ||
| 110 | System.arraycopy(r, 0, rSave, 0, blockSize); | ||
| 111 | } | ||
| 112 | |||
| 113 | /** | ||
| 114 | * Restores the content of this cipher to the previous saved one. | ||
| 115 | */ | ||
| 116 | void restore() { | ||
| 117 | System.arraycopy(rSave, 0, r, 0, blockSize); | ||
| 118 | } | ||
| 119 | |||
| 120 | /** | ||
| 121 | * Performs encryption operation. | ||
| 122 | * | ||
| 123 | * <p>The input plain text <code>plain</code>, starting at | ||
| 124 | * <code>plainOffset</code> and ending at | ||
| 125 | * <code>(plainOffset + len - 1)</code>, is encrypted. | ||
| 126 | * The result is stored in <code>cipher</code>, starting at | ||
| 127 | * <code>cipherOffset</code>. | ||
| 128 | * | ||
| 129 | * <p>It is the application's responsibility to make sure that | ||
| 130 | * <code>plainLen</code> is a multiple of the embedded cipher's block size, | ||
| 131 | * as any excess bytes are ignored. | ||
| 132 | * | ||
| 133 | * @param plain the buffer with the input data to be encrypted | ||
| 134 | * @param plainOffset the offset in <code>plain</code> | ||
| 135 | * @param plainLen the length of the input data | ||
| 136 | * @param cipher the buffer for the result | ||
| 137 | * @param cipherOffset the offset in <code>cipher</code> | ||
| 138 | */ | ||
| 139 | void encrypt(byte[] plain, int plainOffset, int plainLen, | ||
| 140 | byte[] cipher, int cipherOffset) | ||
| 141 | { | ||
| 142 | int i; | ||
| 143 | int endIndex = plainOffset + plainLen; | ||
| 144 | |||
| 145 | for (; plainOffset < endIndex; | ||
| 146 | plainOffset+=blockSize, cipherOffset += blockSize) { | ||
| 147 | for (i=0; i<blockSize; i++) { | ||
| 148 | k[i] = (byte)(plain[i+plainOffset] ^ r[i]); | ||
| 149 | } | ||
| 150 | embeddedCipher.encryptBlock(k, 0, cipher, cipherOffset); | ||
| 151 | System.arraycopy(cipher, cipherOffset, r, 0, blockSize); | ||
| 152 | } | ||
| 153 | } | ||
| 154 | |||
| 155 | /** | ||
| 156 | * Performs decryption operation. | ||
| 157 | * | ||
| 158 | * <p>The input cipher text <code>cipher</code>, starting at | ||
| 159 | * <code>cipherOffset</code> and ending at | ||
| 160 | * <code>(cipherOffset + len - 1)</code>, is decrypted. | ||
| 161 | * The result is stored in <code>plain</code>, starting at | ||
| 162 | * <code>plainOffset</code>. | ||
| 163 | * | ||
| 164 | * <p>It is the application's responsibility to make sure that | ||
| 165 | * <code>cipherLen</code> is a multiple of the embedded cipher's block | ||
| 166 | * size, as any excess bytes are ignored. | ||
| 167 | * | ||
| 168 | * <p>It is also the application's responsibility to make sure that | ||
| 169 | * <code>init</code> has been called before this method is called. | ||
| 170 | * (This check is omitted here, to avoid double checking.) | ||
| 171 | * | ||
| 172 | * @param cipher the buffer with the input data to be decrypted | ||
| 173 | * @param cipherOffset the offset in <code>cipherOffset</code> | ||
| 174 | * @param cipherLen the length of the input data | ||
| 175 | * @param plain the buffer for the result | ||
| 176 | * @param plainOffset the offset in <code>plain</code> | ||
| 177 | * | ||
| 178 | * @exception IllegalBlockSizeException if input data whose length does | ||
| 179 | * not correspond to the embedded cipher's block size is passed to the | ||
| 180 | * embedded cipher | ||
| 181 | */ | ||
| 182 | void decrypt(byte[] cipher, int cipherOffset, int cipherLen, | ||
| 183 | byte[] plain, int plainOffset) | ||
| 184 | { | ||
| 185 | int i; | ||
| 186 | byte[] cipherOrig=null; | ||
| 187 | int endIndex = cipherOffset + cipherLen; | ||
| 188 | |||
| 189 | if (cipher==plain && (cipherOffset >= plainOffset) | ||
| 190 | && ((cipherOffset - plainOffset) < blockSize)) { | ||
| 191 | // Save the original ciphertext blocks, so they can be | ||
| 192 | // stored in the feedback register "r". | ||
| 193 | // This is necessary because in this constellation, a | ||
| 194 | // ciphertext block (or parts of it) will be overridden by | ||
| 195 | // the plaintext result. | ||
| 196 | cipherOrig = (byte[])cipher.clone(); | ||
| 197 | } | ||
| 198 | |||
| 199 | for (; cipherOffset < endIndex; | ||
| 200 | cipherOffset += blockSize, plainOffset += blockSize) { | ||
| 201 | embeddedCipher.decryptBlock(cipher, cipherOffset, k, 0); | ||
| 202 | for (i = 0; i < blockSize; i++) { | ||
| 203 | plain[i+plainOffset] = (byte)(k[i] ^ r[i]); | ||
| 204 | } | ||
| 205 | if (cipherOrig==null) { | ||
| 206 | System.arraycopy(cipher, cipherOffset, r, 0, blockSize); | ||
| 207 | } else { | ||
| 208 | System.arraycopy(cipherOrig, cipherOffset, r, 0, blockSize); | ||
| 209 | } | ||
| 210 | } | ||
| 211 | } | ||
| 212 | } | ||
| @@ -0,0 +1,943 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.util.Locale; | ||
| 29 | |||
| 30 | import java.security.*; | ||
| 31 | import java.security.spec.*; | ||
| 32 | import javax.crypto.*; | ||
| 33 | import javax.crypto.spec.*; | ||
| 34 | import javax.crypto.BadPaddingException; | ||
| 35 | |||
| 36 | /** | ||
| 37 | * This class represents the symmetric algorithms in its various modes | ||
| 38 | * (<code>ECB</code>, <code>CFB</code>, <code>OFB</code>, <code>CBC</code>, | ||
| 39 | * <code>PCBC</code>, <code>CTR</code>, and <code>CTS</code>) and | ||
| 40 | * padding schemes (<code>PKCS5Padding</code>, <code>NoPadding</code>, | ||
| 41 | * <code>ISO10126Padding</code>). | ||
| 42 | * | ||
| 43 | * @author Gigi Ankeny | ||
| 44 | * @author Jan Luehe | ||
| 45 | * @see ElectronicCodeBook | ||
| 46 | * @see CipherFeedback | ||
| 47 | * @see OutputFeedback | ||
| 48 | * @see CipherBlockChaining | ||
| 49 | * @see PCBC | ||
| 50 | * @see CounterMode | ||
| 51 | * @see CipherTextStealing | ||
| 52 | */ | ||
| 53 | |||
| 54 | final class CipherCore { | ||
| 55 | |||
| 56 | /* | ||
| 57 | * internal buffer | ||
| 58 | */ | ||
| 59 | private byte[] buffer = null; | ||
| 60 | |||
| 61 | /* | ||
| 62 | * internal buffer | ||
| 63 | */ | ||
| 64 | private int blockSize = 0; | ||
| 65 | |||
| 66 | /* | ||
| 67 | * unit size (number of input bytes that can be processed at a time) | ||
| 68 | */ | ||
| 69 | private int unitBytes = 0; | ||
| 70 | |||
| 71 | /* | ||
| 72 | * index of the content size left in the buffer | ||
| 73 | */ | ||
| 74 | private int buffered = 0; | ||
| 75 | |||
| 76 | /* | ||
| 77 | * minimum number of bytes in the buffer required for | ||
| 78 | * FeedbackCipher.encryptFinal()/decryptFinal() call. | ||
| 79 | * update() must buffer this many bytes before before starting | ||
| 80 | * to encrypt/decrypt data. | ||
| 81 | * currently, only CTS mode has a non-zero value due to its special | ||
| 82 | * handling on the last two blocks (the last one may be incomplete). | ||
| 83 | */ | ||
| 84 | private int minBytes = 0; | ||
| 85 | |||
| 86 | /* | ||
| 87 | * number of bytes needed to make the total input length a multiple | ||
| 88 | * of the blocksize (this is used in feedback mode, when the number of | ||
| 89 | * input bytes that are processed at a time is different from the block | ||
| 90 | * size) | ||
| 91 | */ | ||
| 92 | private int diffBlocksize = 0; | ||
| 93 | |||
| 94 | /* | ||
| 95 | * padding class | ||
| 96 | */ | ||
| 97 | private Padding padding = null; | ||
| 98 | |||
| 99 | /* | ||
| 100 | * internal cipher engine | ||
| 101 | */ | ||
| 102 | private FeedbackCipher cipher = null; | ||
| 103 | |||
| 104 | /* | ||
| 105 | * the cipher mode | ||
| 106 | */ | ||
| 107 | private int cipherMode = ECB_MODE; | ||
| 108 | |||
| 109 | /* | ||
| 110 | * are we encrypting or decrypting? | ||
| 111 | */ | ||
| 112 | private boolean decrypting = false; | ||
| 113 | |||
| 114 | /* | ||
| 115 | * Block Mode constants | ||
| 116 | */ | ||
| 117 | private static final int ECB_MODE = 0; | ||
| 118 | private static final int CBC_MODE = 1; | ||
| 119 | private static final int CFB_MODE = 2; | ||
| 120 | private static final int OFB_MODE = 3; | ||
| 121 | private static final int PCBC_MODE = 4; | ||
| 122 | private static final int CTR_MODE = 5; | ||
| 123 | private static final int CTS_MODE = 6; | ||
| 124 | |||
| 125 | /** | ||
| 126 | * Creates an instance of CipherCore with default ECB mode and | ||
| 127 | * PKCS5Padding. | ||
| 128 | */ | ||
| 129 | CipherCore(SymmetricCipher impl, int blkSize) { | ||
| 130 | blockSize = blkSize; | ||
| 131 | unitBytes = blkSize; | ||
| 132 | diffBlocksize = blkSize; | ||
| 133 | |||
| 134 | /* | ||
| 135 | * The buffer should be usable for all cipher mode and padding | ||
| 136 | * schemes. Thus, it has to be at least (blockSize+1) for CTS. | ||
| 137 | * In decryption mode, it also hold the possible padding block. | ||
| 138 | */ | ||
| 139 | buffer = new byte[blockSize*2]; | ||
| 140 | |||
| 141 | // set mode and padding | ||
| 142 | cipher = new ElectronicCodeBook(impl); | ||
| 143 | padding = new PKCS5Padding(blockSize); | ||
| 144 | } | ||
| 145 | |||
| 146 | /** | ||
| 147 | * Sets the mode of this cipher. | ||
| 148 | * | ||
| 149 | * @param mode the cipher mode | ||
| 150 | * | ||
| 151 | * @exception NoSuchAlgorithmException if the requested cipher mode does | ||
| 152 | * not exist | ||
| 153 | */ | ||
| 154 | void setMode(String mode) throws NoSuchAlgorithmException { | ||
| 155 | if (mode == null) | ||
| 156 | throw new NoSuchAlgorithmException("null mode"); | ||
| 157 | |||
| 158 | String modeUpperCase = mode.toUpperCase(Locale.ENGLISH); | ||
| 159 | |||
| 160 | if (modeUpperCase.equals("ECB")) { | ||
| 161 | return; | ||
| 162 | } | ||
| 163 | |||
| 164 | SymmetricCipher rawImpl = cipher.getEmbeddedCipher(); | ||
| 165 | if (modeUpperCase.equals("CBC")) { | ||
| 166 | cipherMode = CBC_MODE; | ||
| 167 | cipher = new CipherBlockChaining(rawImpl); | ||
| 168 | } | ||
| 169 | else if (modeUpperCase.equals("CTS")) { | ||
| 170 | cipherMode = CTS_MODE; | ||
| 171 | cipher = new CipherTextStealing(rawImpl); | ||
| 172 | minBytes = blockSize+1; | ||
| 173 | padding = null; | ||
| 174 | } | ||
| 175 | else if (modeUpperCase.equals("CTR")) { | ||
| 176 | cipherMode = CTR_MODE; | ||
| 177 | cipher = new CounterMode(rawImpl); | ||
| 178 | unitBytes = 1; | ||
| 179 | padding = null; | ||
| 180 | } | ||
| 181 | else if (modeUpperCase.startsWith("CFB")) { | ||
| 182 | cipherMode = CFB_MODE; | ||
| 183 | unitBytes = getNumOfUnit(mode, "CFB".length(), blockSize); | ||
| 184 | cipher = new CipherFeedback(rawImpl, unitBytes); | ||
| 185 | } | ||
| 186 | else if (modeUpperCase.startsWith("OFB")) { | ||
| 187 | cipherMode = OFB_MODE; | ||
| 188 | unitBytes = getNumOfUnit(mode, "OFB".length(), blockSize); | ||
| 189 | cipher = new OutputFeedback(rawImpl, unitBytes); | ||
| 190 | } | ||
| 191 | else if (modeUpperCase.equals("PCBC")) { | ||
| 192 | cipherMode = PCBC_MODE; | ||
| 193 | cipher = new PCBC(rawImpl); | ||
| 194 | } | ||
| 195 | else { | ||
| 196 | throw new NoSuchAlgorithmException("Cipher mode: " + mode | ||
| 197 | + " not found"); | ||
| 198 | } | ||
| 199 | } | ||
| 200 | |||
| 201 | private static int getNumOfUnit(String mode, int offset, int blockSize) | ||
| 202 | throws NoSuchAlgorithmException { | ||
| 203 | int result = blockSize; // use blockSize as default value | ||
| 204 | if (mode.length() > offset) { | ||
| 205 | int numInt; | ||
| 206 | try { | ||
| 207 | Integer num = Integer.valueOf(mode.substring(offset)); | ||
| 208 | numInt = num.intValue(); | ||
| 209 | result = numInt >> 3; | ||
| 210 | } catch (NumberFormatException e) { | ||
| 211 | throw new NoSuchAlgorithmException | ||
| 212 | ("Algorithm mode: " + mode + " not implemented"); | ||
| 213 | } | ||
| 214 | if ((numInt % 8 != 0) || (result > blockSize)) { | ||
| 215 | throw new NoSuchAlgorithmException | ||
| 216 | ("Invalid algorithm mode: " + mode); | ||
| 217 | } | ||
| 218 | } | ||
| 219 | return result; | ||
| 220 | } | ||
| 221 | |||
| 222 | /** | ||
| 223 | * Sets the padding mechanism of this cipher. | ||
| 224 | * | ||
| 225 | * @param padding the padding mechanism | ||
| 226 | * | ||
| 227 | * @exception NoSuchPaddingException if the requested padding mechanism | ||
| 228 | * does not exist | ||
| 229 | */ | ||
| 230 | void setPadding(String paddingScheme) | ||
| 231 | throws NoSuchPaddingException | ||
| 232 | { | ||
| 233 | if (paddingScheme == null) { | ||
| 234 | throw new NoSuchPaddingException("null padding"); | ||
| 235 | } | ||
| 236 | if (paddingScheme.equalsIgnoreCase("NoPadding")) { | ||
| 237 | padding = null; | ||
| 238 | } else if (paddingScheme.equalsIgnoreCase("ISO10126Padding")) { | ||
| 239 | padding = new ISO10126Padding(blockSize); | ||
| 240 | } else if (!paddingScheme.equalsIgnoreCase("PKCS5Padding")) { | ||
| 241 | throw new NoSuchPaddingException("Padding: " + paddingScheme | ||
| 242 | + " not implemented"); | ||
| 243 | } | ||
| 244 | if ((padding != null) && | ||
| 245 | ((cipherMode == CTR_MODE) || (cipherMode == CTS_MODE))) { | ||
| 246 | padding = null; | ||
| 247 | throw new NoSuchPaddingException | ||
| 248 | ((cipherMode == CTR_MODE? "CTR":"CTS") + | ||
| 249 | " mode must be used with NoPadding"); | ||
| 250 | } | ||
| 251 | } | ||
| 252 | |||
| 253 | /** | ||
| 254 | * Returns the length in bytes that an output buffer would need to be in | ||
| 255 | * order to hold the result of the next <code>update</code> or | ||
| 256 | * <code>doFinal</code> operation, given the input length | ||
| 257 | * <code>inputLen</code> (in bytes). | ||
| 258 | * | ||
| 259 | * <p>This call takes into account any unprocessed (buffered) data from a | ||
| 260 | * previous <code>update</code> call, and padding. | ||
| 261 | * | ||
| 262 | * <p>The actual output length of the next <code>update</code> or | ||
| 263 | * <code>doFinal</code> call may be smaller than the length returned by | ||
| 264 | * this method. | ||
| 265 | * | ||
| 266 | * @param inputLen the input length (in bytes) | ||
| 267 | * | ||
| 268 | * @return the required output buffer size (in bytes) | ||
| 269 | */ | ||
| 270 | int getOutputSize(int inputLen) { | ||
| 271 | int totalLen = buffered + inputLen; | ||
| 272 | |||
| 273 | if (padding == null) | ||
| 274 | return totalLen; | ||
| 275 | |||
| 276 | if (decrypting) | ||
| 277 | return totalLen; | ||
| 278 | |||
| 279 | if (unitBytes != blockSize) { | ||
| 280 | if (totalLen < diffBlocksize) | ||
| 281 | return diffBlocksize; | ||
| 282 | else | ||
| 283 | return (totalLen + blockSize - | ||
| 284 | ((totalLen - diffBlocksize) % blockSize)); | ||
| 285 | } else { | ||
| 286 | return totalLen + padding.padLength(totalLen); | ||
| 287 | } | ||
| 288 | } | ||
| 289 | |||
| 290 | /** | ||
| 291 | * Returns the initialization vector (IV) in a new buffer. | ||
| 292 | * | ||
| 293 | * <p>This is useful in the case where a random IV has been created | ||
| 294 | * (see <a href = "#init">init</a>), | ||
| 295 | * or in the context of password-based encryption or | ||
| 296 | * decryption, where the IV is derived from a user-provided password. | ||
| 297 | * | ||
| 298 | * @return the initialization vector in a new buffer, or null if the | ||
| 299 | * underlying algorithm does not use an IV, or if the IV has not yet | ||
| 300 | * been set. | ||
| 301 | */ | ||
| 302 | byte[] getIV() { | ||
| 303 | byte[] iv = cipher.getIV(); | ||
| 304 | return (iv == null) ? null : (byte[])iv.clone(); | ||
| 305 | } | ||
| 306 | |||
| 307 | /** | ||
| 308 | * Returns the parameters used with this cipher. | ||
| 309 | * | ||
| 310 | * <p>The returned parameters may be the same that were used to initialize | ||
| 311 | * this cipher, or may contain the default set of parameters or a set of | ||
| 312 | * randomly generated parameters used by the underlying cipher | ||
| 313 | * implementation (provided that the underlying cipher implementation | ||
| 314 | * uses a default set of parameters or creates new parameters if it needs | ||
| 315 | * parameters but was not initialized with any). | ||
| 316 | * | ||
| 317 | * @return the parameters used with this cipher, or null if this cipher | ||
| 318 | * does not use any parameters. | ||
| 319 | */ | ||
| 320 | AlgorithmParameters getParameters(String algName) { | ||
| 321 | AlgorithmParameters params = null; | ||
| 322 | if (cipherMode == ECB_MODE) return null; | ||
| 323 | byte[] iv = getIV(); | ||
| 324 | if (iv != null) { | ||
| 325 | AlgorithmParameterSpec ivSpec; | ||
| 326 | if (algName.equals("RC2")) { | ||
| 327 | RC2Crypt rawImpl = (RC2Crypt) cipher.getEmbeddedCipher(); | ||
| 328 | ivSpec = new RC2ParameterSpec(rawImpl.getEffectiveKeyBits(), | ||
| 329 | iv); | ||
| 330 | } else { | ||
| 331 | ivSpec = new IvParameterSpec(iv); | ||
| 332 | } | ||
| 333 | try { | ||
| 334 | params = AlgorithmParameters.getInstance(algName, "SunJCE"); | ||
| 335 | } catch (NoSuchAlgorithmException nsae) { | ||
| 336 | // should never happen | ||
| 337 | throw new RuntimeException("Cannot find " + algName + | ||
| 338 | " AlgorithmParameters implementation in SunJCE provider"); | ||
| 339 | } catch (NoSuchProviderException nspe) { | ||
| 340 | // should never happen | ||
| 341 | throw new RuntimeException("Cannot find SunJCE provider"); | ||
| 342 | } | ||
| 343 | try { | ||
| 344 | params.init(ivSpec); | ||
| 345 | } catch (InvalidParameterSpecException ipse) { | ||
| 346 | // should never happen | ||
| 347 | throw new RuntimeException("IvParameterSpec not supported"); | ||
| 348 | } | ||
| 349 | } | ||
| 350 | return params; | ||
| 351 | } | ||
| 352 | |||
| 353 | /** | ||
| 354 | * Initializes this cipher with a key and a source of randomness. | ||
| 355 | * | ||
| 356 | * <p>The cipher is initialized for one of the following four operations: | ||
| 357 | * encryption, decryption, key wrapping or key unwrapping, depending on | ||
| 358 | * the value of <code>opmode</code>. | ||
| 359 | * | ||
| 360 | * <p>If this cipher requires an initialization vector (IV), it will get | ||
| 361 | * it from <code>random</code>. | ||
| 362 | * This behaviour should only be used in encryption or key wrapping | ||
| 363 | * mode, however. | ||
| 364 | * When initializing a cipher that requires an IV for decryption or | ||
| 365 | * key unwrapping, the IV | ||
| 366 | * (same IV that was used for encryption or key wrapping) must be provided | ||
| 367 | * explicitly as a | ||
| 368 | * parameter, in order to get the correct result. | ||
| 369 | * | ||
| 370 | * <p>This method also cleans existing buffer and other related state | ||
| 371 | * information. | ||
| 372 | * | ||
| 373 | * @param opmode the operation mode of this cipher (this is one of | ||
| 374 | * the following: | ||
| 375 | * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, | ||
| 376 | * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) | ||
| 377 | * @param key the secret key | ||
| 378 | * @param random the source of randomness | ||
| 379 | * | ||
| 380 | * @exception InvalidKeyException if the given key is inappropriate for | ||
| 381 | * initializing this cipher | ||
| 382 | */ | ||
| 383 | void init(int opmode, Key key, SecureRandom random) | ||
| 384 | throws InvalidKeyException { | ||
| 385 | try { | ||
| 386 | init(opmode, key, (AlgorithmParameterSpec)null, random); | ||
| 387 | } catch (InvalidAlgorithmParameterException e) { | ||
| 388 | throw new InvalidKeyException(e.getMessage()); | ||
| 389 | } | ||
| 390 | } | ||
| 391 | |||
| 392 | /** | ||
| 393 | * Initializes this cipher with a key, a set of | ||
| 394 | * algorithm parameters, and a source of randomness. | ||
| 395 | * | ||
| 396 | * <p>The cipher is initialized for one of the following four operations: | ||
| 397 | * encryption, decryption, key wrapping or key unwrapping, depending on | ||
| 398 | * the value of <code>opmode</code>. | ||
| 399 | * | ||
| 400 | * <p>If this cipher (including its underlying feedback or padding scheme) | ||
| 401 | * requires any random bytes, it will get them from <code>random</code>. | ||
| 402 | * | ||
| 403 | * @param opmode the operation mode of this cipher (this is one of | ||
| 404 | * the following: | ||
| 405 | * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, | ||
| 406 | * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) | ||
| 407 | * @param key the encryption key | ||
| 408 | * @param params the algorithm parameters | ||
| 409 | * @param random the source of randomness | ||
| 410 | * | ||
| 411 | * @exception InvalidKeyException if the given key is inappropriate for | ||
| 412 | * initializing this cipher | ||
| 413 | * @exception InvalidAlgorithmParameterException if the given algorithm | ||
| 414 | * parameters are inappropriate for this cipher | ||
| 415 | */ | ||
| 416 | void init(int opmode, Key key, AlgorithmParameterSpec params, | ||
| 417 | SecureRandom random) | ||
| 418 | throws InvalidKeyException, InvalidAlgorithmParameterException { | ||
| 419 | decrypting = (opmode == Cipher.DECRYPT_MODE) | ||
| 420 | || (opmode == Cipher.UNWRAP_MODE); | ||
| 421 | |||
| 422 | byte[] keyBytes = getKeyBytes(key); | ||
| 423 | |||
| 424 | byte[] ivBytes; | ||
| 425 | if (params == null) { | ||
| 426 | ivBytes = null; | ||
| 427 | } else if (params instanceof IvParameterSpec) { | ||
| 428 | ivBytes = ((IvParameterSpec)params).getIV(); | ||
| 429 | if ((ivBytes == null) || (ivBytes.length != blockSize)) { | ||
| 430 | throw new InvalidAlgorithmParameterException | ||
| 431 | ("Wrong IV length: must be " + blockSize + | ||
| 432 | " bytes long"); | ||
| 433 | } | ||
| 434 | } else if (params instanceof RC2ParameterSpec) { | ||
| 435 | ivBytes = ((RC2ParameterSpec)params).getIV(); | ||
| 436 | if ((ivBytes != null) && (ivBytes.length != blockSize)) { | ||
| 437 | throw new InvalidAlgorithmParameterException | ||
| 438 | ("Wrong IV length: must be " + blockSize + | ||
| 439 | " bytes long"); | ||
| 440 | } | ||
| 441 | } else { | ||
| 442 | throw new InvalidAlgorithmParameterException("Wrong parameter " | ||
| 443 | + "type: IV " | ||
| 444 | + "expected"); | ||
| 445 | } | ||
| 446 | |||
| 447 | if (cipherMode == ECB_MODE) { | ||
| 448 | if (ivBytes != null) { | ||
| 449 | throw new InvalidAlgorithmParameterException | ||
| 450 | ("ECB mode cannot use IV"); | ||
| 451 | } | ||
| 452 | } else if (ivBytes == null) { | ||
| 453 | if (decrypting) { | ||
| 454 | throw new InvalidAlgorithmParameterException("Parameters " | ||
| 455 | + "missing"); | ||
| 456 | } | ||
| 457 | if (random == null) { | ||
| 458 | random = SunJCE.RANDOM; | ||
| 459 | } | ||
| 460 | ivBytes = new byte[blockSize]; | ||
| 461 | random.nextBytes(ivBytes); | ||
| 462 | } | ||
| 463 | |||
| 464 | buffered = 0; | ||
| 465 | diffBlocksize = blockSize; | ||
| 466 | |||
| 467 | String algorithm = key.getAlgorithm(); | ||
| 468 | |||
| 469 | cipher.init(decrypting, algorithm, keyBytes, ivBytes); | ||
| 470 | } | ||
| 471 | |||
| 472 | void init(int opmode, Key key, AlgorithmParameters params, | ||
| 473 | SecureRandom random) | ||
| 474 | throws InvalidKeyException, InvalidAlgorithmParameterException { | ||
| 475 | IvParameterSpec ivSpec = null; | ||
| 476 | if (params != null) { | ||
| 477 | try { | ||
| 478 | ivSpec = (IvParameterSpec)params.getParameterSpec | ||
| 479 | (IvParameterSpec.class); | ||
| 480 | } catch (InvalidParameterSpecException ipse) { | ||
| 481 | throw new InvalidAlgorithmParameterException("Wrong parameter " | ||
| 482 | + "type: IV " | ||
| 483 | + "expected"); | ||
| 484 | } | ||
| 485 | } | ||
| 486 | init(opmode, key, ivSpec, random); | ||
| 487 | } | ||
| 488 | |||
| 489 | /** | ||
| 490 | * Return the key bytes of the specified key. Throw an InvalidKeyException | ||
| 491 | * if the key is not usable. | ||
| 492 | */ | ||
| 493 | static byte[] getKeyBytes(Key key) throws InvalidKeyException { | ||
| 494 | if (key == null) { | ||
| 495 | throw new InvalidKeyException("No key given"); | ||
| 496 | } | ||
| 497 | // note: key.getFormat() may return null | ||
| 498 | if (!"RAW".equalsIgnoreCase(key.getFormat())) { | ||
| 499 | throw new InvalidKeyException("Wrong format: RAW bytes needed"); | ||
| 500 | } | ||
| 501 | byte[] keyBytes = key.getEncoded(); | ||
| 502 | if (keyBytes == null) { | ||
| 503 | throw new InvalidKeyException("RAW key bytes missing"); | ||
| 504 | } | ||
| 505 | return keyBytes; | ||
| 506 | } | ||
| 507 | |||
| 508 | /** | ||
| 509 | * Continues a multiple-part encryption or decryption operation | ||
| 510 | * (depending on how this cipher was initialized), processing another data | ||
| 511 | * part. | ||
| 512 | * | ||
| 513 | * <p>The first <code>inputLen</code> bytes in the <code>input</code> | ||
| 514 | * buffer, starting at <code>inputOffset</code>, are processed, and the | ||
| 515 | * result is stored in a new buffer. | ||
| 516 | * | ||
| 517 | * @param input the input buffer | ||
| 518 | * @param inputOffset the offset in <code>input</code> where the input | ||
| 519 | * starts | ||
| 520 | * @param inputLen the input length | ||
| 521 | * | ||
| 522 | * @return the new buffer with the result | ||
| 523 | * | ||
| 524 | * @exception IllegalStateException if this cipher is in a wrong state | ||
| 525 | * (e.g., has not been initialized) | ||
| 526 | */ | ||
| 527 | byte[] update(byte[] input, int inputOffset, int inputLen) { | ||
| 528 | byte[] output = null; | ||
| 529 | byte[] out = null; | ||
| 530 | try { | ||
| 531 | output = new byte[getOutputSize(inputLen)]; | ||
| 532 | int len = update(input, inputOffset, inputLen, output, | ||
| 533 | 0); | ||
| 534 | if (len == output.length) { | ||
| 535 | out = output; | ||
| 536 | } else { | ||
| 537 | out = new byte[len]; | ||
| 538 | System.arraycopy(output, 0, out, 0, len); | ||
| 539 | } | ||
| 540 | } catch (ShortBufferException e) { | ||
| 541 | // never thrown | ||
| 542 | } | ||
| 543 | return out; | ||
| 544 | } | ||
| 545 | |||
| 546 | /** | ||
| 547 | * Continues a multiple-part encryption or decryption operation | ||
| 548 | * (depending on how this cipher was initialized), processing another data | ||
| 549 | * part. | ||
| 550 | * | ||
| 551 | * <p>The first <code>inputLen</code> bytes in the <code>input</code> | ||
| 552 | * buffer, starting at <code>inputOffset</code>, are processed, and the | ||
| 553 | * result is stored in the <code>output</code> buffer, starting at | ||
| 554 | * <code>outputOffset</code>. | ||
| 555 | * | ||
| 556 | * @param input the input buffer | ||
| 557 | * @param inputOffset the offset in <code>input</code> where the input | ||
| 558 | * starts | ||
| 559 | * @param inputLen the input length | ||
| 560 | * @param output the buffer for the result | ||
| 561 | * @param outputOffset the offset in <code>output</code> where the result | ||
| 562 | * is stored | ||
| 563 | * | ||
| 564 | * @return the number of bytes stored in <code>output</code> | ||
| 565 | * | ||
| 566 | * @exception ShortBufferException if the given output buffer is too small | ||
| 567 | * to hold the result | ||
| 568 | */ | ||
| 569 | int update(byte[] input, int inputOffset, int inputLen, byte[] output, | ||
| 570 | int outputOffset) throws ShortBufferException { | ||
| 571 | // figure out how much can be sent to crypto function | ||
| 572 | int len = buffered + inputLen - minBytes; | ||
| 573 | if (padding != null && decrypting) { | ||
| 574 | // do not include the padding bytes when decrypting | ||
| 575 | len -= blockSize; | ||
| 576 | } | ||
| 577 | // do not count the trailing bytes which do not make up a unit | ||
| 578 | len = (len > 0 ? (len - (len%unitBytes)) : 0); | ||
| 579 | |||
| 580 | // check output buffer capacity | ||
| 581 | if ((output == null) || ((output.length - outputOffset) < len)) { | ||
| 582 | throw new ShortBufferException("Output buffer must be " | ||
| 583 | + "(at least) " + len | ||
| 584 | + " bytes long"); | ||
| 585 | } | ||
| 586 | if (len != 0) { | ||
| 587 | // there is some work to do | ||
| 588 | byte[] in = new byte[len]; | ||
| 589 | |||
| 590 | int inputConsumed = len - buffered; | ||
| 591 | int bufferedConsumed = buffered; | ||
| 592 | if (inputConsumed < 0) { | ||
| 593 | inputConsumed = 0; | ||
| 594 | bufferedConsumed = len; | ||
| 595 | } | ||
| 596 | |||
| 597 | if (buffered != 0) { | ||
| 598 | System.arraycopy(buffer, 0, in, 0, bufferedConsumed); | ||
| 599 | } | ||
| 600 | if (inputConsumed > 0) { | ||
| 601 | System.arraycopy(input, inputOffset, in, | ||
| 602 | bufferedConsumed, inputConsumed); | ||
| 603 | } | ||
| 604 | |||
| 605 | if (decrypting) { | ||
| 606 | cipher.decrypt(in, 0, len, output, outputOffset); | ||
| 607 | } else { | ||
| 608 | cipher.encrypt(in, 0, len, output, outputOffset); | ||
| 609 | } | ||
| 610 | |||
| 611 | // Let's keep track of how many bytes are needed to make | ||
| 612 | // the total input length a multiple of blocksize when | ||
| 613 | // padding is applied | ||
| 614 | if (unitBytes != blockSize) { | ||
| 615 | if (len < diffBlocksize) | ||
| 616 | diffBlocksize -= len; | ||
| 617 | else | ||
| 618 | diffBlocksize = blockSize - | ||
| 619 | ((len - diffBlocksize) % blockSize); | ||
| 620 | } | ||
| 621 | |||
| 622 | inputLen -= inputConsumed; | ||
| 623 | inputOffset += inputConsumed; | ||
| 624 | outputOffset += len; | ||
| 625 | buffered -= bufferedConsumed; | ||
| 626 | if (buffered > 0) { | ||
| 627 | System.arraycopy(buffer, bufferedConsumed, buffer, 0, | ||
| 628 | buffered); | ||
| 629 | } | ||
| 630 | } | ||
| 631 | // left over again | ||
| 632 | if (inputLen > 0) { | ||
| 633 | System.arraycopy(input, inputOffset, buffer, buffered, | ||
| 634 | inputLen); | ||
| 635 | } | ||
| 636 | buffered += inputLen; | ||
| 637 | return len; | ||
| 638 | } | ||
| 639 | |||
| 640 | /** | ||
| 641 | * Encrypts or decrypts data in a single-part operation, | ||
| 642 | * or finishes a multiple-part operation. | ||
| 643 | * The data is encrypted or decrypted, depending on how this cipher was | ||
| 644 | * initialized. | ||
| 645 | * | ||
| 646 | * <p>The first <code>inputLen</code> bytes in the <code>input</code> | ||
| 647 | * buffer, starting at <code>inputOffset</code>, and any input bytes that | ||
| 648 | * may have been buffered during a previous <code>update</code> operation, | ||
| 649 | * are processed, with padding (if requested) being applied. | ||
| 650 | * The result is stored in a new buffer. | ||
| 651 | * | ||
| 652 | * <p>The cipher is reset to its initial state (uninitialized) after this | ||
| 653 | * call. | ||
| 654 | * | ||
| 655 | * @param input the input buffer | ||
| 656 | * @param inputOffset the offset in <code>input</code> where the input | ||
| 657 | * starts | ||
| 658 | * @param inputLen the input length | ||
| 659 | * | ||
| 660 | * @return the new buffer with the result | ||
| 661 | * | ||
| 662 | * @exception IllegalBlockSizeException if this cipher is a block cipher, | ||
| 663 | * no padding has been requested (only in encryption mode), and the total | ||
| 664 | * input length of the data processed by this cipher is not a multiple of | ||
| 665 | * block size | ||
| 666 | * @exception BadPaddingException if this cipher is in decryption mode, | ||
| 667 | * and (un)padding has been requested, but the decrypted data is not | ||
| 668 | * bounded by the appropriate padding bytes | ||
| 669 | */ | ||
| 670 | byte[] doFinal(byte[] input, int inputOffset, int inputLen) | ||
| 671 | throws IllegalBlockSizeException, BadPaddingException { | ||
| 672 | byte[] output = null; | ||
| 673 | byte[] out = null; | ||
| 674 | try { | ||
| 675 | output = new byte[getOutputSize(inputLen)]; | ||
| 676 | int len = doFinal(input, inputOffset, inputLen, output, 0); | ||
| 677 | if (len < output.length) { | ||
| 678 | out = new byte[len]; | ||
| 679 | if (len != 0) | ||
| 680 | System.arraycopy(output, 0, out, 0, len); | ||
| 681 | } else { | ||
| 682 | out = output; | ||
| 683 | } | ||
| 684 | } catch (ShortBufferException e) { | ||
| 685 | // never thrown | ||
| 686 | } | ||
| 687 | return out; | ||
| 688 | } | ||
| 689 | |||
| 690 | /** | ||
| 691 | * Encrypts or decrypts data in a single-part operation, | ||
| 692 | * or finishes a multiple-part operation. | ||
| 693 | * The data is encrypted or decrypted, depending on how this cipher was | ||
| 694 | * initialized. | ||
| 695 | * | ||
| 696 | * <p>The first <code>inputLen</code> bytes in the <code>input</code> | ||
| 697 | * buffer, starting at <code>inputOffset</code>, and any input bytes that | ||
| 698 | * may have been buffered during a previous <code>update</code> operation, | ||
| 699 | * are processed, with padding (if requested) being applied. | ||
| 700 | * The result is stored in the <code>output</code> buffer, starting at | ||
| 701 | * <code>outputOffset</code>. | ||
| 702 | * | ||
| 703 | * <p>The cipher is reset to its initial state (uninitialized) after this | ||
| 704 | * call. | ||
| 705 | * | ||
| 706 | * @param input the input buffer | ||
| 707 | * @param inputOffset the offset in <code>input</code> where the input | ||
| 708 | * starts | ||
| 709 | * @param inputLen the input length | ||
| 710 | * @param output the buffer for the result | ||
| 711 | * @param outputOffset the offset in <code>output</code> where the result | ||
| 712 | * is stored | ||
| 713 | * | ||
| 714 | * @return the number of bytes stored in <code>output</code> | ||
| 715 | * | ||
| 716 | * @exception IllegalBlockSizeException if this cipher is a block cipher, | ||
| 717 | * no padding has been requested (only in encryption mode), and the total | ||
| 718 | * input length of the data processed by this cipher is not a multiple of | ||
| 719 | * block size | ||
| 720 | * @exception ShortBufferException if the given output buffer is too small | ||
| 721 | * to hold the result | ||
| 722 | * @exception BadPaddingException if this cipher is in decryption mode, | ||
| 723 | * and (un)padding has been requested, but the decrypted data is not | ||
| 724 | * bounded by the appropriate padding bytes | ||
| 725 | */ | ||
| 726 | int doFinal(byte[] input, int inputOffset, int inputLen, byte[] output, | ||
| 727 | int outputOffset) | ||
| 728 | throws IllegalBlockSizeException, ShortBufferException, | ||
| 729 | BadPaddingException { | ||
| 730 | |||
| 731 | // calculate the total input length | ||
| 732 | int totalLen = buffered + inputLen; | ||
| 733 | int paddedLen = totalLen; | ||
| 734 | int paddingLen = 0; | ||
| 735 | |||
| 736 | // will the total input length be a multiple of blockSize? | ||
| 737 | if (unitBytes != blockSize) { | ||
| 738 | if (totalLen < diffBlocksize) { | ||
| 739 | paddingLen = diffBlocksize - totalLen; | ||
| 740 | } else { | ||
| 741 | paddingLen = blockSize - | ||
| 742 | ((totalLen - diffBlocksize) % blockSize); | ||
| 743 | } | ||
| 744 | } else if (padding != null) { | ||
| 745 | paddingLen = padding.padLength(totalLen); | ||
| 746 | } | ||
| 747 | |||
| 748 | if ((paddingLen > 0) && (paddingLen != blockSize) && | ||
| 749 | (padding != null) && decrypting) { | ||
| 750 | throw new IllegalBlockSizeException | ||
| 751 | ("Input length must be multiple of " + blockSize + | ||
| 752 | " when decrypting with padded cipher"); | ||
| 753 | } | ||
| 754 | |||
| 755 | // if encrypting and padding not null, add padding | ||
| 756 | if (!decrypting && padding != null) | ||
| 757 | paddedLen += paddingLen; | ||
| 758 | |||
| 759 | // check output buffer capacity. | ||
| 760 | // if we are decrypting with padding applied, we can perform this | ||
| 761 | // check only after we have determined how many padding bytes there | ||
| 762 | // are. | ||
| 763 | if (output == null) { | ||
| 764 | throw new ShortBufferException("Output buffer is null"); | ||
| 765 | } | ||
| 766 | int outputCapacity = output.length - outputOffset; | ||
| 767 | if (((!decrypting) || (padding == null)) && | ||
| 768 | (outputCapacity < paddedLen) || | ||
| 769 | (decrypting && (outputCapacity < (paddedLen - blockSize)))) { | ||
| 770 | throw new ShortBufferException("Output buffer too short: " | ||
| 771 | + outputCapacity + " bytes given, " | ||
| 772 | + paddedLen + " bytes needed"); | ||
| 773 | } | ||
| 774 | |||
| 775 | // prepare the final input avoiding copying if possible | ||
| 776 | byte[] finalBuf = input; | ||
| 777 | int finalOffset = inputOffset; | ||
| 778 | if ((buffered != 0) || (!decrypting && padding != null)) { | ||
| 779 | finalOffset = 0; | ||
| 780 | finalBuf = new byte[paddedLen]; | ||
| 781 | if (buffered != 0) { | ||
| 782 | System.arraycopy(buffer, 0, finalBuf, 0, buffered); | ||
| 783 | } | ||
| 784 | if (inputLen != 0) { | ||
| 785 | System.arraycopy(input, inputOffset, finalBuf, | ||
| 786 | buffered, inputLen); | ||
| 787 | } | ||
| 788 | if (!decrypting && padding != null) { | ||
| 789 | padding.padWithLen(finalBuf, totalLen, paddingLen); | ||
| 790 | } | ||
| 791 | } | ||
| 792 | |||
| 793 | if (decrypting) { | ||
| 794 | // if the size of specified output buffer is less than | ||
| 795 | // the length of the cipher text, then the current | ||
| 796 | // content of cipher has to be preserved in order for | ||
| 797 | // users to retry the call with a larger buffer in the | ||
| 798 | // case of ShortBufferException. | ||
| 799 | if (outputCapacity < paddedLen) { | ||
| 800 | cipher.save(); | ||
| 801 | } | ||
| 802 | // create temporary output buffer so that only "real" | ||
| 803 | // data bytes are passed to user's output buffer. | ||
| 804 | byte[] outWithPadding = new byte[totalLen]; | ||
| 805 | totalLen = finalNoPadding(finalBuf, finalOffset, outWithPadding, | ||
| 806 | 0, totalLen); | ||
| 807 | |||
| 808 | if (padding != null) { | ||
| 809 | int padStart = padding.unpad(outWithPadding, 0, totalLen); | ||
| 810 | if (padStart < 0) { | ||
| 811 | throw new BadPaddingException("Given final block not " | ||
| 812 | + "properly padded"); | ||
| 813 | } | ||
| 814 | totalLen = padStart; | ||
| 815 | } | ||
| 816 | if ((output.length - outputOffset) < totalLen) { | ||
| 817 | // restore so users can retry with a larger buffer | ||
| 818 | cipher.restore(); | ||
| 819 | throw new ShortBufferException("Output buffer too short: " | ||
| 820 | + (output.length-outputOffset) | ||
| 821 | + " bytes given, " + totalLen | ||
| 822 | + " bytes needed"); | ||
| 823 | } | ||
| 824 | for (int i = 0; i < totalLen; i++) { | ||
| 825 | output[outputOffset + i] = outWithPadding[i]; | ||
| 826 | } | ||
| 827 | } else { // encrypting | ||
| 828 | totalLen = finalNoPadding(finalBuf, finalOffset, output, | ||
| 829 | outputOffset, paddedLen); | ||
| 830 | } | ||
| 831 | |||
| 832 | buffered = 0; | ||
| 833 | diffBlocksize = blockSize; | ||
| 834 | if (cipherMode != ECB_MODE) { | ||
| 835 | ((FeedbackCipher)cipher).reset(); | ||
| 836 | } | ||
| 837 | return totalLen; | ||
| 838 | } | ||
| 839 | |||
| 840 | private int finalNoPadding(byte[] in, int inOff, byte[] out, int outOff, | ||
| 841 | int len) | ||
| 842 | throws IllegalBlockSizeException | ||
| 843 | { | ||
| 844 | if (in == null || len == 0) | ||
| 845 | return 0; | ||
| 846 | |||
| 847 | if ((cipherMode != CFB_MODE) && (cipherMode != OFB_MODE) | ||
| 848 | && ((len % unitBytes) != 0) && (cipherMode != CTS_MODE)) { | ||
| 849 | if (padding != null) { | ||
| 850 | throw new IllegalBlockSizeException | ||
| 851 | ("Input length (with padding) not multiple of " + | ||
| 852 | unitBytes + " bytes"); | ||
| 853 | } else { | ||
| 854 | throw new IllegalBlockSizeException | ||
| 855 | ("Input length not multiple of " + unitBytes | ||
| 856 | + " bytes"); | ||
| 857 | } | ||
| 858 | } | ||
| 859 | |||
| 860 | if (decrypting) { | ||
| 861 | cipher.decryptFinal(in, inOff, len, out, outOff); | ||
| 862 | } else { | ||
| 863 | cipher.encryptFinal(in, inOff, len, out, outOff); | ||
| 864 | } | ||
| 865 | |||
| 866 | return len; | ||
| 867 | } | ||
| 868 | |||
| 869 | // Note: Wrap() and Unwrap() are the same in | ||
| 870 | // each of SunJCE CipherSpi implementation classes. | ||
| 871 | // They are duplicated due to export control requirements: | ||
| 872 | // All CipherSpi implementation must be final. | ||
| 873 | /** | ||
| 874 | * Wrap a key. | ||
| 875 | * | ||
| 876 | * @param key the key to be wrapped. | ||
| 877 | * | ||
| 878 | * @return the wrapped key. | ||
| 879 | * | ||
| 880 | * @exception IllegalBlockSizeException if this cipher is a block | ||
| 881 | * cipher, no padding has been requested, and the length of the | ||
| 882 | * encoding of the key to be wrapped is not a | ||
| 883 | * multiple of the block size. | ||
| 884 | * | ||
| 885 | * @exception InvalidKeyException if it is impossible or unsafe to | ||
| 886 | * wrap the key with this cipher (e.g., a hardware protected key is | ||
| 887 | * being passed to a software only cipher). | ||
| 888 | */ | ||
| 889 | byte[] wrap(Key key) | ||
| 890 | throws IllegalBlockSizeException, InvalidKeyException { | ||
| 891 | byte[] result = null; | ||
| 892 | |||
| 893 | try { | ||
| 894 | byte[] encodedKey = key.getEncoded(); | ||
| 895 | if ((encodedKey == null) || (encodedKey.length == 0)) { | ||
| 896 | throw new InvalidKeyException("Cannot get an encoding of " + | ||
| 897 | "the key to be wrapped"); | ||
| 898 | } | ||
| 899 | result = doFinal(encodedKey, 0, encodedKey.length); | ||
| 900 | } catch (BadPaddingException e) { | ||
| 901 | // Should never happen | ||
| 902 | } | ||
| 903 | return result; | ||
| 904 | } | ||
| 905 | |||
| 906 | /** | ||
| 907 | * Unwrap a previously wrapped key. | ||
| 908 | * | ||
| 909 | * @param wrappedKey the key to be unwrapped. | ||
| 910 | * | ||
| 911 | * @param wrappedKeyAlgorithm the algorithm the wrapped key is for. | ||
| 912 | * | ||
| 913 | * @param wrappedKeyType the type of the wrapped key. | ||
| 914 | * This is one of <code>Cipher.SECRET_KEY</code>, | ||
| 915 | * <code>Cipher.PRIVATE_KEY</code>, or <code>Cipher.PUBLIC_KEY</code>. | ||
| 916 | * | ||
| 917 | * @return the unwrapped key. | ||
| 918 | * | ||
| 919 | * @exception NoSuchAlgorithmException if no installed providers | ||
| 920 | * can create keys of type <code>wrappedKeyType</code> for the | ||
| 921 | * <code>wrappedKeyAlgorithm</code>. | ||
| 922 | * | ||
| 923 | * @exception InvalidKeyException if <code>wrappedKey</code> does not | ||
| 924 | * represent a wrapped key of type <code>wrappedKeyType</code> for | ||
| 925 | * the <code>wrappedKeyAlgorithm</code>. | ||
| 926 | */ | ||
| 927 | Key unwrap(byte[] wrappedKey, String wrappedKeyAlgorithm, | ||
| 928 | int wrappedKeyType) | ||
| 929 | throws InvalidKeyException, NoSuchAlgorithmException { | ||
| 930 | byte[] encodedKey; | ||
| 931 | try { | ||
| 932 | encodedKey = doFinal(wrappedKey, 0, wrappedKey.length); | ||
| 933 | } catch (BadPaddingException ePadding) { | ||
| 934 | throw new InvalidKeyException("The wrapped key is not padded " + | ||
| 935 | "correctly"); | ||
| 936 | } catch (IllegalBlockSizeException eBlockSize) { | ||
| 937 | throw new InvalidKeyException("The wrapped key does not have " + | ||
| 938 | "the correct length"); | ||
| 939 | } | ||
| 940 | return ConstructKeys.constructKey(encodedKey, wrappedKeyAlgorithm, | ||
| 941 | wrappedKeyType); | ||
| 942 | } | ||
| 943 | } | ||
| @@ -0,0 +1,272 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.security.InvalidKeyException; | ||
| 29 | |||
| 30 | /** | ||
| 31 | * This class represents ciphers in cipher-feedback (CFB) mode. | ||
| 32 | * | ||
| 33 | * <p>This mode is implemented independently of a particular cipher. | ||
| 34 | * Ciphers to which this mode should apply (e.g., DES) must be | ||
| 35 | * <i>plugged-in</i> using the constructor. | ||
| 36 | * | ||
| 37 | * <p>NOTE: This class does not deal with buffering or padding. | ||
| 38 | * | ||
| 39 | * @author Gigi Ankeny | ||
| 40 | */ | ||
| 41 | |||
| 42 | final class CipherFeedback extends FeedbackCipher { | ||
| 43 | |||
| 44 | /* | ||
| 45 | * encrypt/decrypt output buffer | ||
| 46 | */ | ||
| 47 | private final byte[] k; | ||
| 48 | |||
| 49 | /* | ||
| 50 | * register value, initialized with iv | ||
| 51 | */ | ||
| 52 | private final byte[] register; | ||
| 53 | |||
| 54 | /* | ||
| 55 | * number of bytes for each stream unit, defaults to the blocksize | ||
| 56 | * of the embedded cipher | ||
| 57 | */ | ||
| 58 | private int numBytes; | ||
| 59 | |||
| 60 | // variables for save/restore calls | ||
| 61 | private byte[] registerSave = null; | ||
| 62 | |||
| 63 | CipherFeedback(SymmetricCipher embeddedCipher, int numBytes) { | ||
| 64 | super(embeddedCipher); | ||
| 65 | if (numBytes > blockSize) { | ||
| 66 | numBytes = blockSize; | ||
| 67 | } | ||
| 68 | this.numBytes = numBytes; | ||
| 69 | k = new byte[blockSize]; | ||
| 70 | register = new byte[blockSize]; | ||
| 71 | } | ||
| 72 | |||
| 73 | /** | ||
| 74 | * Gets the name of this feedback mode. | ||
| 75 | * | ||
| 76 | * @return the string <code>CFB</code> | ||
| 77 | */ | ||
| 78 | String getFeedback() { | ||
| 79 | return "CFB"; | ||
| 80 | } | ||
| 81 | |||
| 82 | /** | ||
| 83 | * Initializes the cipher in the specified mode with the given key | ||
| 84 | * and iv. | ||
| 85 | * | ||
| 86 | * @param decrypting flag indicating encryption or decryption | ||
| 87 | * @param algorithm the algorithm name | ||
| 88 | * @param key the key | ||
| 89 | * @param iv the iv | ||
| 90 | * | ||
| 91 | * @exception InvalidKeyException if the given key is inappropriate for | ||
| 92 | * initializing this cipher | ||
| 93 | */ | ||
| 94 | void init(boolean decrypting, String algorithm, byte[] key, byte[] iv) | ||
| 95 | throws InvalidKeyException { | ||
| 96 | if ((key == null) || (iv == null) || (iv.length != blockSize)) { | ||
| 97 | throw new InvalidKeyException("Internal error"); | ||
| 98 | } | ||
| 99 | this.iv = iv; | ||
| 100 | reset(); | ||
| 101 | // always encrypt mode for embedded cipher | ||
| 102 | embeddedCipher.init(false, algorithm, key); | ||
| 103 | } | ||
| 104 | |||
| 105 | /** | ||
| 106 | * Resets the iv to its original value. | ||
| 107 | * This is used when doFinal is called in the Cipher class, so that the | ||
| 108 | * cipher can be reused (with its original iv). | ||
| 109 | */ | ||
| 110 | void reset() { | ||
| 111 | System.arraycopy(iv, 0, register, 0, blockSize); | ||
| 112 | } | ||
| 113 | |||
| 114 | /** | ||
| 115 | * Save the current content of this cipher. | ||
| 116 | */ | ||
| 117 | void save() { | ||
| 118 | if (registerSave == null) { | ||
| 119 | registerSave = new byte[blockSize]; | ||
| 120 | } | ||
| 121 | System.arraycopy(register, 0, registerSave, 0, blockSize); | ||
| 122 | } | ||
| 123 | |||
| 124 | /** | ||
| 125 | * Restores the content of this cipher to the previous saved one. | ||
| 126 | */ | ||
| 127 | void restore() { | ||
| 128 | System.arraycopy(registerSave, 0, register, 0, blockSize); | ||
| 129 | } | ||
| 130 | |||
| 131 | /** | ||
| 132 | * Performs encryption operation. | ||
| 133 | * | ||
| 134 | * <p>The input plain text <code>plain</code>, starting at | ||
| 135 | * <code>plainOffset</code> and ending at | ||
| 136 | * <code>(plainOffset + len - 1)</code>, is encrypted. | ||
| 137 | * The result is stored in <code>cipher</code>, starting at | ||
| 138 | * <code>cipherOffset</code>. | ||
| 139 | * | ||
| 140 | * <p>It is the application's responsibility to make sure that | ||
| 141 | * <code>plainLen</code> is a multiple of the stream unit size | ||
| 142 | * <code>numBytes</code>, as any excess bytes are ignored. | ||
| 143 | * | ||
| 144 | * <p>It is also the application's responsibility to make sure that | ||
| 145 | * <code>init</code> has been called before this method is called. | ||
| 146 | * (This check is omitted here, to avoid double checking.) | ||
| 147 | * | ||
| 148 | * @param plain the buffer with the input data to be encrypted | ||
| 149 | * @param plainOffset the offset in <code>plain</code> | ||
| 150 | * @param plainLen the length of the input data | ||
| 151 | * @param cipher the buffer for the result | ||
| 152 | * @param cipherOffset the offset in <code>cipher</code> | ||
| 153 | */ | ||
| 154 | void encrypt(byte[] plain, int plainOffset, int plainLen, | ||
| 155 | byte[] cipher, int cipherOffset) | ||
| 156 | { | ||
| 157 | int i, len; | ||
| 158 | len = blockSize - numBytes; | ||
| 159 | int loopCount = plainLen / numBytes; | ||
| 160 | int oddBytes = plainLen % numBytes; | ||
| 161 | |||
| 162 | if (len == 0) { | ||
| 163 | for (; loopCount > 0 ; | ||
| 164 | plainOffset += numBytes, cipherOffset += numBytes, | ||
| 165 | loopCount--) { | ||
| 166 | embeddedCipher.encryptBlock(register, 0, k, 0); | ||
| 167 | for (i = 0; i < blockSize; i++) | ||
| 168 | register[i] = cipher[i+cipherOffset] = | ||
| 169 | (byte)(k[i] ^ plain[i+plainOffset]); | ||
| 170 | } | ||
| 171 | if (oddBytes > 0) { | ||
| 172 | embeddedCipher.encryptBlock(register, 0, k, 0); | ||
| 173 | for (i=0; i<oddBytes; i++) | ||
| 174 | register[i] = cipher[i+cipherOffset] = | ||
| 175 | (byte)(k[i] ^ plain[i+plainOffset]); | ||
| 176 | } | ||
| 177 | } else { | ||
| 178 | for (; loopCount > 0 ; | ||
| 179 | plainOffset += numBytes, cipherOffset += numBytes, | ||
| 180 | loopCount--) { | ||
| 181 | embeddedCipher.encryptBlock(register, 0, k, 0); | ||
| 182 | System.arraycopy(register, numBytes, register, 0, len); | ||
| 183 | for (i=0; i<numBytes; i++) | ||
| 184 | register[i+len] = cipher[i+cipherOffset] = | ||
| 185 | (byte)(k[i] ^ plain[i+plainOffset]); | ||
| 186 | |||
| 187 | } | ||
| 188 | if (oddBytes != 0) { | ||
| 189 | embeddedCipher.encryptBlock(register, 0, k, 0); | ||
| 190 | System.arraycopy(register, numBytes, register, 0, len); | ||
| 191 | for (i=0; i<oddBytes; i++) { | ||
| 192 | register[i+len] = cipher[i+cipherOffset] = | ||
| 193 | (byte)(k[i] ^ plain[i+plainOffset]); | ||
| 194 | } | ||
| 195 | } | ||
| 196 | } | ||
| 197 | } | ||
| 198 | |||
| 199 | /** | ||
| 200 | * Performs decryption operation. | ||
| 201 | * | ||
| 202 | * <p>The input cipher text <code>cipher</code>, starting at | ||
| 203 | * <code>cipherOffset</code> and ending at | ||
| 204 | * <code>(cipherOffset + len - 1)</code>, is decrypted. | ||
| 205 | * The result is stored in <code>plain</code>, starting at | ||
| 206 | * <code>plainOffset</code>. | ||
| 207 | * | ||
| 208 | * <p>It is the application's responsibility to make sure that | ||
| 209 | * <code>cipherLen</code> is a multiple of the stream unit size | ||
| 210 | * <code>numBytes</code>, as any excess bytes are ignored. | ||
| 211 | * | ||
| 212 | * <p>It is also the application's responsibility to make sure that | ||
| 213 | * <code>init</code> has been called before this method is called. | ||
| 214 | * (This check is omitted here, to avoid double checking.) | ||
| 215 | * | ||
| 216 | * @param cipher the buffer with the input data to be decrypted | ||
| 217 | * @param cipherOffset the offset in <code>cipherOffset</code> | ||
| 218 | * @param cipherLen the length of the input data | ||
| 219 | * @param plain the buffer for the result | ||
| 220 | * @param plainOffset the offset in <code>plain</code> | ||
| 221 | */ | ||
| 222 | void decrypt(byte[] cipher, int cipherOffset, int cipherLen, | ||
| 223 | byte[] plain, int plainOffset) | ||
| 224 | { | ||
| 225 | int i, len; | ||
| 226 | len = blockSize - numBytes; | ||
| 227 | int loopCount = cipherLen / numBytes; | ||
| 228 | int oddBytes = cipherLen % numBytes; | ||
| 229 | |||
| 230 | if (len == 0) { | ||
| 231 | for (; loopCount > 0; | ||
| 232 | plainOffset += numBytes, cipherOffset += numBytes, | ||
| 233 | loopCount--) { | ||
| 234 | embeddedCipher.encryptBlock(register, 0, k, 0); | ||
| 235 | for (i = 0; i < blockSize; i++) { | ||
| 236 | register[i] = cipher[i+cipherOffset]; | ||
| 237 | plain[i+plainOffset] | ||
| 238 | = (byte)(cipher[i+cipherOffset] ^ k[i]); | ||
| 239 | } | ||
| 240 | } | ||
| 241 | if (oddBytes > 0) { | ||
| 242 | embeddedCipher.encryptBlock(register, 0, k, 0); | ||
| 243 | for (i=0; i<oddBytes; i++) { | ||
| 244 | register[i] = cipher[i+cipherOffset]; | ||
| 245 | plain[i+plainOffset] | ||
| 246 | = (byte)(cipher[i+cipherOffset] ^ k[i]); | ||
| 247 | } | ||
| 248 | } | ||
| 249 | } else { | ||
| 250 | for (; loopCount > 0; | ||
| 251 | plainOffset += numBytes, cipherOffset += numBytes, | ||
| 252 | loopCount--) { | ||
| 253 | embeddedCipher.encryptBlock(register, 0, k, 0); | ||
| 254 | System.arraycopy(register, numBytes, register, 0, len); | ||
| 255 | for (i=0; i<numBytes; i++) { | ||
| 256 | register[i+len] = cipher[i+cipherOffset]; | ||
| 257 | plain[i+plainOffset] | ||
| 258 | = (byte)(cipher[i+cipherOffset] ^ k[i]); | ||
| 259 | } | ||
| 260 | } | ||
| 261 | if (oddBytes != 0) { | ||
| 262 | embeddedCipher.encryptBlock(register, 0, k, 0); | ||
| 263 | System.arraycopy(register, numBytes, register, 0, len); | ||
| 264 | for (i=0; i<oddBytes; i++) { | ||
| 265 | register[i+len] = cipher[i+cipherOffset]; | ||
| 266 | plain[i+plainOffset] | ||
| 267 | = (byte)(cipher[i+cipherOffset] ^ k[i]); | ||
| 268 | } | ||
| 269 | } | ||
| 270 | } | ||
| 271 | } | ||
| 272 | } | ||
| @@ -0,0 +1,215 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import javax.crypto.IllegalBlockSizeException; | ||
| 29 | import javax.crypto.ShortBufferException; | ||
| 30 | |||
| 31 | /** | ||
| 32 | * This class represents ciphers in cipher text stealing (CTS) mode. | ||
| 33 | * <br>CTS provides a way to allow block ciphers to operate on partial | ||
| 34 | * blocks without padding, and all bits of the message go through | ||
| 35 | * the encryption algorithm, rather than simply being XOR'd. | ||
| 36 | * <br>More details can be found in RFC 2040 section 8 "Description | ||
| 37 | * of RC5-CTS". | ||
| 38 | * | ||
| 39 | * <p>This mode is implemented independently of a particular cipher. | ||
| 40 | * Ciphers to which this mode should apply (e.g., DES) must be | ||
| 41 | * <i>plugged-in</i> using the constructor. | ||
| 42 | * | ||
| 43 | * <p>NOTE#1: CTS requires the input data to be at least one block | ||
| 44 | * long. Thus, callers of this class has to buffer the input data | ||
| 45 | * to make sure the input data passed to encryptFinal()/decryptFinal() | ||
| 46 | * is not shorter than a block. | ||
| 47 | * <p>NOTE#2: This class does not deal with buffering or padding | ||
| 48 | * just like all other cipher mode implementations. | ||
| 49 | * | ||
| 50 | * @author Valerie Peng | ||
| 51 | */ | ||
| 52 | |||
| 53 | final class CipherTextStealing extends CipherBlockChaining { | ||
| 54 | |||
| 55 | CipherTextStealing(SymmetricCipher embeddedCipher) { | ||
| 56 | super(embeddedCipher); | ||
| 57 | } | ||
| 58 | |||
| 59 | /** | ||
| 60 | * Gets the name of this feedback mode. | ||
| 61 | * | ||
| 62 | * @return the string <code>CBC</code> | ||
| 63 | */ | ||
| 64 | String getFeedback() { | ||
| 65 | return "CTS"; | ||
| 66 | } | ||
| 67 | |||
| 68 | /** | ||
| 69 | * Performs the last encryption operation. | ||
| 70 | * | ||
| 71 | * <p>The input plain text <code>plain</code>, starting at | ||
| 72 | * <code>plainOffset</code> and ending at | ||
| 73 | * <code>(plainOffset + len - 1)</code>, is encrypted. | ||
| 74 | * The result is stored in <code>cipher</code>, starting at | ||
| 75 | * <code>cipherOffset</code>. | ||
| 76 | * | ||
| 77 | * <p>It is the application's responsibility to make sure that | ||
| 78 | * <code>plainLen</code> is a multiple of the embedded cipher's block size, | ||
| 79 | * as any excess bytes are ignored. | ||
| 80 | * | ||
| 81 | * @param plain the buffer with the input data to be encrypted | ||
| 82 | * @param plainOffset the offset in <code>plain</code> | ||
| 83 | * @param plainLen the length of the input data | ||
| 84 | * @param cipher the buffer for the result | ||
| 85 | * @param cipherOffset the offset in <code>cipher</code> | ||
| 86 | */ | ||
| 87 | void encryptFinal(byte[] plain, int plainOffset, int plainLen, | ||
| 88 | byte[] cipher, int cipherOffset) | ||
| 89 | throws IllegalBlockSizeException { | ||
| 90 | |||
| 91 | if (plainLen < blockSize) { | ||
| 92 | throw new IllegalBlockSizeException("input is too short!"); | ||
| 93 | } else if (plainLen == blockSize) { | ||
| 94 | encrypt(plain, plainOffset, plainLen, cipher, cipherOffset); | ||
| 95 | } else { | ||
| 96 | // number of bytes in the last block | ||
| 97 | int nLeft = plainLen % blockSize; | ||
| 98 | if (nLeft == 0) { | ||
| 99 | encrypt(plain, plainOffset, plainLen, cipher, cipherOffset); | ||
| 100 | // swap the last two blocks after encryption | ||
| 101 | int lastBlkIndex = cipherOffset + plainLen - blockSize; | ||
| 102 | int nextToLastBlkIndex = lastBlkIndex - blockSize; | ||
| 103 | byte[] tmp = new byte[blockSize]; | ||
| 104 | System.arraycopy(cipher, lastBlkIndex, tmp, 0, blockSize); | ||
| 105 | System.arraycopy(cipher, nextToLastBlkIndex, | ||
| 106 | cipher, lastBlkIndex, blockSize); | ||
| 107 | System.arraycopy(tmp, 0, cipher, nextToLastBlkIndex, | ||
| 108 | blockSize); | ||
| 109 | } else { | ||
| 110 | int newPlainLen = plainLen - (blockSize + nLeft); | ||
| 111 | if (newPlainLen > 0) { | ||
| 112 | encrypt(plain, plainOffset, newPlainLen, cipher, | ||
| 113 | cipherOffset); | ||
| 114 | plainOffset += newPlainLen; | ||
| 115 | cipherOffset += newPlainLen; | ||
| 116 | } | ||
| 117 | |||
| 118 | // Do final CTS step for last two blocks (the second of which | ||
| 119 | // may or may not be incomplete). | ||
| 120 | byte[] tmp = new byte[blockSize]; | ||
| 121 | // now encrypt the next-to-last block | ||
| 122 | for (int i = 0; i < blockSize; i++) { | ||
| 123 | tmp[i] = (byte) (plain[plainOffset+i] ^ r[i]); | ||
| 124 | } | ||
| 125 | byte[] tmp2 = new byte[blockSize]; | ||
| 126 | embeddedCipher.encryptBlock(tmp, 0, tmp2, 0); | ||
| 127 | System.arraycopy(tmp2, 0, cipher, | ||
| 128 | cipherOffset+blockSize, nLeft); | ||
| 129 | // encrypt the last block | ||
| 130 | for (int i=0; i<nLeft; i++) { | ||
| 131 | tmp2[i] = (byte) | ||
| 132 | (plain[plainOffset+blockSize+i] ^ tmp2[i]); | ||
| 133 | } | ||
| 134 | embeddedCipher.encryptBlock(tmp2, 0, cipher, cipherOffset); | ||
| 135 | } | ||
| 136 | } | ||
| 137 | } | ||
| 138 | |||
| 139 | /** | ||
| 140 | * Performs decryption operation. | ||
| 141 | * | ||
| 142 | * <p>The input cipher text <code>cipher</code>, starting at | ||
| 143 | * <code>cipherOffset</code> and ending at | ||
| 144 | * <code>(cipherOffset + len - 1)</code>, is decrypted. | ||
| 145 | * The result is stored in <code>plain</code>, starting at | ||
| 146 | * <code>plainOffset</code>. | ||
| 147 | * | ||
| 148 | * <p>It is the application's responsibility to make sure that | ||
| 149 | * <code>cipherLen</code> is a multiple of the embedded cipher's block | ||
| 150 | * size, as any excess bytes are ignored. | ||
| 151 | * | ||
| 152 | * <p>It is also the application's responsibility to make sure that | ||
| 153 | * <code>init</code> has been called before this method is called. | ||
| 154 | * (This check is omitted here, to avoid double checking.) | ||
| 155 | * | ||
| 156 | * @param cipher the buffer with the input data to be decrypted | ||
| 157 | * @param cipherOffset the offset in <code>cipherOffset</code> | ||
| 158 | * @param cipherLen the length of the input data | ||
| 159 | * @param plain the buffer for the result | ||
| 160 | * @param plainOffset the offset in <code>plain</code> | ||
| 161 | */ | ||
| 162 | void decryptFinal(byte[] cipher, int cipherOffset, int cipherLen, | ||
| 163 | byte[] plain, int plainOffset) | ||
| 164 | throws IllegalBlockSizeException { | ||
| 165 | if (cipherLen < blockSize) { | ||
| 166 | throw new IllegalBlockSizeException("input is too short!"); | ||
| 167 | } else if (cipherLen == blockSize) { | ||
| 168 | decrypt(cipher, cipherOffset, cipherLen, plain, plainOffset); | ||
| 169 | } else { | ||
| 170 | // number of bytes in the last block | ||
| 171 | int nLeft = cipherLen % blockSize; | ||
| 172 | if (nLeft == 0) { | ||
| 173 | // swap the last two blocks before decryption | ||
| 174 | int lastBlkIndex = cipherOffset + cipherLen - blockSize; | ||
| 175 | int nextToLastBlkIndex = | ||
| 176 | cipherOffset + cipherLen - 2*blockSize; | ||
| 177 | byte[] tmp = new byte[2*blockSize]; | ||
| 178 | System.arraycopy(cipher, lastBlkIndex, tmp, 0, blockSize); | ||
| 179 | System.arraycopy(cipher, nextToLastBlkIndex, | ||
| 180 | tmp, blockSize, blockSize); | ||
| 181 | int cipherLen2 = cipherLen-2*blockSize; | ||
| 182 | decrypt(cipher, cipherOffset, cipherLen2, plain, plainOffset); | ||
| 183 | decrypt(tmp, 0, 2*blockSize, plain, plainOffset+cipherLen2); | ||
| 184 | } else { | ||
| 185 | int newCipherLen = cipherLen-(blockSize+nLeft); | ||
| 186 | if (newCipherLen > 0) { | ||
| 187 | decrypt(cipher, cipherOffset, newCipherLen, plain, | ||
| 188 | plainOffset); | ||
| 189 | cipherOffset += newCipherLen; | ||
| 190 | plainOffset += newCipherLen; | ||
| 191 | } | ||
| 192 | // Do final CTS step for last two blocks (the second of which | ||
| 193 | // may or may not be incomplete). | ||
| 194 | |||
| 195 | // now decrypt the next-to-last block | ||
| 196 | byte[] tmp = new byte[blockSize]; | ||
| 197 | embeddedCipher.decryptBlock(cipher, cipherOffset, tmp, 0); | ||
| 198 | for (int i = 0; i < nLeft; i++) { | ||
| 199 | plain[plainOffset+blockSize+i] = | ||
| 200 | (byte) (cipher[cipherOffset+blockSize+i] ^ tmp[i]); | ||
| 201 | } | ||
| 202 | |||
| 203 | // decrypt the last block | ||
| 204 | System.arraycopy(cipher, cipherOffset+blockSize, tmp, 0, | ||
| 205 | nLeft); | ||
| 206 | embeddedCipher.decryptBlock(tmp, 0, plain, plainOffset); | ||
| 207 | //System.arraycopy(r, 0, tmp, 0, r.length); | ||
| 208 | for (int i=0; i<blockSize; i++) { | ||
| 209 | plain[plainOffset+i] = (byte) | ||
| 210 | (plain[plainOffset+i]^r[i]); | ||
| 211 | } | ||
| 212 | } | ||
| 213 | } | ||
| 214 | } | ||
| 215 | } | ||
| @@ -0,0 +1,261 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.security.Key; | ||
| 29 | import java.security.PublicKey; | ||
| 30 | import java.security.PrivateKey; | ||
| 31 | import java.security.KeyFactory; | ||
| 32 | import java.security.InvalidKeyException; | ||
| 33 | import java.security.NoSuchProviderException; | ||
| 34 | import java.security.NoSuchAlgorithmException; | ||
| 35 | import java.security.spec.PKCS8EncodedKeySpec; | ||
| 36 | import java.security.spec.X509EncodedKeySpec; | ||
| 37 | import java.security.spec.InvalidKeySpecException; | ||
| 38 | |||
| 39 | import javax.crypto.Cipher; | ||
| 40 | import javax.crypto.CipherSpi; | ||
| 41 | import javax.crypto.SecretKey; | ||
| 42 | import javax.crypto.IllegalBlockSizeException; | ||
| 43 | import javax.crypto.BadPaddingException; | ||
| 44 | import javax.crypto.spec.SecretKeySpec; | ||
| 45 | |||
| 46 | /** | ||
| 47 | * This class entends the javax.crypto.CipherSpi class with a concrete | ||
| 48 | * implementation of the methods for wrapping and unwrapping | ||
| 49 | * keys. | ||
| 50 | * | ||
| 51 | * @author Sharon Liu | ||
| 52 | * | ||
| 53 | * | ||
| 54 | * @see javax.crypto.CipherSpi | ||
| 55 | * @see BlowfishCipher | ||
| 56 | * @see DESCipher | ||
| 57 | * @see PBEWithMD5AndDESCipher | ||
| 58 | */ | ||
| 59 | |||
| 60 | public abstract class CipherWithWrappingSpi extends CipherSpi { | ||
| 61 | |||
| 62 | /** | ||
| 63 | * Wrap a key. | ||
| 64 | * | ||
| 65 | * @param key the key to be wrapped. | ||
| 66 | * | ||
| 67 | * @return the wrapped key. | ||
| 68 | * | ||
| 69 | * @exception IllegalBlockSizeException if this cipher is a block | ||
| 70 | * cipher, no padding has been requested, and the length of the | ||
| 71 | * encoding of the key to be wrapped is not a | ||
| 72 | * multiple of the block size. | ||
| 73 | * | ||
| 74 | * @exception InvalidKeyException if it is impossible or unsafe to | ||
| 75 | * wrap the key with this cipher (e.g., a hardware protected key is | ||
| 76 | * being passed to a software only cipher). | ||
| 77 | */ | ||
| 78 | protected final byte[] engineWrap(Key key) | ||
| 79 | throws IllegalBlockSizeException, InvalidKeyException | ||
| 80 | { | ||
| 81 | byte[] result = null; | ||
| 82 | |||
| 83 | try { | ||
| 84 | byte[] encodedKey = key.getEncoded(); | ||
| 85 | if ((encodedKey == null) || (encodedKey.length == 0)) { | ||
| 86 | throw new InvalidKeyException("Cannot get an encoding of " + | ||
| 87 | "the key to be wrapped"); | ||
| 88 | } | ||
| 89 | |||
| 90 | result = engineDoFinal(encodedKey, 0, encodedKey.length); | ||
| 91 | } catch (BadPaddingException e) { | ||
| 92 | // Should never happen | ||
| 93 | } | ||
| 94 | |||
| 95 | return result; | ||
| 96 | } | ||
| 97 | |||
| 98 | /** | ||
| 99 | * Unwrap a previously wrapped key. | ||
| 100 | * | ||
| 101 | * @param wrappedKey the key to be unwrapped. | ||
| 102 | * | ||
| 103 | * @param wrappedKeyAlgorithm the algorithm the wrapped key is for. | ||
| 104 | * | ||
| 105 | * @param wrappedKeyType the type of the wrapped key. | ||
| 106 | * This is one of <code>Cipher.SECRET_KEY</code>, | ||
| 107 | * <code>Cipher.PRIVATE_KEY</code>, or <code>Cipher.PUBLIC_KEY</code>. | ||
| 108 | * | ||
| 109 | * @return the unwrapped key. | ||
| 110 | * | ||
| 111 | * @exception InvalidKeyException if <code>wrappedKey</code> does not | ||
| 112 | * represent a wrapped key, or if the algorithm associated with the | ||
| 113 | * wrapped key is different from <code>wrappedKeyAlgorithm</code> | ||
| 114 | * and/or its key type is different from <code>wrappedKeyType</code>. | ||
| 115 | * | ||
| 116 | * @exception NoSuchAlgorithmException if no installed providers | ||
| 117 | * can create keys for the <code>wrappedKeyAlgorithm</code>. | ||
| 118 | */ | ||
| 119 | protected final Key engineUnwrap(byte[] wrappedKey, | ||
| 120 | String wrappedKeyAlgorithm, | ||
| 121 | int wrappedKeyType) | ||
| 122 | throws InvalidKeyException, NoSuchAlgorithmException | ||
| 123 | { | ||
| 124 | byte[] encodedKey; | ||
| 125 | Key result = null; | ||
| 126 | |||
| 127 | try { | ||
| 128 | encodedKey = engineDoFinal(wrappedKey, 0, | ||
| 129 | wrappedKey.length); | ||
| 130 | } catch (BadPaddingException ePadding) { | ||
| 131 | throw new InvalidKeyException(); | ||
| 132 | } catch (IllegalBlockSizeException eBlockSize) { | ||
| 133 | throw new InvalidKeyException(); | ||
| 134 | } | ||
| 135 | |||
| 136 | switch (wrappedKeyType) { | ||
| 137 | case Cipher.SECRET_KEY: | ||
| 138 | result = constructSecretKey(encodedKey, | ||
| 139 | wrappedKeyAlgorithm); | ||
| 140 | break; | ||
| 141 | case Cipher.PRIVATE_KEY: | ||
| 142 | result = constructPrivateKey(encodedKey, | ||
| 143 | wrappedKeyAlgorithm); | ||
| 144 | break; | ||
| 145 | case Cipher.PUBLIC_KEY: | ||
| 146 | result = constructPublicKey(encodedKey, | ||
| 147 | wrappedKeyAlgorithm); | ||
| 148 | break; | ||
| 149 | } | ||
| 150 | |||
| 151 | return result; | ||
| 152 | |||
| 153 | } | ||
| 154 | |||
| 155 | /** | ||
| 156 | * Construct a public key from its encoding. | ||
| 157 | * | ||
| 158 | * @param encodedKey the encoding of a public key. | ||
| 159 | * | ||
| 160 | * @param encodedKeyAlgorithm the algorithm the encodedKey is for. | ||
| 161 | * | ||
| 162 | * @return a public key constructed from the encodedKey. | ||
| 163 | */ | ||
| 164 | private final PublicKey constructPublicKey(byte[] encodedKey, | ||
| 165 | String encodedKeyAlgorithm) | ||
| 166 | throws InvalidKeyException, NoSuchAlgorithmException | ||
| 167 | { | ||
| 168 | PublicKey key = null; | ||
| 169 | |||
| 170 | try { | ||
| 171 | KeyFactory keyFactory = | ||
| 172 | KeyFactory.getInstance(encodedKeyAlgorithm, "SunJCE"); | ||
| 173 | X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encodedKey); | ||
| 174 | key = keyFactory.generatePublic(keySpec); | ||
| 175 | } catch (NoSuchAlgorithmException nsae) { | ||
| 176 | // Try to see whether there is another | ||
| 177 | // provider which supports this algorithm | ||
| 178 | try { | ||
| 179 | KeyFactory keyFactory = | ||
| 180 | KeyFactory.getInstance(encodedKeyAlgorithm); | ||
| 181 | X509EncodedKeySpec keySpec = | ||
| 182 | new X509EncodedKeySpec(encodedKey); | ||
| 183 | key = keyFactory.generatePublic(keySpec); | ||
| 184 | } catch (NoSuchAlgorithmException nsae2) { | ||
| 185 | throw new NoSuchAlgorithmException("No installed providers " + | ||
| 186 | "can create keys for the " + | ||
| 187 | encodedKeyAlgorithm + | ||
| 188 | "algorithm"); | ||
| 189 | } catch (InvalidKeySpecException ikse2) { | ||
| 190 | // Should never happen. | ||
| 191 | } | ||
| 192 | } catch (InvalidKeySpecException ikse) { | ||
| 193 | // Should never happen. | ||
| 194 | } catch (NoSuchProviderException nspe) { | ||
| 195 | // Should never happen. | ||
| 196 | } | ||
| 197 | |||
| 198 | return key; | ||
| 199 | } | ||
| 200 | |||
| 201 | /** | ||
| 202 | * Construct a private key from its encoding. | ||
| 203 | * | ||
| 204 | * @param encodedKey the encoding of a private key. | ||
| 205 | * | ||
| 206 | * @param encodedKeyAlgorithm the algorithm the wrapped key is for. | ||
| 207 | * | ||
| 208 | * @return a private key constructed from the encodedKey. | ||
| 209 | */ | ||
| 210 | private final PrivateKey constructPrivateKey(byte[] encodedKey, | ||
| 211 | String encodedKeyAlgorithm) | ||
| 212 | throws InvalidKeyException, NoSuchAlgorithmException | ||
| 213 | { | ||
| 214 | PrivateKey key = null; | ||
| 215 | |||
| 216 | try { | ||
| 217 | KeyFactory keyFactory = | ||
| 218 | KeyFactory.getInstance(encodedKeyAlgorithm, "SunJCE"); | ||
| 219 | PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encodedKey); | ||
| 220 | return keyFactory.generatePrivate(keySpec); | ||
| 221 | } catch (NoSuchAlgorithmException nsae) { | ||
| 222 | // Try to see whether there is another | ||
| 223 | // provider which supports this algorithm | ||
| 224 | try { | ||
| 225 | KeyFactory keyFactory = | ||
| 226 | KeyFactory.getInstance(encodedKeyAlgorithm); | ||
| 227 | PKCS8EncodedKeySpec keySpec = | ||
| 228 | new PKCS8EncodedKeySpec(encodedKey); | ||
| 229 | key = keyFactory.generatePrivate(keySpec); | ||
| 230 | } catch (NoSuchAlgorithmException nsae2) { | ||
| 231 | throw new NoSuchAlgorithmException("No installed providers " + | ||
| 232 | "can create keys for the " + | ||
| 233 | encodedKeyAlgorithm + | ||
| 234 | "algorithm"); | ||
| 235 | } catch (InvalidKeySpecException ikse2) { | ||
| 236 | // Should never happen. | ||
| 237 | } | ||
| 238 | } catch (InvalidKeySpecException ikse) { | ||
| 239 | // Should never happen. | ||
| 240 | } catch (NoSuchProviderException nspe) { | ||
| 241 | // Should never happen. | ||
| 242 | } | ||
| 243 | |||
| 244 | return key; | ||
| 245 | } | ||
| 246 | |||
| 247 | /** | ||
| 248 | * Construct a secret key from its encoding. | ||
| 249 | * | ||
| 250 | * @param encodedKey the encoding of a secret key. | ||
| 251 | * | ||
| 252 | * @param encodedKeyAlgorithm the algorithm the secret key is for. | ||
| 253 | * | ||
| 254 | * @return a secret key constructed from the encodedKey. | ||
| 255 | */ | ||
| 256 | private final SecretKey constructSecretKey(byte[] encodedKey, | ||
| 257 | String encodedKeyAlgorithm) | ||
| 258 | { | ||
| 259 | return (new SecretKeySpec(encodedKey, encodedKeyAlgorithm)); | ||
| 260 | } | ||
| 261 | } | ||
| @@ -0,0 +1,191 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.security.Key; | ||
| 29 | import java.security.PublicKey; | ||
| 30 | import java.security.PrivateKey; | ||
| 31 | import java.security.KeyFactory; | ||
| 32 | import java.security.InvalidKeyException; | ||
| 33 | import java.security.NoSuchProviderException; | ||
| 34 | import java.security.NoSuchAlgorithmException; | ||
| 35 | import java.security.spec.PKCS8EncodedKeySpec; | ||
| 36 | import java.security.spec.X509EncodedKeySpec; | ||
| 37 | import java.security.spec.InvalidKeySpecException; | ||
| 38 | |||
| 39 | import javax.crypto.SecretKey; | ||
| 40 | import javax.crypto.Cipher; | ||
| 41 | import javax.crypto.spec.SecretKeySpec; | ||
| 42 | |||
| 43 | /** | ||
| 44 | * This class is a helper class which construct key objects | ||
| 45 | * from encoded keys. | ||
| 46 | * | ||
| 47 | * @author Sharon Liu | ||
| 48 | * | ||
| 49 | */ | ||
| 50 | |||
| 51 | final class ConstructKeys { | ||
| 52 | /** | ||
| 53 | * Construct a public key from its encoding. | ||
| 54 | * | ||
| 55 | * @param encodedKey the encoding of a public key. | ||
| 56 | * | ||
| 57 | * @param encodedKeyAlgorithm the algorithm the encodedKey is for. | ||
| 58 | * | ||
| 59 | * @return a public key constructed from the encodedKey. | ||
| 60 | */ | ||
| 61 | private static final PublicKey constructPublicKey(byte[] encodedKey, | ||
| 62 | String encodedKeyAlgorithm) | ||
| 63 | throws InvalidKeyException, NoSuchAlgorithmException | ||
| 64 | { | ||
| 65 | PublicKey key = null; | ||
| 66 | |||
| 67 | try { | ||
| 68 | KeyFactory keyFactory = | ||
| 69 | KeyFactory.getInstance(encodedKeyAlgorithm, "SunJCE"); | ||
| 70 | X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encodedKey); | ||
| 71 | key = keyFactory.generatePublic(keySpec); | ||
| 72 | } catch (NoSuchAlgorithmException nsae) { | ||
| 73 | // Try to see whether there is another | ||
| 74 | // provider which supports this algorithm | ||
| 75 | try { | ||
| 76 | KeyFactory keyFactory = | ||
| 77 | KeyFactory.getInstance(encodedKeyAlgorithm); | ||
| 78 | X509EncodedKeySpec keySpec = | ||
| 79 | new X509EncodedKeySpec(encodedKey); | ||
| 80 | key = keyFactory.generatePublic(keySpec); | ||
| 81 | } catch (NoSuchAlgorithmException nsae2) { | ||
| 82 | throw new NoSuchAlgorithmException("No installed providers " + | ||
| 83 | "can create keys for the " + | ||
| 84 | encodedKeyAlgorithm + | ||
| 85 | "algorithm"); | ||
| 86 | } catch (InvalidKeySpecException ikse2) { | ||
| 87 | InvalidKeyException ike = | ||
| 88 | new InvalidKeyException("Cannot construct public key"); | ||
| 89 | ike.initCause(ikse2); | ||
| 90 | throw ike; | ||
| 91 | } | ||
| 92 | } catch (InvalidKeySpecException ikse) { | ||
| 93 | InvalidKeyException ike = | ||
| 94 | new InvalidKeyException("Cannot construct public key"); | ||
| 95 | ike.initCause(ikse); | ||
| 96 | throw ike; | ||
| 97 | } catch (NoSuchProviderException nspe) { | ||
| 98 | // Should never happen. | ||
| 99 | } | ||
| 100 | |||
| 101 | return key; | ||
| 102 | } | ||
| 103 | |||
| 104 | /** | ||
| 105 | * Construct a private key from its encoding. | ||
| 106 | * | ||
| 107 | * @param encodedKey the encoding of a private key. | ||
| 108 | * | ||
| 109 | * @param encodedKeyAlgorithm the algorithm the wrapped key is for. | ||
| 110 | * | ||
| 111 | * @return a private key constructed from the encodedKey. | ||
| 112 | */ | ||
| 113 | private static final PrivateKey constructPrivateKey(byte[] encodedKey, | ||
| 114 | String encodedKeyAlgorithm) | ||
| 115 | throws InvalidKeyException, NoSuchAlgorithmException | ||
| 116 | { | ||
| 117 | PrivateKey key = null; | ||
| 118 | |||
| 119 | try { | ||
| 120 | KeyFactory keyFactory = | ||
| 121 | KeyFactory.getInstance(encodedKeyAlgorithm, "SunJCE"); | ||
| 122 | PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encodedKey); | ||
| 123 | return keyFactory.generatePrivate(keySpec); | ||
| 124 | } catch (NoSuchAlgorithmException nsae) { | ||
| 125 | // Try to see whether there is another | ||
| 126 | // provider which supports this algorithm | ||
| 127 | try { | ||
| 128 | KeyFactory keyFactory = | ||
| 129 | KeyFactory.getInstance(encodedKeyAlgorithm); | ||
| 130 | PKCS8EncodedKeySpec keySpec = | ||
| 131 | new PKCS8EncodedKeySpec(encodedKey); | ||
| 132 | key = keyFactory.generatePrivate(keySpec); | ||
| 133 | } catch (NoSuchAlgorithmException nsae2) { | ||
| 134 | throw new NoSuchAlgorithmException("No installed providers " + | ||
| 135 | "can create keys for the " + | ||
| 136 | encodedKeyAlgorithm + | ||
| 137 | "algorithm"); | ||
| 138 | } catch (InvalidKeySpecException ikse2) { | ||
| 139 | InvalidKeyException ike = | ||
| 140 | new InvalidKeyException("Cannot construct private key"); | ||
| 141 | ike.initCause(ikse2); | ||
| 142 | throw ike; | ||
| 143 | } | ||
| 144 | } catch (InvalidKeySpecException ikse) { | ||
| 145 | InvalidKeyException ike = | ||
| 146 | new InvalidKeyException("Cannot construct private key"); | ||
| 147 | ike.initCause(ikse); | ||
| 148 | throw ike; | ||
| 149 | } catch (NoSuchProviderException nspe) { | ||
| 150 | // Should never happen. | ||
| 151 | } | ||
| 152 | |||
| 153 | return key; | ||
| 154 | } | ||
| 155 | |||
| 156 | /** | ||
| 157 | * Construct a secret key from its encoding. | ||
| 158 | * | ||
| 159 | * @param encodedKey the encoding of a secret key. | ||
| 160 | * | ||
| 161 | * @param encodedKeyAlgorithm the algorithm the secret key is for. | ||
| 162 | * | ||
| 163 | * @return a secret key constructed from the encodedKey. | ||
| 164 | */ | ||
| 165 | private static final SecretKey constructSecretKey(byte[] encodedKey, | ||
| 166 | String encodedKeyAlgorithm) | ||
| 167 | { | ||
| 168 | return (new SecretKeySpec(encodedKey, encodedKeyAlgorithm)); | ||
| 169 | } | ||
| 170 | |||
| 171 | static final Key constructKey(byte[] encoding, String keyAlgorithm, | ||
| 172 | int keyType) | ||
| 173 | throws InvalidKeyException, NoSuchAlgorithmException { | ||
| 174 | Key result = null; | ||
| 175 | switch (keyType) { | ||
| 176 | case Cipher.SECRET_KEY: | ||
| 177 | result = ConstructKeys.constructSecretKey(encoding, | ||
| 178 | keyAlgorithm); | ||
| 179 | break; | ||
| 180 | case Cipher.PRIVATE_KEY: | ||
| 181 | result = ConstructKeys.constructPrivateKey(encoding, | ||
| 182 | keyAlgorithm); | ||
| 183 | break; | ||
| 184 | case Cipher.PUBLIC_KEY: | ||
| 185 | result = ConstructKeys.constructPublicKey(encoding, | ||
| 186 | keyAlgorithm); | ||
| 187 | break; | ||
| 188 | } | ||
| 189 | return result; | ||
| 190 | } | ||
| 191 | } | ||
| @@ -0,0 +1,210 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.security.InvalidKeyException; | ||
| 29 | |||
| 30 | /** | ||
| 31 | * This class represents ciphers in counter (CTR) mode. | ||
| 32 | * | ||
| 33 | * <p>This mode is implemented independently of a particular cipher. | ||
| 34 | * Ciphers to which this mode should apply (e.g., DES) must be | ||
| 35 | * <i>plugged-in</i> using the constructor. | ||
| 36 | * | ||
| 37 | * <p>NOTE: This class does not deal with buffering or padding. | ||
| 38 | * | ||
| 39 | * @author Andreas Sterbenz | ||
| 40 | * @since 1.4.2 | ||
| 41 | */ | ||
| 42 | final class CounterMode extends FeedbackCipher { | ||
| 43 | |||
| 44 | // current counter value | ||
| 45 | private final byte[] counter; | ||
| 46 | |||
| 47 | // encrypted bytes of the previous counter value | ||
| 48 | private final byte[] encryptedCounter; | ||
| 49 | |||
| 50 | // number of bytes in encryptedCounter already used up | ||
| 51 | private int used; | ||
| 52 | |||
| 53 | // variables for save/restore calls | ||
| 54 | private byte[] counterSave = null; | ||
| 55 | private byte[] encryptedCounterSave = null; | ||
| 56 | private int usedSave = 0; | ||
| 57 | |||
| 58 | CounterMode(SymmetricCipher embeddedCipher) { | ||
| 59 | super(embeddedCipher); | ||
| 60 | counter = new byte[blockSize]; | ||
| 61 | encryptedCounter = new byte[blockSize]; | ||
| 62 | } | ||
| 63 | |||
| 64 | /** | ||
| 65 | * Gets the name of the feedback mechanism | ||
| 66 | * | ||
| 67 | * @return the name of the feedback mechanism | ||
| 68 | */ | ||
| 69 | String getFeedback() { | ||
| 70 | return "CTR"; | ||
| 71 | } | ||
| 72 | |||
| 73 | /** | ||
| 74 | * Resets the iv to its original value. | ||
| 75 | * This is used when doFinal is called in the Cipher class, so that the | ||
| 76 | * cipher can be reused (with its original iv). | ||
| 77 | */ | ||
| 78 | void reset() { | ||
| 79 | System.arraycopy(iv, 0, counter, 0, blockSize); | ||
| 80 | used = blockSize; | ||
| 81 | } | ||
| 82 | |||
| 83 | /** | ||
| 84 | * Save the current content of this cipher. | ||
| 85 | */ | ||
| 86 | void save() { | ||
| 87 | if (counterSave == null) { | ||
| 88 | counterSave = new byte[blockSize]; | ||
| 89 | encryptedCounterSave = new byte[blockSize]; | ||
| 90 | } | ||
| 91 | System.arraycopy(counter, 0, counterSave, 0, blockSize); | ||
| 92 | System.arraycopy(encryptedCounter, 0, encryptedCounterSave, 0, | ||
| 93 | blockSize); | ||
| 94 | usedSave = used; | ||
| 95 | } | ||
| 96 | |||
| 97 | /** | ||
| 98 | * Restores the content of this cipher to the previous saved one. | ||
| 99 | */ | ||
| 100 | void restore() { | ||
| 101 | System.arraycopy(counterSave, 0, counter, 0, blockSize); | ||
| 102 | System.arraycopy(encryptedCounterSave, 0, encryptedCounter, 0, | ||
| 103 | blockSize); | ||
| 104 | used = usedSave; | ||
| 105 | } | ||
| 106 | |||
| 107 | /** | ||
| 108 | * Initializes the cipher in the specified mode with the given key | ||
| 109 | * and iv. | ||
| 110 | * | ||
| 111 | * @param decrypting flag indicating encryption or decryption | ||
| 112 | * @param algorithm the algorithm name | ||
| 113 | * @param key the key | ||
| 114 | * @param iv the iv | ||
| 115 | * | ||
| 116 | * @exception InvalidKeyException if the given key is inappropriate for | ||
| 117 | * initializing this cipher | ||
| 118 | */ | ||
| 119 | void init(boolean decrypting, String algorithm, byte[] key, byte[] iv) | ||
| 120 | throws InvalidKeyException { | ||
| 121 | if ((key == null) || (iv == null) || (iv.length != blockSize)) { | ||
| 122 | throw new InvalidKeyException("Internal error"); | ||
| 123 | } | ||
| 124 | this.iv = iv; | ||
| 125 | reset(); | ||
| 126 | // always encrypt mode for embedded cipher | ||
| 127 | embeddedCipher.init(false, algorithm, key); | ||
| 128 | } | ||
| 129 | |||
| 130 | /** | ||
| 131 | * Performs encryption operation. | ||
| 132 | * | ||
| 133 | * <p>The input plain text <code>plain</code>, starting at | ||
| 134 | * <code>plainOffset</code> and ending at | ||
| 135 | * <code>(plainOffset + len - 1)</code>, is encrypted. | ||
| 136 | * The result is stored in <code>cipher</code>, starting at | ||
| 137 | * <code>cipherOffset</code>. | ||
| 138 | * | ||
| 139 | * <p>It is the application's responsibility to make sure that | ||
| 140 | * <code>plainLen</code> is a multiple of the embedded cipher's block size, | ||
| 141 | * as any excess bytes are ignored. | ||
| 142 | * | ||
| 143 | * <p>It is also the application's responsibility to make sure that | ||
| 144 | * <code>init</code> has been called before this method is called. | ||
| 145 | * (This check is omitted here, to avoid double checking.) | ||
| 146 | * | ||
| 147 | * @param in the buffer with the input data to be encrypted | ||
| 148 | * @param inOffset the offset in <code>plain</code> | ||
| 149 | * @param len the length of the input data | ||
| 150 | * @param out the buffer for the result | ||
| 151 | * @param outOff the offset in <code>cipher</code> | ||
| 152 | */ | ||
| 153 | void encrypt(byte[] in, int inOff, int len, byte[] out, int outOff) { | ||
| 154 | crypt(in, inOff, len, out, outOff); | ||
| 155 | } | ||
| 156 | |||
| 157 | /** | ||
| 158 | * Performs decryption operation. | ||
| 159 | * | ||
| 160 | * <p>The input cipher text <code>cipher</code>, starting at | ||
| 161 | * <code>cipherOffset</code> and ending at | ||
| 162 | * <code>(cipherOffset + len - 1)</code>, is decrypted. | ||
| 163 | * The result is stored in <code>plain</code>, starting at | ||
| 164 | * <code>plainOffset</code>. | ||
| 165 | * | ||
| 166 | * <p>It is the application's responsibility to make sure that | ||
| 167 | * <code>cipherLen</code> is a multiple of the embedded cipher's block | ||
| 168 | * size, as any excess bytes are ignored. | ||
| 169 | * | ||
| 170 | * <p>It is also the application's responsibility to make sure that | ||
| 171 | * <code>init</code> has been called before this method is called. | ||
| 172 | * (This check is omitted here, to avoid double checking.) | ||
| 173 | * | ||
| 174 | * @param in the buffer with the input data to be decrypted | ||
| 175 | * @param inOff the offset in <code>cipherOffset</code> | ||
| 176 | * @param len the length of the input data | ||
| 177 | * @param out the buffer for the result | ||
| 178 | * @param outOff the offset in <code>plain</code> | ||
| 179 | */ | ||
| 180 | void decrypt(byte[] in, int inOff, int len, byte[] out, int outOff) { | ||
| 181 | crypt(in, inOff, len, out, outOff); | ||
| 182 | } | ||
| 183 | |||
| 184 | /** | ||
| 185 | * Increment the counter value. | ||
| 186 | */ | ||
| 187 | private static void increment(byte[] b) { | ||
| 188 | int n = b.length - 1; | ||
| 189 | while ((n >= 0) && (++b[n] == 0)) { | ||
| 190 | n--; | ||
| 191 | } | ||
| 192 | } | ||
| 193 | |||
| 194 | /** | ||
| 195 | * Do the actual encryption/decryption operation. | ||
| 196 | * Essentially we XOR the input plaintext/ciphertext stream with a | ||
| 197 | * keystream generated by encrypting the counter values. Counter values | ||
| 198 | * are encrypted on demand. | ||
| 199 | */ | ||
| 200 | private void crypt(byte[] in, int inOff, int len, byte[] out, int outOff) { | ||
| 201 | while (len-- > 0) { | ||
| 202 | if (used >= blockSize) { | ||
| 203 | embeddedCipher.encryptBlock(counter, 0, encryptedCounter, 0); | ||
| 204 | increment(counter); | ||
| 205 | used = 0; | ||
| 206 | } | ||
| 207 | out[outOff++] = (byte)(in[inOff++] ^ encryptedCounter[used++]); | ||
| 208 | } | ||
| 209 | } | ||
| 210 | } | ||
| @@ -0,0 +1,428 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.security.*; | ||
| 29 | import java.security.spec.*; | ||
| 30 | import javax.crypto.*; | ||
| 31 | import javax.crypto.spec.*; | ||
| 32 | import javax.crypto.BadPaddingException; | ||
| 33 | |||
| 34 | /** | ||
| 35 | * This class implements the DES algorithm in its various modes | ||
| 36 | * (<code>ECB</code>, <code>CFB</code>, <code>OFB</code>, <code>CBC</code>, | ||
| 37 | * <code>PCBC</code>) and padding schemes (<code>PKCS5Padding</code>, | ||
| 38 | * <code>NoPadding</code>, <code>ISO10126Padding</code>). | ||
| 39 | * | ||
| 40 | * @author Gigi Ankeny | ||
| 41 | * @author Jan Luehe | ||
| 42 | * @see DESCrypt | ||
| 43 | * @see CipherBlockChaining | ||
| 44 | * @see ElectronicCodeBook | ||
| 45 | * @see CipherFeedback | ||
| 46 | * @see OutputFeedback | ||
| 47 | */ | ||
| 48 | |||
| 49 | public final class DESCipher extends CipherSpi { | ||
| 50 | |||
| 51 | /* | ||
| 52 | * internal CipherCore object which does the real work. | ||
| 53 | */ | ||
| 54 | private CipherCore core = null; | ||
| 55 | |||
| 56 | /** | ||
| 57 | * Creates an instance of DES cipher with default ECB mode and | ||
| 58 | * PKCS5Padding. | ||
| 59 | */ | ||
| 60 | public DESCipher() { | ||
| 61 | core = new CipherCore(new DESCrypt(), DESConstants.DES_BLOCK_SIZE); | ||
| 62 | } | ||
| 63 | |||
| 64 | /** | ||
| 65 | * Sets the mode of this cipher. | ||
| 66 | * | ||
| 67 | * @param mode the cipher mode | ||
| 68 | * | ||
| 69 | * @exception NoSuchAlgorithmException if the requested cipher mode does | ||
| 70 | * not exist | ||
| 71 | */ | ||
| 72 | protected void engineSetMode(String mode) | ||
| 73 | throws NoSuchAlgorithmException { | ||
| 74 | core.setMode(mode); | ||
| 75 | } | ||
| 76 | |||
| 77 | /** | ||
| 78 | * Sets the padding mechanism of this cipher. | ||
| 79 | * | ||
| 80 | * @param padding the padding mechanism | ||
| 81 | * | ||
| 82 | * @exception NoSuchPaddingException if the requested padding mechanism | ||
| 83 | * does not exist | ||
| 84 | */ | ||
| 85 | protected void engineSetPadding(String paddingScheme) | ||
| 86 | throws NoSuchPaddingException { | ||
| 87 | core.setPadding(paddingScheme); | ||
| 88 | } | ||
| 89 | |||
| 90 | /** | ||
| 91 | * Returns the block size (in bytes). | ||
| 92 | * | ||
| 93 | * @return the block size (in bytes), or 0 if the underlying algorithm is | ||
| 94 | * not a block cipher | ||
| 95 | */ | ||
| 96 | protected int engineGetBlockSize() { | ||
| 97 | return DESConstants.DES_BLOCK_SIZE; | ||
| 98 | } | ||
| 99 | |||
| 100 | /** | ||
| 101 | * Returns the length in bytes that an output buffer would need to be in | ||
| 102 | * order to hold the result of the next <code>update</code> or | ||
| 103 | * <code>doFinal</code> operation, given the input length | ||
| 104 | * <code>inputLen</code> (in bytes). | ||
| 105 | * | ||
| 106 | * <p>This call takes into account any unprocessed (buffered) data from a | ||
| 107 | * previous <code>update</code> call, and padding. | ||
| 108 | * | ||
| 109 | * <p>The actual output length of the next <code>update</code> or | ||
| 110 | * <code>doFinal</code> call may be smaller than the length returned by | ||
| 111 | * this method. | ||
| 112 | * | ||
| 113 | * @param inputLen the input length (in bytes) | ||
| 114 | * | ||
| 115 | * @return the required output buffer size (in bytes) | ||
| 116 | */ | ||
| 117 | protected int engineGetOutputSize(int inputLen) { | ||
| 118 | return core.getOutputSize(inputLen); | ||
| 119 | } | ||
| 120 | |||
| 121 | /** | ||
| 122 | * Returns the initialization vector (IV) in a new buffer. | ||
| 123 | * | ||
| 124 | * <p>This is useful in the case where a random IV has been created | ||
| 125 | * (see <a href = "#init">init</a>), | ||
| 126 | * or in the context of password-based encryption or | ||
| 127 | * decryption, where the IV is derived from a user-provided password. | ||
| 128 | * | ||
| 129 | * @return the initialization vector in a new buffer, or null if the | ||
| 130 | * underlying algorithm does not use an IV, or if the IV has not yet | ||
| 131 | * been set. | ||
| 132 | */ | ||
| 133 | protected byte[] engineGetIV() { | ||
| 134 | return core.getIV(); | ||
| 135 | } | ||
| 136 | |||
| 137 | /** | ||
| 138 | * Returns the parameters used with this cipher. | ||
| 139 | * | ||
| 140 | * <p>The returned parameters may be the same that were used to initialize | ||
| 141 | * this cipher, or may contain the default set of parameters or a set of | ||
| 142 | * randomly generated parameters used by the underlying cipher | ||
| 143 | * implementation (provided that the underlying cipher implementation | ||
| 144 | * uses a default set of parameters or creates new parameters if it needs | ||
| 145 | * parameters but was not initialized with any). | ||
| 146 | * | ||
| 147 | * @return the parameters used with this cipher, or null if this cipher | ||
| 148 | * does not use any parameters. | ||
| 149 | */ | ||
| 150 | protected AlgorithmParameters engineGetParameters() { | ||
| 151 | return core.getParameters("DES"); | ||
| 152 | } | ||
| 153 | |||
| 154 | /** | ||
| 155 | * Initializes this cipher with a key and a source of randomness. | ||
| 156 | * | ||
| 157 | * <p>The cipher is initialized for one of the following four operations: | ||
| 158 | * encryption, decryption, key wrapping or key unwrapping, depending on | ||
| 159 | * the value of <code>opmode</code>. | ||
| 160 | * | ||
| 161 | * <p>If this cipher requires an initialization vector (IV), it will get | ||
| 162 | * it from <code>random</code>. | ||
| 163 | * This behaviour should only be used in encryption or key wrapping | ||
| 164 | * mode, however. | ||
| 165 | * When initializing a cipher that requires an IV for decryption or | ||
| 166 | * key unwrapping, the IV | ||
| 167 | * (same IV that was used for encryption or key wrapping) must be provided | ||
| 168 | * explicitly as a | ||
| 169 | * parameter, in order to get the correct result. | ||
| 170 | * | ||
| 171 | * <p>This method also cleans existing buffer and other related state | ||
| 172 | * information. | ||
| 173 | * | ||
| 174 | * @param opmode the operation mode of this cipher (this is one of | ||
| 175 | * the following: | ||
| 176 | * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, | ||
| 177 | * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) | ||
| 178 | * @param key the secret key | ||
| 179 | * @param random the source of randomness | ||
| 180 | * | ||
| 181 | * @exception InvalidKeyException if the given key is inappropriate for | ||
| 182 | * initializing this cipher | ||
| 183 | */ | ||
| 184 | protected void engineInit(int opmode, Key key, SecureRandom random) | ||
| 185 | throws InvalidKeyException { | ||
| 186 | core.init(opmode, key, random); | ||
| 187 | } | ||
| 188 | |||
| 189 | /** | ||
| 190 | * Initializes this cipher with a key, a set of | ||
| 191 | * algorithm parameters, and a source of randomness. | ||
| 192 | * | ||
| 193 | * <p>The cipher is initialized for one of the following four operations: | ||
| 194 | * encryption, decryption, key wrapping or key unwrapping, depending on | ||
| 195 | * the value of <code>opmode</code>. | ||
| 196 | * | ||
| 197 | * <p>If this cipher (including its underlying feedback or padding scheme) | ||
| 198 | * requires any random bytes, it will get them from <code>random</code>. | ||
| 199 | * | ||
| 200 | * @param opmode the operation mode of this cipher (this is one of | ||
| 201 | * the following: | ||
| 202 | * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, | ||
| 203 | * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) | ||
| 204 | * @param key the encryption key | ||
| 205 | * @param params the algorithm parameters | ||
| 206 | * @param random the source of randomness | ||
| 207 | * | ||
| 208 | * @exception InvalidKeyException if the given key is inappropriate for | ||
| 209 | * initializing this cipher | ||
| 210 | * @exception InvalidAlgorithmParameterException if the given algorithm | ||
| 211 | * parameters are inappropriate for this cipher | ||
| 212 | */ | ||
| 213 | protected void engineInit(int opmode, Key key, | ||
| 214 | AlgorithmParameterSpec params, | ||
| 215 | SecureRandom random) | ||
| 216 | throws InvalidKeyException, InvalidAlgorithmParameterException { | ||
| 217 | core.init(opmode, key, params, random); | ||
| 218 | } | ||
| 219 | |||
| 220 | protected void engineInit(int opmode, Key key, | ||
| 221 | AlgorithmParameters params, | ||
| 222 | SecureRandom random) | ||
| 223 | throws InvalidKeyException, InvalidAlgorithmParameterException { | ||
| 224 | core.init(opmode, key, params, random); | ||
| 225 | } | ||
| 226 | |||
| 227 | /** | ||
| 228 | * Continues a multiple-part encryption or decryption operation | ||
| 229 | * (depending on how this cipher was initialized), processing another data | ||
| 230 | * part. | ||
| 231 | * | ||
| 232 | * <p>The first <code>inputLen</code> bytes in the <code>input</code> | ||
| 233 | * buffer, starting at <code>inputOffset</code>, are processed, and the | ||
| 234 | * result is stored in a new buffer. | ||
| 235 | * | ||
| 236 | * @param input the input buffer | ||
| 237 | * @param inputOffset the offset in <code>input</code> where the input | ||
| 238 | * starts | ||
| 239 | * @param inputLen the input length | ||
| 240 | * | ||
| 241 | * @return the new buffer with the result | ||
| 242 | * | ||
| 243 | * @exception IllegalStateException if this cipher is in a wrong state | ||
| 244 | * (e.g., has not been initialized) | ||
| 245 | */ | ||
| 246 | protected byte[] engineUpdate(byte[] input, int inputOffset, | ||
| 247 | int inputLen) { | ||
| 248 | return core.update(input, inputOffset, inputLen); | ||
| 249 | } | ||
| 250 | |||
| 251 | /** | ||
| 252 | * Continues a multiple-part encryption or decryption operation | ||
| 253 | * (depending on how this cipher was initialized), processing another data | ||
| 254 | * part. | ||
| 255 | * | ||
| 256 | * <p>The first <code>inputLen</code> bytes in the <code>input</code> | ||
| 257 | * buffer, starting at <code>inputOffset</code>, are processed, and the | ||
| 258 | * result is stored in the <code>output</code> buffer, starting at | ||
| 259 | * <code>outputOffset</code>. | ||
| 260 | * | ||
| 261 | * @param input the input buffer | ||
| 262 | * @param inputOffset the offset in <code>input</code> where the input | ||
| 263 | * starts | ||
| 264 | * @param inputLen the input length | ||
| 265 | * @param output the buffer for the result | ||
| 266 | * @param outputOffset the offset in <code>output</code> where the result | ||
| 267 | * is stored | ||
| 268 | * | ||
| 269 | * @return the number of bytes stored in <code>output</code> | ||
| 270 | * | ||
| 271 | * @exception ShortBufferException if the given output buffer is too small | ||
| 272 | * to hold the result | ||
| 273 | */ | ||
| 274 | protected int engineUpdate(byte[] input, int inputOffset, int inputLen, | ||
| 275 | byte[] output, int outputOffset) | ||
| 276 | throws ShortBufferException { | ||
| 277 | return core.update(input, inputOffset, inputLen, output, | ||
| 278 | outputOffset); | ||
| 279 | } | ||
| 280 | |||
| 281 | /** | ||
| 282 | * Encrypts or decrypts data in a single-part operation, | ||
| 283 | * or finishes a multiple-part operation. | ||
| 284 | * The data is encrypted or decrypted, depending on how this cipher was | ||
| 285 | * initialized. | ||
| 286 | * | ||
| 287 | * <p>The first <code>inputLen</code> bytes in the <code>input</code> | ||
| 288 | * buffer, starting at <code>inputOffset</code>, and any input bytes that | ||
| 289 | * may have been buffered during a previous <code>update</code> operation, | ||
| 290 | * are processed, with padding (if requested) being applied. | ||
| 291 | * The result is stored in a new buffer. | ||
| 292 | * | ||
| 293 | * <p>The cipher is reset to its initial state (uninitialized) after this | ||
| 294 | * call. | ||
| 295 | * | ||
| 296 | * @param input the input buffer | ||
| 297 | * @param inputOffset the offset in <code>input</code> where the input | ||
| 298 | * starts | ||
| 299 | * @param inputLen the input length | ||
| 300 | * | ||
| 301 | * @return the new buffer with the result | ||
| 302 | * | ||
| 303 | * @exception IllegalBlockSizeException if this cipher is a block cipher, | ||
| 304 | * no padding has been requested (only in encryption mode), and the total | ||
| 305 | * input length of the data processed by this cipher is not a multiple of | ||
| 306 | * block size | ||
| 307 | * @exception BadPaddingException if this cipher is in decryption mode, | ||
| 308 | * and (un)padding has been requested, but the decrypted data is not | ||
| 309 | * bounded by the appropriate padding bytes | ||
| 310 | */ | ||
| 311 | protected byte[] engineDoFinal(byte[] input, int inputOffset, | ||
| 312 | int inputLen) | ||
| 313 | throws IllegalBlockSizeException, BadPaddingException { | ||
| 314 | return core.doFinal(input, inputOffset, inputLen); | ||
| 315 | } | ||
| 316 | |||
| 317 | /** | ||
| 318 | * Encrypts or decrypts data in a single-part operation, | ||
| 319 | * or finishes a multiple-part operation. | ||
| 320 | * The data is encrypted or decrypted, depending on how this cipher was | ||
| 321 | * initialized. | ||
| 322 | * | ||
| 323 | * <p>The first <code>inputLen</code> bytes in the <code>input</code> | ||
| 324 | * buffer, starting at <code>inputOffset</code>, and any input bytes that | ||
| 325 | * may have been buffered during a previous <code>update</code> operation, | ||
| 326 | * are processed, with padding (if requested) being applied. | ||
| 327 | * The result is stored in the <code>output</code> buffer, starting at | ||
| 328 | * <code>outputOffset</code>. | ||
| 329 | * | ||
| 330 | * <p>The cipher is reset to its initial state (uninitialized) after this | ||
| 331 | * call. | ||
| 332 | * | ||
| 333 | * @param input the input buffer | ||
| 334 | * @param inputOffset the offset in <code>input</code> where the input | ||
| 335 | * starts | ||
| 336 | * @param inputLen the input length | ||
| 337 | * @param output the buffer for the result | ||
| 338 | * @param outputOffset the offset in <code>output</code> where the result | ||
| 339 | * is stored | ||
| 340 | * | ||
| 341 | * @return the number of bytes stored in <code>output</code> | ||
| 342 | * | ||
| 343 | * @exception IllegalBlockSizeException if this cipher is a block cipher, | ||
| 344 | * no padding has been requested (only in encryption mode), and the total | ||
| 345 | * input length of the data processed by this cipher is not a multiple of | ||
| 346 | * block size | ||
| 347 | * @exception ShortBufferException if the given output buffer is too small | ||
| 348 | * to hold the result | ||
| 349 | * @exception BadPaddingException if this cipher is in decryption mode, | ||
| 350 | * and (un)padding has been requested, but the decrypted data is not | ||
| 351 | * bounded by the appropriate padding bytes | ||
| 352 | */ | ||
| 353 | protected int engineDoFinal(byte[] input, int inputOffset, int inputLen, | ||
| 354 | byte[] output, int outputOffset) | ||
| 355 | throws IllegalBlockSizeException, ShortBufferException, | ||
| 356 | BadPaddingException { | ||
| 357 | return core.doFinal(input, inputOffset, inputLen, output, | ||
| 358 | outputOffset); | ||
| 359 | } | ||
| 360 | |||
| 361 | /** | ||
| 362 | * Returns the key size of the given key object. | ||
| 363 | * | ||
| 364 | * @param key the key object. | ||
| 365 | * | ||
| 366 | * @return the key size of the given key object. | ||
| 367 | * | ||
| 368 | * @exception InvalidKeyException if <code>key</code> is invalid. | ||
| 369 | */ | ||
| 370 | protected int engineGetKeySize(Key key) throws InvalidKeyException { | ||
| 371 | byte[] encoded = key.getEncoded(); | ||
| 372 | if (encoded.length != 8) { | ||
| 373 | throw new InvalidKeyException("Invalid key length: " + | ||
| 374 | encoded.length + " bytes"); | ||
| 375 | } | ||
| 376 | return 56; | ||
| 377 | } | ||
| 378 | |||
| 379 | /** | ||
| 380 | * Wrap a key. | ||
| 381 | * | ||
| 382 | * @param key the key to be wrapped. | ||
| 383 | * | ||
| 384 | * @return the wrapped key. | ||
| 385 | * | ||
| 386 | * @exception IllegalBlockSizeException if this cipher is a block | ||
| 387 | * cipher, no padding has been requested, and the length of the | ||
| 388 | * encoding of the key to be wrapped is not a | ||
| 389 | * multiple of the block size. | ||
| 390 | * | ||
| 391 | * @exception InvalidKeyException if it is impossible or unsafe to | ||
| 392 | * wrap the key with this cipher (e.g., a hardware protected key is | ||
| 393 | * being passed to a software only cipher). | ||
| 394 | */ | ||
| 395 | protected byte[] engineWrap(Key key) | ||
| 396 | throws IllegalBlockSizeException, InvalidKeyException { | ||
| 397 | return core.wrap(key); | ||
| 398 | } | ||
| 399 | |||
| 400 | /** | ||
| 401 | * Unwrap a previously wrapped key. | ||
| 402 | * | ||
| 403 | * @param wrappedKey the key to be unwrapped. | ||
| 404 | * | ||
| 405 | * @param wrappedKeyAlgorithm the algorithm the wrapped key is for. | ||
| 406 | * | ||
| 407 | * @param wrappedKeyType the type of the wrapped key. | ||
| 408 | * This is one of <code>Cipher.SECRET_KEY</code>, | ||
| 409 | * <code>Cipher.PRIVATE_KEY</code>, or <code>Cipher.PUBLIC_KEY</code>. | ||
| 410 | * | ||
| 411 | * @return the unwrapped key. | ||
| 412 | * | ||
| 413 | * @exception NoSuchAlgorithmException if no installed providers | ||
| 414 | * can create keys of type <code>wrappedKeyType</code> for the | ||
| 415 | * <code>wrappedKeyAlgorithm</code>. | ||
| 416 | * | ||
| 417 | * @exception InvalidKeyException if <code>wrappedKey</code> does not | ||
| 418 | * represent a wrapped key of type <code>wrappedKeyType</code> for | ||
| 419 | * the <code>wrappedKeyAlgorithm</code>. | ||
| 420 | */ | ||
| 421 | protected Key engineUnwrap(byte[] wrappedKey, | ||
| 422 | String wrappedKeyAlgorithm, | ||
| 423 | int wrappedKeyType) | ||
| 424 | throws InvalidKeyException, NoSuchAlgorithmException { | ||
| 425 | return core.unwrap(wrappedKey, wrappedKeyAlgorithm, | ||
| 426 | wrappedKeyType); | ||
| 427 | } | ||
| 428 | } | ||
| @@ -0,0 +1,39 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | /** | ||
| 29 | * This class defines the constants used by the DES implementation. | ||
| 30 | * | ||
| 31 | * @author Gigi Ankeny | ||
| 32 | * | ||
| 33 | * @see DESCipher | ||
| 34 | */ | ||
| 35 | |||
| 36 | interface DESConstants { | ||
| 37 | |||
| 38 | int DES_BLOCK_SIZE = 8; | ||
| 39 | } | ||
| @@ -0,0 +1,1145 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.security.InvalidKeyException; | ||
| 29 | |||
| 30 | /** | ||
| 31 | * This is the internal DES class responsible for encryption and | ||
| 32 | * decryption of a byte array of size <code>DES_BLOCK_SIZE</code>. | ||
| 33 | * | ||
| 34 | * @author Gigi Ankeny | ||
| 35 | * @author Jan Luehe | ||
| 36 | * | ||
| 37 | * | ||
| 38 | * @see DESConstants | ||
| 39 | * @see DESCipher | ||
| 40 | */ | ||
| 41 | |||
| 42 | class DESCrypt extends SymmetricCipher implements DESConstants { | ||
| 43 | private static final int s0p[] = { | ||
| 44 | 0x00410100, 0x00010000, 0x40400000, 0x40410100, 0x00400000, | ||
| 45 | 0x40010100, 0x40010000, 0x40400000, 0x40010100, 0x00410100, | ||
| 46 | 0x00410000, 0x40000100, 0x40400100, 0x00400000, 0x00000000, | ||
| 47 | 0x40010000, 0x00010000, 0x40000000, 0x00400100, 0x00010100, | ||
| 48 | 0x40410100, 0x00410000, 0x40000100, 0x00400100, 0x40000000, | ||
| 49 | 0x00000100, 0x00010100, 0x40410000, 0x00000100, 0x40400100, | ||
| 50 | 0x40410000, 0x00000000, 0x00000000, 0x40410100, 0x00400100, | ||
| 51 | 0x40010000, 0x00410100, 0x00010000, 0x40000100, 0x00400100, | ||
| 52 | 0x40410000, 0x00000100, 0x00010100, 0x40400000, 0x40010100, | ||
| 53 | 0x40000000, 0x40400000, 0x00410000, 0x40410100, 0x00010100, | ||
| 54 | 0x00410000, 0x40400100, 0x00400000, 0x40000100, 0x40010000, | ||
| 55 | 0x00000000, 0x00010000, 0x00400000, 0x40400100, 0x00410100, | ||
| 56 | 0x40000000, 0x40410000, 0x00000100, 0x40010100, | ||
| 57 | }; | ||
| 58 | |||
| 59 | private static final int s1p[] = { | ||
| 60 | 0x08021002, 0x00000000, 0x00021000, 0x08020000, 0x08000002, | ||
| 61 | 0x00001002, 0x08001000, 0x00021000, 0x00001000, 0x08020002, | ||
| 62 | 0x00000002, 0x08001000, 0x00020002, 0x08021000, 0x08020000, | ||
| 63 | 0x00000002, 0x00020000, 0x08001002, 0x08020002, 0x00001000, | ||
| 64 | 0x00021002, 0x08000000, 0x00000000, 0x00020002, 0x08001002, | ||
| 65 | 0x00021002, 0x08021000, 0x08000002, 0x08000000, 0x00020000, | ||
| 66 | 0x00001002, 0x08021002, 0x00020002, 0x08021000, 0x08001000, | ||
| 67 | 0x00021002, 0x08021002, 0x00020002, 0x08000002, 0x00000000, | ||
| 68 | 0x08000000, 0x00001002, 0x00020000, 0x08020002, 0x00001000, | ||
| 69 | 0x08000000, 0x00021002, 0x08001002, 0x08021000, 0x00001000, | ||
| 70 | 0x00000000, 0x08000002, 0x00000002, 0x08021002, 0x00021000, | ||
| 71 | 0x08020000, 0x08020002, 0x00020000, 0x00001002, 0x08001000, | ||
| 72 | 0x08001002, 0x00000002, 0x08020000, 0x00021000, | ||
| 73 | }; | ||
| 74 | |||
| 75 | private static final int s2p[] = { | ||
| 76 | 0x20800000, 0x00808020, 0x00000020, 0x20800020, 0x20008000, | ||
| 77 | 0x00800000, 0x20800020, 0x00008020, 0x00800020, 0x00008000, | ||
| 78 | 0x00808000, 0x20000000, 0x20808020, 0x20000020, 0x20000000, | ||
| 79 | 0x20808000, 0x00000000, 0x20008000, 0x00808020, 0x00000020, | ||
| 80 | 0x20000020, 0x20808020, 0x00008000, 0x20800000, 0x20808000, | ||
| 81 | 0x00800020, 0x20008020, 0x00808000, 0x00008020, 0x00000000, | ||
| 82 | 0x00800000, 0x20008020, 0x00808020, 0x00000020, 0x20000000, | ||
| 83 | 0x00008000, 0x20000020, 0x20008000, 0x00808000, 0x20800020, | ||
| 84 | 0x00000000, 0x00808020, 0x00008020, 0x20808000, 0x20008000, | ||
| 85 | 0x00800000, 0x20808020, 0x20000000, 0x20008020, 0x20800000, | ||
| 86 | 0x00800000, 0x20808020, 0x00008000, 0x00800020, 0x20800020, | ||
| 87 | 0x00008020, 0x00800020, 0x00000000, 0x20808000, 0x20000020, | ||
| 88 | 0x20800000, 0x20008020, 0x00000020, 0x00808000, | ||
| 89 | }; | ||
| 90 | |||
| 91 | private static final int s3p[] = { | ||
| 92 | 0x00080201, 0x02000200, 0x00000001, 0x02080201, 0x00000000, | ||
| 93 | 0x02080000, 0x02000201, 0x00080001, 0x02080200, 0x02000001, | ||
| 94 | 0x02000000, 0x00000201, 0x02000001, 0x00080201, 0x00080000, | ||
| 95 | 0x02000000, 0x02080001, 0x00080200, 0x00000200, 0x00000001, | ||
| 96 | 0x00080200, 0x02000201, 0x02080000, 0x00000200, 0x00000201, | ||
| 97 | 0x00000000, 0x00080001, 0x02080200, 0x02000200, 0x02080001, | ||
| 98 | 0x02080201, 0x00080000, 0x02080001, 0x00000201, 0x00080000, | ||
| 99 | 0x02000001, 0x00080200, 0x02000200, 0x00000001, 0x02080000, | ||
| 100 | 0x02000201, 0x00000000, 0x00000200, 0x00080001, 0x00000000, | ||
| 101 | 0x02080001, 0x02080200, 0x00000200, 0x02000000, 0x02080201, | ||
| 102 | 0x00080201, 0x00080000, 0x02080201, 0x00000001, 0x02000200, | ||
| 103 | 0x00080201, 0x00080001, 0x00080200, 0x02080000, 0x02000201, | ||
| 104 | 0x00000201, 0x02000000, 0x02000001, 0x02080200, | ||
| 105 | }; | ||
| 106 | |||
| 107 | private static final int s4p[] = { | ||
| 108 | 0x01000000, 0x00002000, 0x00000080, 0x01002084, 0x01002004, | ||
| 109 | 0x01000080, 0x00002084, 0x01002000, 0x00002000, 0x00000004, | ||
| 110 | 0x01000004, 0x00002080, 0x01000084, 0x01002004, 0x01002080, | ||
| 111 | 0x00000000, 0x00002080, 0x01000000, 0x00002004, 0x00000084, | ||
| 112 | 0x01000080, 0x00002084, 0x00000000, 0x01000004, 0x00000004, | ||
| 113 | 0x01000084, 0x01002084, 0x00002004, 0x01002000, 0x00000080, | ||
| 114 | 0x00000084, 0x01002080, 0x01002080, 0x01000084, 0x00002004, | ||
| 115 | 0x01002000, 0x00002000, 0x00000004, 0x01000004, 0x01000080, | ||
| 116 | 0x01000000, 0x00002080, 0x01002084, 0x00000000, 0x00002084, | ||
| 117 | 0x01000000, 0x00000080, 0x00002004, 0x01000084, 0x00000080, | ||
| 118 | 0x00000000, 0x01002084, 0x01002004, 0x01002080, 0x00000084, | ||
| 119 | 0x00002000, 0x00002080, 0x01002004, 0x01000080, 0x00000084, | ||
| 120 | 0x00000004, 0x00002084, 0x01002000, 0x01000004, | ||
| 121 | }; | ||
| 122 | |||
| 123 | private static final int s5p[] = { | ||
| 124 | 0x10000008, 0x00040008, 0x00000000, 0x10040400, 0x00040008, | ||
| 125 | 0x00000400, 0x10000408, 0x00040000, 0x00000408, 0x10040408, | ||
| 126 | 0x00040400, 0x10000000, 0x10000400, 0x10000008, 0x10040000, | ||
| 127 | 0x00040408, 0x00040000, 0x10000408, 0x10040008, 0x00000000, | ||
| 128 | 0x00000400, 0x00000008, 0x10040400, 0x10040008, 0x10040408, | ||
| 129 | 0x10040000, 0x10000000, 0x00000408, 0x00000008, 0x00040400, | ||
| 130 | 0x00040408, 0x10000400, 0x00000408, 0x10000000, 0x10000400, | ||
| 131 | 0x00040408, 0x10040400, 0x00040008, 0x00000000, 0x10000400, | ||
| 132 | 0x10000000, 0x00000400, 0x10040008, 0x00040000, 0x00040008, | ||
| 133 | 0x10040408, 0x00040400, 0x00000008, 0x10040408, 0x00040400, | ||
| 134 | 0x00040000, 0x10000408, 0x10000008, 0x10040000, 0x00040408, | ||
| 135 | 0x00000000, 0x00000400, 0x10000008, 0x10000408, 0x10040400, | ||
| 136 | 0x10040000, 0x00000408, 0x00000008, 0x10040008, | ||
| 137 | }; | ||
| 138 | |||
| 139 | private static final int s6p[] = { | ||
| 140 | 0x00000800, 0x00000040, 0x00200040, 0x80200000, 0x80200840, | ||
| 141 | 0x80000800, 0x00000840, 0x00000000, 0x00200000, 0x80200040, | ||
| 142 | 0x80000040, 0x00200800, 0x80000000, 0x00200840, 0x00200800, | ||
| 143 | 0x80000040, 0x80200040, 0x00000800, 0x80000800, 0x80200840, | ||
| 144 | 0x00000000, 0x00200040, 0x80200000, 0x00000840, 0x80200800, | ||
| 145 | 0x80000840, 0x00200840, 0x80000000, 0x80000840, 0x80200800, | ||
| 146 | 0x00000040, 0x00200000, 0x80000840, 0x00200800, 0x80200800, | ||
| 147 | 0x80000040, 0x00000800, 0x00000040, 0x00200000, 0x80200800, | ||
| 148 | 0x80200040, 0x80000840, 0x00000840, 0x00000000, 0x00000040, | ||
| 149 | 0x80200000, 0x80000000, 0x00200040, 0x00000000, 0x80200040, | ||
| 150 | 0x00200040, 0x00000840, 0x80000040, 0x00000800, 0x80200840, | ||
| 151 | 0x00200000, 0x00200840, 0x80000000, 0x80000800, 0x80200840, | ||
| 152 | 0x80200000, 0x00200840, 0x00200800, 0x80000800, | ||
| 153 | }; | ||
| 154 | |||
| 155 | private static final int s7p[] = { | ||
| 156 | 0x04100010, 0x04104000, 0x00004010, 0x00000000, 0x04004000, | ||
| 157 | 0x00100010, 0x04100000, 0x04104010, 0x00000010, 0x04000000, | ||
| 158 | 0x00104000, 0x00004010, 0x00104010, 0x04004010, 0x04000010, | ||
| 159 | 0x04100000, 0x00004000, 0x00104010, 0x00100010, 0x04004000, | ||
| 160 | 0x04104010, 0x04000010, 0x00000000, 0x00104000, 0x04000000, | ||
| 161 | 0x00100000, 0x04004010, 0x04100010, 0x00100000, 0x00004000, | ||
| 162 | 0x04104000, 0x00000010, 0x00100000, 0x00004000, 0x04000010, | ||
| 163 | 0x04104010, 0x00004010, 0x04000000, 0x00000000, 0x00104000, | ||
| 164 | 0x04100010, 0x04004010, 0x04004000, 0x00100010, 0x04104000, | ||
| 165 | 0x00000010, 0x00100010, 0x04004000, 0x04104010, 0x00100000, | ||
| 166 | 0x04100000, 0x04000010, 0x00104000, 0x00004010, 0x04004010, | ||
| 167 | 0x04100000, 0x00000010, 0x04104000, 0x00104010, 0x00000000, | ||
| 168 | 0x04000000, 0x04100010, 0x00004000, 0x00104010, | ||
| 169 | }; | ||
| 170 | |||
| 171 | private static final int permRight0[] = { | ||
| 172 | 0x00000000, 0x40000000, 0x00400000, 0x40400000, 0x00004000, | ||
| 173 | 0x40004000, 0x00404000, 0x40404000, 0x00000040, 0x40000040, | ||
| 174 | 0x00400040, 0x40400040, 0x00004040, 0x40004040, 0x00404040, | ||
| 175 | 0x40404040, | ||
| 176 | }; | ||
| 177 | |||
| 178 | private static final int permLeft1[] = { | ||
| 179 | 0x00000000, 0x40000000, 0x00400000, 0x40400000, 0x00004000, | ||
| 180 | 0x40004000, 0x00404000, 0x40404000, 0x00000040, 0x40000040, | ||
| 181 | 0x00400040, 0x40400040, 0x00004040, 0x40004040, 0x00404040, | ||
| 182 | 0x40404040, | ||
| 183 | }; | ||
| 184 | |||
| 185 | private static final int permRight2[] = { | ||
| 186 | 0x00000000, 0x10000000, 0x00100000, 0x10100000, 0x00001000, | ||
| 187 | 0x10001000, 0x00101000, 0x10101000, 0x00000010, 0x10000010, | ||
| 188 | 0x00100010, 0x10100010, 0x00001010, 0x10001010, 0x00101010, | ||
| 189 | 0x10101010, | ||
| 190 | }; | ||
| 191 | |||
| 192 | private static final int permLeft3[] = { | ||
| 193 | 0x00000000, 0x10000000, 0x00100000, 0x10100000, 0x00001000, | ||
| 194 | 0x10001000, 0x00101000, 0x10101000, 0x00000010, 0x10000010, | ||
| 195 | 0x00100010, 0x10100010, 0x00001010, 0x10001010, 0x00101010, | ||
| 196 | 0x10101010, | ||
| 197 | }; | ||
| 198 | |||
| 199 | private static final int permRight4[] = { | ||
| 200 | 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000400, | ||
| 201 | 0x04000400, 0x00040400, 0x04040400, 0x00000004, 0x04000004, | ||
| 202 | 0x00040004, 0x04040004, 0x00000404, 0x04000404, 0x00040404, | ||
| 203 | 0x04040404, | ||
| 204 | }; | ||
| 205 | |||
| 206 | private static final int permLeft5[] = { | ||
| 207 | 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000400, | ||
| 208 | 0x04000400, 0x00040400, 0x04040400, 0x00000004, 0x04000004, | ||
| 209 | 0x00040004, 0x04040004, 0x00000404, 0x04000404, 0x00040404, | ||
| 210 | 0x04040404, | ||
| 211 | }; | ||
| 212 | |||
| 213 | private static final int permRight6[] = { | ||
| 214 | 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, | ||
| 215 | 0x01000100, 0x00010100, 0x01010100, 0x00000001, 0x01000001, | ||
| 216 | 0x00010001, 0x01010001, 0x00000101, 0x01000101, 0x00010101, | ||
| 217 | 0x01010101, | ||
| 218 | }; | ||
| 219 | |||
| 220 | private static final int permLeft7[] = { | ||
| 221 | 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, | ||
| 222 | 0x01000100, 0x00010100, 0x01010100, 0x00000001, 0x01000001, | ||
| 223 | 0x00010001, 0x01010001, 0x00000101, 0x01000101, 0x00010101, | ||
| 224 | 0x01010101, | ||
| 225 | }; | ||
| 226 | |||
| 227 | private static final int permRight8[] = { | ||
| 228 | 0x00000000, 0x80000000, 0x00800000, 0x80800000, 0x00008000, | ||
| 229 | 0x80008000, 0x00808000, 0x80808000, 0x00000080, 0x80000080, | ||
| 230 | 0x00800080, 0x80800080, 0x00008080, 0x80008080, 0x00808080, | ||
| 231 | 0x80808080, | ||
| 232 | }; | ||
| 233 | |||
| 234 | private static final int permLeft9[] = { | ||
| 235 | 0x00000000, 0x80000000, 0x00800000, 0x80800000, 0x00008000, | ||
| 236 | 0x80008000, 0x00808000, 0x80808000, 0x00000080, 0x80000080, | ||
| 237 | 0x00800080, 0x80800080, 0x00008080, 0x80008080, 0x00808080, | ||
| 238 | 0x80808080, | ||
| 239 | }; | ||
| 240 | |||
| 241 | private static final int permRightA[] = { | ||
| 242 | 0x00000000, 0x20000000, 0x00200000, 0x20200000, 0x00002000, | ||
| 243 | 0x20002000, 0x00202000, 0x20202000, 0x00000020, 0x20000020, | ||
| 244 | 0x00200020, 0x20200020, 0x00002020, 0x20002020, 0x00202020, | ||
| 245 | 0x20202020, | ||
| 246 | }; | ||
| 247 | |||
| 248 | private static final int permLeftB[] = { | ||
| 249 | 0x00000000, 0x20000000, 0x00200000, 0x20200000, 0x00002000, | ||
| 250 | 0x20002000, 0x00202000, 0x20202000, 0x00000020, 0x20000020, | ||
| 251 | 0x00200020, 0x20200020, 0x00002020, 0x20002020, 0x00202020, | ||
| 252 | 0x20202020, | ||
| 253 | }; | ||
| 254 | |||
| 255 | private static final int permRightC[] = { | ||
| 256 | 0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00000800, | ||
| 257 | 0x08000800, 0x00080800, 0x08080800, 0x00000008, 0x08000008, | ||
| 258 | 0x00080008, 0x08080008, 0x00000808, 0x08000808, 0x00080808, | ||
| 259 | 0x08080808, | ||
| 260 | }; | ||
| 261 | |||
| 262 | private static final int permLeftD[] = { | ||
| 263 | 0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00000800, | ||
| 264 | 0x08000800, 0x00080800, 0x08080800, 0x00000008, 0x08000008, | ||
| 265 | 0x00080008, 0x08080008, 0x00000808, 0x08000808, 0x00080808, | ||
| 266 | 0x08080808, | ||
| 267 | }; | ||
| 268 | |||
| 269 | private static final int permRightE[] = { | ||
| 270 | 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200, | ||
| 271 | 0x02000200, 0x00020200, 0x02020200, 0x00000002, 0x02000002, | ||
| 272 | 0x00020002, 0x02020002, 0x00000202, 0x02000202, 0x00020202, | ||
| 273 | 0x02020202, | ||
| 274 | }; | ||
| 275 | |||
| 276 | private static final int permLeftF[] = { | ||
| 277 | 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200, | ||
| 278 | 0x02000200, 0x00020200, 0x02020200, 0x00000002, 0x02000002, | ||
| 279 | 0x00020002, 0x02020002, 0x00000202, 0x02000202, 0x00020202, | ||
| 280 | 0x02020202, | ||
| 281 | }; | ||
| 282 | |||
| 283 | /* | ||
| 284 | * Initial Permutation | ||
| 285 | */ | ||
| 286 | private static final int initPermLeft0[] = { | ||
| 287 | 0x00000000, 0x00008000, 0x00000000, 0x00008000, 0x00000080, | ||
| 288 | 0x00008080, 0x00000080, 0x00008080, 0x00000000, 0x00008000, | ||
| 289 | 0x00000000, 0x00008000, 0x00000080, 0x00008080, 0x00000080, | ||
| 290 | 0x00008080, | ||
| 291 | }; | ||
| 292 | |||
| 293 | private static final int initPermRight0[] = { | ||
| 294 | 0x00000000, 0x00000000, 0x00008000, 0x00008000, 0x00000000, | ||
| 295 | 0x00000000, 0x00008000, 0x00008000, 0x00000080, 0x00000080, | ||
| 296 | 0x00008080, 0x00008080, 0x00000080, 0x00000080, 0x00008080, | ||
| 297 | 0x00008080, | ||
| 298 | }; | ||
| 299 | |||
| 300 | private static final int initPermLeft1[] = { | ||
| 301 | 0x00000000, 0x80000000, 0x00000000, 0x80000000, 0x00800000, | ||
| 302 | 0x80800000, 0x00800000, 0x80800000, 0x00000000, 0x80000000, | ||
| 303 | 0x00000000, 0x80000000, 0x00800000, 0x80800000, 0x00800000, | ||
| 304 | 0x80800000, | ||
| 305 | }; | ||
| 306 | |||
| 307 | private static final int initPermRight1[] = { | ||
| 308 | 0x00000000, 0x00000000, 0x80000000, 0x80000000, 0x00000000, | ||
| 309 | 0x00000000, 0x80000000, 0x80000000, 0x00800000, 0x00800000, | ||
| 310 | 0x80800000, 0x80800000, 0x00800000, 0x00800000, 0x80800000, | ||
| 311 | 0x80800000, | ||
| 312 | }; | ||
| 313 | |||
| 314 | private static final int initPermLeft2[] = { | ||
| 315 | 0x00000000, 0x00004000, 0x00000000, 0x00004000, 0x00000040, | ||
| 316 | 0x00004040, 0x00000040, 0x00004040, 0x00000000, 0x00004000, | ||
| 317 | 0x00000000, 0x00004000, 0x00000040, 0x00004040, 0x00000040, | ||
| 318 | 0x00004040, | ||
| 319 | }; | ||
| 320 | |||
| 321 | private static final int initPermRight2[] = { | ||
| 322 | 0x00000000, 0x00000000, 0x00004000, 0x00004000, 0x00000000, | ||
| 323 | 0x00000000, 0x00004000, 0x00004000, 0x00000040, 0x00000040, | ||
| 324 | 0x00004040, 0x00004040, 0x00000040, 0x00000040, 0x00004040, | ||
| 325 | 0x00004040, | ||
| 326 | }; | ||
| 327 | |||
| 328 | private static final int initPermLeft3[] = { | ||
| 329 | 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00400000, | ||
| 330 | 0x40400000, 0x00400000, 0x40400000, 0x00000000, 0x40000000, | ||
| 331 | 0x00000000, 0x40000000, 0x00400000, 0x40400000, 0x00400000, | ||
| 332 | 0x40400000, | ||
| 333 | }; | ||
| 334 | |||
| 335 | private static final int initPermRight3[] = { | ||
| 336 | 0x00000000, 0x00000000, 0x40000000, 0x40000000, 0x00000000, | ||
| 337 | 0x00000000, 0x40000000, 0x40000000, 0x00400000, 0x00400000, | ||
| 338 | 0x40400000, 0x40400000, 0x00400000, 0x00400000, 0x40400000, | ||
| 339 | 0x40400000, | ||
| 340 | }; | ||
| 341 | |||
| 342 | private static final int initPermLeft4[] = { | ||
| 343 | 0x00000000, 0x00002000, 0x00000000, 0x00002000, 0x00000020, | ||
| 344 | 0x00002020, 0x00000020, 0x00002020, 0x00000000, 0x00002000, | ||
| 345 | 0x00000000, 0x00002000, 0x00000020, 0x00002020, 0x00000020, | ||
| 346 | 0x00002020, | ||
| 347 | }; | ||
| 348 | |||
| 349 | private static final int initPermRight4[] = { | ||
| 350 | 0x00000000, 0x00000000, 0x00002000, 0x00002000, 0x00000000, | ||
| 351 | 0x00000000, 0x00002000, 0x00002000, 0x00000020, 0x00000020, | ||
| 352 | 0x00002020, 0x00002020, 0x00000020, 0x00000020, 0x00002020, | ||
| 353 | 0x00002020, | ||
| 354 | }; | ||
| 355 | |||
| 356 | private static final int initPermLeft5[] = { | ||
| 357 | 0x00000000, 0x20000000, 0x00000000, 0x20000000, 0x00200000, | ||
| 358 | 0x20200000, 0x00200000, 0x20200000, 0x00000000, 0x20000000, | ||
| 359 | 0x00000000, 0x20000000, 0x00200000, 0x20200000, 0x00200000, | ||
| 360 | 0x20200000, | ||
| 361 | }; | ||
| 362 | |||
| 363 | private static final int initPermRight5[] = { | ||
| 364 | 0x00000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000, | ||
| 365 | 0x00000000, 0x20000000, 0x20000000, 0x00200000, 0x00200000, | ||
| 366 | 0x20200000, 0x20200000, 0x00200000, 0x00200000, 0x20200000, | ||
| 367 | 0x20200000, | ||
| 368 | }; | ||
| 369 | |||
| 370 | private static final int initPermLeft6[] = { | ||
| 371 | 0x00000000, 0x00001000, 0x00000000, 0x00001000, 0x00000010, | ||
| 372 | 0x00001010, 0x00000010, 0x00001010, 0x00000000, 0x00001000, | ||
| 373 | 0x00000000, 0x00001000, 0x00000010, 0x00001010, 0x00000010, | ||
| 374 | 0x00001010, | ||
| 375 | }; | ||
| 376 | |||
| 377 | private static final int initPermRight6[] = { | ||
| 378 | 0x00000000, 0x00000000, 0x00001000, 0x00001000, 0x00000000, | ||
| 379 | 0x00000000, 0x00001000, 0x00001000, 0x00000010, 0x00000010, | ||
| 380 | 0x00001010, 0x00001010, 0x00000010, 0x00000010, 0x00001010, | ||
| 381 | 0x00001010, | ||
| 382 | }; | ||
| 383 | |||
| 384 | private static final int initPermLeft7[] = { | ||
| 385 | 0x00000000, 0x10000000, 0x00000000, 0x10000000, 0x00100000, | ||
| 386 | 0x10100000, 0x00100000, 0x10100000, 0x00000000, 0x10000000, | ||
| 387 | 0x00000000, 0x10000000, 0x00100000, 0x10100000, 0x00100000, | ||
| 388 | 0x10100000, | ||
| 389 | }; | ||
| 390 | |||
| 391 | private static final int initPermRight7[] = { | ||
| 392 | 0x00000000, 0x00000000, 0x10000000, 0x10000000, 0x00000000, | ||
| 393 | 0x00000000, 0x10000000, 0x10000000, 0x00100000, 0x00100000, | ||
| 394 | 0x10100000, 0x10100000, 0x00100000, 0x00100000, 0x10100000, | ||
| 395 | 0x10100000, | ||
| 396 | }; | ||
| 397 | |||
| 398 | private static final int initPermLeft8[] = { | ||
| 399 | 0x00000000, 0x00000800, 0x00000000, 0x00000800, 0x00000008, | ||
| 400 | 0x00000808, 0x00000008, 0x00000808, 0x00000000, 0x00000800, | ||
| 401 | 0x00000000, 0x00000800, 0x00000008, 0x00000808, 0x00000008, | ||
| 402 | 0x00000808, | ||
| 403 | }; | ||
| 404 | |||
| 405 | private static final int initPermRight8[] = { | ||
| 406 | 0x00000000, 0x00000000, 0x00000800, 0x00000800, 0x00000000, | ||
| 407 | 0x00000000, 0x00000800, 0x00000800, 0x00000008, 0x00000008, | ||
| 408 | 0x00000808, 0x00000808, 0x00000008, 0x00000008, 0x00000808, | ||
| 409 | 0x00000808, | ||
| 410 | }; | ||
| 411 | |||
| 412 | private static final int initPermLeft9[] = { | ||
| 413 | 0x00000000, 0x08000000, 0x00000000, 0x08000000, 0x00080000, | ||
| 414 | 0x08080000, 0x00080000, 0x08080000, 0x00000000, 0x08000000, | ||
| 415 | 0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00080000, | ||
| 416 | 0x08080000, | ||
| 417 | }; | ||
| 418 | |||
| 419 | private static final int initPermRight9[] = { | ||
| 420 | 0x00000000, 0x00000000, 0x08000000, 0x08000000, 0x00000000, | ||
| 421 | 0x00000000, 0x08000000, 0x08000000, 0x00080000, 0x00080000, | ||
| 422 | 0x08080000, 0x08080000, 0x00080000, 0x00080000, 0x08080000, | ||
| 423 | 0x08080000, | ||
| 424 | }; | ||
| 425 | |||
| 426 | private static final int initPermLeftA[] = { | ||
| 427 | 0x00000000, 0x00000400, 0x00000000, 0x00000400, 0x00000004, | ||
| 428 | 0x00000404, 0x00000004, 0x00000404, 0x00000000, 0x00000400, | ||
| 429 | 0x00000000, 0x00000400, 0x00000004, 0x00000404, 0x00000004, | ||
| 430 | 0x00000404, | ||
| 431 | }; | ||
| 432 | |||
| 433 | private static final int initPermRightA[] = { | ||
| 434 | 0x00000000, 0x00000000, 0x00000400, 0x00000400, 0x00000000, | ||
| 435 | 0x00000000, 0x00000400, 0x00000400, 0x00000004, 0x00000004, | ||
| 436 | 0x00000404, 0x00000404, 0x00000004, 0x00000004, 0x00000404, | ||
| 437 | 0x00000404, | ||
| 438 | }; | ||
| 439 | |||
| 440 | private static final int initPermLeftB[] = { | ||
| 441 | 0x00000000, 0x04000000, 0x00000000, 0x04000000, 0x00040000, | ||
| 442 | 0x04040000, 0x00040000, 0x04040000, 0x00000000, 0x04000000, | ||
| 443 | 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00040000, | ||
| 444 | 0x04040000, | ||
| 445 | }; | ||
| 446 | |||
| 447 | private static final int initPermRightB[] = { | ||
| 448 | 0x00000000, 0x00000000, 0x04000000, 0x04000000, 0x00000000, | ||
| 449 | 0x00000000, 0x04000000, 0x04000000, 0x00040000, 0x00040000, | ||
| 450 | 0x04040000, 0x04040000, 0x00040000, 0x00040000, 0x04040000, | ||
| 451 | 0x04040000, | ||
| 452 | }; | ||
| 453 | |||
| 454 | private static final int initPermLeftC[] = { | ||
| 455 | 0x00000000, 0x00000200, 0x00000000, 0x00000200, 0x00000002, | ||
| 456 | 0x00000202, 0x00000002, 0x00000202, 0x00000000, 0x00000200, | ||
| 457 | 0x00000000, 0x00000200, 0x00000002, 0x00000202, 0x00000002, | ||
| 458 | 0x00000202, | ||
| 459 | }; | ||
| 460 | |||
| 461 | private static final int initPermRightC[] = { | ||
| 462 | 0x00000000, 0x00000000, 0x00000200, 0x00000200, 0x00000000, | ||
| 463 | 0x00000000, 0x00000200, 0x00000200, 0x00000002, 0x00000002, | ||
| 464 | 0x00000202, 0x00000202, 0x00000002, 0x00000002, 0x00000202, | ||
| 465 | 0x00000202, | ||
| 466 | }; | ||
| 467 | |||
| 468 | private static final int initPermLeftD[] = { | ||
| 469 | 0x00000000, 0x02000000, 0x00000000, 0x02000000, 0x00020000, | ||
| 470 | 0x02020000, 0x00020000, 0x02020000, 0x00000000, 0x02000000, | ||
| 471 | 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00020000, | ||
| 472 | 0x02020000, | ||
| 473 | }; | ||
| 474 | |||
| 475 | private static final int initPermRightD[] = { | ||
| 476 | 0x00000000, 0x00000000, 0x02000000, 0x02000000, 0x00000000, | ||
| 477 | 0x00000000, 0x02000000, 0x02000000, 0x00020000, 0x00020000, | ||
| 478 | 0x02020000, 0x02020000, 0x00020000, 0x00020000, 0x02020000, | ||
| 479 | 0x02020000, | ||
| 480 | }; | ||
| 481 | |||
| 482 | private static final int initPermLeftE[] = { | ||
| 483 | 0x00000000, 0x00000100, 0x00000000, 0x00000100, 0x00000001, | ||
| 484 | 0x00000101, 0x00000001, 0x00000101, 0x00000000, 0x00000100, | ||
| 485 | 0x00000000, 0x00000100, 0x00000001, 0x00000101, 0x00000001, | ||
| 486 | 0x00000101, | ||
| 487 | }; | ||
| 488 | |||
| 489 | private static final int initPermRightE[] = { | ||
| 490 | 0x00000000, 0x00000000, 0x00000100, 0x00000100, 0x00000000, | ||
| 491 | 0x00000000, 0x00000100, 0x00000100, 0x00000001, 0x00000001, | ||
| 492 | 0x00000101, 0x00000101, 0x00000001, 0x00000001, 0x00000101, | ||
| 493 | 0x00000101, | ||
| 494 | }; | ||
| 495 | |||
| 496 | private static final int initPermLeftF[] = { | ||
| 497 | 0x00000000, 0x01000000, 0x00000000, 0x01000000, 0x00010000, | ||
| 498 | 0x01010000, 0x00010000, 0x01010000, 0x00000000, 0x01000000, | ||
| 499 | 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00010000, | ||
| 500 | 0x01010000, | ||
| 501 | }; | ||
| 502 | |||
| 503 | private static final int initPermRightF[] = { | ||
| 504 | 0x00000000, 0x00000000, 0x01000000, 0x01000000, 0x00000000, | ||
| 505 | 0x00000000, 0x01000000, 0x01000000, 0x00010000, 0x00010000, | ||
| 506 | 0x01010000, 0x01010000, 0x00010000, 0x00010000, 0x01010000, | ||
| 507 | 0x01010000, | ||
| 508 | }; | ||
| 509 | |||
| 510 | /* | ||
| 511 | * the encryption key array after expansion and permutation | ||
| 512 | */ | ||
| 513 | byte[] expandedKey = null; | ||
| 514 | |||
| 515 | /* | ||
| 516 | * Are we encrypting or decrypting? | ||
| 517 | */ | ||
| 518 | boolean decrypting = false; | ||
| 519 | |||
| 520 | /** | ||
| 521 | * Returns this cipher's block size. | ||
| 522 | * | ||
| 523 | * @return this cipher's block size | ||
| 524 | */ | ||
| 525 | int getBlockSize() { | ||
| 526 | return DES_BLOCK_SIZE; | ||
| 527 | } | ||
| 528 | |||
| 529 | void init(boolean decrypting, String algorithm, byte[] rawKey) | ||
| 530 | throws InvalidKeyException { | ||
| 531 | this.decrypting = decrypting; | ||
| 532 | if (!algorithm.equalsIgnoreCase("DES")) { | ||
| 533 | throw new InvalidKeyException("Wrong algorithm: DES required"); | ||
| 534 | } | ||
| 535 | if (rawKey.length != DES_BLOCK_SIZE) { | ||
| 536 | throw new InvalidKeyException("Wrong key size"); | ||
| 537 | } | ||
| 538 | expandKey(rawKey); | ||
| 539 | } | ||
| 540 | |||
| 541 | /** | ||
| 542 | * Performs encryption operation. | ||
| 543 | * | ||
| 544 | * <p>The input plain text <code>plain</code>, starting at | ||
| 545 | * <code>plainOffset</code> and ending at | ||
| 546 | * <code>(plainOffset + len - 1)</code>, is encrypted. | ||
| 547 | * The result is stored in <code>cipher</code>, starting at | ||
| 548 | * <code>cipherOffset</code>. | ||
| 549 | * | ||
| 550 | * <p>The subclass that implements Cipher should ensure that | ||
| 551 | * <code>init</code> has been called before this method is called. | ||
| 552 | * | ||
| 553 | * @param plain the buffer with the input data to be encrypted | ||
| 554 | * @param plainOffset the offset in <code>plain</code> | ||
| 555 | * @param plainLen the length of the input data | ||
| 556 | * @param cipher the buffer for the result | ||
| 557 | * @param cipherOffset the offset in <code>cipher</code> | ||
| 558 | * | ||
| 559 | * @exception IllegalBlockSizeException if the input length is different | ||
| 560 | * from the cipher's block size | ||
| 561 | */ | ||
| 562 | void encryptBlock(byte[] plain, int plainOffset, | ||
| 563 | byte[] cipher, int cipherOffset) | ||
| 564 | { | ||
| 565 | cipherBlock(plain, plainOffset, cipher, cipherOffset); | ||
| 566 | } | ||
| 567 | |||
| 568 | /** | ||
| 569 | * Performs decryption operation. | ||
| 570 | * | ||
| 571 | * <p>The input cipher text <code>cipher</code>, starting at | ||
| 572 | * <code>cipherOffset</code> and ending at | ||
| 573 | * <code>(cipherOffset + len - 1)</code>, is decrypted. | ||
| 574 | * The result is stored in <code>plain</code>, starting at | ||
| 575 | * <code>plainOffset</code>. | ||
| 576 | * | ||
| 577 | * <p>The subclass that implements Cipher should ensure that | ||
| 578 | * <code>init</code> has been called before this method is called. | ||
| 579 | * | ||
| 580 | * @param cipher the buffer with the input data to be decrypted | ||
| 581 | * @param cipherOffset the offset in <code>cipherOffset</code> | ||
| 582 | * @param cipherLen the length of the input data | ||
| 583 | * @param plain the buffer for the result | ||
| 584 | * @param plainOffset the offset in <code>plain</code> | ||
| 585 | * | ||
| 586 | * @exception IllegalBlockSizeException if the input length is different | ||
| 587 | * from the cipher's block size | ||
| 588 | */ | ||
| 589 | void decryptBlock(byte[] cipher, int cipherOffset, | ||
| 590 | byte[] plain, int plainOffset) | ||
| 591 | { | ||
| 592 | cipherBlock(cipher, cipherOffset, plain, plainOffset); | ||
| 593 | } | ||
| 594 | |||
| 595 | |||
| 596 | void cipherBlock(byte[] in, int inOffset, byte[] out, int outOffset) { | ||
| 597 | byte key[]; | ||
| 598 | int temp; | ||
| 599 | int i, j; | ||
| 600 | int offset; | ||
| 601 | int left, right; | ||
| 602 | |||
| 603 | left = initialPermutationLeft(in, inOffset); | ||
| 604 | right = initialPermutationRight(in, inOffset); | ||
| 605 | |||
| 606 | key = expandedKey; | ||
| 607 | |||
| 608 | if (decrypting) { | ||
| 609 | offset = 16 - DES_BLOCK_SIZE; | ||
| 610 | j = 128 - DES_BLOCK_SIZE; | ||
| 611 | |||
| 612 | } else { | ||
| 613 | offset = 0 - DES_BLOCK_SIZE; | ||
| 614 | j = 0; | ||
| 615 | } | ||
| 616 | |||
| 617 | for (i = 0; i < 16; i++) { | ||
| 618 | // make the first and last bit adjacent | ||
| 619 | // move the first bit to the last | ||
| 620 | temp = (right << 1) | ((right >> 31) & 1); | ||
| 621 | |||
| 622 | // mangler function: | ||
| 623 | // every 6 bit is fed into the sbox, which | ||
| 624 | // produces 4-bit output | ||
| 625 | left ^= s0p[(int)((temp & 0x3f) ^ key[j+0])] | ||
| 626 | ^ s1p[(int)(((temp >> 4) & 0x3f) ^ key[j+1])] | ||
| 627 | ^ s2p[(int)(((temp >> 8) & 0x3f) ^ key[j+2])] | ||
| 628 | ^ s3p[(int)(((temp >> 12) & 0x3f) ^ key[j+3])] | ||
| 629 | ^ s4p[(int)(((temp >> 16) & 0x3f) ^ key[j+4])] | ||
| 630 | ^ s5p[(int)(((temp >> 20) & 0x3f) ^ key[j+5])] | ||
| 631 | ^ s6p[(int)(((temp >> 24) & 0x3f) ^ key[j+6])]; | ||
| 632 | |||
| 633 | // make the last sbox input the last bit from right[0] | ||
| 634 | temp = ((right & 1) << 5) | ((right >> 27) & 0x1f); | ||
| 635 | left ^= s7p[(int)(temp ^ key[j+7])]; | ||
| 636 | temp = left; | ||
| 637 | left = right; | ||
| 638 | right = temp; | ||
| 639 | j -= offset; | ||
| 640 | } | ||
| 641 | |||
| 642 | temp = left; | ||
| 643 | left = right; | ||
| 644 | right = temp; | ||
| 645 | perm(left, right, out, outOffset); | ||
| 646 | } | ||
| 647 | |||
| 648 | private static void perm(int left, int right, | ||
| 649 | byte out[], int offset) { | ||
| 650 | int low, high, temp; | ||
| 651 | |||
| 652 | temp = left; | ||
| 653 | high = permRight0[temp & 0x0000000f]; | ||
| 654 | temp >>= 4; | ||
| 655 | low = permLeft1[temp & 0x0000000f]; | ||
| 656 | temp >>= 4; | ||
| 657 | high |= permRight2[temp & 0x0000000f]; | ||
| 658 | temp >>= 4; | ||
| 659 | low |= permLeft3[temp & 0x0000000f]; | ||
| 660 | temp >>= 4; | ||
| 661 | high |= permRight4[temp & 0x0000000f]; | ||
| 662 | temp >>= 4; | ||
| 663 | low |= permLeft5[temp & 0x0000000f]; | ||
| 664 | temp >>= 4; | ||
| 665 | high |= permRight6[temp & 0x0000000f]; | ||
| 666 | temp >>= 4; | ||
| 667 | low |= permLeft7[temp & 0x0000000f]; | ||
| 668 | |||
| 669 | temp = right; | ||
| 670 | high |= permRight8[temp & 0x0000000f]; | ||
| 671 | temp >>= 4; | ||
| 672 | low |= permLeft9[temp & 0x0000000f]; | ||
| 673 | temp >>= 4; | ||
| 674 | high |= permRightA[temp & 0x0000000f]; | ||
| 675 | temp >>= 4; | ||
| 676 | low |= permLeftB[temp & 0x0000000f]; | ||
| 677 | temp >>= 4; | ||
| 678 | high |= permRightC[temp & 0x0000000f]; | ||
| 679 | temp >>= 4; | ||
| 680 | low |= permLeftD[temp & 0x0000000f]; | ||
| 681 | temp >>= 4; | ||
| 682 | high |= permRightE[temp & 0x0000000f]; | ||
| 683 | temp >>= 4; | ||
| 684 | low |= permLeftF[temp & 0x0000000f]; | ||
| 685 | |||
| 686 | |||
| 687 | out[offset + 0] = (byte)low; | ||
| 688 | out[offset + 1] = (byte)(low >> 8); | ||
| 689 | out[offset + 2] = (byte)(low >> 16); | ||
| 690 | out[offset + 3] = (byte)(low >> 24); | ||
| 691 | out[offset + 4] = (byte)high; | ||
| 692 | out[offset + 5] = (byte)(high >> 8); | ||
| 693 | out[offset + 6] = (byte)(high >> 16); | ||
| 694 | out[offset + 7] = (byte)(high >> 24); | ||
| 695 | |||
| 696 | } | ||
| 697 | |||
| 698 | private static int initialPermutationLeft(byte block[], int offset) { | ||
| 699 | int l; | ||
| 700 | |||
| 701 | l = initPermLeft1[block[offset] & 0xf]; | ||
| 702 | l |= initPermLeft0[(block[offset] >> 4) & 0xf]; | ||
| 703 | l |= initPermLeft3[block[offset + 1] & 0xf]; | ||
| 704 | l |= initPermLeft2[(block[offset + 1] >> 4) & 0xf]; | ||
| 705 | l |= initPermLeft5[block[offset + 2] & 0xf]; | ||
| 706 | l |= initPermLeft4[(block[offset + 2] >> 4) & 0xf]; | ||
| 707 | l |= initPermLeft7[block[offset + 3] & 0xf]; | ||
| 708 | l |= initPermLeft6[(block[offset + 3] >> 4) & 0xf]; | ||
| 709 | l |= initPermLeft9[block[offset + 4] & 0xf]; | ||
| 710 | l |= initPermLeft8[(block[offset + 4] >> 4) & 0xf]; | ||
| 711 | l |= initPermLeftB[block[offset + 5] & 0xf]; | ||
| 712 | l |= initPermLeftA[(block[offset + 5] >> 4) & 0xf]; | ||
| 713 | l |= initPermLeftD[block[offset + 6] & 0xf]; | ||
| 714 | l |= initPermLeftC[(block[offset + 6] >> 4) & 0xf]; | ||
| 715 | l |= initPermLeftF[block[offset + 7] & 0xf]; | ||
| 716 | l |= initPermLeftE[(block[offset + 7] >> 4) & 0xf]; | ||
| 717 | return l; | ||
| 718 | } | ||
| 719 | |||
| 720 | private static int initialPermutationRight(byte block[], int offset) { | ||
| 721 | int l; | ||
| 722 | |||
| 723 | l = initPermRight1[block[offset] & 0xf]; | ||
| 724 | l |= initPermRight0[(block[offset] >> 4) & 0xf]; | ||
| 725 | l |= initPermRight3[block[offset + 1] & 0xf]; | ||
| 726 | l |= initPermRight2[(block[offset + 1] >> 4) & 0xf]; | ||
| 727 | l |= initPermRight5[block[offset + 2] & 0xf]; | ||
| 728 | l |= initPermRight4[(block[offset + 2] >> 4) & 0xf]; | ||
| 729 | l |= initPermRight7[block[offset + 3] & 0xf]; | ||
| 730 | l |= initPermRight6[(block[offset + 3] >> 4) & 0xf]; | ||
| 731 | l |= initPermRight9[block[offset + 4] & 0xf]; | ||
| 732 | l |= initPermRight8[(block[offset + 4] >> 4) & 0xf]; | ||
| 733 | l |= initPermRightB[block[offset + 5] & 0xf]; | ||
| 734 | l |= initPermRightA[(block[offset + 5] >> 4) & 0xf]; | ||
| 735 | l |= initPermRightD[block[offset + 6] & 0xf]; | ||
| 736 | l |= initPermRightC[(block[offset + 6] >> 4) & 0xf]; | ||
| 737 | l |= initPermRightF[block[offset + 7] & 0xf]; | ||
| 738 | l |= initPermRightE[(block[offset + 7] >> 4) & 0xf]; | ||
| 739 | return l; | ||
| 740 | } | ||
| 741 | |||
| 742 | void expandKey(byte key[]) { | ||
| 743 | int octet; | ||
| 744 | byte ek[] = new byte[128]; | ||
| 745 | |||
| 746 | octet = key[0]; | ||
| 747 | if ((octet & 0x80) != 0) { | ||
| 748 | ek[ 3] |= 2; ek[ 9] |= 8; ek[ 18] |= 8; | ||
| 749 | ek[ 27] |= 32; ek[ 33] |= 2; ek[ 42] |= 16; | ||
| 750 | ek[ 48] |= 8; ek[ 65] |= 16; ek[ 74] |= 2; | ||
| 751 | ek[ 80] |= 2; ek[ 89] |= 4; ek[ 99] |= 16; | ||
| 752 | ek[104] |= 4; ek[122] |= 32; | ||
| 753 | } | ||
| 754 | if ((octet & 0x40) != 0) { | ||
| 755 | ek[ 1] |= 4; ek[ 8] |= 1; ek[ 18] |= 4; | ||
| 756 | ek[ 25] |= 32; ek[ 34] |= 32; ek[ 41] |= 8; | ||
| 757 | ek[ 50] |= 8; ek[ 59] |= 32; ek[ 64] |= 16; | ||
| 758 | ek[ 75] |= 4; ek[ 90] |= 1; ek[ 97] |= 16; | ||
| 759 | ek[106] |= 2; ek[112] |= 2; ek[123] |= 1; | ||
| 760 | } | ||
| 761 | if ((octet & 0x20) != 0) { | ||
| 762 | ek[ 2] |= 1; ek[ 19] |= 8; ek[ 35] |= 1; | ||
| 763 | ek[ 40] |= 1; ek[ 50] |= 4; ek[ 57] |= 32; | ||
| 764 | ek[ 75] |= 2; ek[ 80] |= 32; ek[ 89] |= 1; | ||
| 765 | ek[ 96] |= 16; ek[107] |= 4; ek[120] |= 8; | ||
| 766 | } | ||
| 767 | if ((octet & 0x10) != 0) { | ||
| 768 | ek[ 4] |= 32; ek[ 20] |= 2; ek[ 31] |= 4; | ||
| 769 | ek[ 37] |= 32; ek[ 47] |= 1; ek[ 54] |= 1; | ||
| 770 | ek[ 63] |= 2; ek[ 68] |= 1; ek[ 78] |= 4; | ||
| 771 | ek[ 84] |= 8; ek[101] |= 16; ek[108] |= 4; | ||
| 772 | ek[119] |= 16; ek[126] |= 8; | ||
| 773 | } | ||
| 774 | if ((octet & 0x8) != 0) { | ||
| 775 | ek[ 5] |= 4; ek[ 15] |= 4; ek[ 21] |= 32; | ||
| 776 | ek[ 31] |= 1; ek[ 38] |= 1; ek[ 47] |= 2; | ||
| 777 | ek[ 53] |= 2; ek[ 68] |= 8; ek[ 85] |= 16; | ||
| 778 | ek[ 92] |= 4; ek[103] |= 16; ek[108] |= 32; | ||
| 779 | ek[118] |= 32; ek[124] |= 2; | ||
| 780 | } | ||
| 781 | if ((octet & 0x4) != 0) { | ||
| 782 | ek[ 15] |= 2; ek[ 21] |= 2; ek[ 39] |= 8; | ||
| 783 | ek[ 46] |= 16; ek[ 55] |= 32; ek[ 61] |= 1; | ||
| 784 | ek[ 71] |= 16; ek[ 76] |= 32; ek[ 86] |= 32; | ||
| 785 | ek[ 93] |= 4; ek[102] |= 2; ek[108] |= 16; | ||
| 786 | ek[117] |= 8; ek[126] |= 1; | ||
| 787 | } | ||
| 788 | if ((octet & 0x2) != 0) { | ||
| 789 | ek[ 14] |= 16; ek[ 23] |= 32; ek[ 29] |= 1; | ||
| 790 | ek[ 38] |= 8; ek[ 52] |= 2; ek[ 63] |= 4; | ||
| 791 | ek[ 70] |= 2; ek[ 76] |= 16; ek[ 85] |= 8; | ||
| 792 | ek[100] |= 1; ek[110] |= 4; ek[116] |= 8; | ||
| 793 | ek[127] |= 8; | ||
| 794 | } | ||
| 795 | octet = key[1]; | ||
| 796 | if ((octet & 0x80) != 0) { | ||
| 797 | ek[ 1] |= 8; ek[ 8] |= 32; ek[ 17] |= 1; | ||
| 798 | ek[ 24] |= 16; ek[ 35] |= 4; ek[ 50] |= 1; | ||
| 799 | ek[ 57] |= 16; ek[ 67] |= 8; ek[ 83] |= 1; | ||
| 800 | ek[ 88] |= 1; ek[ 98] |= 4; ek[105] |= 32; | ||
| 801 | ek[114] |= 32; ek[123] |= 2; | ||
| 802 | } | ||
| 803 | if ((octet & 0x40) != 0) { | ||
| 804 | ek[ 0] |= 1; ek[ 11] |= 16; ek[ 16] |= 4; | ||
| 805 | ek[ 35] |= 2; ek[ 40] |= 32; ek[ 49] |= 1; | ||
| 806 | ek[ 56] |= 16; ek[ 65] |= 2; ek[ 74] |= 16; | ||
| 807 | ek[ 80] |= 8; ek[ 99] |= 8; ek[115] |= 1; | ||
| 808 | ek[121] |= 4; | ||
| 809 | } | ||
| 810 | if ((octet & 0x20) != 0) { | ||
| 811 | ek[ 9] |= 16; ek[ 18] |= 2; ek[ 24] |= 2; | ||
| 812 | ek[ 33] |= 4; ek[ 43] |= 16; ek[ 48] |= 4; | ||
| 813 | ek[ 66] |= 32; ek[ 73] |= 8; ek[ 82] |= 8; | ||
| 814 | ek[ 91] |= 32; ek[ 97] |= 2; ek[106] |= 16; | ||
| 815 | ek[112] |= 8; ek[122] |= 1; | ||
| 816 | } | ||
| 817 | if ((octet & 0x10) != 0) { | ||
| 818 | ek[ 14] |= 32; ek[ 21] |= 4; ek[ 30] |= 2; | ||
| 819 | ek[ 36] |= 16; ek[ 45] |= 8; ek[ 60] |= 1; | ||
| 820 | ek[ 69] |= 2; ek[ 87] |= 8; ek[ 94] |= 16; | ||
| 821 | ek[103] |= 32; ek[109] |= 1; ek[118] |= 8; | ||
| 822 | ek[124] |= 32; | ||
| 823 | } | ||
| 824 | if ((octet & 0x8) != 0) { | ||
| 825 | ek[ 7] |= 4; ek[ 14] |= 2; ek[ 20] |= 16; | ||
| 826 | ek[ 29] |= 8; ek[ 44] |= 1; ek[ 54] |= 4; | ||
| 827 | ek[ 60] |= 8; ek[ 71] |= 8; ek[ 78] |= 16; | ||
| 828 | ek[ 87] |= 32; ek[ 93] |= 1; ek[102] |= 8; | ||
| 829 | ek[116] |= 2; ek[125] |= 4; | ||
| 830 | } | ||
| 831 | if ((octet & 0x4) != 0) { | ||
| 832 | ek[ 7] |= 2; ek[ 12] |= 1; ek[ 22] |= 4; | ||
| 833 | ek[ 28] |= 8; ek[ 45] |= 16; ek[ 52] |= 4; | ||
| 834 | ek[ 63] |= 16; ek[ 70] |= 8; ek[ 84] |= 2; | ||
| 835 | ek[ 95] |= 4; ek[101] |= 32; ek[111] |= 1; | ||
| 836 | ek[118] |= 1; | ||
| 837 | } | ||
| 838 | if ((octet & 0x2) != 0) { | ||
| 839 | ek[ 6] |= 16; ek[ 13] |= 16; ek[ 20] |= 4; | ||
| 840 | ek[ 31] |= 16; ek[ 36] |= 32; ek[ 46] |= 32; | ||
| 841 | ek[ 53] |= 4; ek[ 62] |= 2; ek[ 69] |= 32; | ||
| 842 | ek[ 79] |= 1; ek[ 86] |= 1; ek[ 95] |= 2; | ||
| 843 | ek[101] |= 2; ek[119] |= 8; | ||
| 844 | } | ||
| 845 | octet = key[2]; | ||
| 846 | if ((octet & 0x80) != 0) { | ||
| 847 | ek[ 0] |= 32; ek[ 10] |= 8; ek[ 19] |= 32; | ||
| 848 | ek[ 25] |= 2; ek[ 34] |= 16; ek[ 40] |= 8; | ||
| 849 | ek[ 59] |= 8; ek[ 66] |= 2; ek[ 72] |= 2; | ||
| 850 | ek[ 81] |= 4; ek[ 91] |= 16; ek[ 96] |= 4; | ||
| 851 | ek[115] |= 2; ek[121] |= 8; | ||
| 852 | } | ||
| 853 | if ((octet & 0x40) != 0) { | ||
| 854 | ek[ 3] |= 16; ek[ 10] |= 4; ek[ 17] |= 32; | ||
| 855 | ek[ 26] |= 32; ek[ 33] |= 8; ek[ 42] |= 8; | ||
| 856 | ek[ 51] |= 32; ek[ 57] |= 2; ek[ 67] |= 4; | ||
| 857 | ek[ 82] |= 1; ek[ 89] |= 16; ek[ 98] |= 2; | ||
| 858 | ek[104] |= 2; ek[113] |= 4; ek[120] |= 1; | ||
| 859 | } | ||
| 860 | if ((octet & 0x20) != 0) { | ||
| 861 | ek[ 1] |= 16; ek[ 11] |= 8; ek[ 27] |= 1; | ||
| 862 | ek[ 32] |= 1; ek[ 42] |= 4; ek[ 49] |= 32; | ||
| 863 | ek[ 58] |= 32; ek[ 67] |= 2; ek[ 72] |= 32; | ||
| 864 | ek[ 81] |= 1; ek[ 88] |= 16; ek[ 99] |= 4; | ||
| 865 | ek[114] |= 1; | ||
| 866 | } | ||
| 867 | if ((octet & 0x10) != 0) { | ||
| 868 | ek[ 6] |= 32; ek[ 12] |= 2; ek[ 23] |= 4; | ||
| 869 | ek[ 29] |= 32; ek[ 39] |= 1; ek[ 46] |= 1; | ||
| 870 | ek[ 55] |= 2; ek[ 61] |= 2; ek[ 70] |= 4; | ||
| 871 | ek[ 76] |= 8; ek[ 93] |= 16; ek[100] |= 4; | ||
| 872 | ek[111] |= 16; ek[116] |= 32; | ||
| 873 | } | ||
| 874 | if ((octet & 0x8) != 0) { | ||
| 875 | ek[ 6] |= 2; ek[ 13] |= 32; ek[ 23] |= 1; | ||
| 876 | ek[ 30] |= 1; ek[ 39] |= 2; ek[ 45] |= 2; | ||
| 877 | ek[ 63] |= 8; ek[ 77] |= 16; ek[ 84] |= 4; | ||
| 878 | ek[ 95] |= 16; ek[100] |= 32; ek[110] |= 32; | ||
| 879 | ek[117] |= 4; ek[127] |= 4; | ||
| 880 | } | ||
| 881 | if ((octet & 0x4) != 0) { | ||
| 882 | ek[ 4] |= 1; ek[ 13] |= 2; ek[ 31] |= 8; | ||
| 883 | ek[ 38] |= 16; ek[ 47] |= 32; ek[ 53] |= 1; | ||
| 884 | ek[ 62] |= 8; ek[ 68] |= 32; ek[ 78] |= 32; | ||
| 885 | ek[ 85] |= 4; ek[ 94] |= 2; ek[100] |= 16; | ||
| 886 | ek[109] |= 8; ek[127] |= 2; | ||
| 887 | } | ||
| 888 | if ((octet & 0x2) != 0) { | ||
| 889 | ek[ 5] |= 16; ek[ 15] |= 32; ek[ 21] |= 1; | ||
| 890 | ek[ 30] |= 8; ek[ 44] |= 2; ek[ 55] |= 4; | ||
| 891 | ek[ 61] |= 32; ek[ 68] |= 16; ek[ 77] |= 8; | ||
| 892 | ek[ 92] |= 1; ek[102] |= 4; ek[108] |= 8; | ||
| 893 | ek[126] |= 16; | ||
| 894 | } | ||
| 895 | octet = key[3]; | ||
| 896 | if ((octet & 0x80) != 0) { | ||
| 897 | ek[ 2] |= 8; ek[ 9] |= 1; ek[ 16] |= 16; | ||
| 898 | ek[ 27] |= 4; ek[ 42] |= 1; ek[ 49] |= 16; | ||
| 899 | ek[ 58] |= 2; ek[ 75] |= 1; ek[ 80] |= 1; | ||
| 900 | ek[ 90] |= 4; ek[ 97] |= 32; ek[106] |= 32; | ||
| 901 | ek[113] |= 8; ek[120] |= 32; | ||
| 902 | } | ||
| 903 | if ((octet & 0x40) != 0) { | ||
| 904 | ek[ 2] |= 4; ek[ 8] |= 4; ek[ 27] |= 2; | ||
| 905 | ek[ 32] |= 32; ek[ 41] |= 1; ek[ 48] |= 16; | ||
| 906 | ek[ 59] |= 4; ek[ 66] |= 16; ek[ 72] |= 8; | ||
| 907 | ek[ 91] |= 8; ek[107] |= 1; ek[112] |= 1; | ||
| 908 | ek[123] |= 16; | ||
| 909 | } | ||
| 910 | if ((octet & 0x20) != 0) { | ||
| 911 | ek[ 3] |= 8; ek[ 10] |= 2; ek[ 16] |= 2; | ||
| 912 | ek[ 25] |= 4; ek[ 35] |= 16; ek[ 40] |= 4; | ||
| 913 | ek[ 59] |= 2; ek[ 65] |= 8; ek[ 74] |= 8; | ||
| 914 | ek[ 83] |= 32; ek[ 89] |= 2; ek[ 98] |= 16; | ||
| 915 | ek[104] |= 8; ek[121] |= 16; | ||
| 916 | } | ||
| 917 | if ((octet & 0x10) != 0) { | ||
| 918 | ek[ 4] |= 2; ek[ 13] |= 4; ek[ 22] |= 2; | ||
| 919 | ek[ 28] |= 16; ek[ 37] |= 8; ek[ 52] |= 1; | ||
| 920 | ek[ 62] |= 4; ek[ 79] |= 8; ek[ 86] |= 16; | ||
| 921 | ek[ 95] |= 32; ek[101] |= 1; ek[110] |= 8; | ||
| 922 | ek[126] |= 32; | ||
| 923 | } | ||
| 924 | if ((octet & 0x8) != 0) { | ||
| 925 | ek[ 5] |= 32; ek[ 12] |= 16; ek[ 21] |= 8; | ||
| 926 | ek[ 36] |= 1; ek[ 46] |= 4; ek[ 52] |= 8; | ||
| 927 | ek[ 70] |= 16; ek[ 79] |= 32; ek[ 85] |= 1; | ||
| 928 | ek[ 94] |= 8; ek[108] |= 2; ek[119] |= 4; | ||
| 929 | ek[126] |= 2; | ||
| 930 | } | ||
| 931 | if ((octet & 0x4) != 0) { | ||
| 932 | ek[ 5] |= 2; ek[ 14] |= 4; ek[ 20] |= 8; | ||
| 933 | ek[ 37] |= 16; ek[ 44] |= 4; ek[ 55] |= 16; | ||
| 934 | ek[ 60] |= 32; ek[ 76] |= 2; ek[ 87] |= 4; | ||
| 935 | ek[ 93] |= 32; ek[103] |= 1; ek[110] |= 1; | ||
| 936 | ek[119] |= 2; ek[124] |= 1; | ||
| 937 | } | ||
| 938 | if ((octet & 0x2) != 0) { | ||
| 939 | ek[ 7] |= 32; ek[ 12] |= 4; ek[ 23] |= 16; | ||
| 940 | ek[ 28] |= 32; ek[ 38] |= 32; ek[ 45] |= 4; | ||
| 941 | ek[ 54] |= 2; ek[ 60] |= 16; ek[ 71] |= 1; | ||
| 942 | ek[ 78] |= 1; ek[ 87] |= 2; ek[ 93] |= 2; | ||
| 943 | ek[111] |= 8; ek[118] |= 16; ek[125] |= 16; | ||
| 944 | } | ||
| 945 | octet = key[4]; | ||
| 946 | if ((octet & 0x80) != 0) { | ||
| 947 | ek[ 1] |= 1; ek[ 11] |= 32; ek[ 17] |= 2; | ||
| 948 | ek[ 26] |= 16; ek[ 32] |= 8; ek[ 51] |= 8; | ||
| 949 | ek[ 64] |= 2; ek[ 73] |= 4; ek[ 83] |= 16; | ||
| 950 | ek[ 88] |= 4; ek[107] |= 2; ek[112] |= 32; | ||
| 951 | ek[122] |= 8; | ||
| 952 | } | ||
| 953 | if ((octet & 0x40) != 0) { | ||
| 954 | ek[ 0] |= 4; ek[ 9] |= 32; ek[ 18] |= 32; | ||
| 955 | ek[ 25] |= 8; ek[ 34] |= 8; ek[ 43] |= 32; | ||
| 956 | ek[ 49] |= 2; ek[ 58] |= 16; ek[ 74] |= 1; | ||
| 957 | ek[ 81] |= 16; ek[ 90] |= 2; ek[ 96] |= 2; | ||
| 958 | ek[105] |= 4; ek[115] |= 16; ek[122] |= 4; | ||
| 959 | } | ||
| 960 | if ((octet & 0x20) != 0) { | ||
| 961 | ek[ 2] |= 2; ek[ 19] |= 1; ek[ 24] |= 1; | ||
| 962 | ek[ 34] |= 4; ek[ 41] |= 32; ek[ 50] |= 32; | ||
| 963 | ek[ 57] |= 8; ek[ 64] |= 32; ek[ 73] |= 1; | ||
| 964 | ek[ 80] |= 16; ek[ 91] |= 4; ek[106] |= 1; | ||
| 965 | ek[113] |= 16; ek[123] |= 8; | ||
| 966 | } | ||
| 967 | if ((octet & 0x10) != 0) { | ||
| 968 | ek[ 3] |= 4; ek[ 10] |= 16; ek[ 16] |= 8; | ||
| 969 | ek[ 35] |= 8; ek[ 51] |= 1; ek[ 56] |= 1; | ||
| 970 | ek[ 67] |= 16; ek[ 72] |= 4; ek[ 91] |= 2; | ||
| 971 | ek[ 96] |= 32; ek[105] |= 1; ek[112] |= 16; | ||
| 972 | ek[121] |= 2; | ||
| 973 | } | ||
| 974 | if ((octet & 0x8) != 0) { | ||
| 975 | ek[ 4] |= 16; ek[ 15] |= 1; ek[ 22] |= 1; | ||
| 976 | ek[ 31] |= 2; ek[ 37] |= 2; ek[ 55] |= 8; | ||
| 977 | ek[ 62] |= 16; ek[ 69] |= 16; ek[ 76] |= 4; | ||
| 978 | ek[ 87] |= 16; ek[ 92] |= 32; ek[102] |= 32; | ||
| 979 | ek[109] |= 4; ek[118] |= 2; ek[125] |= 32; | ||
| 980 | } | ||
| 981 | if ((octet & 0x4) != 0) { | ||
| 982 | ek[ 6] |= 4; ek[ 23] |= 8; ek[ 30] |= 16; | ||
| 983 | ek[ 39] |= 32; ek[ 45] |= 1; ek[ 54] |= 8; | ||
| 984 | ek[ 70] |= 32; ek[ 77] |= 4; ek[ 86] |= 2; | ||
| 985 | ek[ 92] |= 16; ek[101] |= 8; ek[116] |= 1; | ||
| 986 | ek[125] |= 2; | ||
| 987 | } | ||
| 988 | if ((octet & 0x2) != 0) { | ||
| 989 | ek[ 4] |= 4; ek[ 13] |= 1; ek[ 22] |= 8; | ||
| 990 | ek[ 36] |= 2; ek[ 47] |= 4; ek[ 53] |= 32; | ||
| 991 | ek[ 63] |= 1; ek[ 69] |= 8; ek[ 84] |= 1; | ||
| 992 | ek[ 94] |= 4; ek[100] |= 8; ek[117] |= 16; | ||
| 993 | ek[127] |= 32; | ||
| 994 | } | ||
| 995 | octet = key[5]; | ||
| 996 | if ((octet & 0x80) != 0) { | ||
| 997 | ek[ 3] |= 32; ek[ 8] |= 16; ek[ 19] |= 4; | ||
| 998 | ek[ 34] |= 1; ek[ 41] |= 16; ek[ 50] |= 2; | ||
| 999 | ek[ 56] |= 2; ek[ 67] |= 1; ek[ 72] |= 1; | ||
| 1000 | ek[ 82] |= 4; ek[ 89] |= 32; ek[ 98] |= 32; | ||
| 1001 | ek[105] |= 8; ek[114] |= 8; ek[121] |= 1; | ||
| 1002 | } | ||
| 1003 | if ((octet & 0x40) != 0) { | ||
| 1004 | ek[ 1] |= 32; ek[ 19] |= 2; ek[ 24] |= 32; | ||
| 1005 | ek[ 33] |= 1; ek[ 40] |= 16; ek[ 51] |= 4; | ||
| 1006 | ek[ 64] |= 8; ek[ 83] |= 8; ek[ 99] |= 1; | ||
| 1007 | ek[104] |= 1; ek[114] |= 4; ek[120] |= 4; | ||
| 1008 | } | ||
| 1009 | if ((octet & 0x20) != 0) { | ||
| 1010 | ek[ 8] |= 2; ek[ 17] |= 4; ek[ 27] |= 16; | ||
| 1011 | ek[ 32] |= 4; ek[ 51] |= 2; ek[ 56] |= 32; | ||
| 1012 | ek[ 66] |= 8; ek[ 75] |= 32; ek[ 81] |= 2; | ||
| 1013 | ek[ 90] |= 16; ek[ 96] |= 8; ek[115] |= 8; | ||
| 1014 | ek[122] |= 2; | ||
| 1015 | } | ||
| 1016 | if ((octet & 0x10) != 0) { | ||
| 1017 | ek[ 2] |= 16; ek[ 18] |= 1; ek[ 25] |= 16; | ||
| 1018 | ek[ 34] |= 2; ek[ 40] |= 2; ek[ 49] |= 4; | ||
| 1019 | ek[ 59] |= 16; ek[ 66] |= 4; ek[ 73] |= 32; | ||
| 1020 | ek[ 82] |= 32; ek[ 89] |= 8; ek[ 98] |= 8; | ||
| 1021 | ek[107] |= 32; ek[113] |= 2; ek[123] |= 4; | ||
| 1022 | } | ||
| 1023 | if ((octet & 0x8) != 0) { | ||
| 1024 | ek[ 7] |= 1; ek[ 13] |= 8; ek[ 28] |= 1; | ||
| 1025 | ek[ 38] |= 4; ek[ 44] |= 8; ek[ 61] |= 16; | ||
| 1026 | ek[ 71] |= 32; ek[ 77] |= 1; ek[ 86] |= 8; | ||
| 1027 | ek[100] |= 2; ek[111] |= 4; ek[117] |= 32; | ||
| 1028 | ek[124] |= 16; | ||
| 1029 | } | ||
| 1030 | if ((octet & 0x4) != 0) { | ||
| 1031 | ek[ 12] |= 8; ek[ 29] |= 16; ek[ 36] |= 4; | ||
| 1032 | ek[ 47] |= 16; ek[ 52] |= 32; ek[ 62] |= 32; | ||
| 1033 | ek[ 68] |= 2; ek[ 79] |= 4; ek[ 85] |= 32; | ||
| 1034 | ek[ 95] |= 1; ek[102] |= 1; ek[111] |= 2; | ||
| 1035 | ek[117] |= 2; ek[126] |= 4; | ||
| 1036 | } | ||
| 1037 | if ((octet & 0x2) != 0) { | ||
| 1038 | ek[ 5] |= 1; ek[ 15] |= 16; ek[ 20] |= 32; | ||
| 1039 | ek[ 30] |= 32; ek[ 37] |= 4; ek[ 46] |= 2; | ||
| 1040 | ek[ 52] |= 16; ek[ 61] |= 8; ek[ 70] |= 1; | ||
| 1041 | ek[ 79] |= 2; ek[ 85] |= 2; ek[103] |= 8; | ||
| 1042 | ek[110] |= 16; ek[119] |= 32; ek[124] |= 4; | ||
| 1043 | } | ||
| 1044 | octet = key[6]; | ||
| 1045 | if ((octet & 0x80) != 0) { | ||
| 1046 | ek[ 0] |= 16; ek[ 9] |= 2; ek[ 18] |= 16; | ||
| 1047 | ek[ 24] |= 8; ek[ 43] |= 8; ek[ 59] |= 1; | ||
| 1048 | ek[ 65] |= 4; ek[ 75] |= 16; ek[ 80] |= 4; | ||
| 1049 | ek[ 99] |= 2; ek[104] |= 32; ek[113] |= 1; | ||
| 1050 | ek[123] |= 32; | ||
| 1051 | } | ||
| 1052 | if ((octet & 0x40) != 0) { | ||
| 1053 | ek[ 10] |= 32; ek[ 17] |= 8; ek[ 26] |= 8; | ||
| 1054 | ek[ 35] |= 32; ek[ 41] |= 2; ek[ 50] |= 16; | ||
| 1055 | ek[ 56] |= 8; ek[ 66] |= 1; ek[ 73] |= 16; | ||
| 1056 | ek[ 82] |= 2; ek[ 88] |= 2; ek[ 97] |= 4; | ||
| 1057 | ek[107] |= 16; ek[112] |= 4; ek[121] |= 32; | ||
| 1058 | } | ||
| 1059 | if ((octet & 0x20) != 0) { | ||
| 1060 | ek[ 0] |= 2; ek[ 11] |= 1; ek[ 16] |= 1; | ||
| 1061 | ek[ 26] |= 4; ek[ 33] |= 32; ek[ 42] |= 32; | ||
| 1062 | ek[ 49] |= 8; ek[ 58] |= 8; ek[ 65] |= 1; | ||
| 1063 | ek[ 72] |= 16; ek[ 83] |= 4; ek[ 98] |= 1; | ||
| 1064 | ek[105] |= 16; ek[114] |= 2; | ||
| 1065 | } | ||
| 1066 | if ((octet & 0x10) != 0) { | ||
| 1067 | ek[ 8] |= 8; ek[ 27] |= 8; ek[ 43] |= 1; | ||
| 1068 | ek[ 48] |= 1; ek[ 58] |= 4; ek[ 64] |= 4; | ||
| 1069 | ek[ 83] |= 2; ek[ 88] |= 32; ek[ 97] |= 1; | ||
| 1070 | ek[104] |= 16; ek[115] |= 4; ek[122] |= 16; | ||
| 1071 | } | ||
| 1072 | if ((octet & 0x8) != 0) { | ||
| 1073 | ek[ 5] |= 8; ek[ 14] |= 1; ek[ 23] |= 2; | ||
| 1074 | ek[ 29] |= 2; ek[ 47] |= 8; ek[ 54] |= 16; | ||
| 1075 | ek[ 63] |= 32; ek[ 68] |= 4; ek[ 79] |= 16; | ||
| 1076 | ek[ 84] |= 32; ek[ 94] |= 32; ek[101] |= 4; | ||
| 1077 | ek[110] |= 2; ek[116] |= 16; ek[127] |= 1; | ||
| 1078 | } | ||
| 1079 | if ((octet & 0x4) != 0) { | ||
| 1080 | ek[ 4] |= 8; ek[ 15] |= 8; ek[ 22] |= 16; | ||
| 1081 | ek[ 31] |= 32; ek[ 37] |= 1; ek[ 46] |= 8; | ||
| 1082 | ek[ 60] |= 2; ek[ 69] |= 4; ek[ 78] |= 2; | ||
| 1083 | ek[ 84] |= 16; ek[ 93] |= 8; ek[108] |= 1; | ||
| 1084 | ek[118] |= 4; | ||
| 1085 | } | ||
| 1086 | if ((octet & 0x2) != 0) { | ||
| 1087 | ek[ 7] |= 16; ek[ 14] |= 8; ek[ 28] |= 2; | ||
| 1088 | ek[ 39] |= 4; ek[ 45] |= 32; ek[ 55] |= 1; | ||
| 1089 | ek[ 62] |= 1; ek[ 76] |= 1; ek[ 86] |= 4; | ||
| 1090 | ek[ 92] |= 8; ek[109] |= 16; ek[116] |= 4; | ||
| 1091 | ek[125] |= 1; | ||
| 1092 | } | ||
| 1093 | octet = key[7]; | ||
| 1094 | if ((octet & 0x80) != 0) { | ||
| 1095 | ek[ 1] |= 2; ek[ 11] |= 4; ek[ 26] |= 1; | ||
| 1096 | ek[ 33] |= 16; ek[ 42] |= 2; ek[ 48] |= 2; | ||
| 1097 | ek[ 57] |= 4; ek[ 64] |= 1; ek[ 74] |= 4; | ||
| 1098 | ek[ 81] |= 32; ek[ 90] |= 32; ek[ 97] |= 8; | ||
| 1099 | ek[106] |= 8; ek[115] |= 32; ek[120] |= 16; | ||
| 1100 | } | ||
| 1101 | if ((octet & 0x40) != 0) { | ||
| 1102 | ek[ 2] |= 32; ek[ 11] |= 2; ek[ 16] |= 32; | ||
| 1103 | ek[ 25] |= 1; ek[ 32] |= 16; ek[ 43] |= 4; | ||
| 1104 | ek[ 58] |= 1; ek[ 75] |= 8; ek[ 91] |= 1; | ||
| 1105 | ek[ 96] |= 1; ek[106] |= 4; ek[113] |= 32; | ||
| 1106 | } | ||
| 1107 | if ((octet & 0x20) != 0) { | ||
| 1108 | ek[ 3] |= 1; ek[ 9] |= 4; ek[ 19] |= 16; | ||
| 1109 | ek[ 24] |= 4; ek[ 43] |= 2; ek[ 48] |= 32; | ||
| 1110 | ek[ 57] |= 1; ek[ 67] |= 32; ek[ 73] |= 2; | ||
| 1111 | ek[ 82] |= 16; ek[ 88] |= 8; ek[107] |= 8; | ||
| 1112 | ek[120] |= 2; | ||
| 1113 | } | ||
| 1114 | if ((octet & 0x10) != 0) { | ||
| 1115 | ek[ 0] |= 8; ek[ 10] |= 1; ek[ 17] |= 16; | ||
| 1116 | ek[ 26] |= 2; ek[ 32] |= 2; ek[ 41] |= 4; | ||
| 1117 | ek[ 51] |= 16; ek[ 56] |= 4; ek[ 65] |= 32; | ||
| 1118 | ek[ 74] |= 32; ek[ 81] |= 8; ek[ 90] |= 8; | ||
| 1119 | ek[ 99] |= 32; ek[105] |= 2; ek[114] |= 16; | ||
| 1120 | } | ||
| 1121 | if ((octet & 0x8) != 0) { | ||
| 1122 | ek[ 6] |= 1; ek[ 20] |= 1; ek[ 30] |= 4; | ||
| 1123 | ek[ 36] |= 8; ek[ 53] |= 16; ek[ 60] |= 4; | ||
| 1124 | ek[ 69] |= 1; ek[ 78] |= 8; ek[ 92] |= 2; | ||
| 1125 | ek[103] |= 4; ek[109] |= 32; ek[119] |= 1; | ||
| 1126 | ek[125] |= 8; | ||
| 1127 | } | ||
| 1128 | if ((octet & 0x4) != 0) { | ||
| 1129 | ek[ 7] |= 8; ek[ 21] |= 16; ek[ 28] |= 4; | ||
| 1130 | ek[ 39] |= 16; ek[ 44] |= 32; ek[ 54] |= 32; | ||
| 1131 | ek[ 61] |= 4; ek[ 71] |= 4; ek[ 77] |= 32; | ||
| 1132 | ek[ 87] |= 1; ek[ 94] |= 1; ek[103] |= 2; | ||
| 1133 | ek[109] |= 2; ek[124] |= 8; | ||
| 1134 | } | ||
| 1135 | if ((octet & 0x2) != 0) { | ||
| 1136 | ek[ 6] |= 8; ek[ 12] |= 32; ek[ 22] |= 32; | ||
| 1137 | ek[ 29] |= 4; ek[ 38] |= 2; ek[ 44] |= 16; | ||
| 1138 | ek[ 53] |= 8; ek[ 71] |= 2; ek[ 77] |= 2; | ||
| 1139 | ek[ 95] |= 8; ek[102] |= 16; ek[111] |= 32; | ||
| 1140 | ek[117] |= 1; ek[127] |= 16; | ||
| 1141 | } | ||
| 1142 | |||
| 1143 | expandedKey = ek; | ||
| 1144 | } | ||
| 1145 | } | ||
| @@ -0,0 +1,161 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.security.KeyRep; | ||
| 29 | import java.security.InvalidKeyException; | ||
| 30 | import javax.crypto.SecretKey; | ||
| 31 | import javax.crypto.spec.DESKeySpec; | ||
| 32 | |||
| 33 | /** | ||
| 34 | * This class represents a DES key. | ||
| 35 | * | ||
| 36 | * @author Jan Luehe | ||
| 37 | * | ||
| 38 | */ | ||
| 39 | |||
| 40 | final class DESKey implements SecretKey { | ||
| 41 | |||
| 42 | static final long serialVersionUID = 7724971015953279128L; | ||
| 43 | |||
| 44 | private byte[] key; | ||
| 45 | |||
| 46 | /** | ||
| 47 | * Uses the first 8 bytes of the given key as the DES key. | ||
| 48 | * | ||
| 49 | * @param key the buffer with the DES key bytes. | ||
| 50 | * | ||
| 51 | * @exception InvalidKeyException if less than 8 bytes are available for | ||
| 52 | * the key. | ||
| 53 | */ | ||
| 54 | DESKey(byte[] key) throws InvalidKeyException { | ||
| 55 | this(key, 0); | ||
| 56 | } | ||
| 57 | |||
| 58 | /** | ||
| 59 | * Uses the first 8 bytes in <code>key</code>, beginning at | ||
| 60 | * <code>offset</code>, as the DES key | ||
| 61 | * | ||
| 62 | * @param key the buffer with the DES key bytes. | ||
| 63 | * @param offset the offset in <code>key</code>, where the DES key bytes | ||
| 64 | * start. | ||
| 65 | * | ||
| 66 | * @exception InvalidKeyException if less than 8 bytes are available for | ||
| 67 | * the key. | ||
| 68 | */ | ||
| 69 | DESKey(byte[] key, int offset) throws InvalidKeyException { | ||
| 70 | if (key == null || key.length - offset < DESKeySpec.DES_KEY_LEN) { | ||
| 71 | throw new InvalidKeyException("Wrong key size"); | ||
| 72 | } | ||
| 73 | this.key = new byte[DESKeySpec.DES_KEY_LEN]; | ||
| 74 | System.arraycopy(key, offset, this.key, 0, DESKeySpec.DES_KEY_LEN); | ||
| 75 | DESKeyGenerator.setParityBit(this.key, 0); | ||
| 76 | } | ||
| 77 | |||
| 78 | public byte[] getEncoded() { | ||
| 79 | // Return a copy of the key, rather than a reference, | ||
| 80 | // so that the key data cannot be modified from outside | ||
| 81 | return (byte[])this.key.clone(); | ||
| 82 | } | ||
| 83 | |||
| 84 | public String getAlgorithm() { | ||
| 85 | return "DES"; | ||
| 86 | } | ||
| 87 | |||
| 88 | public String getFormat() { | ||
| 89 | return "RAW"; | ||
| 90 | } | ||
| 91 | |||
| 92 | /** | ||
| 93 | * Calculates a hash code value for the object. | ||
| 94 | * Objects that are equal will also have the same hashcode. | ||
| 95 | */ | ||
| 96 | public int hashCode() { | ||
| 97 | int retval = 0; | ||
| 98 | for (int i = 1; i < this.key.length; i++) { | ||
| 99 | retval += this.key[i] * i; | ||
| 100 | } | ||
| 101 | return(retval ^= "des".hashCode()); | ||
| 102 | } | ||
| 103 | |||
| 104 | public boolean equals(Object obj) { | ||
| 105 | if (this == obj) | ||
| 106 | return true; | ||
| 107 | |||
| 108 | if (!(obj instanceof SecretKey)) | ||
| 109 | return false; | ||
| 110 | |||
| 111 | String thatAlg = ((SecretKey)obj).getAlgorithm(); | ||
| 112 | if (!(thatAlg.equalsIgnoreCase("DES"))) | ||
| 113 | return false; | ||
| 114 | |||
| 115 | byte[] thatKey = ((SecretKey)obj).getEncoded(); | ||
| 116 | boolean ret = java.util.Arrays.equals(this.key, thatKey); | ||
| 117 | java.util.Arrays.fill(thatKey, (byte)0x00); | ||
| 118 | return ret; | ||
| 119 | } | ||
| 120 | |||
| 121 | /** | ||
| 122 | * readObject is called to restore the state of this key from | ||
| 123 | * a stream. | ||
| 124 | */ | ||
| 125 | private void readObject(java.io.ObjectInputStream s) | ||
| 126 | throws java.io.IOException, ClassNotFoundException | ||
| 127 | { | ||
| 128 | s.defaultReadObject(); | ||
| 129 | key = (byte[])key.clone(); | ||
| 130 | } | ||
| 131 | |||
| 132 | /** | ||
| 133 | * Replace the DES key to be serialized. | ||
| 134 | * | ||
| 135 | * @return the standard KeyRep object to be serialized | ||
| 136 | * | ||
| 137 | * @throws java.io.ObjectStreamException if a new object representing | ||
| 138 | * this DES key could not be created | ||
| 139 | */ | ||
| 140 | private Object writeReplace() throws java.io.ObjectStreamException { | ||
| 141 | return new KeyRep(KeyRep.Type.SECRET, | ||
| 142 | getAlgorithm(), | ||
| 143 | getFormat(), | ||
| 144 | getEncoded()); | ||
| 145 | } | ||
| 146 | |||
| 147 | /** | ||
| 148 | * Ensures that the bytes of this key are | ||
| 149 | * set to zero when there are no more references to it. | ||
| 150 | */ | ||
| 151 | protected void finalize() throws Throwable { | ||
| 152 | try { | ||
| 153 | if (this.key != null) { | ||
| 154 | java.util.Arrays.fill(this.key, (byte)0x00); | ||
| 155 | this.key = null; | ||
| 156 | } | ||
| 157 | } finally { | ||
| 158 | super.finalize(); | ||
| 159 | } | ||
| 160 | } | ||
| 161 | } | ||
| @@ -0,0 +1,164 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import javax.crypto.SecretKey; | ||
| 29 | import javax.crypto.SecretKeyFactorySpi; | ||
| 30 | import javax.crypto.spec.DESKeySpec; | ||
| 31 | import java.security.InvalidKeyException; | ||
| 32 | import java.security.spec.KeySpec; | ||
| 33 | import java.security.spec.InvalidKeySpecException; | ||
| 34 | |||
| 35 | /** | ||
| 36 | * This class implements the DES key factory of the Sun provider. | ||
| 37 | * | ||
| 38 | * @author Jan Luehe | ||
| 39 | * | ||
| 40 | */ | ||
| 41 | |||
| 42 | public final class DESKeyFactory extends SecretKeyFactorySpi { | ||
| 43 | |||
| 44 | /** | ||
| 45 | * Empty constructor | ||
| 46 | */ | ||
| 47 | public DESKeyFactory() { | ||
| 48 | } | ||
| 49 | |||
| 50 | /** | ||
| 51 | * Generates a <code>SecretKey</code> object from the provided key | ||
| 52 | * specification (key material). | ||
| 53 | * | ||
| 54 | * @param keySpec the specification (key material) of the secret key | ||
| 55 | * | ||
| 56 | * @return the secret key | ||
| 57 | * | ||
| 58 | * @exception InvalidKeySpecException if the given key specification | ||
| 59 | * is inappropriate for this key factory to produce a public key. | ||
| 60 | */ | ||
| 61 | protected SecretKey engineGenerateSecret(KeySpec keySpec) | ||
| 62 | throws InvalidKeySpecException { | ||
| 63 | DESKey desKey = null; | ||
| 64 | |||
| 65 | try { | ||
| 66 | if (!(keySpec instanceof DESKeySpec)) { | ||
| 67 | throw new InvalidKeySpecException | ||
| 68 | ("Inappropriate key specification"); | ||
| 69 | } | ||
| 70 | else { | ||
| 71 | DESKeySpec desKeySpec = (DESKeySpec)keySpec; | ||
| 72 | desKey = new DESKey(desKeySpec.getKey()); | ||
| 73 | } | ||
| 74 | } catch (InvalidKeyException e) { | ||
| 75 | } | ||
| 76 | return desKey; | ||
| 77 | } | ||
| 78 | |||
| 79 | /** | ||
| 80 | * Returns a specification (key material) of the given key | ||
| 81 | * in the requested format. | ||
| 82 | * | ||
| 83 | * @param key the key | ||
| 84 | * | ||
| 85 | * @param keySpec the requested format in which the key material shall be | ||
| 86 | * returned | ||
| 87 | * | ||
| 88 | * @return the underlying key specification (key material) in the | ||
| 89 | * requested format | ||
| 90 | * | ||
| 91 | * @exception InvalidKeySpecException if the requested key specification is | ||
| 92 | * inappropriate for the given key, or the given key cannot be processed | ||
| 93 | * (e.g., the given key has an unrecognized algorithm or format). | ||
| 94 | */ | ||
| 95 | protected KeySpec engineGetKeySpec(SecretKey key, Class keySpec) | ||
| 96 | throws InvalidKeySpecException { | ||
| 97 | |||
| 98 | try { | ||
| 99 | |||
| 100 | if ((key instanceof SecretKey) | ||
| 101 | && (key.getAlgorithm().equalsIgnoreCase("DES")) | ||
| 102 | && (key.getFormat().equalsIgnoreCase("RAW"))) { | ||
| 103 | |||
| 104 | // Check if requested key spec is amongst the valid ones | ||
| 105 | if ((keySpec != null) && | ||
| 106 | DESKeySpec.class.isAssignableFrom(keySpec)) { | ||
| 107 | return new DESKeySpec(key.getEncoded()); | ||
| 108 | |||
| 109 | } else { | ||
| 110 | throw new InvalidKeySpecException | ||
| 111 | ("Inappropriate key specification"); | ||
| 112 | } | ||
| 113 | |||
| 114 | } else { | ||
| 115 | throw new InvalidKeySpecException | ||
| 116 | ("Inappropriate key format/algorithm"); | ||
| 117 | } | ||
| 118 | |||
| 119 | } catch (InvalidKeyException e) { | ||
| 120 | throw new InvalidKeySpecException("Secret key has wrong size"); | ||
| 121 | } | ||
| 122 | } | ||
| 123 | |||
| 124 | /** | ||
| 125 | * Translates a <code>SecretKey</code> object, whose provider may be | ||
| 126 | * unknown or potentially untrusted, into a corresponding | ||
| 127 | * <code>SecretKey</code> object of this key factory. | ||
| 128 | * | ||
| 129 | * @param key the key whose provider is unknown or untrusted | ||
| 130 | * | ||
| 131 | * @return the translated key | ||
| 132 | * | ||
| 133 | * @exception InvalidKeyException if the given key cannot be processed by | ||
| 134 | * this key factory. | ||
| 135 | */ | ||
| 136 | protected SecretKey engineTranslateKey(SecretKey key) | ||
| 137 | throws InvalidKeyException { | ||
| 138 | |||
| 139 | try { | ||
| 140 | |||
| 141 | if ((key != null) && | ||
| 142 | (key.getAlgorithm().equalsIgnoreCase("DES")) && | ||
| 143 | (key.getFormat().equalsIgnoreCase("RAW"))) { | ||
| 144 | |||
| 145 | // Check if key originates from this factory | ||
| 146 | if (key instanceof com.sun.crypto.provider.DESKey) { | ||
| 147 | return key; | ||
| 148 | } | ||
| 149 | // Convert key to spec | ||
| 150 | DESKeySpec desKeySpec | ||
| 151 | = (DESKeySpec)engineGetKeySpec(key, DESKeySpec.class); | ||
| 152 | // Create key from spec, and return it | ||
| 153 | return engineGenerateSecret(desKeySpec); | ||
| 154 | |||
| 155 | } else { | ||
| 156 | throw new InvalidKeyException | ||
| 157 | ("Inappropriate key format/algorithm"); | ||
| 158 | } | ||
| 159 | |||
| 160 | } catch (InvalidKeySpecException e) { | ||
| 161 | throw new InvalidKeyException("Cannot translate key"); | ||
| 162 | } | ||
| 163 | } | ||
| 164 | } | ||
| @@ -0,0 +1,147 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.security.SecureRandom; | ||
| 29 | import java.security.InvalidParameterException; | ||
| 30 | import java.security.InvalidAlgorithmParameterException; | ||
| 31 | import java.security.InvalidKeyException; | ||
| 32 | import java.security.spec.AlgorithmParameterSpec; | ||
| 33 | import javax.crypto.KeyGeneratorSpi; | ||
| 34 | import javax.crypto.SecretKey; | ||
| 35 | import javax.crypto.spec.DESKeySpec; | ||
| 36 | |||
| 37 | /** | ||
| 38 | * This class generates a DES key. | ||
| 39 | * | ||
| 40 | * @author Jan Luehe | ||
| 41 | * | ||
| 42 | */ | ||
| 43 | |||
| 44 | public final class DESKeyGenerator extends KeyGeneratorSpi { | ||
| 45 | |||
| 46 | private SecureRandom random = null; | ||
| 47 | |||
| 48 | /** | ||
| 49 | * Empty constructor | ||
| 50 | */ | ||
| 51 | public DESKeyGenerator() { | ||
| 52 | } | ||
| 53 | |||
| 54 | /** | ||
| 55 | * Initializes this key generator. | ||
| 56 | * | ||
| 57 | * @param random the source of randomness for this generator | ||
| 58 | */ | ||
| 59 | protected void engineInit(SecureRandom random) { | ||
| 60 | this.random = random; | ||
| 61 | } | ||
| 62 | |||
| 63 | /** | ||
| 64 | * Initializes this key generator with the specified parameter | ||
| 65 | * set and a user-provided source of randomness. | ||
| 66 | * | ||
| 67 | * @param params the key generation parameters | ||
| 68 | * @param random the source of randomness for this key generator | ||
| 69 | * | ||
| 70 | * @exception InvalidAlgorithmParameterException if <code>params</code> is | ||
| 71 | * inappropriate for this key generator | ||
| 72 | */ | ||
| 73 | protected void engineInit(AlgorithmParameterSpec params, | ||
| 74 | SecureRandom random) | ||
| 75 | throws InvalidAlgorithmParameterException { | ||
| 76 | throw new InvalidAlgorithmParameterException | ||
| 77 | ("DES key generation does not take any parameters"); | ||
| 78 | } | ||
| 79 | |||
| 80 | /** | ||
| 81 | * Initializes this key generator for a certain keysize, using the given | ||
| 82 | * source of randomness. | ||
| 83 | * | ||
| 84 | * @param keysize the keysize. This is an algorithm-specific | ||
| 85 | * metric specified in number of bits. | ||
| 86 | * @param random the source of randomness for this key generator | ||
| 87 | */ | ||
| 88 | protected void engineInit(int keysize, SecureRandom random) { | ||
| 89 | if (keysize != 56) { | ||
| 90 | throw new InvalidParameterException("Wrong keysize: must " | ||
| 91 | + "be equal to 56"); | ||
| 92 | } | ||
| 93 | this.engineInit(random); | ||
| 94 | } | ||
| 95 | |||
| 96 | /** | ||
| 97 | * Generates the DES key. | ||
| 98 | * | ||
| 99 | * @return the new DES key | ||
| 100 | */ | ||
| 101 | protected SecretKey engineGenerateKey() { | ||
| 102 | DESKey desKey = null; | ||
| 103 | |||
| 104 | if (this.random == null) { | ||
| 105 | this.random = SunJCE.RANDOM; | ||
| 106 | } | ||
| 107 | |||
| 108 | try { | ||
| 109 | byte[] key = new byte[DESKeySpec.DES_KEY_LEN]; | ||
| 110 | do { | ||
| 111 | this.random.nextBytes(key); | ||
| 112 | setParityBit(key, 0); | ||
| 113 | } while (DESKeySpec.isWeak(key, 0)); | ||
| 114 | desKey = new DESKey(key); | ||
| 115 | } catch (InvalidKeyException e) { | ||
| 116 | // this is never thrown | ||
| 117 | } | ||
| 118 | |||
| 119 | return desKey; | ||
| 120 | } | ||
| 121 | |||
| 122 | /* | ||
| 123 | * Does parity adjustment, using bit in position 8 as the parity bit, | ||
| 124 | * for 8 key bytes, starting at <code>offset</code>. | ||
| 125 | * | ||
| 126 | * The 8 parity bits of a DES key are only used for sanity-checking | ||
| 127 | * of the key, to see if the key could actually be a key. If you check | ||
| 128 | * the parity of the quantity, and it winds up not having the correct | ||
| 129 | * parity, then you'll know something went wrong. | ||
| 130 | * | ||
| 131 | * A key that is not parity adjusted (e.g. e4e4e4e4e4e4e4e4) produces the | ||
| 132 | * same output as a key that is parity adjusted (e.g. e5e5e5e5e5e5e5e5), | ||
| 133 | * because it is the 56 bits of the DES key that are cryptographically | ||
| 134 | * significant/"effective" -- the other 8 bits are just used for parity | ||
| 135 | * checking. | ||
| 136 | */ | ||
| 137 | static void setParityBit(byte[] key, int offset) { | ||
| 138 | if (key == null) | ||
| 139 | return; | ||
| 140 | |||
| 141 | for (int i = 0; i < DESKeySpec.DES_KEY_LEN; i++) { | ||
| 142 | int b = key[offset] & 0xfe; | ||
| 143 | b |= (Integer.bitCount(b) & 1) ^ 1; | ||
| 144 | key[offset++] = (byte)b; | ||
| 145 | } | ||
| 146 | } | ||
| 147 | } | ||
| @@ -0,0 +1,88 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.util.*; | ||
| 29 | import java.io.*; | ||
| 30 | import sun.security.util.*; | ||
| 31 | import java.security.AlgorithmParametersSpi; | ||
| 32 | import java.security.spec.AlgorithmParameterSpec; | ||
| 33 | import java.security.spec.InvalidParameterSpecException; | ||
| 34 | import javax.crypto.spec.IvParameterSpec; | ||
| 35 | |||
| 36 | /** | ||
| 37 | * This class implements the parameter (IV) used with the DES algorithm in | ||
| 38 | * feedback-mode. IV is defined in the standards as follows: | ||
| 39 | * | ||
| 40 | * <pre> | ||
| 41 | * IV ::= OCTET STRING -- 8 octets | ||
| 42 | * </pre> | ||
| 43 | * | ||
| 44 | * @author Jan Luehe | ||
| 45 | * | ||
| 46 | */ | ||
| 47 | |||
| 48 | public final class DESParameters extends AlgorithmParametersSpi { | ||
| 49 | |||
| 50 | private BlockCipherParamsCore core; | ||
| 51 | |||
| 52 | public DESParameters() { | ||
| 53 | core = new BlockCipherParamsCore(DESConstants.DES_BLOCK_SIZE); | ||
| 54 | } | ||
| 55 | |||
| 56 | protected void engineInit(AlgorithmParameterSpec paramSpec) | ||
| 57 | throws InvalidParameterSpecException { | ||
| 58 | core.init(paramSpec); | ||
| 59 | } | ||
| 60 | |||
| 61 | protected void engineInit(byte[] encoded) | ||
| 62 | throws IOException { | ||
| 63 | core.init(encoded); | ||
| 64 | } | ||
| 65 | |||
| 66 | protected void engineInit(byte[] encoded, String decodingMethod) | ||
| 67 | throws IOException { | ||
| 68 | core.init(encoded, decodingMethod); | ||
| 69 | } | ||
| 70 | |||
| 71 | protected AlgorithmParameterSpec engineGetParameterSpec(Class paramSpec) | ||
| 72 | throws InvalidParameterSpecException { | ||
| 73 | return core.getParameterSpec(paramSpec); | ||
| 74 | } | ||
| 75 | |||
| 76 | protected byte[] engineGetEncoded() throws IOException { | ||
| 77 | return core.getEncoded(); | ||
| 78 | } | ||
| 79 | |||
| 80 | protected byte[] engineGetEncoded(String encodingMethod) | ||
| 81 | throws IOException { | ||
| 82 | return core.getEncoded(); | ||
| 83 | } | ||
| 84 | |||
| 85 | protected String engineToString() { | ||
| 86 | return core.toString(); | ||
| 87 | } | ||
| 88 | } | ||
| @@ -0,0 +1,426 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.security.*; | ||
| 29 | import java.security.spec.*; | ||
| 30 | import javax.crypto.*; | ||
| 31 | import javax.crypto.spec.*; | ||
| 32 | |||
| 33 | /** | ||
| 34 | * This class implements the DESede algorithm (DES-EDE, tripleDES) in | ||
| 35 | * its various modes (<code>ECB</code>, <code>CFB</code>, <code>OFB</code>, | ||
| 36 | * <code>CBC</code>, <code>PCBC</code>) and padding schemes | ||
| 37 | * (<code>PKCS5Padding</code>, <code>NoPadding</code>, | ||
| 38 | * <code>ISO10126Padding</code>). | ||
| 39 | * | ||
| 40 | * @author Gigi Ankeny | ||
| 41 | * | ||
| 42 | * | ||
| 43 | * @see DESCipher | ||
| 44 | */ | ||
| 45 | |||
| 46 | public final class DESedeCipher extends CipherSpi { | ||
| 47 | |||
| 48 | /* | ||
| 49 | * internal CipherCore object which does the real work. | ||
| 50 | */ | ||
| 51 | private CipherCore core = null; | ||
| 52 | |||
| 53 | /** | ||
| 54 | * Creates an instance of DESede cipher with default ECB mode and | ||
| 55 | * PKCS5Padding. | ||
| 56 | */ | ||
| 57 | public DESedeCipher() { | ||
| 58 | core = new CipherCore(new DESedeCrypt(), DESConstants.DES_BLOCK_SIZE); | ||
| 59 | } | ||
| 60 | |||
| 61 | /** | ||
| 62 | * Sets the mode of this cipher. | ||
| 63 | * | ||
| 64 | * @param mode the cipher mode | ||
| 65 | * | ||
| 66 | * @exception NoSuchAlgorithmException if the requested cipher mode does | ||
| 67 | * not exist | ||
| 68 | */ | ||
| 69 | protected void engineSetMode(String mode) | ||
| 70 | throws NoSuchAlgorithmException { | ||
| 71 | core.setMode(mode); | ||
| 72 | } | ||
| 73 | |||
| 74 | /** | ||
| 75 | * Sets the padding mechanism of this cipher. | ||
| 76 | * | ||
| 77 | * @param padding the padding mechanism | ||
| 78 | * | ||
| 79 | * @exception NoSuchPaddingException if the requested padding mechanism | ||
| 80 | * does not exist | ||
| 81 | */ | ||
| 82 | protected void engineSetPadding(String paddingScheme) | ||
| 83 | throws NoSuchPaddingException { | ||
| 84 | core.setPadding(paddingScheme); | ||
| 85 | } | ||
| 86 | |||
| 87 | /** | ||
| 88 | * Returns the block size (in bytes). | ||
| 89 | * | ||
| 90 | * @return the block size (in bytes), or 0 if the underlying algorithm is | ||
| 91 | * not a block cipher | ||
| 92 | */ | ||
| 93 | protected int engineGetBlockSize() { | ||
| 94 | return DESConstants.DES_BLOCK_SIZE; | ||
| 95 | } | ||
| 96 | |||
| 97 | /** | ||
| 98 | * Returns the length in bytes that an output buffer would need to be in | ||
| 99 | * order to hold the result of the next <code>update</code> or | ||
| 100 | * <code>doFinal</code> operation, given the input length | ||
| 101 | * <code>inputLen</code> (in bytes). | ||
| 102 | * | ||
| 103 | * <p>This call takes into account any unprocessed (buffered) data from a | ||
| 104 | * previous <code>update</code> call, and padding. | ||
| 105 | * | ||
| 106 | * <p>The actual output length of the next <code>update</code> or | ||
| 107 | * <code>doFinal</code> call may be smaller than the length returned by | ||
| 108 | * this method. | ||
| 109 | * | ||
| 110 | * @param inputLen the input length (in bytes) | ||
| 111 | * | ||
| 112 | * @return the required output buffer size (in bytes) | ||
| 113 | */ | ||
| 114 | protected int engineGetOutputSize(int inputLen) { | ||
| 115 | return core.getOutputSize(inputLen); | ||
| 116 | } | ||
| 117 | |||
| 118 | /** | ||
| 119 | * Returns the initialization vector (IV) in a new buffer. | ||
| 120 | * | ||
| 121 | * <p>This is useful in the case where a random IV has been created | ||
| 122 | * (see <a href = "#init">init</a>), | ||
| 123 | * or in the context of password-based encryption or | ||
| 124 | * decryption, where the IV is derived from a user-provided password. | ||
| 125 | * | ||
| 126 | * @return the initialization vector in a new buffer, or null if the | ||
| 127 | * underlying algorithm does not use an IV, or if the IV has not yet | ||
| 128 | * been set. | ||
| 129 | */ | ||
| 130 | protected byte[] engineGetIV() { | ||
| 131 | return core.getIV(); | ||
| 132 | } | ||
| 133 | |||
| 134 | /** | ||
| 135 | * Initializes this cipher with a key and a source of randomness. | ||
| 136 | * | ||
| 137 | * <p>The cipher is initialized for one of the following four operations: | ||
| 138 | * encryption, decryption, key wrapping or key unwrapping, depending on | ||
| 139 | * the value of <code>opmode</code>. | ||
| 140 | * | ||
| 141 | * <p>If this cipher requires an initialization vector (IV), it will get | ||
| 142 | * it from <code>random</code>. | ||
| 143 | * This behaviour should only be used in encryption or key wrapping | ||
| 144 | * mode, however. | ||
| 145 | * When initializing a cipher that requires an IV for decryption or | ||
| 146 | * key unwrapping, the IV | ||
| 147 | * (same IV that was used for encryption or key wrapping) must be provided | ||
| 148 | * explicitly as a | ||
| 149 | * parameter, in order to get the correct result. | ||
| 150 | * | ||
| 151 | * <p>This method also cleans existing buffer and other related state | ||
| 152 | * information. | ||
| 153 | * | ||
| 154 | * @param opmode the operation mode of this cipher (this is one of | ||
| 155 | * the following: | ||
| 156 | * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, | ||
| 157 | * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) | ||
| 158 | * @param key the secret key | ||
| 159 | * @param random the source of randomness | ||
| 160 | * | ||
| 161 | * @exception InvalidKeyException if the given key is inappropriate for | ||
| 162 | * initializing this cipher | ||
| 163 | */ | ||
| 164 | protected void engineInit(int opmode, Key key, SecureRandom random) | ||
| 165 | throws InvalidKeyException { | ||
| 166 | core.init(opmode, key, random); | ||
| 167 | } | ||
| 168 | |||
| 169 | /** | ||
| 170 | * Initializes this cipher with a key, a set of | ||
| 171 | * algorithm parameters, and a source of randomness. | ||
| 172 | * | ||
| 173 | * <p>The cipher is initialized for one of the following four operations: | ||
| 174 | * encryption, decryption, key wrapping or key unwrapping, depending on | ||
| 175 | * the value of <code>opmode</code>. | ||
| 176 | * | ||
| 177 | * <p>If this cipher (including its underlying feedback or padding scheme) | ||
| 178 | * requires any random bytes, it will get them from <code>random</code>. | ||
| 179 | * | ||
| 180 | * @param opmode the operation mode of this cipher (this is one of | ||
| 181 | * the following: | ||
| 182 | * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, | ||
| 183 | * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) | ||
| 184 | * @param key the encryption key | ||
| 185 | * @param params the algorithm parameters | ||
| 186 | * @param random the source of randomness | ||
| 187 | * | ||
| 188 | * @exception InvalidKeyException if the given key is inappropriate for | ||
| 189 | * initializing this cipher | ||
| 190 | * @exception InvalidAlgorithmParameterException if the given algorithm | ||
| 191 | * parameters are inappropriate for this cipher | ||
| 192 | */ | ||
| 193 | protected void engineInit(int opmode, Key key, | ||
| 194 | AlgorithmParameterSpec params, | ||
| 195 | SecureRandom random) | ||
| 196 | throws InvalidKeyException, InvalidAlgorithmParameterException { | ||
| 197 | core.init(opmode, key, params, random); | ||
| 198 | } | ||
| 199 | |||
| 200 | protected void engineInit(int opmode, Key key, | ||
| 201 | AlgorithmParameters params, | ||
| 202 | SecureRandom random) | ||
| 203 | throws InvalidKeyException, InvalidAlgorithmParameterException { | ||
| 204 | core.init(opmode, key, params, random); | ||
| 205 | } | ||
| 206 | |||
| 207 | /** | ||
| 208 | * Continues a multiple-part encryption or decryption operation | ||
| 209 | * (depending on how this cipher was initialized), processing another data | ||
| 210 | * part. | ||
| 211 | * | ||
| 212 | * <p>The first <code>inputLen</code> bytes in the <code>input</code> | ||
| 213 | * buffer, starting at <code>inputOffset</code>, are processed, and the | ||
| 214 | * result is stored in a new buffer. | ||
| 215 | * | ||
| 216 | * @param input the input buffer | ||
| 217 | * @param inputOffset the offset in <code>input</code> where the input | ||
| 218 | * starts | ||
| 219 | * @param inputLen the input length | ||
| 220 | * | ||
| 221 | * @return the new buffer with the result | ||
| 222 | * | ||
| 223 | * @exception IllegalStateException if this cipher is in a wrong state | ||
| 224 | * (e.g., has not been initialized) | ||
| 225 | */ | ||
| 226 | protected byte[] engineUpdate(byte[] input, int inputOffset, | ||
| 227 | int inputLen) { | ||
| 228 | return core.update(input, inputOffset, inputLen); | ||
| 229 | } | ||
| 230 | |||
| 231 | /** | ||
| 232 | * Continues a multiple-part encryption or decryption operation | ||
| 233 | * (depending on how this cipher was initialized), processing another data | ||
| 234 | * part. | ||
| 235 | * | ||
| 236 | * <p>The first <code>inputLen</code> bytes in the <code>input</code> | ||
| 237 | * buffer, starting at <code>inputOffset</code>, are processed, and the | ||
| 238 | * result is stored in the <code>output</code> buffer, starting at | ||
| 239 | * <code>outputOffset</code>. | ||
| 240 | * | ||
| 241 | * @param input the input buffer | ||
| 242 | * @param inputOffset the offset in <code>input</code> where the input | ||
| 243 | * starts | ||
| 244 | * @param inputLen the input length | ||
| 245 | * @param output the buffer for the result | ||
| 246 | * @param outputOffset the offset in <code>output</code> where the result | ||
| 247 | * is stored | ||
| 248 | * | ||
| 249 | * @return the number of bytes stored in <code>output</code> | ||
| 250 | * | ||
| 251 | * @exception ShortBufferException if the given output buffer is too small | ||
| 252 | * to hold the result | ||
| 253 | */ | ||
| 254 | protected int engineUpdate(byte[] input, int inputOffset, int inputLen, | ||
| 255 | byte[] output, int outputOffset) | ||
| 256 | throws ShortBufferException { | ||
| 257 | return core.update(input, inputOffset, inputLen, output, | ||
| 258 | outputOffset); | ||
| 259 | } | ||
| 260 | |||
| 261 | /** | ||
| 262 | * Encrypts or decrypts data in a single-part operation, | ||
| 263 | * or finishes a multiple-part operation. | ||
| 264 | * The data is encrypted or decrypted, depending on how this cipher was | ||
| 265 | * initialized. | ||
| 266 | * | ||
| 267 | * <p>The first <code>inputLen</code> bytes in the <code>input</code> | ||
| 268 | * buffer, starting at <code>inputOffset</code>, and any input bytes that | ||
| 269 | * may have been buffered during a previous <code>update</code> operation, | ||
| 270 | * are processed, with padding (if requested) being applied. | ||
| 271 | * The result is stored in a new buffer. | ||
| 272 | * | ||
| 273 | * <p>The cipher is reset to its initial state (uninitialized) after this | ||
| 274 | * call. | ||
| 275 | * | ||
| 276 | * @param input the input buffer | ||
| 277 | * @param inputOffset the offset in <code>input</code> where the input | ||
| 278 | * starts | ||
| 279 | * @param inputLen the input length | ||
| 280 | * | ||
| 281 | * @return the new buffer with the result | ||
| 282 | * | ||
| 283 | * @exception IllegalBlockSizeException if this cipher is a block cipher, | ||
| 284 | * no padding has been requested (only in encryption mode), and the total | ||
| 285 | * input length of the data processed by this cipher is not a multiple of | ||
| 286 | * block size | ||
| 287 | * @exception BadPaddingException if this cipher is in decryption mode, | ||
| 288 | * and (un)padding has been requested, but the decrypted data is not | ||
| 289 | * bounded by the appropriate padding bytes | ||
| 290 | */ | ||
| 291 | protected byte[] engineDoFinal(byte[] input, int inputOffset, | ||
| 292 | int inputLen) | ||
| 293 | throws IllegalBlockSizeException, BadPaddingException { | ||
| 294 | return core.doFinal(input, inputOffset, inputLen); | ||
| 295 | } | ||
| 296 | |||
| 297 | /** | ||
| 298 | * Encrypts or decrypts data in a single-part operation, | ||
| 299 | * or finishes a multiple-part operation. | ||
| 300 | * The data is encrypted or decrypted, depending on how this cipher was | ||
| 301 | * initialized. | ||
| 302 | * | ||
| 303 | * <p>The first <code>inputLen</code> bytes in the <code>input</code> | ||
| 304 | * buffer, starting at <code>inputOffset</code>, and any input bytes that | ||
| 305 | * may have been buffered during a previous <code>update</code> operation, | ||
| 306 | * are processed, with padding (if requested) being applied. | ||
| 307 | * The result is stored in the <code>output</code> buffer, starting at | ||
| 308 | * <code>outputOffset</code>. | ||
| 309 | * | ||
| 310 | * <p>The cipher is reset to its initial state (uninitialized) after this | ||
| 311 | * call. | ||
| 312 | * | ||
| 313 | * @param input the input buffer | ||
| 314 | * @param inputOffset the offset in <code>input</code> where the input | ||
| 315 | * starts | ||
| 316 | * @param inputLen the input length | ||
| 317 | * @param output the buffer for the result | ||
| 318 | * @param outputOffset the offset in <code>output</code> where the result | ||
| 319 | * is stored | ||
| 320 | * | ||
| 321 | * @return the number of bytes stored in <code>output</code> | ||
| 322 | * | ||
| 323 | * @exception IllegalBlockSizeException if this cipher is a block cipher, | ||
| 324 | * no padding has been requested (only in encryption mode), and the total | ||
| 325 | * input length of the data processed by this cipher is not a multiple of | ||
| 326 | * block size | ||
| 327 | * @exception ShortBufferException if the given output buffer is too small | ||
| 328 | * to hold the result | ||
| 329 | * @exception BadPaddingException if this cipher is in decryption mode, | ||
| 330 | * and (un)padding has been requested, but the decrypted data is not | ||
| 331 | * bounded by the appropriate padding bytes | ||
| 332 | */ | ||
| 333 | protected int engineDoFinal(byte[] input, int inputOffset, int inputLen, | ||
| 334 | byte[] output, int outputOffset) | ||
| 335 | throws IllegalBlockSizeException, ShortBufferException, | ||
| 336 | BadPaddingException { | ||
| 337 | return core.doFinal(input, inputOffset, inputLen, output, | ||
| 338 | outputOffset); | ||
| 339 | } | ||
| 340 | |||
| 341 | /** | ||
| 342 | * Returns the parameters used with this cipher. | ||
| 343 | * | ||
| 344 | * <p>The returned parameters may be the same that were used to initialize | ||
| 345 | * this cipher, or may contain the default set of parameters or a set of | ||
| 346 | * randomly generated parameters used by the underlying cipher | ||
| 347 | * implementation (provided that the underlying cipher implementation | ||
| 348 | * uses a default set of parameters or creates new parameters if it needs | ||
| 349 | * parameters but was not initialized with any). | ||
| 350 | * | ||
| 351 | * @return the parameters used with this cipher, or null if this cipher | ||
| 352 | * does not use any parameters. | ||
| 353 | */ | ||
| 354 | protected AlgorithmParameters engineGetParameters() { | ||
| 355 | return core.getParameters("DESede"); | ||
| 356 | } | ||
| 357 | |||
| 358 | /** | ||
| 359 | * Returns the key size of the given key object. | ||
| 360 | * | ||
| 361 | * @param key the key object. | ||
| 362 | * | ||
| 363 | * @return the "effective" key size of the given key object. | ||
| 364 | * | ||
| 365 | * @exception InvalidKeyException if <code>key</code> is invalid. | ||
| 366 | */ | ||
| 367 | protected int engineGetKeySize(Key key) throws InvalidKeyException { | ||
| 368 | byte[] encoded = key.getEncoded(); | ||
| 369 | if (encoded.length != 24) { | ||
| 370 | throw new InvalidKeyException("Invalid key length: " + | ||
| 371 | encoded.length + " bytes"); | ||
| 372 | } | ||
| 373 | // Return the effective key length | ||
| 374 | return 112; | ||
| 375 | } | ||
| 376 | |||
| 377 | /** | ||
| 378 | * Wrap a key. | ||
| 379 | * | ||
| 380 | * @param key the key to be wrapped. | ||
| 381 | * | ||
| 382 | * @return the wrapped key. | ||
| 383 | * | ||
| 384 | * @exception IllegalBlockSizeException if this cipher is a block | ||
| 385 | * cipher, no padding has been requested, and the length of the | ||
| 386 | * encoding of the key to be wrapped is not a | ||
| 387 | * multiple of the block size. | ||
| 388 | * | ||
| 389 | * @exception InvalidKeyException if it is impossible or unsafe to | ||
| 390 | * wrap the key with this cipher (e.g., a hardware protected key is | ||
| 391 | * being passed to a software only cipher). | ||
| 392 | */ | ||
| 393 | protected byte[] engineWrap(Key key) | ||
| 394 | throws IllegalBlockSizeException, InvalidKeyException { | ||
| 395 | return core.wrap(key); | ||
| 396 | } | ||
| 397 | |||
| 398 | /** | ||
| 399 | * Unwrap a previously wrapped key. | ||
| 400 | * | ||
| 401 | * @param wrappedKey the key to be unwrapped. | ||
| 402 | * | ||
| 403 | * @param wrappedKeyAlgorithm the algorithm the wrapped key is for. | ||
| 404 | * | ||
| 405 | * @param wrappedKeyType the type of the wrapped key. | ||
| 406 | * This is one of <code>Cipher.SECRET_KEY</code>, | ||
| 407 | * <code>Cipher.PRIVATE_KEY</code>, or <code>Cipher.PUBLIC_KEY</code>. | ||
| 408 | * | ||
| 409 | * @return the unwrapped key. | ||
| 410 | * | ||
| 411 | * @exception NoSuchAlgorithmException if no installed providers | ||
| 412 | * can create keys of type <code>wrappedKeyType</code> for the | ||
| 413 | * <code>wrappedKeyAlgorithm</code>. | ||
| 414 | * | ||
| 415 | * @exception InvalidKeyException if <code>wrappedKey</code> does not | ||
| 416 | * represent a wrapped key of type <code>wrappedKeyType</code> for | ||
| 417 | * the <code>wrappedKeyAlgorithm</code>. | ||
| 418 | */ | ||
| 419 | protected Key engineUnwrap(byte[] wrappedKey, | ||
| 420 | String wrappedKeyAlgorithm, | ||
| 421 | int wrappedKeyType) | ||
| 422 | throws InvalidKeyException, NoSuchAlgorithmException { | ||
| 423 | return core.unwrap(wrappedKey, wrappedKeyAlgorithm, | ||
| 424 | wrappedKeyType); | ||
| 425 | } | ||
| 426 | } | ||
| @@ -0,0 +1,168 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.security.InvalidKeyException; | ||
| 29 | |||
| 30 | /** | ||
| 31 | * This class implements the Triple DES algorithm (DES encryption, followed by | ||
| 32 | * DES decryption, followed by DES encryption) on a byte array of size | ||
| 33 | * <code>DES_BLOCK_SIZE</code>. Each DES operation has its own key. | ||
| 34 | * | ||
| 35 | * @author Gigi Ankeny | ||
| 36 | * @author Jan Luehe | ||
| 37 | * | ||
| 38 | * | ||
| 39 | * @see DESConstants | ||
| 40 | * @see DESCipher | ||
| 41 | */ | ||
| 42 | |||
| 43 | final class DESedeCrypt extends DESCrypt implements DESConstants { | ||
| 44 | |||
| 45 | /* | ||
| 46 | * the expanded key used in encrypt/decrypt/encrypt phase | ||
| 47 | */ | ||
| 48 | private byte[] key1 = null; | ||
| 49 | private byte[] key2 = null; | ||
| 50 | private byte[] key3 = null; | ||
| 51 | private byte[] buf1, buf2; | ||
| 52 | |||
| 53 | /* | ||
| 54 | * constructor | ||
| 55 | */ | ||
| 56 | DESedeCrypt() { | ||
| 57 | buf1 = new byte[DES_BLOCK_SIZE]; | ||
| 58 | buf2 = new byte[DES_BLOCK_SIZE]; | ||
| 59 | } | ||
| 60 | |||
| 61 | void init(boolean decrypting, String algorithm, byte[] keys) | ||
| 62 | throws InvalidKeyException { | ||
| 63 | if (!algorithm.equalsIgnoreCase("DESede") | ||
| 64 | && !algorithm.equalsIgnoreCase("TripleDES")) { | ||
| 65 | throw new InvalidKeyException | ||
| 66 | ("Wrong algorithm: DESede or TripleDES required"); | ||
| 67 | } | ||
| 68 | if (keys.length != DES_BLOCK_SIZE * 3) { | ||
| 69 | throw new InvalidKeyException("Wrong key size"); | ||
| 70 | } | ||
| 71 | |||
| 72 | byte[] keybuf = new byte[DES_BLOCK_SIZE]; | ||
| 73 | |||
| 74 | // retrieve the first key | ||
| 75 | key1 = new byte[128]; | ||
| 76 | System.arraycopy(keys, 0, keybuf, 0, DES_BLOCK_SIZE); | ||
| 77 | expandKey(keybuf); | ||
| 78 | System.arraycopy(expandedKey, 0, key1, 0, 128); | ||
| 79 | |||
| 80 | // check if the third key is the same | ||
| 81 | if (keyEquals(keybuf, 0, keys, DES_BLOCK_SIZE*2, DES_BLOCK_SIZE)) { | ||
| 82 | key3 = key1; | ||
| 83 | } else { | ||
| 84 | key3 = new byte[128]; | ||
| 85 | System.arraycopy(keys, DES_BLOCK_SIZE*2, keybuf, 0, | ||
| 86 | DES_BLOCK_SIZE); | ||
| 87 | expandKey(keybuf); | ||
| 88 | System.arraycopy(expandedKey, 0, key3, 0, 128); | ||
| 89 | } | ||
| 90 | |||
| 91 | // retrieve the second key | ||
| 92 | key2 = new byte[128]; | ||
| 93 | System.arraycopy(keys, DES_BLOCK_SIZE, keybuf, 0, DES_BLOCK_SIZE); | ||
| 94 | expandKey(keybuf); | ||
| 95 | System.arraycopy(expandedKey, 0, key2, 0, 128); | ||
| 96 | |||
| 97 | } | ||
| 98 | |||
| 99 | /** | ||
| 100 | * Performs encryption operation. | ||
| 101 | * | ||
| 102 | * <p>The input plain text <code>plain</code>, starting at | ||
| 103 | * <code>plainOffset</code> and ending at | ||
| 104 | * <code>(plainOffset + blockSize - 1)</code>, is encrypted. | ||
| 105 | * The result is stored in <code>cipher</code>, starting at | ||
| 106 | * <code>cipherOffset</code>. | ||
| 107 | * | ||
| 108 | * @param plain the buffer with the input data to be encrypted | ||
| 109 | * @param plainOffset the offset in <code>plain</code> | ||
| 110 | * @param cipher the buffer for the result | ||
| 111 | * @param cipherOffset the offset in <code>cipher</code> | ||
| 112 | */ | ||
| 113 | void encryptBlock(byte[] plain, int plainOffset, | ||
| 114 | byte[] cipher, int cipherOffset) | ||
| 115 | { | ||
| 116 | expandedKey = key1; | ||
| 117 | decrypting = false; | ||
| 118 | cipherBlock(plain, plainOffset, buf1, 0); | ||
| 119 | |||
| 120 | expandedKey = key2; | ||
| 121 | decrypting = true; | ||
| 122 | cipherBlock(buf1, 0, buf2, 0); | ||
| 123 | |||
| 124 | expandedKey = key3; | ||
| 125 | decrypting = false; | ||
| 126 | cipherBlock(buf2, 0, cipher, cipherOffset); | ||
| 127 | } | ||
| 128 | |||
| 129 | /** | ||
| 130 | * Performs decryption operation. | ||
| 131 | * | ||
| 132 | * <p>The input cipher text <code>cipher</code>, starting at | ||
| 133 | * <code>cipherOffset</code> and ending at | ||
| 134 | * <code>(cipherOffset + blockSize - 1)</code>, is decrypted. | ||
| 135 | * The result is stored in <code>plain</code>, starting at | ||
| 136 | * <code>plainOffset</code>. | ||
| 137 | * | ||
| 138 | * @param cipher the buffer with the input data to be decrypted | ||
| 139 | * @param cipherOffset the offset in <code>cipherOffset</code> | ||
| 140 | * @param plain the buffer for the result | ||
| 141 | * @param plainOffset the offset in <code>plain</code> | ||
| 142 | */ | ||
| 143 | void decryptBlock(byte[] cipher, int cipherOffset, | ||
| 144 | byte[] plain, int plainOffset) | ||
| 145 | { | ||
| 146 | expandedKey = key3; | ||
| 147 | decrypting = true; | ||
| 148 | cipherBlock(cipher, cipherOffset, buf1, 0); | ||
| 149 | |||
| 150 | expandedKey = key2; | ||
| 151 | decrypting = false; | ||
| 152 | cipherBlock(buf1, 0, buf2, 0); | ||
| 153 | |||
| 154 | expandedKey = key1; | ||
| 155 | decrypting = true; | ||
| 156 | cipherBlock(buf2, 0, plain, plainOffset); | ||
| 157 | } | ||
| 158 | |||
| 159 | private boolean keyEquals(byte[] key1, int off1, | ||
| 160 | byte[] key2, int off2, int len) { | ||
| 161 | |||
| 162 | for (int i=0; i<len; i++) { | ||
| 163 | if (key1[i+off1] != key2[i+off2]) | ||
| 164 | return false; | ||
| 165 | } | ||
| 166 | return true; | ||
| 167 | } | ||
| 168 | } | ||
| @@ -0,0 +1,162 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.security.KeyRep; | ||
| 29 | import java.security.InvalidKeyException; | ||
| 30 | import javax.crypto.SecretKey; | ||
| 31 | import javax.crypto.spec.DESedeKeySpec; | ||
| 32 | |||
| 33 | /** | ||
| 34 | * This class represents a DES-EDE key. | ||
| 35 | * | ||
| 36 | * @author Jan Luehe | ||
| 37 | * | ||
| 38 | */ | ||
| 39 | |||
| 40 | final class DESedeKey implements SecretKey { | ||
| 41 | |||
| 42 | static final long serialVersionUID = 2463986565756745178L; | ||
| 43 | |||
| 44 | private byte[] key; | ||
| 45 | |||
| 46 | /** | ||
| 47 | * Creates a DES-EDE key from a given key. | ||
| 48 | * | ||
| 49 | * @param key the given key | ||
| 50 | * | ||
| 51 | * @exception InvalidKeyException if the given key has a wrong size | ||
| 52 | */ | ||
| 53 | DESedeKey(byte[] key) throws InvalidKeyException { | ||
| 54 | this(key, 0); | ||
| 55 | } | ||
| 56 | |||
| 57 | /** | ||
| 58 | * Uses the first 24 bytes in <code>key</code>, beginning at | ||
| 59 | * <code>offset</code>, as the DES-EDE key | ||
| 60 | * | ||
| 61 | * @param key the buffer with the DES-EDE key | ||
| 62 | * @param offset the offset in <code>key</code>, where the DES-EDE key | ||
| 63 | * starts | ||
| 64 | * | ||
| 65 | * @exception InvalidKeyException if the given key has a wrong size | ||
| 66 | */ | ||
| 67 | DESedeKey(byte[] key, int offset) throws InvalidKeyException { | ||
| 68 | |||
| 69 | if (key==null || ((key.length-offset)<DESedeKeySpec.DES_EDE_KEY_LEN)) { | ||
| 70 | throw new InvalidKeyException("Wrong key size"); | ||
| 71 | } | ||
| 72 | this.key = new byte[DESedeKeySpec.DES_EDE_KEY_LEN]; | ||
| 73 | System.arraycopy(key, offset, this.key, 0, | ||
| 74 | DESedeKeySpec.DES_EDE_KEY_LEN); | ||
| 75 | DESKeyGenerator.setParityBit(this.key, 0); | ||
| 76 | DESKeyGenerator.setParityBit(this.key, 8); | ||
| 77 | DESKeyGenerator.setParityBit(this.key, 16); | ||
| 78 | } | ||
| 79 | |||
| 80 | public byte[] getEncoded() { | ||
| 81 | return (byte[])this.key.clone(); | ||
| 82 | } | ||
| 83 | |||
| 84 | public String getAlgorithm() { | ||
| 85 | return "DESede"; | ||
| 86 | } | ||
| 87 | |||
| 88 | public String getFormat() { | ||
| 89 | return "RAW"; | ||
| 90 | } | ||
| 91 | |||
| 92 | /** | ||
| 93 | * Calculates a hash code value for the object. | ||
| 94 | * Objects that are equal will also have the same hashcode. | ||
| 95 | */ | ||
| 96 | public int hashCode() { | ||
| 97 | int retval = 0; | ||
| 98 | for (int i = 1; i < this.key.length; i++) { | ||
| 99 | retval += this.key[i] * i; | ||
| 100 | } | ||
| 101 | return(retval ^= "desede".hashCode()); | ||
| 102 | } | ||
| 103 | |||
| 104 | public boolean equals(Object obj) { | ||
| 105 | if (this == obj) | ||
| 106 | return true; | ||
| 107 | |||
| 108 | if (!(obj instanceof SecretKey)) | ||
| 109 | return false; | ||
| 110 | |||
| 111 | String thatAlg = ((SecretKey)obj).getAlgorithm(); | ||
| 112 | if (!(thatAlg.equalsIgnoreCase("DESede")) | ||
| 113 | && !(thatAlg.equalsIgnoreCase("TripleDES"))) | ||
| 114 | return false; | ||
| 115 | |||
| 116 | byte[] thatKey = ((SecretKey)obj).getEncoded(); | ||
| 117 | boolean ret = java.util.Arrays.equals(this.key, thatKey); | ||
| 118 | java.util.Arrays.fill(thatKey, (byte)0x00); | ||
| 119 | return ret; | ||
| 120 | } | ||
| 121 | |||
| 122 | /** | ||
| 123 | * readObject is called to restore the state of this key from | ||
| 124 | * a stream. | ||
| 125 | */ | ||
| 126 | private void readObject(java.io.ObjectInputStream s) | ||
| 127 | throws java.io.IOException, ClassNotFoundException | ||
| 128 | { | ||
| 129 | s.defaultReadObject(); | ||
| 130 | key = (byte[])key.clone(); | ||
| 131 | } | ||
| 132 | |||
| 133 | /** | ||
| 134 | * Replace the DESede key to be serialized. | ||
| 135 | * | ||
| 136 | * @return the standard KeyRep object to be serialized | ||
| 137 | * | ||
| 138 | * @throws java.io.ObjectStreamException if a new object representing | ||
| 139 | * this DESede key could not be created | ||
| 140 | */ | ||
| 141 | private Object writeReplace() throws java.io.ObjectStreamException { | ||
| 142 | return new KeyRep(KeyRep.Type.SECRET, | ||
| 143 | getAlgorithm(), | ||
| 144 | getFormat(), | ||
| 145 | getEncoded()); | ||
| 146 | } | ||
| 147 | |||
| 148 | /** | ||
| 149 | * Ensures that the bytes of this key are | ||
| 150 | * set to zero when there are no more references to it. | ||
| 151 | */ | ||
| 152 | protected void finalize() throws Throwable { | ||
| 153 | try { | ||
| 154 | if (this.key != null) { | ||
| 155 | java.util.Arrays.fill(this.key, (byte)0x00); | ||
| 156 | this.key = null; | ||
| 157 | } | ||
| 158 | } finally { | ||
| 159 | super.finalize(); | ||
| 160 | } | ||
| 161 | } | ||
| 162 | } | ||
| @@ -0,0 +1,161 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import javax.crypto.SecretKey; | ||
| 29 | import javax.crypto.SecretKeyFactorySpi; | ||
| 30 | import javax.crypto.spec.DESedeKeySpec; | ||
| 31 | import java.security.InvalidKeyException; | ||
| 32 | import java.security.spec.KeySpec; | ||
| 33 | import java.security.spec.InvalidKeySpecException; | ||
| 34 | |||
| 35 | /** | ||
| 36 | * This class implements the DES-EDE key factory of the Sun provider. | ||
| 37 | * | ||
| 38 | * @author Jan Luehe | ||
| 39 | * | ||
| 40 | */ | ||
| 41 | |||
| 42 | public final class DESedeKeyFactory extends SecretKeyFactorySpi { | ||
| 43 | |||
| 44 | /** | ||
| 45 | * Empty constructor | ||
| 46 | */ | ||
| 47 | public DESedeKeyFactory() { | ||
| 48 | } | ||
| 49 | |||
| 50 | /** | ||
| 51 | * Generates a <code>SecretKey</code> object from the provided key | ||
| 52 | * specification (key material). | ||
| 53 | * | ||
| 54 | * @param keySpec the specification (key material) of the secret key | ||
| 55 | * | ||
| 56 | * @return the secret key | ||
| 57 | * | ||
| 58 | * @exception InvalidKeySpecException if the given key specification | ||
| 59 | * is inappropriate for this key factory to produce a public key. | ||
| 60 | */ | ||
| 61 | protected SecretKey engineGenerateSecret(KeySpec keySpec) | ||
| 62 | throws InvalidKeySpecException { | ||
| 63 | DESedeKey desEdeKey = null; | ||
| 64 | |||
| 65 | try { | ||
| 66 | if (keySpec instanceof DESedeKeySpec) { | ||
| 67 | DESedeKeySpec desEdeKeySpec = (DESedeKeySpec)keySpec; | ||
| 68 | desEdeKey = new DESedeKey(desEdeKeySpec.getKey()); | ||
| 69 | |||
| 70 | } else { | ||
| 71 | throw new InvalidKeySpecException | ||
| 72 | ("Inappropriate key specification"); | ||
| 73 | } | ||
| 74 | } catch (InvalidKeyException e) { | ||
| 75 | } | ||
| 76 | return desEdeKey; | ||
| 77 | } | ||
| 78 | |||
| 79 | /** | ||
| 80 | * Returns a specification (key material) of the given key | ||
| 81 | * in the requested format. | ||
| 82 | * | ||
| 83 | * @param key the key | ||
| 84 | * | ||
| 85 | * @param keySpec the requested format in which the key material shall be | ||
| 86 | * returned | ||
| 87 | * | ||
| 88 | * @return the underlying key specification (key material) in the | ||
| 89 | * requested format | ||
| 90 | * | ||
| 91 | * @exception InvalidKeySpecException if the requested key specification is | ||
| 92 | * inappropriate for the given key, or the given key cannot be processed | ||
| 93 | * (e.g., the given key has an unrecognized algorithm or format). | ||
| 94 | */ | ||
| 95 | protected KeySpec engineGetKeySpec(SecretKey key, Class keySpec) | ||
| 96 | throws InvalidKeySpecException { | ||
| 97 | |||
| 98 | try { | ||
| 99 | if ((key instanceof SecretKey) | ||
| 100 | && (key.getAlgorithm().equalsIgnoreCase("DESede")) | ||
| 101 | && (key.getFormat().equalsIgnoreCase("RAW"))) { | ||
| 102 | |||
| 103 | // Check if requested key spec is amongst the valid ones | ||
| 104 | if (DESedeKeySpec.class.isAssignableFrom(keySpec)) { | ||
| 105 | return new DESedeKeySpec(key.getEncoded()); | ||
| 106 | |||
| 107 | } else { | ||
| 108 | throw new InvalidKeySpecException | ||
| 109 | ("Inappropriate key specification"); | ||
| 110 | } | ||
| 111 | |||
| 112 | } else { | ||
| 113 | throw new InvalidKeySpecException | ||
| 114 | ("Inappropriate key format/algorithm"); | ||
| 115 | } | ||
| 116 | } catch (InvalidKeyException e) { | ||
| 117 | throw new InvalidKeySpecException("Secret key has wrong size"); | ||
| 118 | } | ||
| 119 | } | ||
| 120 | |||
| 121 | /** | ||
| 122 | * Translates a <code>SecretKey</code> object, whose provider may be | ||
| 123 | * unknown or potentially untrusted, into a corresponding | ||
| 124 | * <code>SecretKey</code> object of this key factory. | ||
| 125 | * | ||
| 126 | * @param key the key whose provider is unknown or untrusted | ||
| 127 | * | ||
| 128 | * @return the translated key | ||
| 129 | * | ||
| 130 | * @exception InvalidKeyException if the given key cannot be processed by | ||
| 131 | * this key factory. | ||
| 132 | */ | ||
| 133 | protected SecretKey engineTranslateKey(SecretKey key) | ||
| 134 | throws InvalidKeyException { | ||
| 135 | |||
| 136 | try { | ||
| 137 | |||
| 138 | if ((key != null) | ||
| 139 | && (key.getAlgorithm().equalsIgnoreCase("DESede")) | ||
| 140 | && (key.getFormat().equalsIgnoreCase("RAW"))) { | ||
| 141 | // Check if key originates from this factory | ||
| 142 | if (key instanceof com.sun.crypto.provider.DESedeKey) { | ||
| 143 | return key; | ||
| 144 | } | ||
| 145 | // Convert key to spec | ||
| 146 | DESedeKeySpec desEdeKeySpec | ||
| 147 | = (DESedeKeySpec)engineGetKeySpec(key, | ||
| 148 | DESedeKeySpec.class); | ||
| 149 | // Create key from spec, and return it | ||
| 150 | return engineGenerateSecret(desEdeKeySpec); | ||
| 151 | |||
| 152 | } else { | ||
| 153 | throw new InvalidKeyException | ||
| 154 | ("Inappropriate key format/algorithm"); | ||
| 155 | } | ||
| 156 | |||
| 157 | } catch (InvalidKeySpecException e) { | ||
| 158 | throw new InvalidKeyException("Cannot translate key"); | ||
| 159 | } | ||
| 160 | } | ||
| 161 | } | ||
| @@ -0,0 +1,145 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import javax.crypto.KeyGeneratorSpi; | ||
| 29 | import javax.crypto.SecretKey; | ||
| 30 | import javax.crypto.spec.DESedeKeySpec; | ||
| 31 | import java.security.SecureRandom; | ||
| 32 | import java.security.InvalidParameterException; | ||
| 33 | import java.security.InvalidAlgorithmParameterException; | ||
| 34 | import java.security.InvalidKeyException; | ||
| 35 | import java.security.spec.AlgorithmParameterSpec; | ||
| 36 | |||
| 37 | /** | ||
| 38 | * This class generates a Triple DES key. | ||
| 39 | * | ||
| 40 | * @author Jan Luehe | ||
| 41 | * | ||
| 42 | */ | ||
| 43 | |||
| 44 | public final class DESedeKeyGenerator extends KeyGeneratorSpi { | ||
| 45 | |||
| 46 | private SecureRandom random = null; | ||
| 47 | private int keysize = 168; | ||
| 48 | |||
| 49 | /** | ||
| 50 | * Empty constructor | ||
| 51 | */ | ||
| 52 | public DESedeKeyGenerator() { | ||
| 53 | } | ||
| 54 | |||
| 55 | /** | ||
| 56 | * Initializes this key generator. | ||
| 57 | * | ||
| 58 | * @param random the source of randomness for this generator | ||
| 59 | */ | ||
| 60 | protected void engineInit(SecureRandom random) { | ||
| 61 | this.random = random; | ||
| 62 | } | ||
| 63 | |||
| 64 | /** | ||
| 65 | * Initializes this key generator with the specified parameter | ||
| 66 | * set and a user-provided source of randomness. | ||
| 67 | * | ||
| 68 | * @param params the key generation parameters | ||
| 69 | * @param random the source of randomness for this key generator | ||
| 70 | * | ||
| 71 | * @exception InvalidAlgorithmParameterException if <code>params</code> is | ||
| 72 | * inappropriate for this key generator | ||
| 73 | */ | ||
| 74 | protected void engineInit(AlgorithmParameterSpec params, | ||
| 75 | SecureRandom random) | ||
| 76 | throws InvalidAlgorithmParameterException { | ||
| 77 | throw new InvalidAlgorithmParameterException | ||
| 78 | ("Triple DES key generation does not take any parameters"); | ||
| 79 | } | ||
| 80 | |||
| 81 | /** | ||
| 82 | * Initializes this key generator for a certain keysize, using the given | ||
| 83 | * source of randomness. | ||
| 84 | * | ||
| 85 | * @param keysize the keysize. This is an algorithm-specific | ||
| 86 | * metric specified in number of bits. A keysize with 112 bits of entropy | ||
| 87 | * corresponds to a Triple DES key with 2 intermediate keys, and a keysize | ||
| 88 | * with 168 bits of entropy corresponds to a Triple DES key with 3 | ||
| 89 | * intermediate keys. | ||
| 90 | * @param random the source of randomness for this key generator | ||
| 91 | */ | ||
| 92 | protected void engineInit(int keysize, SecureRandom random) { | ||
| 93 | if ((keysize != 112) && (keysize != 168)) { | ||
| 94 | throw new InvalidParameterException("Wrong keysize: must be " | ||
| 95 | + "equal to 112 or 168"); | ||
| 96 | } | ||
| 97 | this.keysize = keysize; | ||
| 98 | this.engineInit(random); | ||
| 99 | } | ||
| 100 | |||
| 101 | /** | ||
| 102 | * Generates the Triple DES key. | ||
| 103 | * | ||
| 104 | * @return the new Triple DES key | ||
| 105 | */ | ||
| 106 | protected SecretKey engineGenerateKey() { | ||
| 107 | if (this.random == null) { | ||
| 108 | this.random = SunJCE.RANDOM; | ||
| 109 | } | ||
| 110 | |||
| 111 | byte[] rawkey = new byte[DESedeKeySpec.DES_EDE_KEY_LEN]; | ||
| 112 | |||
| 113 | if (keysize == 168) { | ||
| 114 | // 3 intermediate keys | ||
| 115 | this.random.nextBytes(rawkey); | ||
| 116 | |||
| 117 | // Do parity adjustment for each intermediate key | ||
| 118 | DESKeyGenerator.setParityBit(rawkey, 0); | ||
| 119 | DESKeyGenerator.setParityBit(rawkey, 8); | ||
| 120 | DESKeyGenerator.setParityBit(rawkey, 16); | ||
| 121 | } else { | ||
| 122 | // 2 intermediate keys | ||
| 123 | byte[] tmpkey = new byte[16]; | ||
| 124 | this.random.nextBytes(tmpkey); | ||
| 125 | DESKeyGenerator.setParityBit(tmpkey, 0); | ||
| 126 | DESKeyGenerator.setParityBit(tmpkey, 8); | ||
| 127 | System.arraycopy(tmpkey, 0, rawkey, 0, tmpkey.length); | ||
| 128 | // Copy the first 8 bytes into the last | ||
| 129 | System.arraycopy(tmpkey, 0, rawkey, 16, 8); | ||
| 130 | java.util.Arrays.fill(tmpkey, (byte)0x00); | ||
| 131 | } | ||
| 132 | |||
| 133 | DESedeKey desEdeKey = null; | ||
| 134 | try { | ||
| 135 | desEdeKey = new DESedeKey(rawkey); | ||
| 136 | } catch (InvalidKeyException ike) { | ||
| 137 | // this never happens | ||
| 138 | throw new RuntimeException(ike.getMessage()); | ||
| 139 | } | ||
| 140 | |||
| 141 | java.util.Arrays.fill(rawkey, (byte)0x00); | ||
| 142 | |||
| 143 | return desEdeKey; | ||
| 144 | } | ||
| 145 | } | ||
| @@ -0,0 +1,87 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.util.*; | ||
| 29 | import java.io.*; | ||
| 30 | import sun.security.util.*; | ||
| 31 | import java.security.AlgorithmParametersSpi; | ||
| 32 | import java.security.spec.AlgorithmParameterSpec; | ||
| 33 | import java.security.spec.InvalidParameterSpecException; | ||
| 34 | import javax.crypto.spec.IvParameterSpec; | ||
| 35 | |||
| 36 | /** | ||
| 37 | * This class implements the parameter (IV) used with the Triple DES algorithm | ||
| 38 | * in feedback-mode. IV is defined in the standards as follows: | ||
| 39 | * | ||
| 40 | * <pre> | ||
| 41 | * IV ::= OCTET STRING -- 8 octets | ||
| 42 | * </pre> | ||
| 43 | * | ||
| 44 | * @author Jan Luehe | ||
| 45 | * | ||
| 46 | */ | ||
| 47 | public final class DESedeParameters extends AlgorithmParametersSpi { | ||
| 48 | |||
| 49 | private BlockCipherParamsCore core; | ||
| 50 | |||
| 51 | public DESedeParameters() { | ||
| 52 | core = new BlockCipherParamsCore(DESConstants.DES_BLOCK_SIZE); | ||
| 53 | } | ||
| 54 | |||
| 55 | protected void engineInit(AlgorithmParameterSpec paramSpec) | ||
| 56 | throws InvalidParameterSpecException { | ||
| 57 | core.init(paramSpec); | ||
| 58 | } | ||
| 59 | |||
| 60 | protected void engineInit(byte[] encoded) | ||
| 61 | throws IOException { | ||
| 62 | core.init(encoded); | ||
| 63 | } | ||
| 64 | |||
| 65 | protected void engineInit(byte[] encoded, String decodingMethod) | ||
| 66 | throws IOException { | ||
| 67 | core.init(encoded, decodingMethod); | ||
| 68 | } | ||
| 69 | |||
| 70 | protected AlgorithmParameterSpec engineGetParameterSpec(Class paramSpec) | ||
| 71 | throws InvalidParameterSpecException { | ||
| 72 | return core.getParameterSpec(paramSpec); | ||
| 73 | } | ||
| 74 | |||
| 75 | protected byte[] engineGetEncoded() throws IOException { | ||
| 76 | return core.getEncoded(); | ||
| 77 | } | ||
| 78 | |||
| 79 | protected byte[] engineGetEncoded(String encodingMethod) | ||
| 80 | throws IOException { | ||
| 81 | return core.getEncoded(); | ||
| 82 | } | ||
| 83 | |||
| 84 | protected String engineToString() { | ||
| 85 | return core.toString(); | ||
| 86 | } | ||
| 87 | } | ||
| @@ -0,0 +1,567 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2004, 2009, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.util.Arrays; | ||
| 29 | import java.security.*; | ||
| 30 | import java.security.spec.*; | ||
| 31 | import javax.crypto.*; | ||
| 32 | import javax.crypto.spec.*; | ||
| 33 | |||
| 34 | /** | ||
| 35 | * This class implements the CMS DESede KeyWrap algorithm as defined | ||
| 36 | * in <a href=http://www.w3.org/TR/xmlenc-core/#sec-Alg-SymmetricKeyWrap> | ||
| 37 | * "XML Encryption Syntax and Processing" section 5.6.2 | ||
| 38 | * "CMS Triple DES Key Wrap". | ||
| 39 | * Note: only <code>CBC</code> mode and <code>NoPadding</code> padding | ||
| 40 | * scheme can be used for this algorithm. | ||
| 41 | * | ||
| 42 | * @author Valerie Peng | ||
| 43 | * | ||
| 44 | * | ||
| 45 | * @see DESedeCipher | ||
| 46 | */ | ||
| 47 | public final class DESedeWrapCipher extends CipherSpi { | ||
| 48 | |||
| 49 | private static final byte[] IV2 = { | ||
| 50 | (byte) 0x4a, (byte) 0xdd, (byte) 0xa2, (byte) 0x2c, | ||
| 51 | (byte) 0x79, (byte) 0xe8, (byte) 0x21, (byte) 0x05 | ||
| 52 | }; | ||
| 53 | |||
| 54 | /* | ||
| 55 | * internal cipher object which does the real work. | ||
| 56 | */ | ||
| 57 | private FeedbackCipher cipher; | ||
| 58 | |||
| 59 | /* | ||
| 60 | * iv for (re-)initializing the internal cipher object. | ||
| 61 | */ | ||
| 62 | private byte[] iv = null; | ||
| 63 | |||
| 64 | /* | ||
| 65 | * key for re-initializing the internal cipher object. | ||
| 66 | */ | ||
| 67 | private Key cipherKey = null; | ||
| 68 | |||
| 69 | /* | ||
| 70 | * are we encrypting or decrypting? | ||
| 71 | */ | ||
| 72 | private boolean decrypting = false; | ||
| 73 | |||
| 74 | /** | ||
| 75 | * Creates an instance of CMS DESede KeyWrap cipher with default | ||
| 76 | * mode, i.e. "CBC" and padding scheme, i.e. "NoPadding". | ||
| 77 | */ | ||
| 78 | public DESedeWrapCipher() { | ||
| 79 | cipher = new CipherBlockChaining(new DESedeCrypt()); | ||
| 80 | } | ||
| 81 | |||
| 82 | /** | ||
| 83 | * Sets the mode of this cipher. Only "CBC" mode is accepted for this | ||
| 84 | * cipher. | ||
| 85 | * | ||
| 86 | * @param mode the cipher mode. | ||
| 87 | * | ||
| 88 | * @exception NoSuchAlgorithmException if the requested cipher mode | ||
| 89 | * is not "CBC". | ||
| 90 | */ | ||
| 91 | protected void engineSetMode(String mode) | ||
| 92 | throws NoSuchAlgorithmException { | ||
| 93 | if (!mode.equalsIgnoreCase("CBC")) { | ||
| 94 | throw new NoSuchAlgorithmException(mode + " cannot be used"); | ||
| 95 | } | ||
| 96 | } | ||
| 97 | |||
| 98 | /** | ||
| 99 | * Sets the padding mechanism of this cipher. Only "NoPadding" schmem | ||
| 100 | * is accepted for this cipher. | ||
| 101 | * | ||
| 102 | * @param padding the padding mechanism. | ||
| 103 | * | ||
| 104 | * @exception NoSuchPaddingException if the requested padding mechanism | ||
| 105 | * is not "NoPadding". | ||
| 106 | */ | ||
| 107 | protected void engineSetPadding(String padding) | ||
| 108 | throws NoSuchPaddingException { | ||
| 109 | if (!padding.equalsIgnoreCase("NoPadding")) { | ||
| 110 | throw new NoSuchPaddingException(padding + " cannot be used"); | ||
| 111 | } | ||
| 112 | } | ||
| 113 | |||
| 114 | /** | ||
| 115 | * Returns the block size (in bytes), i.e. 8 bytes. | ||
| 116 | * | ||
| 117 | * @return the block size (in bytes), i.e. 8 bytes. | ||
| 118 | */ | ||
| 119 | protected int engineGetBlockSize() { | ||
| 120 | return DESConstants.DES_BLOCK_SIZE; | ||
| 121 | } | ||
| 122 | |||
| 123 | /** | ||
| 124 | * Returns the length in bytes that an output buffer would need to be | ||
| 125 | * given the input length <code>inputLen</code> (in bytes). | ||
| 126 | * | ||
| 127 | * <p>The actual output length of the next <code>update</code> or | ||
| 128 | * <code>doFinal</code> call may be smaller than the length returned | ||
| 129 | * by this method. | ||
| 130 | * | ||
| 131 | * @param inputLen the input length (in bytes). | ||
| 132 | * | ||
| 133 | * @return the required output buffer size (in bytes). | ||
| 134 | */ | ||
| 135 | protected int engineGetOutputSize(int inputLen) { | ||
| 136 | // can only return an upper-limit if not initialized yet. | ||
| 137 | int result = 0; | ||
| 138 | if (decrypting) { | ||
| 139 | result = inputLen - 16; | ||
| 140 | } else { | ||
| 141 | result = inputLen + 16; | ||
| 142 | } | ||
| 143 | return (result < 0? 0:result); | ||
| 144 | } | ||
| 145 | |||
| 146 | /** | ||
| 147 | * Returns the initialization vector (IV) in a new buffer. | ||
| 148 | * | ||
| 149 | * @return the initialization vector, or null if the underlying | ||
| 150 | * algorithm does not use an IV, or if the IV has not yet | ||
| 151 | * been set. | ||
| 152 | */ | ||
| 153 | protected byte[] engineGetIV() { | ||
| 154 | return (iv == null? null:(byte[]) iv.clone()); | ||
| 155 | } | ||
| 156 | |||
| 157 | /** | ||
| 158 | * Initializes this cipher with a key and a source of randomness. | ||
| 159 | * | ||
| 160 | * <p>The cipher only supports the following two operation modes:<b> | ||
| 161 | * Cipher.WRAP_MODE, and <b> | ||
| 162 | * Cipher.UNWRAP_MODE. | ||
| 163 | * <p>For modes other than the above two, UnsupportedOperationException | ||
| 164 | * will be thrown. | ||
| 165 | * <p>If this cipher requires an initialization vector (IV), it will get | ||
| 166 | * it from <code>random</code>. | ||
| 167 | * | ||
| 168 | * @param opmode the operation mode of this cipher. Only | ||
| 169 | * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) are accepted. | ||
| 170 | * @param key the secret key. | ||
| 171 | * @param random the source of randomness. | ||
| 172 | * | ||
| 173 | * @exception InvalidKeyException if the given key is inappropriate | ||
| 174 | * or if parameters are required but not supplied. | ||
| 175 | */ | ||
| 176 | protected void engineInit(int opmode, Key key, SecureRandom random) | ||
| 177 | throws InvalidKeyException { | ||
| 178 | try { | ||
| 179 | engineInit(opmode, key, (AlgorithmParameterSpec) null, random); | ||
| 180 | } catch (InvalidAlgorithmParameterException iape) { | ||
| 181 | // should never happen | ||
| 182 | InvalidKeyException ike = | ||
| 183 | new InvalidKeyException("Parameters required"); | ||
| 184 | ike.initCause(iape); | ||
| 185 | throw ike; | ||
| 186 | } | ||
| 187 | } | ||
| 188 | |||
| 189 | /** | ||
| 190 | * Initializes this cipher with a key, a set of algorithm parameters, | ||
| 191 | * and a source of randomness. | ||
| 192 | * | ||
| 193 | * <p>The cipher only supports the following two operation modes:<b> | ||
| 194 | * Cipher.WRAP_MODE, and <b> | ||
| 195 | * Cipher.UNWRAP_MODE. | ||
| 196 | * <p>For modes other than the above two, UnsupportedOperationException | ||
| 197 | * will be thrown. | ||
| 198 | * <p>If this cipher requires an initialization vector (IV), it will get | ||
| 199 | * it from <code>random</code>. | ||
| 200 | * | ||
| 201 | * @param opmode the operation mode of this cipher. Only | ||
| 202 | * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) are accepted. | ||
| 203 | * @param key the secret key. | ||
| 204 | * @param params the algorithm parameters. | ||
| 205 | * @param random the source of randomness. | ||
| 206 | * | ||
| 207 | * @exception InvalidKeyException if the given key is inappropriate. | ||
| 208 | * @exception InvalidAlgorithmParameterException if the given algorithm | ||
| 209 | * parameters are inappropriate for this cipher. | ||
| 210 | */ | ||
| 211 | protected void engineInit(int opmode, Key key, | ||
| 212 | AlgorithmParameterSpec params, | ||
| 213 | SecureRandom random) | ||
| 214 | throws InvalidKeyException, InvalidAlgorithmParameterException { | ||
| 215 | byte[] currIv = null; | ||
| 216 | if (opmode == Cipher.WRAP_MODE) { | ||
| 217 | decrypting = false; | ||
| 218 | if (params == null) { | ||
| 219 | iv = new byte[8]; | ||
| 220 | if (random == null) { | ||
| 221 | random = SunJCE.RANDOM; | ||
| 222 | } | ||
| 223 | random.nextBytes(iv); | ||
| 224 | } | ||
| 225 | else if (params instanceof IvParameterSpec) { | ||
| 226 | iv = ((IvParameterSpec) params).getIV(); | ||
| 227 | } else { | ||
| 228 | throw new InvalidAlgorithmParameterException | ||
| 229 | ("Wrong parameter type: IV expected"); | ||
| 230 | } | ||
| 231 | currIv = iv; | ||
| 232 | } else if (opmode == Cipher.UNWRAP_MODE) { | ||
| 233 | if (params != null) { | ||
| 234 | throw new InvalidAlgorithmParameterException | ||
| 235 | ("No parameter accepted for unwrapping keys"); | ||
| 236 | } | ||
| 237 | iv = null; | ||
| 238 | decrypting = true; | ||
| 239 | currIv = IV2; | ||
| 240 | } else { | ||
| 241 | throw new UnsupportedOperationException("This cipher can " + | ||
| 242 | "only be used for key wrapping and unwrapping"); | ||
| 243 | } | ||
| 244 | cipher.init(decrypting, key.getAlgorithm(), key.getEncoded(), | ||
| 245 | currIv); | ||
| 246 | cipherKey = key; | ||
| 247 | } | ||
| 248 | |||
| 249 | /** | ||
| 250 | * Initializes this cipher with a key, a set of algorithm parameters, | ||
| 251 | * and a source of randomness. | ||
| 252 | * | ||
| 253 | * <p>The cipher only supports the following two operation modes:<b> | ||
| 254 | * Cipher.WRAP_MODE, and <b> | ||
| 255 | * Cipher.UNWRAP_MODE. | ||
| 256 | * <p>For modes other than the above two, UnsupportedOperationException | ||
| 257 | * will be thrown. | ||
| 258 | * <p>If this cipher requires an initialization vector (IV), it will get | ||
| 259 | * it from <code>random</code>. | ||
| 260 | * | ||
| 261 | * @param opmode the operation mode of this cipher. Only | ||
| 262 | * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) are accepted. | ||
| 263 | * @param key the secret key. | ||
| 264 | * @param params the algorithm parameters. | ||
| 265 | * @param random the source of randomness. | ||
| 266 | * | ||
| 267 | * @exception InvalidKeyException if the given key is inappropriate. | ||
| 268 | * @exception InvalidAlgorithmParameterException if the given algorithm | ||
| 269 | * parameters are inappropriate for this cipher. | ||
| 270 | */ | ||
| 271 | protected void engineInit(int opmode, Key key, | ||
| 272 | AlgorithmParameters params, | ||
| 273 | SecureRandom random) | ||
| 274 | throws InvalidKeyException, InvalidAlgorithmParameterException { | ||
| 275 | IvParameterSpec ivSpec = null; | ||
| 276 | if (params != null) { | ||
| 277 | try { | ||
| 278 | DESedeParameters paramsEng = new DESedeParameters(); | ||
| 279 | paramsEng.engineInit(params.getEncoded()); | ||
| 280 | ivSpec = (IvParameterSpec) | ||
| 281 | paramsEng.engineGetParameterSpec(IvParameterSpec.class); | ||
| 282 | } catch (Exception ex) { | ||
| 283 | InvalidAlgorithmParameterException iape = | ||
| 284 | new InvalidAlgorithmParameterException | ||
| 285 | ("Wrong parameter type: IV expected"); | ||
| 286 | iape.initCause(ex); | ||
| 287 | throw iape; | ||
| 288 | } | ||
| 289 | } | ||
| 290 | engineInit(opmode, key, ivSpec, random); | ||
| 291 | } | ||
| 292 | |||
| 293 | /** | ||
| 294 | * This operation is not supported by this cipher. | ||
| 295 | * Since it's impossible to initialize this cipher given the | ||
| 296 | * current Cipher.engineInit(...) implementation, | ||
| 297 | * IllegalStateException will always be thrown upon invocation. | ||
| 298 | * | ||
| 299 | * @param in the input buffer. | ||
| 300 | * @param inOffset the offset in <code>in</code> where the input | ||
| 301 | * starts. | ||
| 302 | * @param inLen the input length. | ||
| 303 | * | ||
| 304 | * @return n/a. | ||
| 305 | * | ||
| 306 | * @exception IllegalStateException upon invocation of this method. | ||
| 307 | */ | ||
| 308 | protected byte[] engineUpdate(byte[] in, int inOffset, int inLen) { | ||
| 309 | throw new IllegalStateException("Cipher has not been initialized"); | ||
| 310 | } | ||
| 311 | |||
| 312 | /** | ||
| 313 | * This operation is not supported by this cipher. | ||
| 314 | * Since it's impossible to initialize this cipher given the | ||
| 315 | * current Cipher.engineInit(...) implementation, | ||
| 316 | * IllegalStateException will always be thrown upon invocation. | ||
| 317 | * | ||
| 318 | * @param in the input buffer. | ||
| 319 | * @param inOffset the offset in <code>in</code> where the input | ||
| 320 | * starts. | ||
| 321 | * @param inLen the input length. | ||
| 322 | * @param out the buffer for the result. | ||
| 323 | * @param outOffset the offset in <code>out</code> where the result | ||
| 324 | * is stored. | ||
| 325 | * | ||
| 326 | * @return n/a. | ||
| 327 | * | ||
| 328 | * @exception IllegalStateException upon invocation of this method. | ||
| 329 | */ | ||
| 330 | protected int engineUpdate(byte[] in, int inOffset, int inLen, | ||
| 331 | byte[] out, int outOffset) | ||
| 332 | throws ShortBufferException { | ||
| 333 | throw new IllegalStateException("Cipher has not been initialized"); | ||
| 334 | } | ||
| 335 | |||
| 336 | /** | ||
| 337 | * This operation is not supported by this cipher. | ||
| 338 | * Since it's impossible to initialize this cipher given the | ||
| 339 | * current Cipher.engineInit(...) implementation, | ||
| 340 | * IllegalStateException will always be thrown upon invocation. | ||
| 341 | * | ||
| 342 | * @param in the input buffer. | ||
| 343 | * @param inOffset the offset in <code>in</code> where the input | ||
| 344 | * starts. | ||
| 345 | * @param inLen the input length. | ||
| 346 | * | ||
| 347 | * @return the new buffer with the result. | ||
| 348 | * | ||
| 349 | * @exception IllegalStateException upon invocation of this method. | ||
| 350 | */ | ||
| 351 | protected byte[] engineDoFinal(byte[] in, int inOffset, int inLen) | ||
| 352 | throws IllegalBlockSizeException, BadPaddingException { | ||
| 353 | throw new IllegalStateException("Cipher has not been initialized"); | ||
| 354 | } | ||
| 355 | |||
| 356 | /** | ||
| 357 | * This operation is not supported by this cipher. | ||
| 358 | * Since it's impossible to initialize this cipher given the | ||
| 359 | * current Cipher.engineInit(...) implementation, | ||
| 360 | * IllegalStateException will always be thrown upon invocation. | ||
| 361 | * | ||
| 362 | * @param in the input buffer. | ||
| 363 | * @param inOffset the offset in <code>in</code> where the input | ||
| 364 | * starts. | ||
| 365 | * @param inLen the input length. | ||
| 366 | * @param out the buffer for the result. | ||
| 367 | * @param outOffset the ofset in <code>out</code> where the result | ||
| 368 | * is stored. | ||
| 369 | * | ||
| 370 | * @return the number of bytes stored in <code>out</code>. | ||
| 371 | * | ||
| 372 | * @exception IllegalStateException upon invocation of this method. | ||
| 373 | */ | ||
| 374 | protected int engineDoFinal(byte[] input, int inputOffset, int inputLen, | ||
| 375 | byte[] output, int outputOffset) | ||
| 376 | throws IllegalBlockSizeException, ShortBufferException, | ||
| 377 | BadPaddingException { | ||
| 378 | throw new IllegalStateException("Cipher has not been initialized"); | ||
| 379 | } | ||
| 380 | |||
| 381 | /** | ||
| 382 | * Returns the parameters used with this cipher. | ||
| 383 | * Note that null maybe returned if this cipher does not use any | ||
| 384 | * parameters or when it has not be set, e.g. initialized with | ||
| 385 | * UNWRAP_MODE but wrapped key data has not been given. | ||
| 386 | * | ||
| 387 | * @return the parameters used with this cipher; can be null. | ||
| 388 | */ | ||
| 389 | protected AlgorithmParameters engineGetParameters() { | ||
| 390 | AlgorithmParameters params = null; | ||
| 391 | if (iv != null) { | ||
| 392 | String algo = cipherKey.getAlgorithm(); | ||
| 393 | try { | ||
| 394 | params = AlgorithmParameters.getInstance(algo, "SunJCE"); | ||
| 395 | } catch (NoSuchAlgorithmException nsae) { | ||
| 396 | // should never happen | ||
| 397 | throw new RuntimeException("Cannot find " + algo + | ||
| 398 | " AlgorithmParameters implementation in SunJCE provider"); | ||
| 399 | } catch (NoSuchProviderException nspe) { | ||
| 400 | // should never happen | ||
| 401 | throw new RuntimeException("Cannot find SunJCE provider"); | ||
| 402 | } | ||
| 403 | try { | ||
| 404 | params.init(new IvParameterSpec(iv)); | ||
| 405 | } catch (InvalidParameterSpecException ipse) { | ||
| 406 | // should never happen | ||
| 407 | throw new RuntimeException("IvParameterSpec not supported"); | ||
| 408 | } | ||
| 409 | } | ||
| 410 | return params; | ||
| 411 | } | ||
| 412 | |||
| 413 | /** | ||
| 414 | * Returns the key size of the given key object in number of bits. | ||
| 415 | * This cipher always return the same key size as the DESede ciphers. | ||
| 416 | * | ||
| 417 | * @param key the key object. | ||
| 418 | * | ||
| 419 | * @return the "effective" key size of the given key object. | ||
| 420 | * | ||
| 421 | * @exception InvalidKeyException if <code>key</code> is invalid. | ||
| 422 | */ | ||
| 423 | protected int engineGetKeySize(Key key) throws InvalidKeyException { | ||
| 424 | byte[] encoded = key.getEncoded(); | ||
| 425 | if (encoded.length != 24) { | ||
| 426 | throw new InvalidKeyException("Invalid key length: " + | ||
| 427 | encoded.length + " bytes"); | ||
| 428 | } | ||
| 429 | // Return the effective key length | ||
| 430 | return 112; | ||
| 431 | } | ||
| 432 | |||
| 433 | /** | ||
| 434 | * Wrap a key. | ||
| 435 | * | ||
| 436 | * @param key the key to be wrapped. | ||
| 437 | * | ||
| 438 | * @return the wrapped key. | ||
| 439 | * | ||
| 440 | * @exception IllegalBlockSizeException if this cipher is a block | ||
| 441 | * cipher, no padding has been requested, and the length of the | ||
| 442 | * encoding of the key to be wrapped is not a | ||
| 443 | * multiple of the block size. | ||
| 444 | * | ||
| 445 | * @exception InvalidKeyException if it is impossible or unsafe to | ||
| 446 | * wrap the key with this cipher (e.g., a hardware protected key is | ||
| 447 | * being passed to a software only cipher). | ||
| 448 | */ | ||
| 449 | protected byte[] engineWrap(Key key) | ||
| 450 | throws IllegalBlockSizeException, InvalidKeyException { | ||
| 451 | byte[] keyVal = key.getEncoded(); | ||
| 452 | if ((keyVal == null) || (keyVal.length == 0)) { | ||
| 453 | throw new InvalidKeyException("Cannot get an encoding of " + | ||
| 454 | "the key to be wrapped"); | ||
| 455 | } | ||
| 456 | |||
| 457 | byte[] cks = getChecksum(keyVal); | ||
| 458 | byte[] out = new byte[iv.length + keyVal.length + cks.length]; | ||
| 459 | |||
| 460 | System.arraycopy(keyVal, 0, out, iv.length, keyVal.length); | ||
| 461 | System.arraycopy(cks, 0, out, iv.length+keyVal.length, cks.length); | ||
| 462 | cipher.encrypt(out, iv.length, keyVal.length+cks.length, | ||
| 463 | out, iv.length); | ||
| 464 | |||
| 465 | System.arraycopy(iv, 0, out, 0, iv.length); | ||
| 466 | // reverse the array content | ||
| 467 | for (int i = 0; i < out.length/2; i++) { | ||
| 468 | byte temp = out[i]; | ||
| 469 | out[i] = out[out.length-1-i]; | ||
| 470 | out[out.length-1-i] = temp; | ||
| 471 | } | ||
| 472 | try { | ||
| 473 | cipher.init(false, cipherKey.getAlgorithm(), | ||
| 474 | cipherKey.getEncoded(), IV2); | ||
| 475 | } catch (InvalidKeyException ike) { | ||
| 476 | // should never happen | ||
| 477 | throw new RuntimeException("Internal cipher key is corrupted"); | ||
| 478 | } | ||
| 479 | cipher.encrypt(out, 0, out.length, out, 0); | ||
| 480 | |||
| 481 | // restore cipher state to prior to this call | ||
| 482 | try { | ||
| 483 | cipher.init(decrypting, cipherKey.getAlgorithm(), | ||
| 484 | cipherKey.getEncoded(), iv); | ||
| 485 | } catch (InvalidKeyException ike) { | ||
| 486 | // should never happen | ||
| 487 | throw new RuntimeException("Internal cipher key is corrupted"); | ||
| 488 | } | ||
| 489 | return out; | ||
| 490 | } | ||
| 491 | |||
| 492 | /** | ||
| 493 | * Unwrap a previously wrapped key. | ||
| 494 | * | ||
| 495 | * @param wrappedKey the key to be unwrapped. | ||
| 496 | * | ||
| 497 | * @param wrappedKeyAlgorithm the algorithm the wrapped key is for. | ||
| 498 | * | ||
| 499 | * @param wrappedKeyType the type of the wrapped key. | ||
| 500 | * This is one of <code>Cipher.SECRET_KEY</code>, | ||
| 501 | * <code>Cipher.PRIVATE_KEY</code>, or <code>Cipher.PUBLIC_KEY</code>. | ||
| 502 | * | ||
| 503 | * @return the unwrapped key. | ||
| 504 | * | ||
| 505 | * @exception NoSuchAlgorithmException if no installed providers | ||
| 506 | * can create keys of type <code>wrappedKeyType</code> for the | ||
| 507 | * <code>wrappedKeyAlgorithm</code>. | ||
| 508 | * | ||
| 509 | * @exception InvalidKeyException if <code>wrappedKey</code> does not | ||
| 510 | * represent a wrapped key of type <code>wrappedKeyType</code> for | ||
| 511 | * the <code>wrappedKeyAlgorithm</code>. | ||
| 512 | */ | ||
| 513 | protected Key engineUnwrap(byte[] wrappedKey, | ||
| 514 | String wrappedKeyAlgorithm, | ||
| 515 | int wrappedKeyType) | ||
| 516 | throws InvalidKeyException, NoSuchAlgorithmException { | ||
| 517 | if (wrappedKey.length == 0) { | ||
| 518 | throw new InvalidKeyException("The wrapped key is empty"); | ||
| 519 | } | ||
| 520 | byte[] buffer = new byte[wrappedKey.length]; | ||
| 521 | cipher.decrypt(wrappedKey, 0, wrappedKey.length, buffer, 0); | ||
| 522 | |||
| 523 | // reverse array content | ||
| 524 | for (int i = 0; i < buffer.length/2; i++) { | ||
| 525 | byte temp = buffer[i]; | ||
| 526 | buffer[i] = buffer[buffer.length-1-i]; | ||
| 527 | buffer[buffer.length-1-i] = temp; | ||
| 528 | } | ||
| 529 | iv = new byte[IV2.length]; | ||
| 530 | System.arraycopy(buffer, 0, iv, 0, iv.length); | ||
| 531 | cipher.init(true, cipherKey.getAlgorithm(), cipherKey.getEncoded(), | ||
| 532 | iv); | ||
| 533 | cipher.decrypt(buffer, iv.length, buffer.length-iv.length, | ||
| 534 | buffer, iv.length); | ||
| 535 | int origLen = buffer.length - iv.length - 8; | ||
| 536 | byte[] cks = getChecksum(buffer, iv.length, origLen); | ||
| 537 | int offset = iv.length + origLen; | ||
| 538 | for (int i = 0; i < cks.length; i++) { | ||
| 539 | if (buffer[offset + i] != cks[i]) { | ||
| 540 | throw new InvalidKeyException("Checksum comparison failed"); | ||
| 541 | } | ||
| 542 | } | ||
| 543 | // restore cipher state to prior to this call | ||
| 544 | cipher.init(decrypting, cipherKey.getAlgorithm(), | ||
| 545 | cipherKey.getEncoded(), IV2); | ||
| 546 | byte[] out = new byte[origLen]; | ||
| 547 | System.arraycopy(buffer, iv.length, out, 0, out.length); | ||
| 548 | return ConstructKeys.constructKey(out, wrappedKeyAlgorithm, | ||
| 549 | wrappedKeyType); | ||
| 550 | } | ||
| 551 | |||
| 552 | private static final byte[] getChecksum(byte[] in) { | ||
| 553 | return getChecksum(in, 0, in.length); | ||
| 554 | } | ||
| 555 | private static final byte[] getChecksum(byte[] in, int offset, int len) { | ||
| 556 | MessageDigest md = null; | ||
| 557 | try { | ||
| 558 | md = MessageDigest.getInstance("SHA1"); | ||
| 559 | } catch (NoSuchAlgorithmException nsae) { | ||
| 560 | throw new RuntimeException("SHA1 message digest not available"); | ||
| 561 | } | ||
| 562 | md.update(in, offset, len); | ||
| 563 | byte[] cks = new byte[8]; | ||
| 564 | System.arraycopy(md.digest(), 0, cks, 0, cks.length); | ||
| 565 | return cks; | ||
| 566 | } | ||
| 567 | } | ||
| @@ -0,0 +1,412 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.util.*; | ||
| 29 | import java.lang.*; | ||
| 30 | import java.math.BigInteger; | ||
| 31 | import java.security.InvalidAlgorithmParameterException; | ||
| 32 | import java.security.InvalidKeyException; | ||
| 33 | import java.security.Key; | ||
| 34 | import java.security.NoSuchAlgorithmException; | ||
| 35 | import java.security.SecureRandom; | ||
| 36 | import java.security.spec.AlgorithmParameterSpec; | ||
| 37 | import java.security.spec.InvalidKeySpecException; | ||
| 38 | import javax.crypto.KeyAgreementSpi; | ||
| 39 | import javax.crypto.ShortBufferException; | ||
| 40 | import javax.crypto.SecretKey; | ||
| 41 | import javax.crypto.spec.*; | ||
| 42 | |||
| 43 | /** | ||
| 44 | * This class implements the Diffie-Hellman key agreement protocol between | ||
| 45 | * any number of parties. | ||
| 46 | * | ||
| 47 | * @author Jan Luehe | ||
| 48 | * | ||
| 49 | */ | ||
| 50 | |||
| 51 | public final class DHKeyAgreement | ||
| 52 | extends KeyAgreementSpi { | ||
| 53 | |||
| 54 | private boolean generateSecret = false; | ||
| 55 | private BigInteger init_p = null; | ||
| 56 | private BigInteger init_g = null; | ||
| 57 | private BigInteger x = BigInteger.ZERO; // the private value | ||
| 58 | private BigInteger y = BigInteger.ZERO; | ||
| 59 | |||
| 60 | /** | ||
| 61 | * Empty constructor | ||
| 62 | */ | ||
| 63 | public DHKeyAgreement() { | ||
| 64 | } | ||
| 65 | |||
| 66 | /** | ||
| 67 | * Initializes this key agreement with the given key and source of | ||
| 68 | * randomness. The given key is required to contain all the algorithm | ||
| 69 | * parameters required for this key agreement. | ||
| 70 | * | ||
| 71 | * <p> If the key agreement algorithm requires random bytes, it gets them | ||
| 72 | * from the given source of randomness, <code>random</code>. | ||
| 73 | * However, if the underlying | ||
| 74 | * algorithm implementation does not require any random bytes, | ||
| 75 | * <code>random</code> is ignored. | ||
| 76 | * | ||
| 77 | * @param key the party's private information. For example, in the case | ||
| 78 | * of the Diffie-Hellman key agreement, this would be the party's own | ||
| 79 | * Diffie-Hellman private key. | ||
| 80 | * @param random the source of randomness | ||
| 81 | * | ||
| 82 | * @exception InvalidKeyException if the given key is | ||
| 83 | * inappropriate for this key agreement, e.g., is of the wrong type or | ||
| 84 | * has an incompatible algorithm type. | ||
| 85 | */ | ||
| 86 | protected void engineInit(Key key, SecureRandom random) | ||
| 87 | throws InvalidKeyException | ||
| 88 | { | ||
| 89 | try { | ||
| 90 | engineInit(key, null, random); | ||
| 91 | } catch (InvalidAlgorithmParameterException e) { | ||
| 92 | // never happens, because we did not pass any parameters | ||
| 93 | } | ||
| 94 | } | ||
| 95 | |||
| 96 | /** | ||
| 97 | * Initializes this key agreement with the given key, set of | ||
| 98 | * algorithm parameters, and source of randomness. | ||
| 99 | * | ||
| 100 | * @param key the party's private information. For example, in the case | ||
| 101 | * of the Diffie-Hellman key agreement, this would be the party's own | ||
| 102 | * Diffie-Hellman private key. | ||
| 103 | * @param params the key agreement parameters | ||
| 104 | * @param random the source of randomness | ||
| 105 | * | ||
| 106 | * @exception InvalidKeyException if the given key is | ||
| 107 | * inappropriate for this key agreement, e.g., is of the wrong type or | ||
| 108 | * has an incompatible algorithm type. | ||
| 109 | * @exception InvalidAlgorithmParameterException if the given parameters | ||
| 110 | * are inappropriate for this key agreement. | ||
| 111 | */ | ||
| 112 | protected void engineInit(Key key, AlgorithmParameterSpec params, | ||
| 113 | SecureRandom random) | ||
| 114 | throws InvalidKeyException, InvalidAlgorithmParameterException | ||
| 115 | { | ||
| 116 | // ignore "random" parameter, because our implementation does not | ||
| 117 | // require any source of randomness | ||
| 118 | generateSecret = false; | ||
| 119 | init_p = null; | ||
| 120 | init_g = null; | ||
| 121 | |||
| 122 | if ((params != null) && !(params instanceof DHParameterSpec)) { | ||
| 123 | throw new InvalidAlgorithmParameterException | ||
| 124 | ("Diffie-Hellman parameters expected"); | ||
| 125 | } | ||
| 126 | if (!(key instanceof javax.crypto.interfaces.DHPrivateKey)) { | ||
| 127 | throw new InvalidKeyException("Diffie-Hellman private key " | ||
| 128 | + "expected"); | ||
| 129 | } | ||
| 130 | javax.crypto.interfaces.DHPrivateKey dhPrivKey; | ||
| 131 | dhPrivKey = (javax.crypto.interfaces.DHPrivateKey)key; | ||
| 132 | |||
| 133 | // check if private key parameters are compatible with | ||
| 134 | // initialized ones | ||
| 135 | if (params != null) { | ||
| 136 | init_p = ((DHParameterSpec)params).getP(); | ||
| 137 | init_g = ((DHParameterSpec)params).getG(); | ||
| 138 | } | ||
| 139 | BigInteger priv_p = dhPrivKey.getParams().getP(); | ||
| 140 | BigInteger priv_g = dhPrivKey.getParams().getG(); | ||
| 141 | if (init_p != null && priv_p != null && !(init_p.equals(priv_p))) { | ||
| 142 | throw new InvalidKeyException("Incompatible parameters"); | ||
| 143 | } | ||
| 144 | if (init_g != null && priv_g != null && !(init_g.equals(priv_g))) { | ||
| 145 | throw new InvalidKeyException("Incompatible parameters"); | ||
| 146 | } | ||
| 147 | if ((init_p == null && priv_p == null) | ||
| 148 | || (init_g == null && priv_g == null)) { | ||
| 149 | throw new InvalidKeyException("Missing parameters"); | ||
| 150 | } | ||
| 151 | init_p = priv_p; | ||
| 152 | init_g = priv_g; | ||
| 153 | |||
| 154 | // store the x value | ||
| 155 | this.x = dhPrivKey.getX(); | ||
| 156 | } | ||
| 157 | |||
| 158 | /** | ||
| 159 | * Executes the next phase of this key agreement with the given | ||
| 160 | * key that was received from one of the other parties involved in this key | ||
| 161 | * agreement. | ||
| 162 | * | ||
| 163 | * @param key the key for this phase. For example, in the case of | ||
| 164 | * Diffie-Hellman between 2 parties, this would be the other party's | ||
| 165 | * Diffie-Hellman public key. | ||
| 166 | * @param lastPhase flag which indicates whether or not this is the last | ||
| 167 | * phase of this key agreement. | ||
| 168 | * | ||
| 169 | * @return the (intermediate) key resulting from this phase, or null if | ||
| 170 | * this phase does not yield a key | ||
| 171 | * | ||
| 172 | * @exception InvalidKeyException if the given key is inappropriate for | ||
| 173 | * this phase. | ||
| 174 | * @exception IllegalStateException if this key agreement has not been | ||
| 175 | * initialized. | ||
| 176 | */ | ||
| 177 | protected Key engineDoPhase(Key key, boolean lastPhase) | ||
| 178 | throws InvalidKeyException, IllegalStateException | ||
| 179 | { | ||
| 180 | if (!(key instanceof javax.crypto.interfaces.DHPublicKey)) { | ||
| 181 | throw new InvalidKeyException("Diffie-Hellman public key " | ||
| 182 | + "expected"); | ||
| 183 | } | ||
| 184 | javax.crypto.interfaces.DHPublicKey dhPubKey; | ||
| 185 | dhPubKey = (javax.crypto.interfaces.DHPublicKey)key; | ||
| 186 | |||
| 187 | if (init_p == null || init_g == null) { | ||
| 188 | throw new IllegalStateException("Not initialized"); | ||
| 189 | } | ||
| 190 | |||
| 191 | // check if public key parameters are compatible with | ||
| 192 | // initialized ones | ||
| 193 | BigInteger pub_p = dhPubKey.getParams().getP(); | ||
| 194 | BigInteger pub_g = dhPubKey.getParams().getG(); | ||
| 195 | if (pub_p != null && !(init_p.equals(pub_p))) { | ||
| 196 | throw new InvalidKeyException("Incompatible parameters"); | ||
| 197 | } | ||
| 198 | if (pub_g != null && !(init_g.equals(pub_g))) { | ||
| 199 | throw new InvalidKeyException("Incompatible parameters"); | ||
| 200 | } | ||
| 201 | |||
| 202 | // store the y value | ||
| 203 | this.y = dhPubKey.getY(); | ||
| 204 | |||
| 205 | // we've received a public key (from one of the other parties), | ||
| 206 | // so we are ready to create the secret, which may be an | ||
| 207 | // intermediate secret, in which case we wrap it into a | ||
| 208 | // Diffie-Hellman public key object and return it. | ||
| 209 | generateSecret = true; | ||
| 210 | if (lastPhase == false) { | ||
| 211 | byte[] intermediate = engineGenerateSecret(); | ||
| 212 | return new DHPublicKey(new BigInteger(1, intermediate), | ||
| 213 | init_p, init_g); | ||
| 214 | } else { | ||
| 215 | return null; | ||
| 216 | } | ||
| 217 | } | ||
| 218 | |||
| 219 | /** | ||
| 220 | * Generates the shared secret and returns it in a new buffer. | ||
| 221 | * | ||
| 222 | * <p>This method resets this <code>KeyAgreementSpi</code> object, | ||
| 223 | * so that it | ||
| 224 | * can be reused for further key agreements. Unless this key agreement is | ||
| 225 | * reinitialized with one of the <code>engineInit</code> methods, the same | ||
| 226 | * private information and algorithm parameters will be used for | ||
| 227 | * subsequent key agreements. | ||
| 228 | * | ||
| 229 | * @return the new buffer with the shared secret | ||
| 230 | * | ||
| 231 | * @exception IllegalStateException if this key agreement has not been | ||
| 232 | * completed yet | ||
| 233 | */ | ||
| 234 | protected byte[] engineGenerateSecret() | ||
| 235 | throws IllegalStateException | ||
| 236 | { | ||
| 237 | if (generateSecret == false) { | ||
| 238 | throw new IllegalStateException | ||
| 239 | ("Key agreement has not been completed yet"); | ||
| 240 | } | ||
| 241 | |||
| 242 | // Reset the key agreement here (in case anything goes wrong) | ||
| 243 | generateSecret = false; | ||
| 244 | |||
| 245 | // get the modulus | ||
| 246 | BigInteger modulus = init_p; | ||
| 247 | |||
| 248 | BigInteger tmpResult = y.modPow(x, modulus); | ||
| 249 | byte[] secret = tmpResult.toByteArray(); | ||
| 250 | |||
| 251 | /* | ||
| 252 | * BigInteger.toByteArray will sometimes put a sign byte up front, but | ||
| 253 | * we NEVER want one. | ||
| 254 | */ | ||
| 255 | if ((tmpResult.bitLength() % 8) == 0) { | ||
| 256 | byte retval[] = new byte[secret.length - 1]; | ||
| 257 | System.arraycopy(secret, 1, retval, 0, retval.length); | ||
| 258 | return retval; | ||
| 259 | } else { | ||
| 260 | return secret; | ||
| 261 | } | ||
| 262 | } | ||
| 263 | |||
| 264 | /** | ||
| 265 | * Generates the shared secret, and places it into the buffer | ||
| 266 | * <code>sharedSecret</code>, beginning at <code>offset</code>. | ||
| 267 | * | ||
| 268 | * <p>If the <code>sharedSecret</code> buffer is too small to hold the | ||
| 269 | * result, a <code>ShortBufferException</code> is thrown. | ||
| 270 | * In this case, this call should be repeated with a larger output buffer. | ||
| 271 | * | ||
| 272 | * <p>This method resets this <code>KeyAgreementSpi</code> object, | ||
| 273 | * so that it | ||
| 274 | * can be reused for further key agreements. Unless this key agreement is | ||
| 275 | * reinitialized with one of the <code>engineInit</code> methods, the same | ||
| 276 | * private information and algorithm parameters will be used for | ||
| 277 | * subsequent key agreements. | ||
| 278 | * | ||
| 279 | * @param sharedSecret the buffer for the shared secret | ||
| 280 | * @param offset the offset in <code>sharedSecret</code> where the | ||
| 281 | * shared secret will be stored | ||
| 282 | * | ||
| 283 | * @return the number of bytes placed into <code>sharedSecret</code> | ||
| 284 | * | ||
| 285 | * @exception IllegalStateException if this key agreement has not been | ||
| 286 | * completed yet | ||
| 287 | * @exception ShortBufferException if the given output buffer is too small | ||
| 288 | * to hold the secret | ||
| 289 | */ | ||
| 290 | protected int engineGenerateSecret(byte[] sharedSecret, int offset) | ||
| 291 | throws IllegalStateException, ShortBufferException | ||
| 292 | { | ||
| 293 | if (generateSecret == false) { | ||
| 294 | throw new IllegalStateException | ||
| 295 | ("Key agreement has not been completed yet"); | ||
| 296 | } | ||
| 297 | |||
| 298 | if (sharedSecret == null) { | ||
| 299 | throw new ShortBufferException | ||
| 300 | ("No buffer provided for shared secret"); | ||
| 301 | } | ||
| 302 | |||
| 303 | BigInteger modulus = init_p; | ||
| 304 | byte[] secret = this.y.modPow(this.x, modulus).toByteArray(); | ||
| 305 | |||
| 306 | // BigInteger.toByteArray will sometimes put a sign byte up front, | ||
| 307 | // but we NEVER want one. | ||
| 308 | if ((secret.length << 3) != modulus.bitLength()) { | ||
| 309 | if ((sharedSecret.length - offset) < (secret.length - 1)) { | ||
| 310 | throw new ShortBufferException | ||
| 311 | ("Buffer too short for shared secret"); | ||
| 312 | } | ||
| 313 | System.arraycopy(secret, 1, sharedSecret, offset, | ||
| 314 | secret.length - 1); | ||
| 315 | |||
| 316 | // Reset the key agreement here (not earlier!), so that people | ||
| 317 | // can recover from ShortBufferException above without losing | ||
| 318 | // internal state | ||
| 319 | generateSecret = false; | ||
| 320 | |||
| 321 | return secret.length - 1; | ||
| 322 | |||
| 323 | } else { | ||
| 324 | if ((sharedSecret.length - offset) < secret.length) { | ||
| 325 | throw new ShortBufferException | ||
| 326 | ("Buffer too short to hold shared secret"); | ||
| 327 | } | ||
| 328 | System.arraycopy(secret, 0, sharedSecret, offset, secret.length); | ||
| 329 | |||
| 330 | // Reset the key agreement here (not earlier!), so that people | ||
| 331 | // can recover from ShortBufferException above without losing | ||
| 332 | // internal state | ||
| 333 | generateSecret = false; | ||
| 334 | |||
| 335 | return secret.length; | ||
| 336 | } | ||
| 337 | } | ||
| 338 | |||
| 339 | /** | ||
| 340 | * Creates the shared secret and returns it as a secret key object | ||
| 341 | * of the requested algorithm type. | ||
| 342 | * | ||
| 343 | * <p>This method resets this <code>KeyAgreementSpi</code> object, | ||
| 344 | * so that it | ||
| 345 | * can be reused for further key agreements. Unless this key agreement is | ||
| 346 | * reinitialized with one of the <code>engineInit</code> methods, the same | ||
| 347 | * private information and algorithm parameters will be used for | ||
| 348 | * subsequent key agreements. | ||
| 349 | * | ||
| 350 | * @param algorithm the requested secret key algorithm | ||
| 351 | * | ||
| 352 | * @return the shared secret key | ||
| 353 | * | ||
| 354 | * @exception IllegalStateException if this key agreement has not been | ||
| 355 | * completed yet | ||
| 356 | * @exception NoSuchAlgorithmException if the requested secret key | ||
| 357 | * algorithm is not available | ||
| 358 | * @exception InvalidKeyException if the shared secret key material cannot | ||
| 359 | * be used to generate a secret key of the requested algorithm type (e.g., | ||
| 360 | * the key material is too short) | ||
| 361 | */ | ||
| 362 | protected SecretKey engineGenerateSecret(String algorithm) | ||
| 363 | throws IllegalStateException, NoSuchAlgorithmException, | ||
| 364 | InvalidKeyException | ||
| 365 | { | ||
| 366 | if (algorithm == null) { | ||
| 367 | throw new NoSuchAlgorithmException("null algorithm"); | ||
| 368 | } | ||
| 369 | byte[] secret = engineGenerateSecret(); | ||
| 370 | if (algorithm.equalsIgnoreCase("DES")) { | ||
| 371 | // DES | ||
| 372 | return new DESKey(secret); | ||
| 373 | } else if (algorithm.equalsIgnoreCase("DESede") | ||
| 374 | || algorithm.equalsIgnoreCase("TripleDES")) { | ||
| 375 | // Triple DES | ||
| 376 | return new DESedeKey(secret); | ||
| 377 | } else if (algorithm.equalsIgnoreCase("Blowfish")) { | ||
| 378 | // Blowfish | ||
| 379 | int keysize = secret.length; | ||
| 380 | if (keysize >= BlowfishConstants.BLOWFISH_MAX_KEYSIZE) | ||
| 381 | keysize = BlowfishConstants.BLOWFISH_MAX_KEYSIZE; | ||
| 382 | SecretKeySpec skey = new SecretKeySpec(secret, 0, keysize, | ||
| 383 | "Blowfish"); | ||
| 384 | return skey; | ||
| 385 | } else if (algorithm.equalsIgnoreCase("AES")) { | ||
| 386 | // AES | ||
| 387 | int keysize = secret.length; | ||
| 388 | SecretKeySpec skey = null; | ||
| 389 | int idx = AESConstants.AES_KEYSIZES.length - 1; | ||
| 390 | while (skey == null && idx >= 0) { | ||
| 391 | // Generate the strongest key using the shared secret | ||
| 392 | // assuming the key sizes in AESConstants class are | ||
| 393 | // in ascending order | ||
| 394 | if (keysize >= AESConstants.AES_KEYSIZES[idx]) { | ||
| 395 | keysize = AESConstants.AES_KEYSIZES[idx]; | ||
| 396 | skey = new SecretKeySpec(secret, 0, keysize, "AES"); | ||
| 397 | } | ||
| 398 | idx--; | ||
| 399 | } | ||
| 400 | if (skey == null) { | ||
| 401 | throw new InvalidKeyException("Key material is too short"); | ||
| 402 | } | ||
| 403 | return skey; | ||
| 404 | } else if (algorithm.equals("TlsPremasterSecret")) { | ||
| 405 | // return entire secret | ||
| 406 | return new SecretKeySpec(secret, "TlsPremasterSecret"); | ||
| 407 | } else { | ||
| 408 | throw new NoSuchAlgorithmException("Unsupported secret key " | ||
| 409 | + "algorithm: "+ algorithm); | ||
| 410 | } | ||
| 411 | } | ||
| 412 | } | ||
| @@ -0,0 +1,236 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.util.*; | ||
| 29 | import java.lang.*; | ||
| 30 | import java.security.Key; | ||
| 31 | import java.security.PublicKey; | ||
| 32 | import java.security.PrivateKey; | ||
| 33 | import java.security.KeyFactorySpi; | ||
| 34 | import java.security.InvalidKeyException; | ||
| 35 | import java.security.spec.KeySpec; | ||
| 36 | import java.security.spec.InvalidKeySpecException; | ||
| 37 | import java.security.spec.X509EncodedKeySpec; | ||
| 38 | import java.security.spec.PKCS8EncodedKeySpec; | ||
| 39 | import javax.crypto.spec.DHPublicKeySpec; | ||
| 40 | import javax.crypto.spec.DHPrivateKeySpec; | ||
| 41 | import javax.crypto.spec.DHParameterSpec; | ||
| 42 | |||
| 43 | /** | ||
| 44 | * This class implements the Diffie-Hellman key factory of the Sun provider. | ||
| 45 | * | ||
| 46 | * @author Jan Luehe | ||
| 47 | * | ||
| 48 | */ | ||
| 49 | public final class DHKeyFactory extends KeyFactorySpi { | ||
| 50 | |||
| 51 | /** | ||
| 52 | * Empty constructor | ||
| 53 | */ | ||
| 54 | public DHKeyFactory() { | ||
| 55 | } | ||
| 56 | |||
| 57 | /** | ||
| 58 | * Generates a public key object from the provided key specification | ||
| 59 | * (key material). | ||
| 60 | * | ||
| 61 | * @param keySpec the specification (key material) of the public key | ||
| 62 | * | ||
| 63 | * @return the public key | ||
| 64 | * | ||
| 65 | * @exception InvalidKeySpecException if the given key specification | ||
| 66 | * is inappropriate for this key factory to produce a public key. | ||
| 67 | */ | ||
| 68 | protected PublicKey engineGeneratePublic(KeySpec keySpec) | ||
| 69 | throws InvalidKeySpecException | ||
| 70 | { | ||
| 71 | try { | ||
| 72 | if (keySpec instanceof DHPublicKeySpec) { | ||
| 73 | DHPublicKeySpec dhPubKeySpec = (DHPublicKeySpec)keySpec; | ||
| 74 | return new DHPublicKey(dhPubKeySpec.getY(), | ||
| 75 | dhPubKeySpec.getP(), | ||
| 76 | dhPubKeySpec.getG()); | ||
| 77 | |||
| 78 | } else if (keySpec instanceof X509EncodedKeySpec) { | ||
| 79 | return new DHPublicKey | ||
| 80 | (((X509EncodedKeySpec)keySpec).getEncoded()); | ||
| 81 | |||
| 82 | } else { | ||
| 83 | throw new InvalidKeySpecException | ||
| 84 | ("Inappropriate key specification"); | ||
| 85 | } | ||
| 86 | } catch (InvalidKeyException e) { | ||
| 87 | throw new InvalidKeySpecException | ||
| 88 | ("Inappropriate key specification"); | ||
| 89 | } | ||
| 90 | } | ||
| 91 | |||
| 92 | /** | ||
| 93 | * Generates a private key object from the provided key specification | ||
| 94 | * (key material). | ||
| 95 | * | ||
| 96 | * @param keySpec the specification (key material) of the private key | ||
| 97 | * | ||
| 98 | * @return the private key | ||
| 99 | * | ||
| 100 | * @exception InvalidKeySpecException if the given key specification | ||
| 101 | * is inappropriate for this key factory to produce a private key. | ||
| 102 | */ | ||
| 103 | protected PrivateKey engineGeneratePrivate(KeySpec keySpec) | ||
| 104 | throws InvalidKeySpecException | ||
| 105 | { | ||
| 106 | try { | ||
| 107 | if (keySpec instanceof DHPrivateKeySpec) { | ||
| 108 | DHPrivateKeySpec dhPrivKeySpec = (DHPrivateKeySpec)keySpec; | ||
| 109 | return new DHPrivateKey(dhPrivKeySpec.getX(), | ||
| 110 | dhPrivKeySpec.getP(), | ||
| 111 | dhPrivKeySpec.getG()); | ||
| 112 | |||
| 113 | } else if (keySpec instanceof PKCS8EncodedKeySpec) { | ||
| 114 | return new DHPrivateKey | ||
| 115 | (((PKCS8EncodedKeySpec)keySpec).getEncoded()); | ||
| 116 | |||
| 117 | } else { | ||
| 118 | throw new InvalidKeySpecException | ||
| 119 | ("Inappropriate key specification"); | ||
| 120 | } | ||
| 121 | } catch (InvalidKeyException e) { | ||
| 122 | throw new InvalidKeySpecException | ||
| 123 | ("Inappropriate key specification"); | ||
| 124 | } | ||
| 125 | } | ||
| 126 | |||
| 127 | /** | ||
| 128 | * Returns a specification (key material) of the given key object | ||
| 129 | * in the requested format. | ||
| 130 | * | ||
| 131 | * @param key the key | ||
| 132 | * | ||
| 133 | * @param keySpec the requested format in which the key material shall be | ||
| 134 | * returned | ||
| 135 | * | ||
| 136 | * @return the underlying key specification (key material) in the | ||
| 137 | * requested format | ||
| 138 | * | ||
| 139 | * @exception InvalidKeySpecException if the requested key specification is | ||
| 140 | * inappropriate for the given key, or the given key cannot be processed | ||
| 141 | * (e.g., the given key has an unrecognized algorithm or format). | ||
| 142 | */ | ||
| 143 | protected KeySpec engineGetKeySpec(Key key, Class keySpec) | ||
| 144 | throws InvalidKeySpecException { | ||
| 145 | DHParameterSpec params; | ||
| 146 | |||
| 147 | if (key instanceof javax.crypto.interfaces.DHPublicKey) { | ||
| 148 | |||
| 149 | if (DHPublicKeySpec.class.isAssignableFrom(keySpec)) { | ||
| 150 | javax.crypto.interfaces.DHPublicKey dhPubKey | ||
| 151 | = (javax.crypto.interfaces.DHPublicKey) key; | ||
| 152 | params = dhPubKey.getParams(); | ||
| 153 | return new DHPublicKeySpec(dhPubKey.getY(), | ||
| 154 | params.getP(), | ||
| 155 | params.getG()); | ||
| 156 | |||
| 157 | } else if (X509EncodedKeySpec.class.isAssignableFrom(keySpec)) { | ||
| 158 | return new X509EncodedKeySpec(key.getEncoded()); | ||
| 159 | |||
| 160 | } else { | ||
| 161 | throw new InvalidKeySpecException | ||
| 162 | ("Inappropriate key specification"); | ||
| 163 | } | ||
| 164 | |||
| 165 | } else if (key instanceof javax.crypto.interfaces.DHPrivateKey) { | ||
| 166 | |||
| 167 | if (DHPrivateKeySpec.class.isAssignableFrom(keySpec)) { | ||
| 168 | javax.crypto.interfaces.DHPrivateKey dhPrivKey | ||
| 169 | = (javax.crypto.interfaces.DHPrivateKey)key; | ||
| 170 | params = dhPrivKey.getParams(); | ||
| 171 | return new DHPrivateKeySpec(dhPrivKey.getX(), | ||
| 172 | params.getP(), | ||
| 173 | params.getG()); | ||
| 174 | |||
| 175 | } else if (PKCS8EncodedKeySpec.class.isAssignableFrom(keySpec)) { | ||
| 176 | return new PKCS8EncodedKeySpec(key.getEncoded()); | ||
| 177 | |||
| 178 | } else { | ||
| 179 | throw new InvalidKeySpecException | ||
| 180 | ("Inappropriate key specification"); | ||
| 181 | } | ||
| 182 | |||
| 183 | } else { | ||
| 184 | throw new InvalidKeySpecException("Inappropriate key type"); | ||
| 185 | } | ||
| 186 | } | ||
| 187 | |||
| 188 | /** | ||
| 189 | * Translates a key object, whose provider may be unknown or potentially | ||
| 190 | * untrusted, into a corresponding key object of this key factory. | ||
| 191 | * | ||
| 192 | * @param key the key whose provider is unknown or untrusted | ||
| 193 | * | ||
| 194 | * @return the translated key | ||
| 195 | * | ||
| 196 | * @exception InvalidKeyException if the given key cannot be processed by | ||
| 197 | * this key factory. | ||
| 198 | */ | ||
| 199 | protected Key engineTranslateKey(Key key) | ||
| 200 | throws InvalidKeyException | ||
| 201 | { | ||
| 202 | try { | ||
| 203 | |||
| 204 | if (key instanceof javax.crypto.interfaces.DHPublicKey) { | ||
| 205 | // Check if key originates from this factory | ||
| 206 | if (key instanceof com.sun.crypto.provider.DHPublicKey) { | ||
| 207 | return key; | ||
| 208 | } | ||
| 209 | // Convert key to spec | ||
| 210 | DHPublicKeySpec dhPubKeySpec | ||
| 211 | = (DHPublicKeySpec)engineGetKeySpec | ||
| 212 | (key, DHPublicKeySpec.class); | ||
| 213 | // Create key from spec, and return it | ||
| 214 | return engineGeneratePublic(dhPubKeySpec); | ||
| 215 | |||
| 216 | } else if (key instanceof javax.crypto.interfaces.DHPrivateKey) { | ||
| 217 | // Check if key originates from this factory | ||
| 218 | if (key instanceof com.sun.crypto.provider.DHPrivateKey) { | ||
| 219 | return key; | ||
| 220 | } | ||
| 221 | // Convert key to spec | ||
| 222 | DHPrivateKeySpec dhPrivKeySpec | ||
| 223 | = (DHPrivateKeySpec)engineGetKeySpec | ||
| 224 | (key, DHPrivateKeySpec.class); | ||
| 225 | // Create key from spec, and return it | ||
| 226 | return engineGeneratePrivate(dhPrivKeySpec); | ||
| 227 | |||
| 228 | } else { | ||
| 229 | throw new InvalidKeyException("Wrong algorithm type"); | ||
| 230 | } | ||
| 231 | |||
| 232 | } catch (InvalidKeySpecException e) { | ||
| 233 | throw new InvalidKeyException("Cannot translate key"); | ||
| 234 | } | ||
| 235 | } | ||
| 236 | } | ||
| @@ -0,0 +1,186 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.math.BigInteger; | ||
| 29 | import java.security.*; | ||
| 30 | import java.security.spec.AlgorithmParameterSpec; | ||
| 31 | import java.security.spec.InvalidParameterSpecException; | ||
| 32 | import javax.crypto.spec.DHParameterSpec; | ||
| 33 | import javax.crypto.spec.DHGenParameterSpec; | ||
| 34 | |||
| 35 | import sun.security.provider.ParameterCache; | ||
| 36 | |||
| 37 | /** | ||
| 38 | * This class represents the key pair generator for Diffie-Hellman key pairs. | ||
| 39 | * | ||
| 40 | * <p>This key pair generator may be initialized in two different ways: | ||
| 41 | * | ||
| 42 | * <ul> | ||
| 43 | * <li>By providing the size in bits of the prime modulus - | ||
| 44 | * This will be used to create a prime modulus and base generator, which will | ||
| 45 | * then be used to create the Diffie-Hellman key pair. The default size of the | ||
| 46 | * prime modulus is 1024 bits. | ||
| 47 | * <li>By providing a prime modulus and base generator | ||
| 48 | * </ul> | ||
| 49 | * | ||
| 50 | * @author Jan Luehe | ||
| 51 | * | ||
| 52 | * | ||
| 53 | * @see java.security.KeyPairGenerator | ||
| 54 | */ | ||
| 55 | public final class DHKeyPairGenerator extends KeyPairGeneratorSpi { | ||
| 56 | |||
| 57 | // parameters to use or null if not specified | ||
| 58 | private DHParameterSpec params; | ||
| 59 | |||
| 60 | // The size in bits of the prime modulus | ||
| 61 | private int pSize; | ||
| 62 | |||
| 63 | // The size in bits of the random exponent (private value) | ||
| 64 | private int lSize; | ||
| 65 | |||
| 66 | // The source of randomness | ||
| 67 | private SecureRandom random; | ||
| 68 | |||
| 69 | public DHKeyPairGenerator() { | ||
| 70 | super(); | ||
| 71 | initialize(1024, null); | ||
| 72 | } | ||
| 73 | |||
| 74 | /** | ||
| 75 | * Initializes this key pair generator for a certain keysize and source of | ||
| 76 | * randomness. | ||
| 77 | * The keysize is specified as the size in bits of the prime modulus. | ||
| 78 | * | ||
| 79 | * @param keysize the keysize (size of prime modulus) in bits | ||
| 80 | * @param random the source of randomness | ||
| 81 | */ | ||
| 82 | public void initialize(int keysize, SecureRandom random) { | ||
| 83 | if ((keysize < 512) || (keysize > 1024) || (keysize % 64 != 0)) { | ||
| 84 | throw new InvalidParameterException("Keysize must be multiple " | ||
| 85 | + "of 64, and can only range " | ||
| 86 | + "from 512 to 1024 " | ||
| 87 | + "(inclusive)"); | ||
| 88 | } | ||
| 89 | this.pSize = keysize; | ||
| 90 | this.lSize = 0; | ||
| 91 | this.random = random; | ||
| 92 | this.params = null; | ||
| 93 | } | ||
| 94 | |||
| 95 | /** | ||
| 96 | * Initializes this key pair generator for the specified parameter | ||
| 97 | * set and source of randomness. | ||
| 98 | * | ||
| 99 | * <p>The given parameter set contains the prime modulus, the base | ||
| 100 | * generator, and optionally the requested size in bits of the random | ||
| 101 | * exponent (private value). | ||
| 102 | * | ||
| 103 | * @param params the parameter set used to generate the key pair | ||
| 104 | * @param random the source of randomness | ||
| 105 | * | ||
| 106 | * @exception InvalidAlgorithmParameterException if the given parameters | ||
| 107 | * are inappropriate for this key pair generator | ||
| 108 | */ | ||
| 109 | public void initialize(AlgorithmParameterSpec algParams, | ||
| 110 | SecureRandom random) throws InvalidAlgorithmParameterException { | ||
| 111 | if (!(algParams instanceof DHParameterSpec)){ | ||
| 112 | throw new InvalidAlgorithmParameterException | ||
| 113 | ("Inappropriate parameter type"); | ||
| 114 | } | ||
| 115 | |||
| 116 | params = (DHParameterSpec)algParams; | ||
| 117 | pSize = params.getP().bitLength(); | ||
| 118 | if ((pSize < 512) || (pSize > 1024) || | ||
| 119 | (pSize % 64 != 0)) { | ||
| 120 | throw new InvalidAlgorithmParameterException | ||
| 121 | ("Prime size must be multiple of 64, and can only range " | ||
| 122 | + "from 512 to 1024 (inclusive)"); | ||
| 123 | } | ||
| 124 | |||
| 125 | // exponent size is optional, could be 0 | ||
| 126 | lSize = params.getL(); | ||
| 127 | |||
| 128 | // Require exponentSize < primeSize | ||
| 129 | if ((lSize != 0) && (lSize > pSize)) { | ||
| 130 | throw new InvalidAlgorithmParameterException | ||
| 131 | ("Exponent size must not be larger than modulus size"); | ||
| 132 | } | ||
| 133 | this.random = random; | ||
| 134 | } | ||
| 135 | |||
| 136 | /** | ||
| 137 | * Generates a key pair. | ||
| 138 | * | ||
| 139 | * @return the new key pair | ||
| 140 | */ | ||
| 141 | public KeyPair generateKeyPair() { | ||
| 142 | if (random == null) { | ||
| 143 | random = SunJCE.RANDOM; | ||
| 144 | } | ||
| 145 | |||
| 146 | if (params == null) { | ||
| 147 | try { | ||
| 148 | params = ParameterCache.getDHParameterSpec(pSize, random); | ||
| 149 | } catch (GeneralSecurityException e) { | ||
| 150 | // should never happen | ||
| 151 | throw new ProviderException(e); | ||
| 152 | } | ||
| 153 | } | ||
| 154 | |||
| 155 | BigInteger p = params.getP(); | ||
| 156 | BigInteger g = params.getG(); | ||
| 157 | |||
| 158 | if (lSize <= 0) { | ||
| 159 | // use an exponent size of (pSize / 2) but at least 384 bits | ||
| 160 | lSize = Math.max(384, pSize >> 1); | ||
| 161 | // if lSize is larger than pSize, limit by pSize | ||
| 162 | lSize = Math.min(lSize, pSize); | ||
| 163 | } | ||
| 164 | |||
| 165 | BigInteger x; | ||
| 166 | BigInteger pMinus2 = p.subtract(BigInteger.valueOf(2)); | ||
| 167 | |||
| 168 | // | ||
| 169 | // Handbook of Applied Cryptography: Menezes, et.al. | ||
| 170 | // Repeat if the following does not hold: | ||
| 171 | // 1 <= x <= p-2 | ||
| 172 | // | ||
| 173 | do { | ||
| 174 | // generate random x up to 2^lSize bits long | ||
| 175 | x = new BigInteger(lSize, random); | ||
| 176 | } while ((x.compareTo(BigInteger.ONE) < 0) || | ||
| 177 | ((x.compareTo(pMinus2) > 0))); | ||
| 178 | |||
| 179 | // calculate public value y | ||
| 180 | BigInteger y = g.modPow(x, p); | ||
| 181 | |||
| 182 | DHPublicKey pubKey = new DHPublicKey(y, p, g, lSize); | ||
| 183 | DHPrivateKey privKey = new DHPrivateKey(x, p, g, lSize); | ||
| 184 | return new KeyPair(pubKey, privKey); | ||
| 185 | } | ||
| 186 | } | ||
| @@ -0,0 +1,171 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.math.BigInteger; | ||
| 29 | import java.security.*; | ||
| 30 | import java.security.spec.*; | ||
| 31 | import javax.crypto.spec.DHParameterSpec; | ||
| 32 | import javax.crypto.spec.DHGenParameterSpec; | ||
| 33 | |||
| 34 | /* | ||
| 35 | * This class generates parameters for the Diffie-Hellman algorithm. | ||
| 36 | * The parameters are a prime, a base, and optionally the length in bits of | ||
| 37 | * the private value. | ||
| 38 | * | ||
| 39 | * <p>The Diffie-Hellman parameter generation accepts the size in bits of the | ||
| 40 | * prime modulus and the size in bits of the random exponent as input. | ||
| 41 | * The size of the prime modulus defaults to 1024 bits. | ||
| 42 | * | ||
| 43 | * @author Jan Luehe | ||
| 44 | * | ||
| 45 | * | ||
| 46 | * @see java.security.AlgorithmParameters | ||
| 47 | * @see java.security.spec.AlgorithmParameterSpec | ||
| 48 | * @see DHParameters | ||
| 49 | */ | ||
| 50 | public final class DHParameterGenerator | ||
| 51 | extends AlgorithmParameterGeneratorSpi { | ||
| 52 | |||
| 53 | // The size in bits of the prime modulus | ||
| 54 | private int primeSize = 1024; | ||
| 55 | |||
| 56 | // The size in bits of the random exponent (private value) | ||
| 57 | private int exponentSize = 0; | ||
| 58 | |||
| 59 | // The source of randomness | ||
| 60 | private SecureRandom random = null; | ||
| 61 | |||
| 62 | /** | ||
| 63 | * Initializes this parameter generator for a certain keysize | ||
| 64 | * and source of randomness. | ||
| 65 | * The keysize is specified as the size in bits of the prime modulus. | ||
| 66 | * | ||
| 67 | * @param keysize the keysize (size of prime modulus) in bits | ||
| 68 | * @param random the source of randomness | ||
| 69 | */ | ||
| 70 | protected void engineInit(int keysize, SecureRandom random) { | ||
| 71 | if ((keysize < 512) || (keysize > 1024) || (keysize % 64 != 0)) { | ||
| 72 | throw new InvalidParameterException("Keysize must be multiple " | ||
| 73 | + "of 64, and can only range " | ||
| 74 | + "from 512 to 1024 " | ||
| 75 | + "(inclusive)"); | ||
| 76 | } | ||
| 77 | this.primeSize = keysize; | ||
| 78 | this.random = random; | ||
| 79 | } | ||
| 80 | |||
| 81 | /** | ||
| 82 | * Initializes this parameter generator with a set of parameter | ||
| 83 | * generation values, which specify the size of the prime modulus and | ||
| 84 | * the size of the random exponent, both in bits. | ||
| 85 | * | ||
| 86 | * @param params the set of parameter generation values | ||
| 87 | * @param random the source of randomness | ||
| 88 | * | ||
| 89 | * @exception InvalidAlgorithmParameterException if the given parameter | ||
| 90 | * generation values are inappropriate for this parameter generator | ||
| 91 | */ | ||
| 92 | protected void engineInit(AlgorithmParameterSpec genParamSpec, | ||
| 93 | SecureRandom random) | ||
| 94 | throws InvalidAlgorithmParameterException { | ||
| 95 | if (!(genParamSpec instanceof DHGenParameterSpec)) { | ||
| 96 | throw new InvalidAlgorithmParameterException | ||
| 97 | ("Inappropriate parameter type"); | ||
| 98 | } | ||
| 99 | |||
| 100 | DHGenParameterSpec dhParamSpec = (DHGenParameterSpec)genParamSpec; | ||
| 101 | |||
| 102 | primeSize = dhParamSpec.getPrimeSize(); | ||
| 103 | if ((primeSize<512) || (primeSize>1024) || (primeSize%64 != 0)) { | ||
| 104 | throw new InvalidAlgorithmParameterException | ||
| 105 | ("Modulus size must be multiple of 64, and can only range " | ||
| 106 | + "from 512 to 1024 (inclusive)"); | ||
| 107 | } | ||
| 108 | |||
| 109 | exponentSize = dhParamSpec.getExponentSize(); | ||
| 110 | if (exponentSize <= 0) { | ||
| 111 | throw new InvalidAlgorithmParameterException | ||
| 112 | ("Exponent size must be greater than zero"); | ||
| 113 | } | ||
| 114 | |||
| 115 | // Require exponentSize < primeSize | ||
| 116 | if (exponentSize >= primeSize) { | ||
| 117 | throw new InvalidAlgorithmParameterException | ||
| 118 | ("Exponent size must be less than modulus size"); | ||
| 119 | } | ||
| 120 | } | ||
| 121 | |||
| 122 | /** | ||
| 123 | * Generates the parameters. | ||
| 124 | * | ||
| 125 | * @return the new AlgorithmParameters object | ||
| 126 | */ | ||
| 127 | protected AlgorithmParameters engineGenerateParameters() { | ||
| 128 | AlgorithmParameters algParams = null; | ||
| 129 | |||
| 130 | if (this.exponentSize == 0) { | ||
| 131 | this.exponentSize = this.primeSize - 1; | ||
| 132 | } | ||
| 133 | |||
| 134 | if (this.random == null) | ||
| 135 | this.random = SunJCE.RANDOM; | ||
| 136 | |||
| 137 | try { | ||
| 138 | AlgorithmParameterGenerator paramGen; | ||
| 139 | DSAParameterSpec dsaParamSpec; | ||
| 140 | |||
| 141 | paramGen = AlgorithmParameterGenerator.getInstance("DSA"); | ||
| 142 | paramGen.init(this.primeSize, random); | ||
| 143 | algParams = paramGen.generateParameters(); | ||
| 144 | dsaParamSpec = (DSAParameterSpec) | ||
| 145 | algParams.getParameterSpec(DSAParameterSpec.class); | ||
| 146 | |||
| 147 | DHParameterSpec dhParamSpec; | ||
| 148 | if (this.exponentSize > 0) { | ||
| 149 | dhParamSpec = new DHParameterSpec(dsaParamSpec.getP(), | ||
| 150 | dsaParamSpec.getG(), | ||
| 151 | this.exponentSize); | ||
| 152 | } else { | ||
| 153 | dhParamSpec = new DHParameterSpec(dsaParamSpec.getP(), | ||
| 154 | dsaParamSpec.getG()); | ||
| 155 | } | ||
| 156 | algParams = AlgorithmParameters.getInstance("DH", "SunJCE"); | ||
| 157 | algParams.init(dhParamSpec); | ||
| 158 | } catch (InvalidParameterSpecException e) { | ||
| 159 | // this should never happen | ||
| 160 | throw new RuntimeException(e.getMessage()); | ||
| 161 | } catch (NoSuchAlgorithmException e) { | ||
| 162 | // this should never happen, because we provide it | ||
| 163 | throw new RuntimeException(e.getMessage()); | ||
| 164 | } catch (NoSuchProviderException e) { | ||
| 165 | // this should never happen, because we provide it | ||
| 166 | throw new RuntimeException(e.getMessage()); | ||
| 167 | } | ||
| 168 | |||
| 169 | return algParams; | ||
| 170 | } | ||
| 171 | } | ||
| @@ -0,0 +1,144 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.util.*; | ||
| 29 | import java.io.*; | ||
| 30 | import sun.security.util.*; | ||
| 31 | import java.math.BigInteger; | ||
| 32 | import java.security.AlgorithmParametersSpi; | ||
| 33 | import java.security.spec.AlgorithmParameterSpec; | ||
| 34 | import java.security.spec.InvalidParameterSpecException; | ||
| 35 | import javax.crypto.spec.DHParameterSpec; | ||
| 36 | |||
| 37 | /** | ||
| 38 | * This class implements the parameter set used by the | ||
| 39 | * Diffie-Hellman key agreement as defined in the PKCS #3 standard. | ||
| 40 | * | ||
| 41 | * @author Jan Luehe | ||
| 42 | * | ||
| 43 | */ | ||
| 44 | public final class DHParameters extends AlgorithmParametersSpi { | ||
| 45 | |||
| 46 | // The prime (p). | ||
| 47 | private BigInteger p = BigInteger.ZERO; | ||
| 48 | |||
| 49 | // The base (g). | ||
| 50 | private BigInteger g = BigInteger.ZERO; | ||
| 51 | |||
| 52 | // The private-value length (l) | ||
| 53 | private int l = 0; | ||
| 54 | |||
| 55 | protected void engineInit(AlgorithmParameterSpec paramSpec) | ||
| 56 | throws InvalidParameterSpecException { | ||
| 57 | if (!(paramSpec instanceof DHParameterSpec)) { | ||
| 58 | throw new InvalidParameterSpecException | ||
| 59 | ("Inappropriate parameter specification"); | ||
| 60 | } | ||
| 61 | this.p = ((DHParameterSpec)paramSpec).getP(); | ||
| 62 | this.g = ((DHParameterSpec)paramSpec).getG(); | ||
| 63 | this.l = ((DHParameterSpec)paramSpec).getL(); | ||
| 64 | } | ||
| 65 | |||
| 66 | protected void engineInit(byte[] params) throws IOException { | ||
| 67 | try { | ||
| 68 | DerValue encodedParams = new DerValue(params); | ||
| 69 | |||
| 70 | if (encodedParams.tag != DerValue.tag_Sequence) { | ||
| 71 | throw new IOException("DH params parsing error"); | ||
| 72 | } | ||
| 73 | |||
| 74 | encodedParams.data.reset(); | ||
| 75 | |||
| 76 | this.p = encodedParams.data.getBigInteger(); | ||
| 77 | this.g = encodedParams.data.getBigInteger(); | ||
| 78 | |||
| 79 | // Private-value length is OPTIONAL | ||
| 80 | if (encodedParams.data.available() != 0) { | ||
| 81 | this.l = encodedParams.data.getInteger(); | ||
| 82 | } | ||
| 83 | |||
| 84 | if (encodedParams.data.available() != 0) { | ||
| 85 | throw new IOException | ||
| 86 | ("DH parameter parsing error: Extra data"); | ||
| 87 | } | ||
| 88 | } catch (NumberFormatException e) { | ||
| 89 | throw new IOException("Private-value length too big"); | ||
| 90 | } | ||
| 91 | } | ||
| 92 | |||
| 93 | protected void engineInit(byte[] params, String decodingMethod) | ||
| 94 | throws IOException { | ||
| 95 | engineInit(params); | ||
| 96 | } | ||
| 97 | |||
| 98 | protected AlgorithmParameterSpec engineGetParameterSpec(Class paramSpec) | ||
| 99 | throws InvalidParameterSpecException { | ||
| 100 | |||
| 101 | if (DHParameterSpec.class.isAssignableFrom(paramSpec)) { | ||
| 102 | return new DHParameterSpec(this.p, this.g, this.l); | ||
| 103 | } else { | ||
| 104 | throw new InvalidParameterSpecException | ||
| 105 | ("Inappropriate parameter Specification"); | ||
| 106 | } | ||
| 107 | } | ||
| 108 | |||
| 109 | protected byte[] engineGetEncoded() throws IOException { | ||
| 110 | DerOutputStream out = new DerOutputStream(); | ||
| 111 | DerOutputStream bytes = new DerOutputStream(); | ||
| 112 | |||
| 113 | bytes.putInteger(this.p); | ||
| 114 | bytes.putInteger(this.g); | ||
| 115 | // Private-value length is OPTIONAL | ||
| 116 | if (this.l > 0) { | ||
| 117 | bytes.putInteger(this.l); | ||
| 118 | } | ||
| 119 | out.write(DerValue.tag_Sequence, bytes); | ||
| 120 | return out.toByteArray(); | ||
| 121 | } | ||
| 122 | |||
| 123 | protected byte[] engineGetEncoded(String encodingMethod) | ||
| 124 | throws IOException { | ||
| 125 | return engineGetEncoded(); | ||
| 126 | } | ||
| 127 | |||
| 128 | /* | ||
| 129 | * Returns a formatted string describing the parameters. | ||
| 130 | */ | ||
| 131 | protected String engineToString() { | ||
| 132 | String LINE_SEP = System.getProperty("line.separator"); | ||
| 133 | |||
| 134 | StringBuffer strbuf | ||
| 135 | = new StringBuffer("SunJCE Diffie-Hellman Parameters:" | ||
| 136 | + LINE_SEP + "p:" + LINE_SEP | ||
| 137 | + Debug.toHexString(this.p) | ||
| 138 | + LINE_SEP + "g:" + LINE_SEP | ||
| 139 | + Debug.toHexString(this.g)); | ||
| 140 | if (this.l != 0) | ||
| 141 | strbuf.append(LINE_SEP + "l:" + LINE_SEP + " " + this.l); | ||
| 142 | return strbuf.toString(); | ||
| 143 | } | ||
| 144 | } | ||
| @@ -0,0 +1,352 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.io.*; | ||
| 29 | import java.math.BigInteger; | ||
| 30 | import java.security.KeyRep; | ||
| 31 | import java.security.PrivateKey; | ||
| 32 | import java.security.InvalidKeyException; | ||
| 33 | import java.security.ProviderException; | ||
| 34 | import javax.crypto.*; | ||
| 35 | import javax.crypto.spec.DHParameterSpec; | ||
| 36 | import sun.security.util.*; | ||
| 37 | |||
| 38 | /** | ||
| 39 | * A private key in PKCS#8 format for the Diffie-Hellman key agreement | ||
| 40 | * algorithm. | ||
| 41 | * | ||
| 42 | * @author Jan Luehe | ||
| 43 | * | ||
| 44 | * | ||
| 45 | * @see DHPublicKey | ||
| 46 | * @see java.security.KeyAgreement | ||
| 47 | */ | ||
| 48 | final class DHPrivateKey implements PrivateKey, | ||
| 49 | javax.crypto.interfaces.DHPrivateKey, Serializable { | ||
| 50 | |||
| 51 | static final long serialVersionUID = 7565477590005668886L; | ||
| 52 | |||
| 53 | // only supported version of PKCS#8 PrivateKeyInfo | ||
| 54 | private static final BigInteger PKCS8_VERSION = BigInteger.ZERO; | ||
| 55 | |||
| 56 | // the private key | ||
| 57 | private BigInteger x; | ||
| 58 | |||
| 59 | // the key bytes, without the algorithm information | ||
| 60 | private byte[] key; | ||
| 61 | |||
| 62 | // the encoded key | ||
| 63 | private byte[] encodedKey; | ||
| 64 | |||
| 65 | // the prime modulus | ||
| 66 | private BigInteger p; | ||
| 67 | |||
| 68 | // the base generator | ||
| 69 | private BigInteger g; | ||
| 70 | |||
| 71 | // the private-value length | ||
| 72 | private int l; | ||
| 73 | |||
| 74 | private int DH_data[] = { 1, 2, 840, 113549, 1, 3, 1 }; | ||
| 75 | |||
| 76 | /** | ||
| 77 | * Make a DH private key out of a private value <code>x</code>, a prime | ||
| 78 | * modulus <code>p</code>, and a base generator <code>g</code>. | ||
| 79 | * | ||
| 80 | * @param x the private value | ||
| 81 | * @param p the prime modulus | ||
| 82 | * @param g the base generator | ||
| 83 | * | ||
| 84 | * @exception ProviderException if the key cannot be encoded | ||
| 85 | */ | ||
| 86 | DHPrivateKey(BigInteger x, BigInteger p, BigInteger g) | ||
| 87 | throws InvalidKeyException { | ||
| 88 | this(x, p, g, 0); | ||
| 89 | } | ||
| 90 | |||
| 91 | /** | ||
| 92 | * Make a DH private key out of a private value <code>x</code>, a prime | ||
| 93 | * modulus <code>p</code>, a base generator <code>g</code>, and a | ||
| 94 | * private-value length <code>l</code>. | ||
| 95 | * | ||
| 96 | * @param x the private value | ||
| 97 | * @param p the prime modulus | ||
| 98 | * @param g the base generator | ||
| 99 | * @param l the private-value length | ||
| 100 | * | ||
| 101 | * @exception InvalidKeyException if the key cannot be encoded | ||
| 102 | */ | ||
| 103 | DHPrivateKey(BigInteger x, BigInteger p, BigInteger g, int l) { | ||
| 104 | this.x = x; | ||
| 105 | this.p = p; | ||
| 106 | this.g = g; | ||
| 107 | this.l = l; | ||
| 108 | try { | ||
| 109 | this.key = new DerValue(DerValue.tag_Integer, | ||
| 110 | this.x.toByteArray()).toByteArray(); | ||
| 111 | this.encodedKey = getEncoded(); | ||
| 112 | } catch (IOException e) { | ||
| 113 | throw new ProviderException("Cannot produce ASN.1 encoding", e); | ||
| 114 | } | ||
| 115 | } | ||
| 116 | |||
| 117 | /** | ||
| 118 | * Make a DH private key from its DER encoding (PKCS #8). | ||
| 119 | * | ||
| 120 | * @param encodedKey the encoded key | ||
| 121 | * | ||
| 122 | * @exception InvalidKeyException if the encoded key does not represent | ||
| 123 | * a Diffie-Hellman private key | ||
| 124 | */ | ||
| 125 | DHPrivateKey(byte[] encodedKey) throws InvalidKeyException { | ||
| 126 | InputStream inStream = new ByteArrayInputStream(encodedKey); | ||
| 127 | try { | ||
| 128 | DerValue val = new DerValue(inStream); | ||
| 129 | if (val.tag != DerValue.tag_Sequence) { | ||
| 130 | throw new InvalidKeyException ("Key not a SEQUENCE"); | ||
| 131 | } | ||
| 132 | |||
| 133 | // | ||
| 134 | // version | ||
| 135 | // | ||
| 136 | BigInteger parsedVersion = val.data.getBigInteger(); | ||
| 137 | if (!parsedVersion.equals(PKCS8_VERSION)) { | ||
| 138 | throw new IOException("version mismatch: (supported: " + | ||
| 139 | PKCS8_VERSION + ", parsed: " + | ||
| 140 | parsedVersion); | ||
| 141 | } | ||
| 142 | |||
| 143 | // | ||
| 144 | // privateKeyAlgorithm | ||
| 145 | // | ||
| 146 | DerValue algid = val.data.getDerValue(); | ||
| 147 | if (algid.tag != DerValue.tag_Sequence) { | ||
| 148 | throw new InvalidKeyException("AlgId is not a SEQUENCE"); | ||
| 149 | } | ||
| 150 | DerInputStream derInStream = algid.toDerInputStream(); | ||
| 151 | ObjectIdentifier oid = derInStream.getOID(); | ||
| 152 | if (oid == null) { | ||
| 153 | throw new InvalidKeyException("Null OID"); | ||
| 154 | } | ||
| 155 | if (derInStream.available() == 0) { | ||
| 156 | throw new InvalidKeyException("Parameters missing"); | ||
| 157 | } | ||
| 158 | // parse the parameters | ||
| 159 | DerValue params = derInStream.getDerValue(); | ||
| 160 | if (params.tag == DerValue.tag_Null) { | ||
| 161 | throw new InvalidKeyException("Null parameters"); | ||
| 162 | } | ||
| 163 | if (params.tag != DerValue.tag_Sequence) { | ||
| 164 | throw new InvalidKeyException("Parameters not a SEQUENCE"); | ||
| 165 | } | ||
| 166 | params.data.reset(); | ||
| 167 | this.p = params.data.getBigInteger(); | ||
| 168 | this.g = params.data.getBigInteger(); | ||
| 169 | // Private-value length is OPTIONAL | ||
| 170 | if (params.data.available() != 0) { | ||
| 171 | this.l = params.data.getInteger(); | ||
| 172 | } | ||
| 173 | if (params.data.available() != 0) { | ||
| 174 | throw new InvalidKeyException("Extra parameter data"); | ||
| 175 | } | ||
| 176 | |||
| 177 | // | ||
| 178 | // privateKey | ||
| 179 | // | ||
| 180 | this.key = val.data.getOctetString(); | ||
| 181 | parseKeyBits(); | ||
| 182 | |||
| 183 | // ignore OPTIONAL attributes | ||
| 184 | |||
| 185 | this.encodedKey = (byte[])encodedKey.clone(); | ||
| 186 | |||
| 187 | } catch (NumberFormatException e) { | ||
| 188 | InvalidKeyException ike = new InvalidKeyException( | ||
| 189 | "Private-value length too big"); | ||
| 190 | ike.initCause(e); | ||
| 191 | throw ike; | ||
| 192 | } catch (IOException e) { | ||
| 193 | InvalidKeyException ike = new InvalidKeyException( | ||
| 194 | "Error parsing key encoding: " + e.getMessage()); | ||
| 195 | ike.initCause(e); | ||
| 196 | throw ike; | ||
| 197 | } | ||
| 198 | } | ||
| 199 | |||
| 200 | /** | ||
| 201 | * Returns the encoding format of this key: "PKCS#8" | ||
| 202 | */ | ||
| 203 | public String getFormat() { | ||
| 204 | return "PKCS#8"; | ||
| 205 | } | ||
| 206 | |||
| 207 | /** | ||
| 208 | * Returns the name of the algorithm associated with this key: "DH" | ||
| 209 | */ | ||
| 210 | public String getAlgorithm() { | ||
| 211 | return "DH"; | ||
| 212 | } | ||
| 213 | |||
| 214 | /** | ||
| 215 | * Get the encoding of the key. | ||
| 216 | */ | ||
| 217 | public synchronized byte[] getEncoded() { | ||
| 218 | if (this.encodedKey == null) { | ||
| 219 | try { | ||
| 220 | DerOutputStream tmp = new DerOutputStream(); | ||
| 221 | |||
| 222 | // | ||
| 223 | // version | ||
| 224 | // | ||
| 225 | tmp.putInteger(PKCS8_VERSION); | ||
| 226 | |||
| 227 | // | ||
| 228 | // privateKeyAlgorithm | ||
| 229 | // | ||
| 230 | DerOutputStream algid = new DerOutputStream(); | ||
| 231 | |||
| 232 | // store OID | ||
| 233 | algid.putOID(new ObjectIdentifier(DH_data)); | ||
| 234 | // encode parameters | ||
| 235 | DerOutputStream params = new DerOutputStream(); | ||
| 236 | params.putInteger(this.p); | ||
| 237 | params.putInteger(this.g); | ||
| 238 | if (this.l != 0) | ||
| 239 | params.putInteger(this.l); | ||
| 240 | // wrap parameters into SEQUENCE | ||
| 241 | DerValue paramSequence = new DerValue(DerValue.tag_Sequence, | ||
| 242 | params.toByteArray()); | ||
| 243 | // store parameter SEQUENCE in algid | ||
| 244 | algid.putDerValue(paramSequence); | ||
| 245 | // wrap algid into SEQUENCE | ||
| 246 | tmp.write(DerValue.tag_Sequence, algid); | ||
| 247 | |||
| 248 | // privateKey | ||
| 249 | tmp.putOctetString(this.key); | ||
| 250 | |||
| 251 | // make it a SEQUENCE | ||
| 252 | DerOutputStream derKey = new DerOutputStream(); | ||
| 253 | derKey.write(DerValue.tag_Sequence, tmp); | ||
| 254 | this.encodedKey = derKey.toByteArray(); | ||
| 255 | } catch (IOException e) { | ||
| 256 | return null; | ||
| 257 | } | ||
| 258 | } | ||
| 259 | return (byte[])this.encodedKey.clone(); | ||
| 260 | } | ||
| 261 | |||
| 262 | /** | ||
| 263 | * Returns the private value, <code>x</code>. | ||
| 264 | * | ||
| 265 | * @return the private value, <code>x</code> | ||
| 266 | */ | ||
| 267 | public BigInteger getX() { | ||
| 268 | return this.x; | ||
| 269 | } | ||
| 270 | |||
| 271 | /** | ||
| 272 | * Returns the key parameters. | ||
| 273 | * | ||
| 274 | * @return the key parameters | ||
| 275 | */ | ||
| 276 | public DHParameterSpec getParams() { | ||
| 277 | if (this.l != 0) | ||
| 278 | return new DHParameterSpec(this.p, this.g, this.l); | ||
| 279 | else | ||
| 280 | return new DHParameterSpec(this.p, this.g); | ||
| 281 | } | ||
| 282 | |||
| 283 | public String toString() { | ||
| 284 | String LINE_SEP = System.getProperty("line.separator"); | ||
| 285 | |||
| 286 | StringBuffer strbuf | ||
| 287 | = new StringBuffer("SunJCE Diffie-Hellman Private Key:" | ||
| 288 | + LINE_SEP + "x:" + LINE_SEP | ||
| 289 | + Debug.toHexString(this.x) | ||
| 290 | + LINE_SEP + "p:" + LINE_SEP | ||
| 291 | + Debug.toHexString(this.p) | ||
| 292 | + LINE_SEP + "g:" + LINE_SEP | ||
| 293 | + Debug.toHexString(this.g)); | ||
| 294 | if (this.l != 0) | ||
| 295 | strbuf.append(LINE_SEP + "l:" + LINE_SEP + " " + this.l); | ||
| 296 | return strbuf.toString(); | ||
| 297 | } | ||
| 298 | |||
| 299 | private void parseKeyBits() throws InvalidKeyException { | ||
| 300 | try { | ||
| 301 | DerInputStream in = new DerInputStream(this.key); | ||
| 302 | this.x = in.getBigInteger(); | ||
| 303 | } catch (IOException e) { | ||
| 304 | InvalidKeyException ike = new InvalidKeyException( | ||
| 305 | "Error parsing key encoding: " + e.getMessage()); | ||
| 306 | ike.initCause(e); | ||
| 307 | throw ike; | ||
| 308 | } | ||
| 309 | } | ||
| 310 | |||
| 311 | /** | ||
| 312 | * Calculates a hash code value for the object. | ||
| 313 | * Objects that are equal will also have the same hashcode. | ||
| 314 | */ | ||
| 315 | public int hashCode() { | ||
| 316 | int retval = 0; | ||
| 317 | byte[] enc = getEncoded(); | ||
| 318 | |||
| 319 | for (int i = 1; i < enc.length; i++) { | ||
| 320 | retval += enc[i] * i; | ||
| 321 | } | ||
| 322 | return(retval); | ||
| 323 | } | ||
| 324 | |||
| 325 | public boolean equals(Object obj) { | ||
| 326 | if (this == obj) | ||
| 327 | return true; | ||
| 328 | |||
| 329 | if (!(obj instanceof PrivateKey)) | ||
| 330 | return false; | ||
| 331 | |||
| 332 | byte[] thisEncoded = this.getEncoded(); | ||
| 333 | byte[] thatEncoded = ((PrivateKey)obj).getEncoded(); | ||
| 334 | |||
| 335 | return java.util.Arrays.equals(thisEncoded, thatEncoded); | ||
| 336 | } | ||
| 337 | |||
| 338 | /** | ||
| 339 | * Replace the DH private key to be serialized. | ||
| 340 | * | ||
| 341 | * @return the standard KeyRep object to be serialized | ||
| 342 | * | ||
| 343 | * @throws java.io.ObjectStreamException if a new object representing | ||
| 344 | * this DH private key could not be created | ||
| 345 | */ | ||
| 346 | private Object writeReplace() throws java.io.ObjectStreamException { | ||
| 347 | return new KeyRep(KeyRep.Type.PRIVATE, | ||
| 348 | getAlgorithm(), | ||
| 349 | getFormat(), | ||
| 350 | getEncoded()); | ||
| 351 | } | ||
| 352 | } | ||
| @@ -0,0 +1,331 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.io.*; | ||
| 29 | import java.math.BigInteger; | ||
| 30 | import java.security.KeyRep; | ||
| 31 | import java.security.InvalidKeyException; | ||
| 32 | import java.security.InvalidAlgorithmParameterException; | ||
| 33 | import java.security.ProviderException; | ||
| 34 | import java.security.PublicKey; | ||
| 35 | import javax.crypto.*; | ||
| 36 | import javax.crypto.spec.DHParameterSpec; | ||
| 37 | import sun.security.util.*; | ||
| 38 | |||
| 39 | |||
| 40 | /** | ||
| 41 | * A public key in X.509 format for the Diffie-Hellman key agreement algorithm. | ||
| 42 | * | ||
| 43 | * @author Jan Luehe | ||
| 44 | * | ||
| 45 | * | ||
| 46 | * @see DHPrivateKey | ||
| 47 | * @see java.security.KeyAgreement | ||
| 48 | */ | ||
| 49 | final class DHPublicKey implements PublicKey, | ||
| 50 | javax.crypto.interfaces.DHPublicKey, Serializable { | ||
| 51 | |||
| 52 | static final long serialVersionUID = 7647557958927458271L; | ||
| 53 | |||
| 54 | // the public key | ||
| 55 | private BigInteger y; | ||
| 56 | |||
| 57 | // the key bytes, without the algorithm information | ||
| 58 | private byte[] key; | ||
| 59 | |||
| 60 | // the encoded key | ||
| 61 | private byte[] encodedKey; | ||
| 62 | |||
| 63 | // the prime modulus | ||
| 64 | private BigInteger p; | ||
| 65 | |||
| 66 | // the base generator | ||
| 67 | private BigInteger g; | ||
| 68 | |||
| 69 | // the private-value length | ||
| 70 | private int l; | ||
| 71 | |||
| 72 | private int DH_data[] = { 1, 2, 840, 113549, 1, 3, 1 }; | ||
| 73 | |||
| 74 | /** | ||
| 75 | * Make a DH public key out of a public value <code>y</code>, a prime | ||
| 76 | * modulus <code>p</code>, and a base generator <code>g</code>. | ||
| 77 | * | ||
| 78 | * @param y the public value | ||
| 79 | * @param p the prime modulus | ||
| 80 | * @param g the base generator | ||
| 81 | * | ||
| 82 | * @exception InvalidKeyException if the key cannot be encoded | ||
| 83 | */ | ||
| 84 | DHPublicKey(BigInteger y, BigInteger p, BigInteger g) | ||
| 85 | throws InvalidKeyException { | ||
| 86 | this(y, p, g, 0); | ||
| 87 | } | ||
| 88 | |||
| 89 | /** | ||
| 90 | * Make a DH public key out of a public value <code>y</code>, a prime | ||
| 91 | * modulus <code>p</code>, a base generator <code>g</code>, and a | ||
| 92 | * private-value length <code>l</code>. | ||
| 93 | * | ||
| 94 | * @param y the public value | ||
| 95 | * @param p the prime modulus | ||
| 96 | * @param g the base generator | ||
| 97 | * @param l the private-value length | ||
| 98 | * | ||
| 99 | * @exception ProviderException if the key cannot be encoded | ||
| 100 | */ | ||
| 101 | DHPublicKey(BigInteger y, BigInteger p, BigInteger g, int l) { | ||
| 102 | this.y = y; | ||
| 103 | this.p = p; | ||
| 104 | this.g = g; | ||
| 105 | this.l = l; | ||
| 106 | try { | ||
| 107 | this.key = new DerValue(DerValue.tag_Integer, | ||
| 108 | this.y.toByteArray()).toByteArray(); | ||
| 109 | this.encodedKey = getEncoded(); | ||
| 110 | } catch (IOException e) { | ||
| 111 | throw new ProviderException("Cannot produce ASN.1 encoding", e); | ||
| 112 | } | ||
| 113 | } | ||
| 114 | |||
| 115 | /** | ||
| 116 | * Make a DH public key from its DER encoding (X.509). | ||
| 117 | * | ||
| 118 | * @param encodedKey the encoded key | ||
| 119 | * | ||
| 120 | * @exception InvalidKeyException if the encoded key does not represent | ||
| 121 | * a Diffie-Hellman public key | ||
| 122 | */ | ||
| 123 | DHPublicKey(byte[] encodedKey) throws InvalidKeyException { | ||
| 124 | InputStream inStream = new ByteArrayInputStream(encodedKey); | ||
| 125 | try { | ||
| 126 | DerValue derKeyVal = new DerValue(inStream); | ||
| 127 | if (derKeyVal.tag != DerValue.tag_Sequence) { | ||
| 128 | throw new InvalidKeyException ("Invalid key format"); | ||
| 129 | } | ||
| 130 | |||
| 131 | /* | ||
| 132 | * Parse the algorithm identifier | ||
| 133 | */ | ||
| 134 | DerValue algid = derKeyVal.data.getDerValue(); | ||
| 135 | if (algid.tag != DerValue.tag_Sequence) { | ||
| 136 | throw new InvalidKeyException("AlgId is not a SEQUENCE"); | ||
| 137 | } | ||
| 138 | DerInputStream derInStream = algid.toDerInputStream(); | ||
| 139 | ObjectIdentifier oid = derInStream.getOID(); | ||
| 140 | if (oid == null) { | ||
| 141 | throw new InvalidKeyException("Null OID"); | ||
| 142 | } | ||
| 143 | if (derInStream.available() == 0) { | ||
| 144 | throw new InvalidKeyException("Parameters missing"); | ||
| 145 | } | ||
| 146 | |||
| 147 | /* | ||
| 148 | * Parse the parameters | ||
| 149 | */ | ||
| 150 | DerValue params = derInStream.getDerValue(); | ||
| 151 | if (params.tag == DerValue.tag_Null) { | ||
| 152 | throw new InvalidKeyException("Null parameters"); | ||
| 153 | } | ||
| 154 | if (params.tag != DerValue.tag_Sequence) { | ||
| 155 | throw new InvalidKeyException("Parameters not a SEQUENCE"); | ||
| 156 | } | ||
| 157 | params.data.reset(); | ||
| 158 | this.p = params.data.getBigInteger(); | ||
| 159 | this.g = params.data.getBigInteger(); | ||
| 160 | // Private-value length is OPTIONAL | ||
| 161 | if (params.data.available() != 0) { | ||
| 162 | this.l = params.data.getInteger(); | ||
| 163 | } | ||
| 164 | if (params.data.available() != 0) { | ||
| 165 | throw new InvalidKeyException("Extra parameter data"); | ||
| 166 | } | ||
| 167 | |||
| 168 | /* | ||
| 169 | * Parse the key | ||
| 170 | */ | ||
| 171 | this.key = derKeyVal.data.getBitString(); | ||
| 172 | parseKeyBits(); | ||
| 173 | if (derKeyVal.data.available() != 0) { | ||
| 174 | throw new InvalidKeyException("Excess key data"); | ||
| 175 | } | ||
| 176 | |||
| 177 | this.encodedKey = (byte[])encodedKey.clone(); | ||
| 178 | |||
| 179 | } catch (NumberFormatException e) { | ||
| 180 | throw new InvalidKeyException("Private-value length too big"); | ||
| 181 | |||
| 182 | } catch (IOException e) { | ||
| 183 | throw new InvalidKeyException( | ||
| 184 | "Error parsing key encoding: " + e.toString()); | ||
| 185 | } | ||
| 186 | } | ||
| 187 | |||
| 188 | /** | ||
| 189 | * Returns the encoding format of this key: "X.509" | ||
| 190 | */ | ||
| 191 | public String getFormat() { | ||
| 192 | return "X.509"; | ||
| 193 | } | ||
| 194 | |||
| 195 | /** | ||
| 196 | * Returns the name of the algorithm associated with this key: "DH" | ||
| 197 | */ | ||
| 198 | public String getAlgorithm() { | ||
| 199 | return "DH"; | ||
| 200 | } | ||
| 201 | |||
| 202 | /** | ||
| 203 | * Get the encoding of the key. | ||
| 204 | */ | ||
| 205 | public synchronized byte[] getEncoded() { | ||
| 206 | if (this.encodedKey == null) { | ||
| 207 | try { | ||
| 208 | DerOutputStream algid = new DerOutputStream(); | ||
| 209 | |||
| 210 | // store oid in algid | ||
| 211 | algid.putOID(new ObjectIdentifier(DH_data)); | ||
| 212 | |||
| 213 | // encode parameters | ||
| 214 | DerOutputStream params = new DerOutputStream(); | ||
| 215 | params.putInteger(this.p); | ||
| 216 | params.putInteger(this.g); | ||
| 217 | if (this.l != 0) | ||
| 218 | params.putInteger(this.l); | ||
| 219 | // wrap parameters into SEQUENCE | ||
| 220 | DerValue paramSequence = new DerValue(DerValue.tag_Sequence, | ||
| 221 | params.toByteArray()); | ||
| 222 | // store parameter SEQUENCE in algid | ||
| 223 | algid.putDerValue(paramSequence); | ||
| 224 | |||
| 225 | // wrap algid into SEQUENCE, and store it in key encoding | ||
| 226 | DerOutputStream tmpDerKey = new DerOutputStream(); | ||
| 227 | tmpDerKey.write(DerValue.tag_Sequence, algid); | ||
| 228 | |||
| 229 | // store key data | ||
| 230 | tmpDerKey.putBitString(this.key); | ||
| 231 | |||
| 232 | // wrap algid and key into SEQUENCE | ||
| 233 | DerOutputStream derKey = new DerOutputStream(); | ||
| 234 | derKey.write(DerValue.tag_Sequence, tmpDerKey); | ||
| 235 | this.encodedKey = derKey.toByteArray(); | ||
| 236 | } catch (IOException e) { | ||
| 237 | return null; | ||
| 238 | } | ||
| 239 | } | ||
| 240 | return (byte[])this.encodedKey.clone(); | ||
| 241 | } | ||
| 242 | |||
| 243 | /** | ||
| 244 | * Returns the public value, <code>y</code>. | ||
| 245 | * | ||
| 246 | * @return the public value, <code>y</code> | ||
| 247 | */ | ||
| 248 | public BigInteger getY() { | ||
| 249 | return this.y; | ||
| 250 | } | ||
| 251 | |||
| 252 | /** | ||
| 253 | * Returns the key parameters. | ||
| 254 | * | ||
| 255 | * @return the key parameters | ||
| 256 | */ | ||
| 257 | public DHParameterSpec getParams() { | ||
| 258 | if (this.l != 0) | ||
| 259 | return new DHParameterSpec(this.p, this.g, this.l); | ||
| 260 | else | ||
| 261 | return new DHParameterSpec(this.p, this.g); | ||
| 262 | } | ||
| 263 | |||
| 264 | public String toString() { | ||
| 265 | String LINE_SEP = System.getProperty("line.separator"); | ||
| 266 | |||
| 267 | StringBuffer strbuf | ||
| 268 | = new StringBuffer("SunJCE Diffie-Hellman Public Key:" | ||
| 269 | + LINE_SEP + "y:" + LINE_SEP | ||
| 270 | + Debug.toHexString(this.y) | ||
| 271 | + LINE_SEP + "p:" + LINE_SEP | ||
| 272 | + Debug.toHexString(this.p) | ||
| 273 | + LINE_SEP + "g:" + LINE_SEP | ||
| 274 | + Debug.toHexString(this.g)); | ||
| 275 | if (this.l != 0) | ||
| 276 | strbuf.append(LINE_SEP + "l:" + LINE_SEP + " " + this.l); | ||
| 277 | return strbuf.toString(); | ||
| 278 | } | ||
| 279 | |||
| 280 | private void parseKeyBits() throws InvalidKeyException { | ||
| 281 | try { | ||
| 282 | DerInputStream in = new DerInputStream(this.key); | ||
| 283 | this.y = in.getBigInteger(); | ||
| 284 | } catch (IOException e) { | ||
| 285 | throw new InvalidKeyException( | ||
| 286 | "Error parsing key encoding: " + e.toString()); | ||
| 287 | } | ||
| 288 | } | ||
| 289 | |||
| 290 | /** | ||
| 291 | * Calculates a hash code value for the object. | ||
| 292 | * Objects that are equal will also have the same hashcode. | ||
| 293 | */ | ||
| 294 | public int hashCode() { | ||
| 295 | int retval = 0; | ||
| 296 | byte[] enc = getEncoded(); | ||
| 297 | |||
| 298 | for (int i = 1; i < enc.length; i++) { | ||
| 299 | retval += enc[i] * i; | ||
| 300 | } | ||
| 301 | return(retval); | ||
| 302 | } | ||
| 303 | |||
| 304 | public boolean equals(Object obj) { | ||
| 305 | if (this == obj) | ||
| 306 | return true; | ||
| 307 | |||
| 308 | if (!(obj instanceof PublicKey)) | ||
| 309 | return false; | ||
| 310 | |||
| 311 | byte[] thisEncoded = this.getEncoded(); | ||
| 312 | byte[] thatEncoded = ((PublicKey)obj).getEncoded(); | ||
| 313 | |||
| 314 | return java.util.Arrays.equals(thisEncoded, thatEncoded); | ||
| 315 | } | ||
| 316 | |||
| 317 | /** | ||
| 318 | * Replace the DH public key to be serialized. | ||
| 319 | * | ||
| 320 | * @return the standard KeyRep object to be serialized | ||
| 321 | * | ||
| 322 | * @throws java.io.ObjectStreamException if a new object representing | ||
| 323 | * this DH public key could not be created | ||
| 324 | */ | ||
| 325 | private Object writeReplace() throws java.io.ObjectStreamException { | ||
| 326 | return new KeyRep(KeyRep.Type.PUBLIC, | ||
| 327 | getAlgorithm(), | ||
| 328 | getFormat(), | ||
| 329 | getEncoded()); | ||
| 330 | } | ||
| 331 | } | ||
| @@ -0,0 +1,160 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.security.InvalidKeyException; | ||
| 29 | |||
| 30 | /** | ||
| 31 | * This class represents ciphers in electronic codebook (ECB) mode. | ||
| 32 | * | ||
| 33 | * <p>This mode is implemented independently of a particular cipher. | ||
| 34 | * Ciphers to which this mode should apply (e.g., DES) must be | ||
| 35 | * <i>plugged-in</i> using the constructor. | ||
| 36 | * | ||
| 37 | * <p>NOTE: This class does not deal with buffering or padding. | ||
| 38 | * | ||
| 39 | * @author Gigi Ankeny | ||
| 40 | */ | ||
| 41 | |||
| 42 | final class ElectronicCodeBook extends FeedbackCipher { | ||
| 43 | |||
| 44 | ElectronicCodeBook(SymmetricCipher embeddedCipher) { | ||
| 45 | super(embeddedCipher); | ||
| 46 | } | ||
| 47 | |||
| 48 | /** | ||
| 49 | * Gets the name of the feedback mechanism | ||
| 50 | * | ||
| 51 | * @return the name of the feedback mechanism | ||
| 52 | */ | ||
| 53 | String getFeedback() { | ||
| 54 | return "ECB"; | ||
| 55 | } | ||
| 56 | |||
| 57 | /** | ||
| 58 | * Resets the iv to its original value. | ||
| 59 | * This is used when doFinal is called in the Cipher class, so that the | ||
| 60 | * cipher can be reused (with its original iv). | ||
| 61 | */ | ||
| 62 | void reset() { | ||
| 63 | // empty | ||
| 64 | } | ||
| 65 | |||
| 66 | /** | ||
| 67 | * Save the current content of this cipher. | ||
| 68 | */ | ||
| 69 | void save() {} | ||
| 70 | |||
| 71 | /** | ||
| 72 | * Restores the content of this cipher to the previous saved one. | ||
| 73 | */ | ||
| 74 | void restore() {} | ||
| 75 | |||
| 76 | /** | ||
| 77 | * Initializes the cipher in the specified mode with the given key | ||
| 78 | * and iv. | ||
| 79 | * | ||
| 80 | * @param decrypting flag indicating encryption or decryption | ||
| 81 | * @param algorithm the algorithm name | ||
| 82 | * @param key the key | ||
| 83 | * @param iv the iv | ||
| 84 | * | ||
| 85 | * @exception InvalidKeyException if the given key is inappropriate for | ||
| 86 | * initializing this cipher | ||
| 87 | */ | ||
| 88 | void init(boolean decrypting, String algorithm, byte[] key, byte[] iv) | ||
| 89 | throws InvalidKeyException { | ||
| 90 | if ((key == null) || (iv != null)) { | ||
| 91 | throw new InvalidKeyException("Internal error"); | ||
| 92 | } | ||
| 93 | embeddedCipher.init(decrypting, algorithm, key); | ||
| 94 | } | ||
| 95 | |||
| 96 | /** | ||
| 97 | * Performs encryption operation. | ||
| 98 | * | ||
| 99 | * <p>The input plain text <code>plain</code>, starting at | ||
| 100 | * <code>plainOffset</code> and ending at | ||
| 101 | * <code>(plainOffset + len - 1)</code>, is encrypted. | ||
| 102 | * The result is stored in <code>cipher</code>, starting at | ||
| 103 | * <code>cipherOffset</code>. | ||
| 104 | * | ||
| 105 | * <p>It is the application's responsibility to make sure that | ||
| 106 | * <code>plainLen</code> is a multiple of the embedded cipher's block size, | ||
| 107 | * as any excess bytes are ignored. | ||
| 108 | * | ||
| 109 | * <p>It is also the application's responsibility to make sure that | ||
| 110 | * <code>init</code> has been called before this method is called. | ||
| 111 | * (This check is omitted here, to avoid double checking.) | ||
| 112 | * | ||
| 113 | * @param in the buffer with the input data to be encrypted | ||
| 114 | * @param inOffset the offset in <code>plain</code> | ||
| 115 | * @param len the length of the input data | ||
| 116 | * @param out the buffer for the result | ||
| 117 | * @param outOff the offset in <code>cipher</code> | ||
| 118 | */ | ||
| 119 | void encrypt(byte[] in, int inOff, int len, byte[] out, int outOff) { | ||
| 120 | while (len >= blockSize) { | ||
| 121 | embeddedCipher.encryptBlock(in, inOff, out, outOff); | ||
| 122 | len -= blockSize; | ||
| 123 | inOff += blockSize; | ||
| 124 | outOff += blockSize; | ||
| 125 | } | ||
| 126 | } | ||
| 127 | |||
| 128 | /** | ||
| 129 | * Performs decryption operation. | ||
| 130 | * | ||
| 131 | * <p>The input cipher text <code>cipher</code>, starting at | ||
| 132 | * <code>cipherOffset</code> and ending at | ||
| 133 | * <code>(cipherOffset + len - 1)</code>, is decrypted. | ||
| 134 | * The result is stored in <code>plain</code>, starting at | ||
| 135 | * <code>plainOffset</code>. | ||
| 136 | * | ||
| 137 | * <p>It is the application's responsibility to make sure that | ||
| 138 | * <code>cipherLen</code> is a multiple of the embedded cipher's block | ||
| 139 | * size, as any excess bytes are ignored. | ||
| 140 | * | ||
| 141 | * <p>It is also the application's responsibility to make sure that | ||
| 142 | * <code>init</code> has been called before this method is called. | ||
| 143 | * (This check is omitted here, to avoid double checking.) | ||
| 144 | * | ||
| 145 | * @param in the buffer with the input data to be decrypted | ||
| 146 | * @param inOff the offset in <code>cipherOffset</code> | ||
| 147 | * @param len the length of the input data | ||
| 148 | * @param out the buffer for the result | ||
| 149 | * @param outOff the offset in <code>plain</code> | ||
| 150 | */ | ||
| 151 | void decrypt(byte[] in, int inOff, int len, byte[] out, int outOff) { | ||
| 152 | while (len >= blockSize) { | ||
| 153 | embeddedCipher.decryptBlock(in, inOff, out, outOff); | ||
| 154 | len -= blockSize; | ||
| 155 | inOff += blockSize; | ||
| 156 | outOff += blockSize; | ||
| 157 | } | ||
| 158 | } | ||
| 159 | |||
| 160 | } | ||
| @@ -0,0 +1,130 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.io.*; | ||
| 29 | import sun.security.x509.AlgorithmId; | ||
| 30 | import sun.security.util.*; | ||
| 31 | |||
| 32 | /** | ||
| 33 | * This class implements the <code>EncryptedPrivateKeyInfo</code> type, | ||
| 34 | * which is defined in PKCS #8 as follows: | ||
| 35 | * | ||
| 36 | * <pre> | ||
| 37 | * EncryptedPrivateKeyInfo ::= SEQUENCE { | ||
| 38 | * encryptionAlgorithm AlgorithmIdentifier, | ||
| 39 | * encryptedData OCTET STRING } | ||
| 40 | * </pre> | ||
| 41 | * | ||
| 42 | * @author Jan Luehe | ||
| 43 | */ | ||
| 44 | final class EncryptedPrivateKeyInfo { | ||
| 45 | |||
| 46 | // the "encryptionAlgorithm" field | ||
| 47 | private AlgorithmId algid; | ||
| 48 | |||
| 49 | // the "encryptedData" field | ||
| 50 | private byte[] encryptedData; | ||
| 51 | |||
| 52 | // the ASN.1 encoded contents of this class | ||
| 53 | private byte[] encoded; | ||
| 54 | |||
| 55 | /** | ||
| 56 | * Constructs (i.e., parses) an <code>EncryptedPrivateKeyInfo</code> from | ||
| 57 | * its encoding. | ||
| 58 | */ | ||
| 59 | EncryptedPrivateKeyInfo(byte[] encoded) throws IOException { | ||
| 60 | DerValue val = new DerValue(encoded); | ||
| 61 | |||
| 62 | DerValue[] seq = new DerValue[2]; | ||
| 63 | |||
| 64 | seq[0] = val.data.getDerValue(); | ||
| 65 | seq[1] = val.data.getDerValue(); | ||
| 66 | |||
| 67 | if (val.data.available() != 0) { | ||
| 68 | throw new IOException("overrun, bytes = " + val.data.available()); | ||
| 69 | } | ||
| 70 | |||
| 71 | this.algid = AlgorithmId.parse(seq[0]); | ||
| 72 | if (seq[0].data.available() != 0) { | ||
| 73 | throw new IOException("encryptionAlgorithm field overrun"); | ||
| 74 | } | ||
| 75 | |||
| 76 | this.encryptedData = seq[1].getOctetString(); | ||
| 77 | if (seq[1].data.available() != 0) | ||
| 78 | throw new IOException("encryptedData field overrun"); | ||
| 79 | |||
| 80 | this.encoded = (byte[])encoded.clone(); | ||
| 81 | } | ||
| 82 | |||
| 83 | /** | ||
| 84 | * Constructs an <code>EncryptedPrivateKeyInfo</code> from the | ||
| 85 | * encryption algorithm and the encrypted data. | ||
| 86 | */ | ||
| 87 | EncryptedPrivateKeyInfo(AlgorithmId algid, byte[] encryptedData) { | ||
| 88 | this.algid = algid; | ||
| 89 | this.encryptedData = (byte[])encryptedData.clone(); | ||
| 90 | this.encoded = null; // lazy generation of encoding | ||
| 91 | } | ||
| 92 | |||
| 93 | /** | ||
| 94 | * Returns the encryption algorithm. | ||
| 95 | */ | ||
| 96 | AlgorithmId getAlgorithm() { | ||
| 97 | return this.algid; | ||
| 98 | } | ||
| 99 | |||
| 100 | /** | ||
| 101 | * Returns the encrypted data. | ||
| 102 | */ | ||
| 103 | byte[] getEncryptedData() { | ||
| 104 | return (byte[])this.encryptedData.clone(); | ||
| 105 | } | ||
| 106 | |||
| 107 | /** | ||
| 108 | * Returns the ASN.1 encoding of this class. | ||
| 109 | */ | ||
| 110 | byte[] getEncoded() | ||
| 111 | throws IOException | ||
| 112 | { | ||
| 113 | if (this.encoded != null) return (byte[])this.encoded.clone(); | ||
| 114 | |||
| 115 | DerOutputStream out = new DerOutputStream(); | ||
| 116 | DerOutputStream tmp = new DerOutputStream(); | ||
| 117 | |||
| 118 | // encode encryption algorithm | ||
| 119 | algid.encode(tmp); | ||
| 120 | |||
| 121 | // encode encrypted data | ||
| 122 | tmp.putOctetString(encryptedData); | ||
| 123 | |||
| 124 | // wrap everything into a SEQUENCE | ||
| 125 | out.write(DerValue.tag_Sequence, tmp); | ||
| 126 | this.encoded = out.toByteArray(); | ||
| 127 | |||
| 128 | return (byte[])this.encoded.clone(); | ||
| 129 | } | ||
| 130 | } | ||
| @@ -0,0 +1,199 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package com.sun.crypto.provider; | ||
| 27 | |||
| 28 | import java.security.InvalidKeyException; | ||
| 29 | import javax.crypto.IllegalBlockSizeException; | ||
| 30 | |||
| 31 | /** | ||
| 32 | * This class represents a block cipher in one of its modes. It wraps | ||
| 33 | * a SymmetricCipher maintaining the mode state and providing | ||
| 34 | * the capability to encrypt amounts of data larger than a single block. | ||
| 35 | * | ||
| 36 | * @author Jan Luehe | ||
| 37 | * @see ElectronicCodeBook | ||
| 38 | * @see CipherBlockChaining | ||
| 39 | * @see CipherFeedback | ||
| 40 | * @see OutputFeedback | ||
| 41 | * @see PCBC | ||
| 42 | */ | ||
| 43 | abstract class FeedbackCipher { | ||
| 44 | |||
| 45 | // the embedded block cipher | ||
| 46 | final SymmetricCipher embeddedCipher; | ||
| 47 | |||
| 48 | // the block size of the embedded block cipher | ||
| 49 | final int blockSize; | ||
| 50 | |||
| 51 | // the initialization vector | ||
| 52 | byte[] iv; | ||
| 53 | |||
| 54 | FeedbackCipher(SymmetricCipher embeddedCipher) { | ||
| 55 | this.embeddedCipher = embeddedCipher; | ||
| 56 | blockSize = embeddedCipher.getBlockSize(); | ||
| 57 | } | ||
| 58 | |||
| 59 | final SymmetricCipher getEmbeddedCipher() { | ||
| 60 | return embeddedCipher; | ||
| 61 | } | ||
| 62 | |||
| 63 | /** | ||
| 64 | * Gets the block size of the embedded cipher. | ||
| 65 | * | ||
| 66 | * @return the block size of the embedded cipher | ||
| 67 | */ | ||
| 68 | final int getBlockSize() { | ||
| 69 | return blockSize; | ||
| 70 | } | ||
| 71 | |||
| 72 | /** | ||
| 73 | * Gets the name of the feedback mechanism | ||
| 74 | * | ||
| 75 | * @return the name of the feedback mechanism | ||
| 76 | */ | ||
| 77 | abstract String getFeedback(); | ||
| 78 | |||
| 79 | /** | ||
| 80 | * Save the current content of this cipher. | ||
| 81 | */ | ||
| 82 | abstract void save(); | ||
117 more lines aren’t shown here.
This diff is large: its 349 lines aren’t shown here.
This diff is large: its 134 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 204 lines aren’t shown here.
This diff is large: its 134 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 124 lines aren’t shown here.
This diff is large: its 904 lines aren’t shown here.
This diff is large: its 222 lines aren’t shown here.
This diff is large: its 411 lines aren’t shown here.
This diff is large: its 260 lines aren’t shown here.
This diff is large: its 230 lines aren’t shown here.
This diff is large: its 542 lines aren’t shown here.
This diff is large: its 155 lines aren’t shown here.
This diff is large: its 204 lines aren’t shown here.
This diff is large: its 144 lines aren’t shown here.
This diff is large: its 430 lines aren’t shown here.
This diff is large: its 436 lines aren’t shown here.
This diff is large: its 155 lines aren’t shown here.
This diff is large: its 283 lines aren’t shown here.
This diff is large: its 199 lines aren’t shown here.
This diff is large: its 522 lines aren’t shown here.
This diff is large: its 129 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 91 lines aren’t shown here.
This diff is large: its 152 lines aren’t shown here.
This diff is large: its 321 lines aren’t shown here.
This diff is large: its 230 lines aren’t shown here.
This diff is large: its 445 lines aren’t shown here.
This diff is large: its 265 lines aren’t shown here.
This diff is large: its 457 lines aren’t shown here.
This diff is large: its 103 lines aren’t shown here.
This diff is large: its 278 lines aren’t shown here.
This diff is large: its 176 lines aren’t shown here.
This diff is large: its 369 lines aren’t shown here.
This diff is large: its 86 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 103 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
Binary file not shown.
This diff is large: its 54 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 1822 lines aren’t shown here.
Binary file not shown.
This diff is large: its 95 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 1533 lines aren’t shown here.
Binary file not shown.
This diff is large: its 107 lines aren’t shown here.
Binary file not shown.
This diff is large: its 308 lines aren’t shown here.
This diff is large: its 209 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
Binary file not shown.
This diff is large: its 124 lines aren’t shown here.
Binary file not shown.
This diff is large: its 137 lines aren’t shown here.
Binary file not shown.
This diff is large: its 34 lines aren’t shown here.
Binary file not shown.
This diff is large: its 63 lines aren’t shown here.
Binary file not shown.
This diff is large: its 1168 lines aren’t shown here.
Binary file not shown.
This diff is large: its 50 lines aren’t shown here.
Binary file not shown.
This diff is large: its 147 lines aren’t shown here.
Binary file not shown.
This diff is large: its 219 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 487 lines aren’t shown here.
Binary file not shown.
This diff is large: its 217 lines aren’t shown here.
Binary file not shown.
This diff is large: its 500 lines aren’t shown here.
This diff is large: its 211 lines aren’t shown here.
Binary file not shown.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
Binary file not shown.
This diff is large: its 447 lines aren’t shown here.
This diff is large: its 172 lines aren’t shown here.
This diff is large: its 105 lines aren’t shown here.
Binary file not shown.
This diff is large: its 1029 lines aren’t shown here.
Binary file not shown.
This diff is large: its 100 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 1318 lines aren’t shown here.
Binary file not shown.
This diff is large: its 105 lines aren’t shown here.
Binary file not shown.
This diff is large: its 318 lines aren’t shown here.
Binary file not shown.
This diff is large: its 321 lines aren’t shown here.
This diff is large: its 107 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
Binary file not shown.
This diff is large: its 403 lines aren’t shown here.
Binary file not shown.
This diff is large: its 268 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
Binary file not shown.
This diff is large: its 137 lines aren’t shown here.
Binary file not shown.
This diff is large: its 134 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 261 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 310 lines aren’t shown here.
Binary file not shown.
This diff is large: its 84 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 1565 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 372 lines aren’t shown here.
Binary file not shown.
This diff is large: its 255 lines aren’t shown here.
This diff is large: its 367 lines aren’t shown here.
This diff is large: its 144 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 1676 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
Binary file not shown.
This diff is large: its 89 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 1810 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
Binary file not shown.
This diff is large: its 99 lines aren’t shown here.
Binary file not shown.
This diff is large: its 2417 lines aren’t shown here.
This diff is large: its 158 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
Binary file not shown.
This diff is large: its 225 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 285 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 242 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 1593 lines aren’t shown here.
Binary file not shown.
This diff is large: its 104 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 1172 lines aren’t shown here.
Binary file not shown.
This diff is large: its 127 lines aren’t shown here.
Binary file not shown.
This diff is large: its 2047 lines aren’t shown here.
This diff is large: its 501 lines aren’t shown here.
This diff is large: its 220 lines aren’t shown here.
Binary file not shown.
This diff is large: its 193 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
Binary file not shown.
This diff is large: its 323 lines aren’t shown here.
Binary file not shown.
This diff is large: its 131 lines aren’t shown here.
Binary file not shown.
This diff is large: its 316 lines aren’t shown here.
Binary file not shown.
This diff is large: its 94 lines aren’t shown here.
Binary file not shown.
This diff is large: its 135 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
Binary file not shown.
This diff is large: its 64 lines aren’t shown here.
Binary file not shown.
This diff is large: its 65 lines aren’t shown here.
Binary file not shown.
This diff is large: its 78 lines aren’t shown here.
Binary file not shown.
This diff is large: its 77 lines aren’t shown here.
Binary file not shown.
This diff is large: its 66 lines aren’t shown here.
Binary file not shown.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
Binary file not shown.
This diff is large: its 55 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 135 lines aren’t shown here.
Binary file not shown.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 90 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 90 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 221 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 1304 lines aren’t shown here.
This diff is large: its 168 lines aren’t shown here.
This diff is large: its 119 lines aren’t shown here.
This diff is large: its 636 lines aren’t shown here.
This diff is large: its 1399 lines aren’t shown here.
This diff is large: its 145 lines aren’t shown here.
This diff is large: its 352 lines aren’t shown here.
This diff is large: its 1740 lines aren’t shown here.
This diff is large: its 1498 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 1142 lines aren’t shown here.
This diff is large: its 183 lines aren’t shown here.
This diff is large: its 2156 lines aren’t shown here.
This diff is large: its 234 lines aren’t shown here.
This diff is large: its 832 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 3 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 84 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 179 lines aren’t shown here.
This diff is large: its 3 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 735 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 151 lines aren’t shown here.
This diff is large: its 108 lines aren’t shown here.
This diff is large: its 91 lines aren’t shown here.
This diff is large: its 362 lines aren’t shown here.
This diff is large: its 366 lines aren’t shown here.
This diff is large: its 268 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 847 lines aren’t shown here.
This diff is large: its 477 lines aren’t shown here.
This diff is large: its 461 lines aren’t shown here.
This diff is large: its 375 lines aren’t shown here.
This diff is large: its 224 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 1284 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 152 lines aren’t shown here.
This diff is large: its 115 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 115 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 114 lines aren’t shown here.
This diff is large: its 105 lines aren’t shown here.
This diff is large: its 212 lines aren’t shown here.
This diff is large: its 109 lines aren’t shown here.
This diff is large: its 144 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 160 lines aren’t shown here.
This diff is large: its 296 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 307 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 176 lines aren’t shown here.
This diff is large: its 126 lines aren’t shown here.
This diff is large: its 114 lines aren’t shown here.
This diff is large: its 167 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 3 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 3 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 429 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 286 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 566 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 337 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 321 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 105 lines aren’t shown here.
This diff is large: its 96 lines aren’t shown here.
Binary file not shown.
This diff is large: its 45 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 566 lines aren’t shown here.
This diff is large: its 99 lines aren’t shown here.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 1310 lines aren’t shown here.
Binary file not shown.
This diff is large: its 212 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 904 lines aren’t shown here.
This diff is large: its 560 lines aren’t shown here.
This diff is large: its 135 lines aren’t shown here.
This diff is large: its 113 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 2621 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 187 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 178 lines aren’t shown here.
Binary file not shown.
This diff is large: its 47 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 296 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 95 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 225 lines aren’t shown here.
This diff is large: its 96 lines aren’t shown here.
This diff is large: its 401 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 131 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 185 lines aren’t shown here.
This diff is large: its 480 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 235 lines aren’t shown here.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 228 lines aren’t shown here.
This diff is large: its 246 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 176 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 237 lines aren’t shown here.
This diff is large: its 182 lines aren’t shown here.
This diff is large: its 125 lines aren’t shown here.
This diff is large: its 100 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 235 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 752 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 3 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 3 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
Binary file not shown.
This diff is large: its 299 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 1623 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 2683 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 495 lines aren’t shown here.
Binary file not shown.
This diff is large: its 258 lines aren’t shown here.
Binary file not shown.
This diff is large: its 400 lines aren’t shown here.
Binary file not shown.
This diff is large: its 908 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 1490 lines aren’t shown here.
Binary file not shown.
This diff is large: its 44 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 1219 lines aren’t shown here.
Binary file not shown.
This diff is large: its 437 lines aren’t shown here.
This diff is large: its 726 lines aren’t shown here.
This diff is large: its 132 lines aren’t shown here.
Binary file not shown.
This diff is large: its 175 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 547 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 819 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 665 lines aren’t shown here.
Binary file not shown.
This diff is large: its 323 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 1323 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 2205 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 1620 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 643 lines aren’t shown here.
Binary file not shown.
This diff is large: its 501 lines aren’t shown here.
Binary file not shown.
This diff is large: its 339 lines aren’t shown here.
Binary file not shown.
This diff is large: its 98 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 282 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 345 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 105 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 108 lines aren’t shown here.
This diff is large: its 210 lines aren’t shown here.
This diff is large: its 97 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 94 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 373 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 136 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 82 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 114 lines aren’t shown here.
This diff is large: its 154 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 262 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 430 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 445 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 124 lines aren’t shown here.
This diff is large: its 831 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 240 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 102 lines aren’t shown here.
This diff is large: its 474 lines aren’t shown here.
This diff is large: its 150 lines aren’t shown here.
This diff is large: its 130 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 182 lines aren’t shown here.
This diff is large: its 864 lines aren’t shown here.
This diff is large: its 431 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 286 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 118 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 201 lines aren’t shown here.
This diff is large: its 378 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 3 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 172 lines aren’t shown here.
This diff is large: its 95 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 125 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 211 lines aren’t shown here.
This diff is large: its 545 lines aren’t shown here.
This diff is large: its 156 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 117 lines aren’t shown here.
This diff is large: its 120 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 117 lines aren’t shown here.
This diff is large: its 117 lines aren’t shown here.
This diff is large: its 116 lines aren’t shown here.
This diff is large: its 116 lines aren’t shown here.
This diff is large: its 136 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 121 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
Binary file not shown.
This diff is large: its 233 lines aren’t shown here.
Binary file not shown.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 2065 lines aren’t shown here.
Binary file not shown.
This diff is large: its 131 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 305 lines aren’t shown here.
Binary file not shown.
This diff is large: its 229 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 1493 lines aren’t shown here.
Binary file not shown.
This diff is large: its 68 lines aren’t shown here.
Binary file not shown.
This diff is large: its 78 lines aren’t shown here.
Binary file not shown.
This diff is large: its 47 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 779 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 1498 lines aren’t shown here.
This diff is large: its 115 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 271 lines aren’t shown here.
Binary file not shown.
This diff is large: its 719 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 470 lines aren’t shown here.
Binary file not shown.
This diff is large: its 322 lines aren’t shown here.
Binary file not shown.
This diff is large: its 275 lines aren’t shown here.
Binary file not shown.
This diff is large: its 366 lines aren’t shown here.
Binary file not shown.
This diff is large: its 189 lines aren’t shown here.
Binary file not shown.
This diff is large: its 211 lines aren’t shown here.
Binary file not shown.
This diff is large: its 125 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 176 lines aren’t shown here.
Binary file not shown.
This diff is large: its 179 lines aren’t shown here.
Binary file not shown.
This diff is large: its 71 lines aren’t shown here.
Binary file not shown.
This diff is large: its 123 lines aren’t shown here.
Binary file not shown.
This diff is large: its 69 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 281 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 679 lines aren’t shown here.
Binary file not shown.
This diff is large: its 65 lines aren’t shown here.
Binary file not shown.
This diff is large: its 193 lines aren’t shown here.
Binary file not shown.
This diff is large: its 96 lines aren’t shown here.
Binary file not shown.
This diff is large: its 91 lines aren’t shown here.
Binary file not shown.
This diff is large: its 242 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 138 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 839 lines aren’t shown here.
Binary file not shown.
This diff is large: its 103 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 253 lines aren’t shown here.
Binary file not shown.
This diff is large: its 107 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 911 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 189 lines aren’t shown here.
Binary file not shown.
This diff is large: its 111 lines aren’t shown here.
Binary file not shown.
This diff is large: its 73 lines aren’t shown here.
Binary file not shown.
This diff is large: its 41 lines aren’t shown here.
Binary file not shown.
This diff is large: its 104 lines aren’t shown here.
Binary file not shown.
This diff is large: its 60 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 233 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 495 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 120 lines aren’t shown here.
This diff is large: its 242 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
Binary file not shown.
This diff is large: its 571 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 347 lines aren’t shown here.
Binary file not shown.
This diff is large: its 107 lines aren’t shown here.
Binary file not shown.
This diff is large: its 666 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 545 lines aren’t shown here.
Binary file not shown.
This diff is large: its 111 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 149 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
Binary file not shown.
This diff is large: its 122 lines aren’t shown here.
Binary file not shown.
This diff is large: its 56 lines aren’t shown here.
Binary file not shown.
This diff is large: its 247 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 809 lines aren’t shown here.
Binary file not shown.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 758 lines aren’t shown here.
This diff is large: its 478 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 309 lines aren’t shown here.
This diff is large: its 220 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 403 lines aren’t shown here.
This diff is large: its 264 lines aren’t shown here.
This diff is large: its 288 lines aren’t shown here.
This diff is large: its 143 lines aren’t shown here.
This diff is large: its 182 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 150 lines aren’t shown here.
This diff is large: its 267 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 138 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 218 lines aren’t shown here.
This diff is large: its 1286 lines aren’t shown here.
This diff is large: its 949 lines aren’t shown here.
This diff is large: its 381 lines aren’t shown here.
This diff is large: its 112 lines aren’t shown here.
This diff is large: its 1515 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 90 lines aren’t shown here.
This diff is large: its 149 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 156 lines aren’t shown here.
This diff is large: its 487 lines aren’t shown here.
This diff is large: its 108 lines aren’t shown here.
This diff is large: its 161 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 129 lines aren’t shown here.
This diff is large: its 171 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 100 lines aren’t shown here.
This diff is large: its 215 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 490 lines aren’t shown here.
This diff is large: its 118 lines aren’t shown here.
This diff is large: its 100 lines aren’t shown here.
This diff is large: its 283 lines aren’t shown here.
This diff is large: its 218 lines aren’t shown here.
This diff is large: its 363 lines aren’t shown here.
This diff is large: its 477 lines aren’t shown here.
This diff is large: its 184 lines aren’t shown here.
This diff is large: its 101 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 125 lines aren’t shown here.
This diff is large: its 120 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 95 lines aren’t shown here.
This diff is large: its 132 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 94 lines aren’t shown here.
This diff is large: its 111 lines aren’t shown here.
This diff is large: its 105 lines aren’t shown here.
This diff is large: its 96 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 147 lines aren’t shown here.
This diff is large: its 279 lines aren’t shown here.
This diff is large: its 194 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 126 lines aren’t shown here.
This diff is large: its 99 lines aren’t shown here.
This diff is large: its 512 lines aren’t shown here.
This diff is large: its 97 lines aren’t shown here.
This diff is large: its 327 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 207 lines aren’t shown here.
This diff is large: its 133 lines aren’t shown here.
This diff is large: its 574 lines aren’t shown here.
This diff is large: its 191 lines aren’t shown here.
This diff is large: its 1027 lines aren’t shown here.
This diff is large: its 758 lines aren’t shown here.
This diff is large: its 317 lines aren’t shown here.
This diff is large: its 195 lines aren’t shown here.
This diff is large: its 520 lines aren’t shown here.
This diff is large: its 156 lines aren’t shown here.
This diff is large: its 415 lines aren’t shown here.
This diff is large: its 562 lines aren’t shown here.
This diff is large: its 176 lines aren’t shown here.
This diff is large: its 243 lines aren’t shown here.
This diff is large: its 210 lines aren’t shown here.
This diff is large: its 2571 lines aren’t shown here.
This diff is large: its 1072 lines aren’t shown here.
This diff is large: its 120 lines aren’t shown here.
This diff is large: its 265 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 142 lines aren’t shown here.
This diff is large: its 572 lines aren’t shown here.
This diff is large: its 125 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 134 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 1376 lines aren’t shown here.
This diff is large: its 172 lines aren’t shown here.
This diff is large: its 2660 lines aren’t shown here.
This diff is large: its 701 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 270 lines aren’t shown here.
This diff is large: its 1153 lines aren’t shown here.
This diff is large: its 346 lines aren’t shown here.
This diff is large: its 273 lines aren’t shown here.
This diff is large: its 631 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 246 lines aren’t shown here.
This diff is large: its 179 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 93 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 425 lines aren’t shown here.
This diff is large: its 165 lines aren’t shown here.
This diff is large: its 123 lines aren’t shown here.
This diff is large: its 137 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 148 lines aren’t shown here.
This diff is large: its 163 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 177 lines aren’t shown here.
This diff is large: its 179 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 126 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 93 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 247 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 237 lines aren’t shown here.
This diff is large: its 1161 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 501 lines aren’t shown here.
This diff is large: its 129 lines aren’t shown here.
This diff is large: its 243 lines aren’t shown here.
This diff is large: its 224 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 700 lines aren’t shown here.
This diff is large: its 1069 lines aren’t shown here.
This diff is large: its 260 lines aren’t shown here.
This diff is large: its 609 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 120 lines aren’t shown here.
This diff is large: its 127 lines aren’t shown here.
This diff is large: its 157 lines aren’t shown here.
This diff is large: its 193 lines aren’t shown here.
This diff is large: its 590 lines aren’t shown here.
This diff is large: its 141 lines aren’t shown here.
This diff is large: its 206 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
Binary file not shown.
This diff is large: its 119 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 108 lines aren’t shown here.
Binary file not shown.
This diff is large: its 335 lines aren’t shown here.
Binary file not shown.
This diff is large: its 430 lines aren’t shown here.
Binary file not shown.
This diff is large: its 45 lines aren’t shown here.
Binary file not shown.
This diff is large: its 225 lines aren’t shown here.
Binary file not shown.
This diff is large: its 1014 lines aren’t shown here.
Binary file not shown.
This diff is large: its 101 lines aren’t shown here.
Binary file not shown.
This diff is large: its 119 lines aren’t shown here.
Binary file not shown.
This diff is large: its 168 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 179 lines aren’t shown here.
Binary file not shown.
This diff is large: its 351 lines aren’t shown here.
Binary file not shown.
This diff is large: its 863 lines aren’t shown here.
Binary file not shown.
This diff is large: its 215 lines aren’t shown here.
Binary file not shown.
This diff is large: its 94 lines aren’t shown here.
Binary file not shown.
This diff is larger than a page shows: the files after these aren’t listed. Clone the repository to see all of it.