Mercurial > hg > openjdk > jdk7 > jdk
changeset 4323:49244980d692
Merge
author | asaha |
---|---|
date | Thu, 05 May 2011 22:29:05 -0700 |
parents | e6fdfb249e31 (current diff) 631c23c29000 (diff) |
children | 647b031200f0 |
files | src/share/classes/sun/security/util/SignatureFileManifest.java |
diffstat | 33 files changed, 437 insertions(+), 712 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Wed May 04 16:39:05 2011 -0700 +++ b/.hgtags Thu May 05 22:29:05 2011 -0700 @@ -114,3 +114,5 @@ 29296ea6529a418037ccce95903249665ef31c11 jdk7-b137 60d3d55dcc9c31a30ced9caa6ef5c0dcd7db031d jdk7-b138 d80954a89b49fda47c0c5cace65a17f5a758b8bd jdk7-b139 +9315c733fb17ddfb9fb44be7e0ffea37bf3c727d jdk7-b140 +63eeefe118da18c75ba3d36266768cd1ccaaca6b jdk7-b141
--- a/make/common/Defs-linux.gmk Wed May 04 16:39:05 2011 -0700 +++ b/make/common/Defs-linux.gmk Thu May 05 22:29:05 2011 -0700 @@ -354,7 +354,7 @@ # Japanese manpages # JA_SOURCE_ENCODING = eucJP -JA_TARGET_ENCODINGS = eucJP +JA_TARGET_ENCODINGS = UTF-8 # Settings for the JDI - Serviceability Agent binding. HOTSPOT_SALIB_PATH = $(HOTSPOT_IMPORT_PATH)/jre/lib/$(LIBARCH)
--- a/make/common/Release.gmk Wed May 04 16:39:05 2011 -0700 +++ b/make/common/Release.gmk Thu May 05 22:29:05 2011 -0700 @@ -164,7 +164,7 @@ ifeq ($(PLATFORM), linux) MANBASEDIRS=$(JDK_TOPDIR)/src/linux/doc $(IMPORTDOCDIR) MAN1SUBDIR=man - JA_DIRNAME=ja_JP.$(JA_SOURCE_ENCODING) + JA_DIRNAME=ja_JP.UTF-8 endif # linux define copy-man-pages @@ -190,8 +190,7 @@ done $(java-vm-cleanup) if [ "$(JA_DIRNAME)" != "" ] ; then \ - $(MV) $1/man/ja $1/man/$(JA_DIRNAME); \ - $(CD) $1/man && $(LN) -s $(JA_DIRNAME) ja; \ + $(CD) $1/man && $(RM) ja && $(LN) -s $(JA_DIRNAME) ja; \ fi endef
--- a/make/common/shared/Platform.gmk Wed May 04 16:39:05 2011 -0700 +++ b/make/common/shared/Platform.gmk Thu May 05 22:29:05 2011 -0700 @@ -428,8 +428,6 @@ # Machines with 512Mb or less of real memory are considered low memory # build machines and adjustments will be made to prevent excessing # system swapping during the build. -# If we don't know, assume 512. Subtract 128 from MB for VM MAX. -# Don't set VM max over 1024-128=896. ifeq ($(JDK_HAS_MEM_INFO),) JDK_HAS_MEM_INFO=true export JDK_HAS_MEM_INFO @@ -440,18 +438,8 @@ else \ echo "false"; \ fi) - MAX_VM_MEMORY := $(shell \ - if [ $(MB_OF_MEMORY) -le 1024 ] ; then \ - expr $(MB_OF_MEMORY) '-' 128 2> $(DEV_NULL) ; \ - else \ - echo "896"; \ - fi) - MIN_VM_MEMORY := $(shell \ - if [ $(MAX_VM_MEMORY) -le 128 ] ; then \ - expr $(MAX_VM_MEMORY) '-' 8 2> $(DEV_NULL) ; \ - else \ - echo "128"; \ - fi) + MAX_VM_MEMORY := 512 + MIN_VM_MEMORY := $(MAX_VM_MEMORY) else MB_OF_MEMORY := unknown LOW_MEMORY_MACHINE := true
--- a/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk.properties Wed May 04 16:39:05 2011 -0700 +++ b/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk.properties Thu May 05 22:29:05 2011 -0700 @@ -56,9 +56,9 @@ FileChooser.renameFileButtonText=Rename File FileChooser.renameFileButtonMnemonic=82 FileChooser.cancelButtonText=Cancel -FileChooser.cancelButtonMnemonic=67 +#FileChooser.cancelButtonMnemonic=67 FileChooser.saveButtonText=OK -FileChooser.saveButtonMnemonic=79 +#FileChooser.saveButtonMnemonic=79 FileChooser.openButtonText=OK FileChooser.openButtonMnemonic=79 FileChooser.saveDialogTitleText=Save @@ -79,9 +79,5 @@ FileChooser.renameFileErrorTitle=Error FileChooser.renameFileErrorText=Error renaming file "{0}" to "{1}" -# dummy resource added for translation automation -OptionPane.okButtonText=OK -OptionPane.okButtonMnemonic=79 -# dummy resource added for translation automation -OptionPane.cancelButtonText=Cancel -OptionPane.cancelButtonMnemonic=67 +#OptionPane.okButtonMnemonic=79 +#OptionPane.cancelButtonMnemonic=67
--- a/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_de.properties Wed May 04 16:39:05 2011 -0700 +++ b/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_de.properties Thu May 05 22:29:05 2011 -0700 @@ -24,7 +24,7 @@ GTKColorChooserPanel.hueMnemonic=70 GTKColorChooserPanel.redText=Rot: -GTKColorChooserPanel.redMnemonic=79 +GTKColorChooserPanel.redMnemonic=82 GTKColorChooserPanel.saturationText=S\u00E4ttigung: GTKColorChooserPanel.saturationMnemonic=83
--- a/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_es.properties Wed May 04 16:39:05 2011 -0700 +++ b/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_es.properties Thu May 05 22:29:05 2011 -0700 @@ -30,7 +30,7 @@ GTKColorChooserPanel.saturationMnemonic=83 GTKColorChooserPanel.greenText=Verde: -GTKColorChooserPanel.greenMnemonic=86 +GTKColorChooserPanel.greenMnemonic=69 GTKColorChooserPanel.valueText=Valor: GTKColorChooserPanel.valueMnemonic=86
--- a/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_fr.properties Wed May 04 16:39:05 2011 -0700 +++ b/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_fr.properties Thu May 05 22:29:05 2011 -0700 @@ -30,7 +30,7 @@ GTKColorChooserPanel.saturationMnemonic=83 GTKColorChooserPanel.greenText=Vert : -GTKColorChooserPanel.greenMnemonic=86 +GTKColorChooserPanel.greenMnemonic=69 GTKColorChooserPanel.valueText=Valeur : GTKColorChooserPanel.valueMnemonic=86
--- a/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_it.properties Wed May 04 16:39:05 2011 -0700 +++ b/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_it.properties Thu May 05 22:29:05 2011 -0700 @@ -30,7 +30,7 @@ GTKColorChooserPanel.saturationMnemonic=83 GTKColorChooserPanel.greenText=Verde: -GTKColorChooserPanel.greenMnemonic=86 +GTKColorChooserPanel.greenMnemonic=69 GTKColorChooserPanel.valueText=Valore: GTKColorChooserPanel.valueMnemonic=86
--- a/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_ja.properties Wed May 04 16:39:05 2011 -0700 +++ b/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_ja.properties Thu May 05 22:29:05 2011 -0700 @@ -55,11 +55,11 @@ FileChooser.deleteFileButtonMnemonic=76 FileChooser.renameFileButtonText=\u30D5\u30A1\u30A4\u30EB\u306E\u540D\u524D\u5909\u66F4(R) FileChooser.renameFileButtonMnemonic=82 -FileChooser.cancelButtonText=\u53D6\u6D88(C) +FileChooser.cancelButtonText=\u53D6\u6D88 FileChooser.cancelButtonMnemonic=67 -FileChooser.saveButtonText=OK(O) +FileChooser.saveButtonText=OK FileChooser.saveButtonMnemonic=79 -FileChooser.openButtonText=OK(O) +FileChooser.openButtonText=OK FileChooser.openButtonMnemonic=79 FileChooser.saveDialogTitleText=\u4FDD\u5B58 FileChooser.openDialogTitleText=\u958B\u304F @@ -79,10 +79,6 @@ FileChooser.renameFileErrorTitle=\u30A8\u30E9\u30FC FileChooser.renameFileErrorText=\u30D5\u30A1\u30A4\u30EB"{0}"\u306E"{1}"\u3078\u306E\u5909\u66F4\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F -# dummy resource added for translation automation -OptionPane.okButtonText=OK(O) -OptionPane.okButtonMnemonic=79 -# dummy resource added for translation automation -OptionPane.cancelButtonText=\u53D6\u6D88(C) -OptionPane.cancelButtonMnemonic=67 +#OptionPane.okButtonMnemonic=79 +#OptionPane.cancelButtonMnemonic=67
--- a/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_ko.properties Wed May 04 16:39:05 2011 -0700 +++ b/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_ko.properties Thu May 05 22:29:05 2011 -0700 @@ -55,11 +55,11 @@ FileChooser.deleteFileButtonMnemonic=76 FileChooser.renameFileButtonText=\uD30C\uC77C \uC774\uB984 \uBC14\uAFB8\uAE30(R) FileChooser.renameFileButtonMnemonic=82 -FileChooser.cancelButtonText=\uCDE8\uC18C(C) +FileChooser.cancelButtonText=\uCDE8\uC18C FileChooser.cancelButtonMnemonic=67 -FileChooser.saveButtonText=\uD655\uC778(O) +FileChooser.saveButtonText=\uD655\uC778 FileChooser.saveButtonMnemonic=79 -FileChooser.openButtonText=\uD655\uC778(O) +FileChooser.openButtonText=\uD655\uC778 FileChooser.openButtonMnemonic=79 FileChooser.saveDialogTitleText=\uC800\uC7A5 FileChooser.openDialogTitleText=\uC5F4\uAE30 @@ -79,10 +79,6 @@ FileChooser.renameFileErrorTitle=\uC624\uB958 FileChooser.renameFileErrorText="{0}" \uD30C\uC77C\uC758 \uC774\uB984\uC744 "{1}"(\uC73C)\uB85C \uBC14\uAFB8\uB294 \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4. -# dummy resource added for translation automation -OptionPane.okButtonText=\uD655\uC778(O) -OptionPane.okButtonMnemonic=79 -# dummy resource added for translation automation -OptionPane.cancelButtonText=\uCDE8\uC18C(C) -OptionPane.cancelButtonMnemonic=67 +#OptionPane.okButtonMnemonic=79 +#OptionPane.cancelButtonMnemonic=67
--- a/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_pt_BR.properties Wed May 04 16:39:05 2011 -0700 +++ b/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_pt_BR.properties Thu May 05 22:29:05 2011 -0700 @@ -30,7 +30,7 @@ GTKColorChooserPanel.saturationMnemonic=83 GTKColorChooserPanel.greenText=Verde: -GTKColorChooserPanel.greenMnemonic=86 +GTKColorChooserPanel.greenMnemonic=68 GTKColorChooserPanel.valueText=Valor: GTKColorChooserPanel.valueMnemonic=86
--- a/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_sv.properties Wed May 04 16:39:05 2011 -0700 +++ b/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_sv.properties Thu May 05 22:29:05 2011 -0700 @@ -39,7 +39,7 @@ GTKColorChooserPanel.blueMnemonic=66 GTKColorChooserPanel.colorNameText=F\u00E4rgnamn: -GTKColorChooserPanel.colorNameMnemonic=78 +GTKColorChooserPanel.colorNameMnemonic=70
--- a/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_zh_CN.properties Wed May 04 16:39:05 2011 -0700 +++ b/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_zh_CN.properties Thu May 05 22:29:05 2011 -0700 @@ -55,11 +55,11 @@ FileChooser.deleteFileButtonMnemonic=76 FileChooser.renameFileButtonText=\u91CD\u547D\u540D\u6587\u4EF6(R) FileChooser.renameFileButtonMnemonic=82 -FileChooser.cancelButtonText=\u53D6\u6D88(C) +FileChooser.cancelButtonText=\u53D6\u6D88 FileChooser.cancelButtonMnemonic=67 -FileChooser.saveButtonText=\u786E\u5B9A(O) +FileChooser.saveButtonText=\u786E\u5B9A FileChooser.saveButtonMnemonic=79 -FileChooser.openButtonText=\u786E\u5B9A(O) +FileChooser.openButtonText=\u786E\u5B9A FileChooser.openButtonMnemonic=79 FileChooser.saveDialogTitleText=\u4FDD\u5B58 FileChooser.openDialogTitleText=\u6253\u5F00 @@ -79,10 +79,6 @@ FileChooser.renameFileErrorTitle=\u9519\u8BEF FileChooser.renameFileErrorText=\u5C06\u6587\u4EF6 "{0}" \u91CD\u547D\u540D\u4E3A "{1}" \u65F6\u51FA\u9519 -# dummy resource added for translation automation -OptionPane.okButtonText=\u786E\u5B9A(O) -OptionPane.okButtonMnemonic=79 -# dummy resource added for translation automation -OptionPane.cancelButtonText=\u53D6\u6D88(C) -OptionPane.cancelButtonMnemonic=67 +#OptionPane.okButtonMnemonic=79 +#OptionPane.cancelButtonMnemonic=67
--- a/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_zh_TW.properties Wed May 04 16:39:05 2011 -0700 +++ b/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_zh_TW.properties Thu May 05 22:29:05 2011 -0700 @@ -55,11 +55,11 @@ FileChooser.deleteFileButtonMnemonic=76 FileChooser.renameFileButtonText=\u91CD\u65B0\u547D\u540D\u6A94\u6848(R) FileChooser.renameFileButtonMnemonic=82 -FileChooser.cancelButtonText=\u53D6\u6D88(C) +FileChooser.cancelButtonText=\u53D6\u6D88 FileChooser.cancelButtonMnemonic=67 -FileChooser.saveButtonText=\u78BA\u5B9A(O) +FileChooser.saveButtonText=\u78BA\u5B9A FileChooser.saveButtonMnemonic=79 -FileChooser.openButtonText=\u78BA\u5B9A(O) +FileChooser.openButtonText=\u78BA\u5B9A FileChooser.openButtonMnemonic=79 FileChooser.saveDialogTitleText=\u5132\u5B58 FileChooser.openDialogTitleText=\u958B\u555F @@ -79,10 +79,6 @@ FileChooser.renameFileErrorTitle=\u932F\u8AA4 FileChooser.renameFileErrorText=\u5C07\u6A94\u6848 "{0}" \u91CD\u65B0\u547D\u540D\u70BA "{1}" \u6642\u51FA\u73FE\u932F\u8AA4 -# dummy resource added for translation automation -OptionPane.okButtonText=\u78BA\u5B9A(O) -OptionPane.okButtonMnemonic=79 -# dummy resource added for translation automation -OptionPane.cancelButtonText=\u53D6\u6D88(C) -OptionPane.cancelButtonMnemonic=67 +#OptionPane.okButtonMnemonic=79 +#OptionPane.cancelButtonMnemonic=67
--- a/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic.properties Wed May 04 16:39:05 2011 -0700 +++ b/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic.properties Thu May 05 22:29:05 2011 -0700 @@ -57,7 +57,7 @@ Specify a different file name. FileChooser.acceptAllFileFilterText=All Files FileChooser.cancelButtonText=Cancel -FileChooser.cancelButtonMnemonic=67 +#FileChooser.cancelButtonMnemonic=67 // not needed? FileChooser.saveButtonText=Save FileChooser.saveButtonMnemonic=83 // not needed? FileChooser.openButtonText=Open @@ -146,9 +146,9 @@ OptionPane.noButtonText=No OptionPane.noButtonMnemonic=78 OptionPane.okButtonText=OK -OptionPane.okButtonMnemonic=0 +#OptionPane.okButtonMnemonic=0 OptionPane.cancelButtonText=Cancel -OptionPane.cancelButtonMnemonic=0 +#OptionPane.cancelButtonMnemonic=0 OptionPane.titleText=Select an Option # Title for the dialog for the showInputDialog methods. Only used if # the developer uses one of the variants that doesn't take a title.
--- a/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ja.properties Wed May 04 16:39:05 2011 -0700 +++ b/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ja.properties Thu May 05 22:29:05 2011 -0700 @@ -55,7 +55,7 @@ FileChooser.renameErrorText={0}\u306E\u540D\u524D\u3092\u5909\u66F4\u3067\u304D\u307E\u305B\u3093 FileChooser.renameErrorFileExistsText={0}\u306E\u540D\u524D\u3092\u5909\u66F4\u3067\u304D\u307E\u305B\u3093: \u6307\u5B9A\u3057\u305F\u540D\u524D\u306E\u30D5\u30A1\u30A4\u30EB\u306F\u3059\u3067\u306B\u5B58\u5728\u3057\u307E\u3059\u3002\u5225\u306E\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002 FileChooser.acceptAllFileFilterText=\u3059\u3079\u3066\u306E\u30D5\u30A1\u30A4\u30EB -FileChooser.cancelButtonText=\u53D6\u6D88(C) +FileChooser.cancelButtonText=\u53D6\u6D88 FileChooser.cancelButtonMnemonic=67 FileChooser.saveButtonText=\u4FDD\u5B58 FileChooser.saveButtonMnemonic=83 @@ -146,7 +146,7 @@ OptionPane.noButtonMnemonic=78 OptionPane.okButtonText=OK OptionPane.okButtonMnemonic=O -OptionPane.cancelButtonText=\u53D6\u6D88(0) +OptionPane.cancelButtonText=\u53D6\u6D88 OptionPane.cancelButtonMnemonic=0 OptionPane.titleText=\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u9078\u629E # Title for the dialog for the showInputDialog methods. Only used if
--- a/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ko.properties Wed May 04 16:39:05 2011 -0700 +++ b/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ko.properties Thu May 05 22:29:05 2011 -0700 @@ -55,7 +55,7 @@ FileChooser.renameErrorText={0}\uC758 \uC774\uB984\uC744 \uBC14\uAFC0 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. FileChooser.renameErrorFileExistsText={0}\uC758 \uC774\uB984\uC744 \uBC14\uAFC0 \uC218 \uC5C6\uC74C: \uC9C0\uC815\uD55C \uC774\uB984\uC744 \uC0AC\uC6A9\uD558\uB294 \uD30C\uC77C\uC774 \uC874\uC7AC\uD569\uB2C8\uB2E4. \uB2E4\uB978 \uD30C\uC77C \uC774\uB984\uC744 \uC9C0\uC815\uD558\uC2ED\uC2DC\uC624. FileChooser.acceptAllFileFilterText=\uBAA8\uB4E0 \uD30C\uC77C -FileChooser.cancelButtonText=\uCDE8\uC18C(C) +FileChooser.cancelButtonText=\uCDE8\uC18C FileChooser.cancelButtonMnemonic=67 FileChooser.saveButtonText=\uC800\uC7A5 FileChooser.saveButtonMnemonic=83 @@ -146,7 +146,7 @@ OptionPane.noButtonMnemonic=78 OptionPane.okButtonText=OK OptionPane.okButtonMnemonic=O -OptionPane.cancelButtonText=\uCDE8\uC18C(0) +OptionPane.cancelButtonText=\uCDE8\uC18C OptionPane.cancelButtonMnemonic=0 OptionPane.titleText=\uC635\uC158 \uC120\uD0DD # Title for the dialog for the showInputDialog methods. Only used if
--- a/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_sv.properties Wed May 04 16:39:05 2011 -0700 +++ b/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_sv.properties Thu May 05 22:29:05 2011 -0700 @@ -96,7 +96,7 @@ ColorChooser.cancelText=Avbryt ColorChooser.resetText=\u00C5terst\u00E4ll # VK_XXX constant for 'ColorChooser.resetText' button to make mnemonic -ColorChooser.resetMnemonic=82 +ColorChooser.resetMnemonic=84 ColorChooser.sampleText=Exempeltext Exempeltext ColorChooser.swatchesNameText=Prov ColorChooser.swatchesMnemonic=80
--- a/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_CN.properties Wed May 04 16:39:05 2011 -0700 +++ b/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_CN.properties Thu May 05 22:29:05 2011 -0700 @@ -55,7 +55,7 @@ FileChooser.renameErrorText=\u65E0\u6CD5\u91CD\u547D\u540D{0} FileChooser.renameErrorFileExistsText=\u65E0\u6CD5\u91CD\u547D\u540D{0}: \u5DF2\u5B58\u5728\u5177\u6709\u6240\u6307\u5B9A\u540D\u79F0\u7684\u6587\u4EF6\u3002\u8BF7\u6307\u5B9A\u5176\u4ED6\u6587\u4EF6\u540D\u3002 FileChooser.acceptAllFileFilterText=\u6240\u6709\u6587\u4EF6 -FileChooser.cancelButtonText=\u53D6\u6D88(C) +FileChooser.cancelButtonText=\u53D6\u6D88 FileChooser.cancelButtonMnemonic=67 FileChooser.saveButtonText=\u4FDD\u5B58 FileChooser.saveButtonMnemonic=83 @@ -146,7 +146,7 @@ OptionPane.noButtonMnemonic=78 OptionPane.okButtonText=OK OptionPane.okButtonMnemonic=O -OptionPane.cancelButtonText=\u53D6\u6D88(0) +OptionPane.cancelButtonText=\u53D6\u6D88 OptionPane.cancelButtonMnemonic=0 OptionPane.titleText=\u9009\u62E9\u4E00\u4E2A\u9009\u9879 # Title for the dialog for the showInputDialog methods. Only used if
--- a/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_TW.properties Wed May 04 16:39:05 2011 -0700 +++ b/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_TW.properties Thu May 05 22:29:05 2011 -0700 @@ -55,7 +55,7 @@ FileChooser.renameErrorText=\u7121\u6CD5\u91CD\u65B0\u547D\u540D {0} FileChooser.renameErrorFileExistsText=\u7121\u6CD5\u91CD\u65B0\u547D\u540D {0}: \u5DF2\u7D93\u5B58\u5728\u60A8\u6240\u6307\u5B9A\u540D\u7A31\u7684\u6A94\u6848\u3002\u8ACB\u6307\u5B9A\u4E0D\u540C\u7684\u540D\u7A31\u3002 FileChooser.acceptAllFileFilterText=\u6240\u6709\u6A94\u6848 -FileChooser.cancelButtonText=\u53D6\u6D88(C) +FileChooser.cancelButtonText=\u53D6\u6D88 FileChooser.cancelButtonMnemonic=67 FileChooser.saveButtonText=\u5132\u5B58 FileChooser.saveButtonMnemonic=83 @@ -146,7 +146,7 @@ OptionPane.noButtonMnemonic=78 OptionPane.okButtonText=OK OptionPane.okButtonMnemonic=O -OptionPane.cancelButtonText=\u53D6\u6D88(0) +OptionPane.cancelButtonText=\u53D6\u6D88 OptionPane.cancelButtonMnemonic=0 OptionPane.titleText=\u9078\u53D6\u4E00\u500B\u9078\u9805 # Title for the dialog for the showInputDialog methods. Only used if
--- a/src/share/classes/java/util/jar/JarFile.java Wed May 04 16:39:05 2011 -0700 +++ b/src/share/classes/java/util/jar/JarFile.java Thu May 05 22:29:05 2011 -0700 @@ -37,7 +37,6 @@ import sun.security.action.GetPropertyAction; import sun.security.util.ManifestEntryVerifier; import sun.misc.SharedSecrets; -import sun.security.util.SignatureFileVerifier; /** * The <code>JarFile</code> class is used to read the contents of a jar file @@ -179,7 +178,7 @@ byte[] b = getBytes(manEntry); man = new Manifest(new ByteArrayInputStream(b)); if (!jvInitialized) { - jv = new JarVerifier(b, man); + jv = new JarVerifier(b); } } else { man = new Manifest(super.getInputStream(manEntry)); @@ -298,7 +297,10 @@ if (names != null) { for (int i = 0; i < names.length; i++) { String name = names[i].toUpperCase(Locale.ENGLISH); - if (SignatureFileVerifier.isBlockOrSF(name)) { + if (name.endsWith(".DSA") || + name.endsWith(".RSA") || + name.endsWith(".EC") || + name.endsWith(".SF")) { // Assume since we found a signature-related file // that the jar is signed and that we therefore // need a JarVerifier and Manifest @@ -327,17 +329,17 @@ if (names != null) { for (int i = 0; i < names.length; i++) { JarEntry e = getJarEntry(names[i]); - if (!e.isDirectory() && - SignatureFileVerifier.isBlock(names[i])) { + if (!e.isDirectory()) { if (mev == null) { mev = new ManifestEntryVerifier (getManifestFromReference()); } - String key = names[i].substring( - 0, names[i].lastIndexOf(".")); - jv.verifyBlock(names[i], - getBytes(e), - super.getInputStream(getJarEntry(key + ".SF"))); + byte[] b = getBytes(e); + if (b != null && b.length > 0) { + jv.beginEntry(e, mev); + jv.update(b.length, b, 0, b.length, mev); + jv.update(-1, null, 0, 0, mev); + } } } }
--- a/src/share/classes/java/util/jar/JarInputStream.java Wed May 04 16:39:05 2011 -0700 +++ b/src/share/classes/java/util/jar/JarInputStream.java Thu May 05 22:29:05 2011 -0700 @@ -95,7 +95,7 @@ man.read(new ByteArrayInputStream(bytes)); closeEntry(); if (doVerify) { - jv = new JarVerifier(bytes, man); + jv = new JarVerifier(bytes); mev = new ManifestEntryVerifier(man); } return (JarEntry)super.getNextEntry();
--- a/src/share/classes/java/util/jar/JarVerifier.java Wed May 04 16:39:05 2011 -0700 +++ b/src/share/classes/java/util/jar/JarVerifier.java Thu May 05 22:29:05 2011 -0700 @@ -48,18 +48,35 @@ /* a table mapping names to code signers, for jar entries that have had their actual hashes verified */ - private Map verifiedSigners; + private Hashtable verifiedSigners; /* a table mapping names to code signers, for jar entries that have passed the .SF/.DSA/.EC -> MANIFEST check */ - private Map sigFileSigners; + private Hashtable sigFileSigners; + + /* a hash table to hold .SF bytes */ + private Hashtable sigFileData; + + /** "queue" of pending PKCS7 blocks that we couldn't parse + * until we parsed the .SF file */ + private ArrayList pendingBlocks; /* cache of CodeSigner objects */ private ArrayList signerCache; + /* Are we parsing a block? */ + private boolean parsingBlockOrSF = false; + + /* Are we done parsing META-INF entries? */ + private boolean parsingMeta = true; + /* Are there are files to verify? */ private boolean anyToVerify = true; + /* The output stream to use when keeping track of files we are interested + in */ + private ByteArrayOutputStream baos; + /** The ManifestDigester object */ private volatile ManifestDigester manDig; @@ -75,20 +92,20 @@ /** collect -DIGEST-MANIFEST values for blacklist */ private List manifestDigests; - /** The manifest object */ - Manifest man = null; - - public JarVerifier(byte rawBytes[], Manifest man) { - this.man = man; + public JarVerifier(byte rawBytes[]) { manifestRawBytes = rawBytes; - sigFileSigners = new HashMap(); - verifiedSigners = new HashMap(); + sigFileSigners = new Hashtable(); + verifiedSigners = new Hashtable(); + sigFileData = new Hashtable(11); + pendingBlocks = new ArrayList(); + baos = new ByteArrayOutputStream(); manifestDigests = new ArrayList(); } /** - * This method scans to see which entry we're parsing and keeps - * various state information depending on the file being parsed. + * This method scans to see which entry we're parsing and + * keeps various state information depending on what type of + * file is being parsed. */ public void beginEntry(JarEntry je, ManifestEntryVerifier mev) throws IOException @@ -112,6 +129,30 @@ * b. digest mismatch between the actual jar entry and the manifest */ + if (parsingMeta) { + String uname = name.toUpperCase(Locale.ENGLISH); + if ((uname.startsWith("META-INF/") || + uname.startsWith("/META-INF/"))) { + + if (je.isDirectory()) { + mev.setEntry(null, je); + return; + } + + if (SignatureFileVerifier.isBlockOrSF(uname)) { + /* We parse only DSA, RSA or EC PKCS7 blocks. */ + parsingBlockOrSF = true; + baos.reset(); + mev.setEntry(null, je); + } + return; + } + } + + if (parsingMeta) { + doneWithMeta(); + } + if (je.isDirectory()) { mev.setEntry(null, je); return; @@ -147,7 +188,11 @@ throws IOException { if (b != -1) { - mev.update((byte)b); + if (parsingBlockOrSF) { + baos.write(b); + } else { + mev.update((byte)b); + } } else { processEntry(mev); } @@ -162,7 +207,11 @@ throws IOException { if (n != -1) { - mev.update(b, off, n); + if (parsingBlockOrSF) { + baos.write(b, off, n); + } else { + mev.update(b, off, n); + } } else { processEntry(mev); } @@ -174,10 +223,101 @@ private void processEntry(ManifestEntryVerifier mev) throws IOException { - JarEntry je = mev.getEntry(); - if ((je != null) && (je.signers == null)) { - je.signers = mev.verify(verifiedSigners, sigFileSigners); - je.certs = mapSignersToCertArray(je.signers); + if (!parsingBlockOrSF) { + JarEntry je = mev.getEntry(); + if ((je != null) && (je.signers == null)) { + je.signers = mev.verify(verifiedSigners, sigFileSigners); + je.certs = mapSignersToCertArray(je.signers); + } + } else { + + try { + parsingBlockOrSF = false; + + if (debug != null) { + debug.println("processEntry: processing block"); + } + + String uname = mev.getEntry().getName() + .toUpperCase(Locale.ENGLISH); + + if (uname.endsWith(".SF")) { + String key = uname.substring(0, uname.length()-3); + byte bytes[] = baos.toByteArray(); + // add to sigFileData in case future blocks need it + sigFileData.put(key, bytes); + // check pending blocks, we can now process + // anyone waiting for this .SF file + Iterator it = pendingBlocks.iterator(); + while (it.hasNext()) { + SignatureFileVerifier sfv = + (SignatureFileVerifier) it.next(); + if (sfv.needSignatureFile(key)) { + if (debug != null) { + debug.println( + "processEntry: processing pending block"); + } + + sfv.setSignatureFile(bytes); + sfv.process(sigFileSigners, manifestDigests); + } + } + return; + } + + // now we are parsing a signature block file + + String key = uname.substring(0, uname.lastIndexOf(".")); + + if (signerCache == null) + signerCache = new ArrayList(); + + if (manDig == null) { + synchronized(manifestRawBytes) { + if (manDig == null) { + manDig = new ManifestDigester(manifestRawBytes); + manifestRawBytes = null; + } + } + } + + SignatureFileVerifier sfv = + new SignatureFileVerifier(signerCache, + manDig, uname, baos.toByteArray()); + + if (sfv.needSignatureFileBytes()) { + // see if we have already parsed an external .SF file + byte[] bytes = (byte[]) sigFileData.get(key); + + if (bytes == null) { + // put this block on queue for later processing + // since we don't have the .SF bytes yet + // (uname, block); + if (debug != null) { + debug.println("adding pending block"); + } + pendingBlocks.add(sfv); + return; + } else { + sfv.setSignatureFile(bytes); + } + } + sfv.process(sigFileSigners, manifestDigests); + + } catch (IOException ioe) { + // e.g. sun.security.pkcs.ParsingException + if (debug != null) debug.println("processEntry caught: "+ioe); + // ignore and treat as unsigned + } catch (SignatureException se) { + if (debug != null) debug.println("processEntry caught: "+se); + // ignore and treat as unsigned + } catch (NoSuchAlgorithmException nsae) { + if (debug != null) debug.println("processEntry caught: "+nsae); + // ignore and treat as unsigned + } catch (CertificateException ce) { + if (debug != null) debug.println("processEntry caught: "+ce); + // ignore and treat as unsigned + } } } @@ -214,15 +354,15 @@ * Force a read of the entry data to generate the * verification hash. */ - try (InputStream s = jar.getInputStream(entry)) { + try { + InputStream s = jar.getInputStream(entry); byte[] buffer = new byte[1024]; int n = buffer.length; while (n != -1) { n = s.read(buffer, 0, buffer.length); } + s.close(); } catch (IOException e) { - // Ignore. When an exception is thrown, code signer - // will not be assigned. } } return getCodeSigners(name); @@ -268,7 +408,11 @@ */ void doneWithMeta() { + parsingMeta = false; anyToVerify = !sigFileSigners.isEmpty(); + baos = null; + sigFileData = null; + pendingBlocks = null; signerCache = null; manDig = null; // MANIFEST.MF is always treated as signed and verified, @@ -279,41 +423,6 @@ } } - /** - * Verifies a PKCS7 SignedData block - * @param key name of block - * @param block the pkcs7 file - * @param ins the clear data - */ - void verifyBlock(String key, byte[] block, InputStream ins) { - try { - if (signerCache == null) - signerCache = new ArrayList(); - - if (manDig == null) { - synchronized(manifestRawBytes) { - if (manDig == null) { - manDig = new ManifestDigester(manifestRawBytes); - manifestRawBytes = null; - } - } - } - SignatureFileVerifier sfv = - new SignatureFileVerifier(signerCache, man, - manDig, key, block); - - if (sfv.needSignatureFile()) { - // see if we have already parsed an external .SF file - sfv.setSignatureFile(ins); - } - sfv.process(sigFileSigners, manifestDigests); - } catch (Exception e) { - if (debug != null) { - e.printStackTrace(); - } - } - } - static class VerifierStream extends java.io.InputStream { private InputStream is; @@ -444,7 +553,10 @@ * but this handles a CodeSource of any type, just in case. */ CodeSource[] sources = mapSignersToCodeSources(cs.getLocation(), getJarCodeSigners(), true); - List sourceList = Arrays.asList(sources); + List sourceList = new ArrayList(); + for (int i = 0; i < sources.length; i++) { + sourceList.add(sources[i]); + } int j = sourceList.indexOf(cs); if (j != -1) { CodeSigner[] match;
--- a/src/share/classes/sun/print/resources/serviceui_fr.properties Wed May 04 16:39:05 2011 -0700 +++ b/src/share/classes/sun/print/resources/serviceui_fr.properties Thu May 05 22:29:05 2011 -0700 @@ -49,7 +49,7 @@ label.source.mnemonic=C label.status=Statut : label.username=Nom utilisateur : -label.username.mnemonic=U +label.username.mnemonic=O label.millimetres=(mm) label.inches=(po) label.topmargin=haut @@ -62,7 +62,7 @@ label.rightmargin.mnemonic=D # radiobutton.color=Couleur -radiobutton.color.mnemonic=U +radiobutton.color.mnemonic=C radiobutton.draftq=Brouillon radiobutton.draftq.mnemonic=L radiobutton.duplex=Duplex @@ -70,7 +70,7 @@ radiobutton.highq=Max. radiobutton.highq.mnemonic=X radiobutton.landscape=Paysage -radiobutton.landscape.mnemonic=S +radiobutton.landscape.mnemonic=Y radiobutton.monochrome=Monochrome radiobutton.monochrome.mnemonic=M radiobutton.normalq=Normal
--- a/src/share/classes/sun/print/resources/serviceui_pt_BR.properties Wed May 04 16:39:05 2011 -0700 +++ b/src/share/classes/sun/print/resources/serviceui_pt_BR.properties Thu May 05 22:29:05 2011 -0700 @@ -15,10 +15,10 @@ button.ok=OK button.print=Imprimir button.properties=Propriedades... -button.properties.mnemonic=R +button.properties.mnemonic=D # checkbox.collate=Agrupar -checkbox.collate.mnemonic=A +checkbox.collate.mnemonic=R checkbox.jobsheets=P\u00E1gina com Banner checkbox.jobsheets.mnemonic=B checkbox.printtofile=Imprimir em Arquivo @@ -38,7 +38,7 @@ label.numcopies=N\u00FAmero de c\u00F3pias: label.numcopies.mnemonic=O label.priority=Prioridade: -label.priority.mnemonic=R +label.priority.mnemonic=P label.psname=Nome: label.psname.mnemonic=N label.pstype=Tipo: @@ -59,7 +59,7 @@ label.leftmargin=esquerda: label.leftmargin.mnemonic=Q label.rightmargin=direita -label.rightmargin.mnemonic=R +label.rightmargin.mnemonic=D # radiobutton.color=Cor radiobutton.color.mnemonic=O @@ -68,7 +68,7 @@ radiobutton.duplex=Duplex radiobutton.duplex.mnemonic=D radiobutton.highq=Alta -radiobutton.highq.mnemonic=A +radiobutton.highq.mnemonic=T radiobutton.landscape=Paisagem radiobutton.landscape.mnemonic=P radiobutton.monochrome=Monocrom\u00E1tico @@ -76,7 +76,7 @@ radiobutton.normalq=Normal radiobutton.normalq.mnemonic=N radiobutton.oneside=Um Lado -radiobutton.oneside.mnemonic=O +radiobutton.oneside.mnemonic=L radiobutton.portrait=Retrato radiobutton.portrait.mnemonic=R radiobutton.rangeall=Tudo @@ -86,7 +86,7 @@ radiobutton.revlandscape=Paisagem Invertida radiobutton.revlandscape.mnemonic=N radiobutton.revportrait=Retrato Invertido -radiobutton.revportrait.mnemonic=I +radiobutton.revportrait.mnemonic=E radiobutton.tumble=Virar radiobutton.tumble.mnemonic=V # The vkMnemonics correspond with the constants defined in KeyEvent, eg @@ -96,7 +96,7 @@ tab.general=Geral tab.general.vkMnemonic=71 tab.pagesetup=Configura\u00E7\u00E3o de P\u00E1gina -tab.pagesetup.vkMnemonic=80 +tab.pagesetup.vkMnemonic=67 # error.pagerange=Faixa de p\u00E1ginas inv\u00E1lida; insira novamente os valores (por exemplo, 1-3,5,7-10) error.destination=Nome de arquivo inv\u00E1lido; tente novamente
--- a/src/share/classes/sun/security/pkcs/PKCS7.java Wed May 04 16:39:05 2011 -0700 +++ b/src/share/classes/sun/security/pkcs/PKCS7.java Thu May 05 22:29:05 2011 -0700 @@ -38,7 +38,6 @@ import sun.security.util.*; import sun.security.x509.AlgorithmId; import sun.security.x509.CertificateIssuerName; -import sun.security.x509.KeyUsageExtension; import sun.security.x509.X509CertImpl; import sun.security.x509.X509CertInfo; import sun.security.x509.X509CRLImpl; @@ -493,7 +492,7 @@ // CRLs (optional) if (crls != null && crls.length != 0) { // cast to X509CRLImpl[] since X509CRLImpl implements DerEncoder - Set<X509CRLImpl> implCRLs = new HashSet<>(crls.length); + Set<X509CRLImpl> implCRLs = new HashSet<X509CRLImpl>(crls.length); for (X509CRL crl: crls) { if (crl instanceof X509CRLImpl) implCRLs.add((X509CRLImpl) crl); @@ -531,168 +530,6 @@ } /** - * Verifying signed data using an external chunked data source. - */ - public static class PKCS7Verifier { - - private final SignerInfo si; // Signer to verify - private final MessageDigest md; // MessageDigest object for chunks - private final Signature sig; // Signature object for chunks - - private PKCS7Verifier(SignerInfo si, MessageDigest md, Signature sig) { - this.si = si; - this.md = md; - this.sig = sig; - } - - public static PKCS7Verifier from(PKCS7 block, SignerInfo si) throws - SignatureException, NoSuchAlgorithmException { - - try { - MessageDigest md = null; - Signature sig; - - ContentInfo content = block.getContentInfo(); - String digestAlgname = si.getDigestAlgorithmId().getName(); - - // if there are authenticate attributes, feed data chunks to - // the message digest. In this case, pv.md is not null - if (si.authenticatedAttributes != null) { - // first, check content type - ObjectIdentifier contentType = (ObjectIdentifier) - si.authenticatedAttributes.getAttributeValue( - PKCS9Attribute.CONTENT_TYPE_OID); - if (contentType == null || - !contentType.equals(content.contentType)) - return null; // contentType does not match, bad SignerInfo - - // now, check message digest - byte[] messageDigest = (byte[]) - si.authenticatedAttributes.getAttributeValue( - PKCS9Attribute.MESSAGE_DIGEST_OID); - - if (messageDigest == null) // fail if there is no message digest - return null; - - md = MessageDigest.getInstance(digestAlgname); - } - - // put together digest algorithm and encryption algorithm - // to form signing algorithm - String encryptionAlgname = - si.getDigestEncryptionAlgorithmId().getName(); - - // Workaround: sometimes the encryptionAlgname is actually - // a signature name - String tmp = AlgorithmId.getEncAlgFromSigAlg(encryptionAlgname); - if (tmp != null) encryptionAlgname = tmp; - String algname = AlgorithmId.makeSigAlg( - digestAlgname, encryptionAlgname); - - sig = Signature.getInstance(algname); - X509Certificate cert = si.getCertificate(block); - - if (cert == null) { - return null; - } - if (cert.hasUnsupportedCriticalExtension()) { - throw new SignatureException("Certificate has unsupported " - + "critical extension(s)"); - } - - // Make sure that if the usage of the key in the certificate is - // restricted, it can be used for digital signatures. - // XXX We may want to check for additional extensions in the - // future. - boolean[] keyUsageBits = cert.getKeyUsage(); - if (keyUsageBits != null) { - KeyUsageExtension keyUsage; - try { - // We don't care whether or not this extension was marked - // critical in the certificate. - // We're interested only in its value (i.e., the bits set) - // and treat the extension as critical. - keyUsage = new KeyUsageExtension(keyUsageBits); - } catch (IOException ioe) { - throw new SignatureException("Failed to parse keyUsage " - + "extension"); - } - - boolean digSigAllowed = ((Boolean)keyUsage.get( - KeyUsageExtension.DIGITAL_SIGNATURE)).booleanValue(); - - boolean nonRepuAllowed = ((Boolean)keyUsage.get( - KeyUsageExtension.NON_REPUDIATION)).booleanValue(); - - if (!digSigAllowed && !nonRepuAllowed) { - throw new SignatureException("Key usage restricted: " - + "cannot be used for " - + "digital signatures"); - } - } - - PublicKey key = cert.getPublicKey(); - sig.initVerify(key); - return new PKCS7Verifier(si, md, sig); - } catch (IOException e) { - throw new SignatureException("IO error verifying signature:\n" + - e.getMessage()); - - } catch (InvalidKeyException e) { - throw new SignatureException("InvalidKey: " + e.getMessage()); - - } - } - - public void update(byte[] data, int off, int end) - throws SignatureException { - if (md != null) { - md.update(data, off, end-off); - } else { - sig.update(data, off, end-off); - } - } - - public SignerInfo verify() throws SignatureException { - try { - // if there are authenticate attributes, get the message - // digest and compare it with the digest of data - if (md != null) { - // now, check message digest - byte[] messageDigest = (byte[]) - si.authenticatedAttributes.getAttributeValue( - PKCS9Attribute.MESSAGE_DIGEST_OID); - - byte[] computedMessageDigest = md.digest(); - - if (!MessageDigest.isEqual( - messageDigest, computedMessageDigest)) { - return null; - } - - // message digest attribute matched - // digest of original data - - // the data actually signed is the DER encoding of - // the authenticated attributes (tagged with - // the "SET OF" tag, not 0xA0). - byte[] dataSigned = si.authenticatedAttributes.getDerEncoding(); - sig.update(dataSigned); - } - - if (sig.verify(si.getEncryptedDigest())) { - return si; - } - - } catch (IOException e) { - throw new SignatureException("IO error verifying signature:\n" + - e.getMessage()); - } - return null; - } - } - - /** * This verifies a given SignerInfo. * * @param info the signer information. @@ -717,16 +554,19 @@ public SignerInfo[] verify(byte[] bytes) throws NoSuchAlgorithmException, SignatureException { - List<SignerInfo> intResult = new ArrayList<>(); + Vector<SignerInfo> intResult = new Vector<SignerInfo>(); for (int i = 0; i < signerInfos.length; i++) { SignerInfo signerInfo = verify(signerInfos[i], bytes); if (signerInfo != null) { - intResult.add(signerInfo); + intResult.addElement(signerInfo); } } - if (!intResult.isEmpty()) { - return intResult.toArray(new SignerInfo[intResult.size()]); + if (intResult.size() != 0) { + + SignerInfo[] result = new SignerInfo[intResult.size()]; + intResult.copyInto(result); + return result; } return null; }
--- a/src/share/classes/sun/security/pkcs/SignerInfo.java Wed May 04 16:39:05 2011 -0700 +++ b/src/share/classes/sun/security/pkcs/SignerInfo.java Thu May 05 22:29:05 2011 -0700 @@ -230,7 +230,7 @@ if (userCert == null) return null; - ArrayList<X509Certificate> certList = new ArrayList<>(); + ArrayList<X509Certificate> certList = new ArrayList<X509Certificate>(); certList.add(userCert); X509Certificate[] pkcsCerts = block.getCertificates(); @@ -276,20 +276,132 @@ /* Returns null if verify fails, this signerInfo if verify succeeds. */ SignerInfo verify(PKCS7 block, byte[] data) - throws NoSuchAlgorithmException, SignatureException { + throws NoSuchAlgorithmException, SignatureException { + + try { + + ContentInfo content = block.getContentInfo(); + if (data == null) { + data = content.getContentBytes(); + } + + String digestAlgname = getDigestAlgorithmId().getName(); + + byte[] dataSigned; + + // if there are authenticate attributes, get the message + // digest and compare it with the digest of data + if (authenticatedAttributes == null) { + dataSigned = data; + } else { + + // first, check content type + ObjectIdentifier contentType = (ObjectIdentifier) + authenticatedAttributes.getAttributeValue( + PKCS9Attribute.CONTENT_TYPE_OID); + if (contentType == null || + !contentType.equals(content.contentType)) + return null; // contentType does not match, bad SignerInfo + + // now, check message digest + byte[] messageDigest = (byte[]) + authenticatedAttributes.getAttributeValue( + PKCS9Attribute.MESSAGE_DIGEST_OID); + + if (messageDigest == null) // fail if there is no message digest + return null; + + MessageDigest md = MessageDigest.getInstance(digestAlgname); + byte[] computedMessageDigest = md.digest(data); + + if (messageDigest.length != computedMessageDigest.length) + return null; + for (int i = 0; i < messageDigest.length; i++) { + if (messageDigest[i] != computedMessageDigest[i]) + return null; + } + + // message digest attribute matched + // digest of original data + + // the data actually signed is the DER encoding of + // the authenticated attributes (tagged with + // the "SET OF" tag, not 0xA0). + dataSigned = authenticatedAttributes.getDerEncoding(); + } + + // put together digest algorithm and encryption algorithm + // to form signing algorithm + String encryptionAlgname = + getDigestEncryptionAlgorithmId().getName(); - PKCS7.PKCS7Verifier p7v = PKCS7.PKCS7Verifier.from(block, this); - if (p7v == null) return null; - if (data == null) { - try { - data = block.getContentInfo().getContentBytes(); - } catch (IOException e) { - throw new SignatureException("IO error verifying signature:\n" + - e.getMessage()); + // Workaround: sometimes the encryptionAlgname is actually + // a signature name + String tmp = AlgorithmId.getEncAlgFromSigAlg(encryptionAlgname); + if (tmp != null) encryptionAlgname = tmp; + String algname = AlgorithmId.makeSigAlg( + digestAlgname, encryptionAlgname); + + Signature sig = Signature.getInstance(algname); + X509Certificate cert = getCertificate(block); + + if (cert == null) { + return null; + } + if (cert.hasUnsupportedCriticalExtension()) { + throw new SignatureException("Certificate has unsupported " + + "critical extension(s)"); } + + // Make sure that if the usage of the key in the certificate is + // restricted, it can be used for digital signatures. + // XXX We may want to check for additional extensions in the + // future. + boolean[] keyUsageBits = cert.getKeyUsage(); + if (keyUsageBits != null) { + KeyUsageExtension keyUsage; + try { + // We don't care whether or not this extension was marked + // critical in the certificate. + // We're interested only in its value (i.e., the bits set) + // and treat the extension as critical. + keyUsage = new KeyUsageExtension(keyUsageBits); + } catch (IOException ioe) { + throw new SignatureException("Failed to parse keyUsage " + + "extension"); + } + + boolean digSigAllowed = ((Boolean)keyUsage.get( + KeyUsageExtension.DIGITAL_SIGNATURE)).booleanValue(); + + boolean nonRepuAllowed = ((Boolean)keyUsage.get( + KeyUsageExtension.NON_REPUDIATION)).booleanValue(); + + if (!digSigAllowed && !nonRepuAllowed) { + throw new SignatureException("Key usage restricted: " + + "cannot be used for " + + "digital signatures"); + } + } + + PublicKey key = cert.getPublicKey(); + sig.initVerify(key); + + sig.update(dataSigned); + + if (sig.verify(encryptedDigest)) { + return this; + } + + } catch (IOException e) { + throw new SignatureException("IO error verifying signature:\n" + + e.getMessage()); + + } catch (InvalidKeyException e) { + throw new SignatureException("InvalidKey: " + e.getMessage()); + } - p7v.update(data, 0, data.length); - return p7v.verify(); + return null; } /* Verify the content of the pkcs7 block. */
--- a/src/share/classes/sun/security/util/ManifestEntryVerifier.java Wed May 04 16:39:05 2011 -0700 +++ b/src/share/classes/sun/security/util/ManifestEntryVerifier.java Thu May 05 22:29:05 2011 -0700 @@ -191,8 +191,8 @@ * * */ - public CodeSigner[] verify(Map<String, CodeSigner[]> verifiedSigners, - Map<String, CodeSigner[]> sigFileSigners) + public CodeSigner[] verify(Hashtable<String, CodeSigner[]> verifiedSigners, + Hashtable<String, CodeSigner[]> sigFileSigners) throws JarException { if (skip) {
--- a/src/share/classes/sun/security/util/SignatureFileManifest.java Wed May 04 16:39:05 2011 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,251 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.security.util; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; -import java.util.jar.Attributes; -import java.util.jar.Manifest; - -/** - * This class provides streaming mode reading of manifest files. - * Used by {@link SignatureFileVerifier}. - */ -class SignatureFileManifest extends Manifest { - - /* - * Reading a manifest into this object by calling update(byte[]) on chunks. - * During the reading, the bytes are saved in (@code current} until a line - * is complete and the key-value pair is saved in {@code currentAttr}. When - * a section is complete, {@code consumeAttr} is called to merge - * {@code currentAttr} into main attributes or a named entry. - */ - - // Internal state during update() style reading - // 0. not in update mode - // 1, in update mode but main attributes not completed yet - // 2. main attributes completed, still reading the entries - private int state = 0; - - // The partial line read - private byte[] current; - - // Number of bytes in current - private int currentPos = 0; - - // The current Attribute - private Attributes currentAttr; - - /** - * Reads a manifest in chunks. - * <p> - * This method must be called in a row, reading chunks from a single - * manifest file by order. After all chunks are read, caller must call - * {@code update(null)} to fully consume the manifest. - * <p> - * The entry names and attributes read will be merged in with the current - * manifest entries. The {@link #read} method cannot be called inside a - * row of update calls. - * <p> - * Along with the calls, caller can call {@link #getMainAttributes()}, - * {@link #getAttributes(java.lang.String)} or {@link #getEntries()} - * to get already available contents. However, in order not to return - * partial result, when the main attributes in the new manifest is not - * consumed completely, {@link #getMainAttributes()} throws an - * {@code IllegalStateException}. When a certain named entry is not - * consumed completely, {@link #getAttributes(java.lang.String)} - * returns the old {@code Attributes} for the name (if it exists). - * - * @param data null for last call, otherwise, feeding chunks - * @param offset offset into data to begin read - * @param length length of data after offset to read - * @exception IOException if an I/O error has occurred - * @exception IllegalStateException if {@code update(null)} is called - * without any previous {@code update(non-null)} call - */ - public void update(byte[] data, int offset, int length) throws IOException { - - // The last call - if (data == null) { - if (state == 0) { - throw new IllegalStateException("No data to update"); - } - // We accept manifest not ended with \n or \n\n - if (hasLastByte()) { - consumeCurrent(); - } - // We accept empty lines at the end - if (!currentAttr.isEmpty()) { - consumeAttr(); - } - state = 0; // back to non-update state - current = null; - currentAttr = null; - return; - } - - // The first call - if (state == 0) { - current = new byte[1024]; - currentAttr = super.getMainAttributes(); // the main attribute - state = 1; - } - - int end = offset + length; - - while (offset < end) { - switch (data[offset]) { - case '\r': - break; // always skip - case '\n': - if (hasLastByte() && lastByte() == '\n') { // new section - consumeCurrent(); - consumeAttr(); - if (state == 1) { - state = 2; - } - currentAttr = new Attributes(2); - } else { - if (hasLastByte()) { - // save \n into current but do not parse, - // there might be a continuation later - ensureCapacity(); - current[currentPos++] = data[offset]; - } else if (state == 1) { - // there can be multiple empty lines between - // sections, but cannot be at the beginning - throw new IOException("invalid manifest format"); - } - } - break; - case ' ': - if (!hasLastByte()) { - throw new IOException("invalid manifest format"); - } else if (lastByte() == '\n') { - currentPos--; // continuation, remove last \n - } else { // a very normal ' ' - ensureCapacity(); - current[currentPos++] = data[offset]; - } - break; - default: - if (hasLastByte() && lastByte() == '\n') { - // The start of a new pair, not continuation - consumeCurrent(); // the last line read - } - ensureCapacity(); - current[currentPos++] = data[offset]; - break; - } - offset++; - } - } - - /** - * Returns the main Attributes for the Manifest. - * @exception IllegalStateException the main attributes is being read - * @return the main Attributes for the Manifest - */ - public Attributes getMainAttributes() { - if (state == 1) { - throw new IllegalStateException(); - } - return super.getMainAttributes(); - } - - /** - * Reads the Manifest from the specified InputStream. The entry - * names and attributes read will be merged in with the current - * manifest entries. - * - * @param is the input stream - * @exception IOException if an I/O error has occurred - * @exception IllegalStateException if called between two {@link #update} - * calls - */ - public void read(InputStream is) throws IOException { - if (state != 0) { - throw new IllegalStateException("Cannot call read between updates"); - } - super.read(is); - } - - /* - * ---------- Helper methods ----------------- - */ - - private void ensureCapacity() { - if (currentPos >= current.length-1) { - current = Arrays.copyOf(current, current.length*2); - } - } - - private boolean hasLastByte() { - return currentPos > 0; - } - - private byte lastByte() { - return current[currentPos-1]; - } - - // Parse current as key:value and save into currentAttr. - // There MUST be something inside current. - private void consumeCurrent() throws IOException { - // current normally has a \n end, except for the last line - if (current[currentPos-1] == '\n') currentPos--; - for (int i=0; i<currentPos; i++) { - if (current[i] == ':') { - String key = new String(current, 0, 0, i); - i++; - while (i < currentPos && current[i] == ' ') { i++; } - String value = new String(current, i, currentPos-i, "UTF-8"); - currentAttr.putValue(key, value); - currentPos = 0; - return; - } - } - throw new IOException("invalid header field"); - } - - // Merge currentAttr into Manifest - private void consumeAttr() throws IOException { - // Only needed for named entries. For the main attribute, key/value - // is added into attr directly, but since getMainAttributes() throws - // an exception, the partial data is not leaked. - if (state != 1) { - String name = currentAttr.getValue("Name"); - if (name != null) { - currentAttr.remove(new Attributes.Name("Name")); - Attributes old = getAttributes(name); - if (old != null) old.putAll(currentAttr); - else getEntries().put(name, currentAttr); - } else { - throw new IOException("invalid manifest format"); - } - } - } -}
--- a/src/share/classes/sun/security/util/SignatureFileVerifier.java Wed May 04 16:39:05 2011 -0700 +++ b/src/share/classes/sun/security/util/SignatureFileVerifier.java Thu May 05 22:29:05 2011 -0700 @@ -55,8 +55,8 @@ /** the PKCS7 block for this .DSA/.RSA/.EC file */ private PKCS7 block; - // the content of the raw .SF file as an InputStream - private InputStream sfStream; + /** the raw bytes of the .SF file */ + private byte sfBytes[]; /** the name of the signature block file, uppercased and without * the extension (.DSA/.RSA/.EC) @@ -66,9 +66,6 @@ /** the ManifestDigester */ private ManifestDigester md; - /** The MANIFEST.MF */ - private Manifest man; - /** cache of created MessageDigest objects */ private HashMap<String, MessageDigest> createdDigests; @@ -86,7 +83,6 @@ * @param rawBytes the raw bytes of the signature block file */ public SignatureFileVerifier(ArrayList<CodeSigner[]> signerCache, - Manifest man, ManifestDigester md, String name, byte rawBytes[]) @@ -98,18 +94,13 @@ try { obj = Providers.startJarVerification(); block = new PKCS7(rawBytes); - byte[] contentData = block.getContentInfo().getData(); - if (contentData != null) { - sfStream = new ByteArrayInputStream(contentData); - } + sfBytes = block.getContentInfo().getData(); certificateFactory = CertificateFactory.getInstance("X509"); } finally { Providers.stopJarVerification(obj); } this.name = name.substring(0, name.lastIndexOf(".")) .toUpperCase(Locale.ENGLISH); - - this.man = man; this.md = md; this.signerCache = signerCache; } @@ -117,13 +108,31 @@ /** * returns true if we need the .SF file */ - public boolean needSignatureFile() + public boolean needSignatureFileBytes() { - return sfStream == null; + + return sfBytes == null; } - public void setSignatureFile(InputStream ins) { - this.sfStream = ins; + + /** + * returns true if we need this .SF file. + * + * @param name the name of the .SF file without the extension + * + */ + public boolean needSignatureFile(String name) + { + return this.name.equalsIgnoreCase(name); + } + + /** + * used to set the raw bytes of the .SF file when it + * is external to the signature block file. + */ + public void setSignatureFile(byte sfBytes[]) + { + this.sfBytes = sfBytes; } /** @@ -136,18 +145,12 @@ * Signature File or PKCS7 block file name */ public static boolean isBlockOrSF(String s) { - return s.endsWith(".SF") || isBlock(s); - } - - /** - * Utility method used by JarVerifier to determine PKCS7 block - * files names that are supported - * - * @param s file name - * @return true if the input file name is a PKCS7 block file name - */ - public static boolean isBlock(String s) { - return s.endsWith(".DSA") || s.endsWith(".RSA") || s.endsWith(".EC"); + // we currently only support DSA and RSA PKCS7 blocks + if (s.endsWith(".SF") || s.endsWith(".DSA") || + s.endsWith(".RSA") || s.endsWith(".EC")) { + return true; + } + return false; } /** get digest from cache */ @@ -177,7 +180,7 @@ * * */ - public void process(Map<String, CodeSigner[]> signers, + public void process(Hashtable<String, CodeSigner[]> signers, List manifestDigests) throws IOException, SignatureException, NoSuchAlgorithmException, JarException, CertificateException @@ -194,86 +197,31 @@ } - private void processImpl(Map<String, CodeSigner[]> signers, + private void processImpl(Hashtable<String, CodeSigner[]> signers, List manifestDigests) throws IOException, SignatureException, NoSuchAlgorithmException, JarException, CertificateException { - SignatureFileManifest sf = new SignatureFileManifest(); - InputStream ins = sfStream; + Manifest sf = new Manifest(); + sf.read(new ByteArrayInputStream(sfBytes)); - byte[] buffer = new byte[4096]; - int sLen = block.getSignerInfos().length; - boolean mainOK = false; // main attributes of SF is available... - boolean manifestSigned = false; // and it matches MANIFEST.MF - BASE64Decoder decoder = new BASE64Decoder(); + String version = + sf.getMainAttributes().getValue(Attributes.Name.SIGNATURE_VERSION); - PKCS7.PKCS7Verifier[] pvs = new PKCS7.PKCS7Verifier[sLen]; - for (int i=0; i<sLen; i++) { - pvs[i] = PKCS7.PKCS7Verifier.from(block, block.getSignerInfos()[i]); + if ((version == null) || !(version.equalsIgnoreCase("1.0"))) { + // XXX: should this be an exception? + // for now we just ignore this signature file + return; } - /* - * Verify SF in streaming mode. The chunks of the file are fed into - * the Manifest object sf and all PKCS7Verifiers. As soon as the main - * attributes is available, we'll check if manifestSigned is true. If - * yes, there is no need to fill in sf's entries field, since it should - * be identical to entries in man. - */ - while (true) { - int len = ins.read(buffer); - if (len < 0) { - if (!manifestSigned) { - sf.update(null, 0, 0); - } - break; - } else { - for (int i=0; i<sLen; i++) { - if (pvs[i] != null) pvs[i].update(buffer, 0, len); - } - // Continue reading if verifyManifestHash fails (or, the - // main attributes is not available yet) - if (!manifestSigned) { - sf.update(buffer, 0, len); - if (!mainOK) { - try { - Attributes attr = sf.getMainAttributes(); - String version = attr.getValue( - Attributes.Name.SIGNATURE_VERSION); + SignerInfo[] infos = block.verify(sfBytes); - if ((version == null) || - !(version.equalsIgnoreCase("1.0"))) { - // XXX: should this be an exception? - // for now we just ignore this signature file - return; - } - - mainOK = true; - manifestSigned = verifyManifestHash( - sf, md, decoder, manifestDigests); - } catch (IllegalStateException ise) { - // main attributes not available yet - } - } - } - } - } - List<SignerInfo> intResult = new ArrayList<>(sLen); - for (int i = 0; i < sLen; i++) { - if (pvs[i] != null) { - SignerInfo signerInfo = pvs[i].verify(); - if (signerInfo != null) { - intResult.add(signerInfo); - } - } - } - if (intResult.isEmpty()) { + if (infos == null) { throw new SecurityException("cannot verify signature block file " + name); } - SignerInfo[] infos = - intResult.toArray(new SignerInfo[intResult.size()]); + BASE64Decoder decoder = new BASE64Decoder(); CodeSigner[] newSigners = getSigners(infos, block); @@ -281,37 +229,26 @@ if (newSigners == null) return; + Iterator<Map.Entry<String,Attributes>> entries = + sf.getEntries().entrySet().iterator(); + + // see if we can verify the whole manifest first + boolean manifestSigned = verifyManifestHash(sf, md, decoder, manifestDigests); + // verify manifest main attributes if (!manifestSigned && !verifyManifestMainAttrs(sf, md, decoder)) { throw new SecurityException ("Invalid signature file digest for Manifest main attributes"); } - Iterator<Map.Entry<String,Attributes>> entries; - - if (manifestSigned) { - if (debug != null) { - debug.println("full manifest signature match, " - + "update signer info from MANIFEST.MF"); - } - entries = man.getEntries().entrySet().iterator(); - } else { - if (debug != null) { - debug.println("full manifest signature unmatch, " - + "update signer info from SF file"); - } - entries = sf.getEntries().entrySet().iterator(); - } - - // go through each section - + // go through each section in the signature file while(entries.hasNext()) { Map.Entry<String,Attributes> e = entries.next(); String name = e.getKey(); if (manifestSigned || - (verifySection(e.getValue(), name, md, decoder))) { + (verifySection(e.getValue(), name, md, decoder))) { if (name.startsWith("./")) name = name.substring(2); @@ -656,6 +593,7 @@ if (set == subset) return true; + boolean match; for (int i = 0; i < subset.length; i++) { if (!contains(set, subset[i])) return false; @@ -675,6 +613,8 @@ if ((oldSigners == null) && (signers == newSigners)) return true; + boolean match; + // make sure all oldSigners are in signers if ((oldSigners != null) && !isSubSet(oldSigners, signers)) return false; @@ -698,7 +638,7 @@ } void updateSigners(CodeSigner[] newSigners, - Map<String, CodeSigner[]> signers, String name) { + Hashtable<String, CodeSigner[]> signers, String name) { CodeSigner[] oldSigners = signers.get(name);
--- a/test/java/util/jar/JarInputStream/ScanSignedJar.java Wed May 04 16:39:05 2011 -0700 +++ b/test/java/util/jar/JarInputStream/ScanSignedJar.java Thu May 05 22:29:05 2011 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,11 +27,9 @@ * @summary Confirm that JarEntry.getCertificates identifies signed entries. */ -import java.io.*; import java.net.URL; import java.security.CodeSigner; import java.security.cert.Certificate; -import java.util.Enumeration; import java.util.jar.*; /* @@ -72,6 +70,9 @@ if (signers == null && certificates == null) { System.out.println("[unsigned]\t" + name + "\t(" + size + " bytes)"); + if (name.equals("Count.class")) { + throw new Exception("Count.class should be signed"); + } } else if (signers != null && certificates != null) { System.out.println("[" + signers.length + (signers.length == 1 ? " signer" : " signers") + "]\t" +
--- a/test/java/util/jar/JarInputStream/TestIndexedJarWithBadSignature.java Wed May 04 16:39:05 2011 -0700 +++ b/test/java/util/jar/JarInputStream/TestIndexedJarWithBadSignature.java Thu May 05 22:29:05 2011 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ public static void main(String...args) throws Throwable { try (JarInputStream jis = new JarInputStream( - new FileInputStream(System.getProperty("tst.src", ".") + + new FileInputStream(System.getProperty("test.src", ".") + System.getProperty("file.separator") + "BadSignedJar.jar"))) {