diff --git a/.hgtags b/.hgtags index c0dcf6c4b8da306cf744af8a227b6dff1b40f823..69b70ae869aa9ecf5482f32393e03e8c11ce9447 100644 --- a/.hgtags +++ b/.hgtags @@ -571,6 +571,7 @@ c44179bce874a97e93ffd7b76a226af417e017a4 jdk8u77-b03 71f59a00df6c8f3bd5c6d6631a4988a431adab56 jdk8u91-b00 7ade7a1ab10ff893f62cce9440b4a839aa19c250 jdk8u91-b13 f8725698a870b6be82fad578e78a55910b259975 jdk8u91-b14 +29380f4d81bd92a6a7aa7a984ca4541ff3ac3a67 jdk8u91-b15 39baa472e20c13c0eb1243eb5dce589e82f78143 jdk8u76-b00 6ea3aea950d19d803475b3f4d704a2942e71b302 jdk8u76-b01 4de4cffb5988cd68959ce4bbd14c6d4547078c91 jdk8u76-b02 @@ -592,4 +593,32 @@ f6cc9dbb5db5883385c91bb71ca02081220aaf3d jdk8u81-b00 00f8f39308687cde45f23282871c46cc6c2f10b3 jdk8u101-b01 6042757c329b1b96fa6bc931e09306794f5c50c0 jdk8u101-b02 25934d0d38fe10383ff22eb3f39bf5e8b9e73ac9 jdk8u101-b03 +ebc56c2e803597ef409a5296addc986b390d934d jdk8u101-b04 +c387bd2fb7db40467bd9aa803c8510a04ca32bae jdk8u101-b05 +a15cdf2e91e7c2d71510280b31ae11048fb2f31e jdk8u101-b06 +fdc0b30af431e17ffaed24ef5d545ae4cf7ddf6d jdk8u101-b07 +4dc4099e933a6f4584b51305b26b5798f042699b jdk8u101-b08 +5e7489ac05f0001e234e6d1c8730b465e74c9626 jdk8u101-b09 +9486707c119ab3940f7ea06c1af23a4f6367c77b jdk8u101-b10 +a9136f8d24d9ed01009df847176e0be67b354d15 jdk8u101-b11 +3eab3ce82c31d1332bc383a1a3201eaee220c001 jdk8u101-b12 +39baa472e20c13c0eb1243eb5dce589e82f78143 jdk8u76-b00 +6ea3aea950d19d803475b3f4d704a2942e71b302 jdk8u76-b01 +4de4cffb5988cd68959ce4bbd14c6d4547078c91 jdk8u76-b02 +8bef978e2374604f449b4d1d7f90cb26618540d7 jdk8u76-b03 +e057622070e5415c13b6d8511b97dce8bd2e398d jdk8u76-b04 +fa5a91b29658aa9eb7aff54ae34898c149ff7149 jdk8u102-b00 +fa5a91b29658aa9eb7aff54ae34898c149ff7149 jdk8u82-b00 +569e105bed3c517a47f0f1ebce0abcaf776a8e89 jdk8u102-b01 +5d5b55014d0da5bafb42366dc6d668ced4b8dec4 jdk8u102-b02 +abab8d5270997ad25e0699151eed48ce8db40787 jdk8u102-b03 +50809de3dcc24eb8cf86b8518cf0cc0423b61f4b jdk8u102-b04 +cdfb600c2dce889af220ebb6c4b0764066baa741 jdk8u102-b05 +59698da7972e97f4a18845b9c879f165b3c52e98 jdk8u102-b06 +725b400c93e0209c64f36f6191b8d1fd3ef9ed30 jdk8u102-b07 +c260a0aab5bff09f439914829b81f037715029bb jdk8u102-b08 +605340e782425b68342c1bc6485b747708de6101 jdk8u102-b09 +b64716a25e409798fcd7ed6143d55681ee4a4baa jdk8u102-b10 +e915a408ebf7ba05b36d1b714e166a1d9e5c7edd jdk8u102-b11 +8e12cb096db33b525ec010de5e857ef1cc985ddd jdk8u102-b12 ebc56c2e803597ef409a5296addc986b390d934d jdk8u111-b00 diff --git a/make/CopyIntoClasses.gmk b/make/CopyIntoClasses.gmk index d46363ceb986dd877314d7f98df0622424a9b13f..10c4f94fe020d7673f7640c5fd1b2704e7b1ffc7 100644 --- a/make/CopyIntoClasses.gmk +++ b/make/CopyIntoClasses.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2016, 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 @@ -190,7 +190,11 @@ ifdef OPENJDK SRC_SERVICES_FILES := $(filter-out %sun/java2d/cmm/kcms/META-INF/services/sun.java2d.cmm.CMMServiceProvider, $(SRC_SERVICES_FILES)) else SRC_SERVICES_FILES := $(filter-out %sun/java2d/pisces/META-INF/services/sun.java2d.pipe.RenderingEngine, $(SRC_SERVICES_FILES)) - SRC_SERVICES_FILES := $(filter-out %sun/java2d/cmm/lcms/META-INF/services/sun.java2d.cmm.CMMServiceProvider, $(SRC_SERVICES_FILES)) + ifeq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU_ARCH), linux-sparc) + SRC_SERVICES_FILES := $(filter-out %sun/java2d/cmm/kcms/META-INF/services/sun.java2d.cmm.CMMServiceProvider, $(SRC_SERVICES_FILES)) + else + SRC_SERVICES_FILES := $(filter-out %sun/java2d/cmm/lcms/META-INF/services/sun.java2d.cmm.CMMServiceProvider, $(SRC_SERVICES_FILES)) + endif endif # The number of services files are relatively few. If the increase in numbers, then diff --git a/make/data/tzdata/VERSION b/make/data/tzdata/VERSION index 55966f28162b4dd55673e9ced22d9c041c68c48b..5aaf0c5889296ddc5968f91c248a3892f92dcb51 100644 --- a/make/data/tzdata/VERSION +++ b/make/data/tzdata/VERSION @@ -21,4 +21,4 @@ # or visit www.oracle.com if you need additional information or have any # questions. # -tzdata2016a +tzdata2016d diff --git a/make/data/tzdata/asia b/make/data/tzdata/asia index 056a5f9c5523b95e64f1ff76ee75708fc5831a0c..58b43e9965576f2bb9a7ee8ee0e97da5c9fb3c76 100644 --- a/make/data/tzdata/asia +++ b/make/data/tzdata/asia @@ -102,13 +102,9 @@ Rule E-EurAsia 1979 1995 - Sep lastSun 0:00 0 - Rule E-EurAsia 1996 max - Oct lastSun 0:00 0 - Rule RussiaAsia 1981 1984 - Apr 1 0:00 1:00 S Rule RussiaAsia 1981 1983 - Oct 1 0:00 0 - -Rule RussiaAsia 1984 1991 - Sep lastSun 2:00s 0 - -Rule RussiaAsia 1985 1991 - Mar lastSun 2:00s 1:00 S -Rule RussiaAsia 1992 only - Mar lastSat 23:00 1:00 S -Rule RussiaAsia 1992 only - Sep lastSat 23:00 0 - -Rule RussiaAsia 1993 max - Mar lastSun 2:00s 1:00 S -Rule RussiaAsia 1993 1995 - Sep lastSun 2:00s 0 - -Rule RussiaAsia 1996 max - Oct lastSun 2:00s 0 - +Rule RussiaAsia 1984 1995 - Sep lastSun 2:00s 0 - +Rule RussiaAsia 1985 2011 - Mar lastSun 2:00s 1:00 S +Rule RussiaAsia 1996 2011 - Oct lastSun 2:00s 0 - # Afghanistan # Zone NAME GMTOFF RULES FORMAT [UNTIL] @@ -148,17 +144,26 @@ Zone Asia/Yerevan 2:58:00 - LMT 1924 May 2 3:00 1:00 YERST 1991 Sep 23 # independence 3:00 RussiaAsia AM%sT 1995 Sep 24 2:00s 4:00 - AMT 1997 - 4:00 RussiaAsia AM%sT 2012 Mar 25 2:00s + 4:00 RussiaAsia AM%sT 2012 Feb 9 4:00 - AMT # Azerbaijan + # From Rustam Aliyev of the Azerbaijan Internet Forum (2005-10-23): # According to the resolution of Cabinet of Ministers, 1997 # From Paul Eggert (2015-09-17): It was Resolution No. 21 (1997-03-17). # http://code.az/files/daylight_res.pdf + +# From Steffen Thorsen (2016-03-17): +# ... the Azerbaijani Cabinet of Ministers has cancelled switching to +# daylight saving time.... +# http://www.azernews.az/azerbaijan/94137.html +# http://vestnikkavkaza.net/news/Azerbaijani-Cabinet-of-Ministers-cancels-daylight-saving-time.html +# http://en.apa.az/xeber_azerbaijan_abolishes_daylight_savings_ti_240862.html + # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S -Rule Azer 1997 max - Mar lastSun 4:00 1:00 S -Rule Azer 1997 max - Oct lastSun 5:00 0 - +Rule Azer 1997 2015 - Mar lastSun 4:00 1:00 S +Rule Azer 1997 2015 - Oct lastSun 5:00 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Asia/Baku 3:19:24 - LMT 1924 May 2 3:00 - BAKT 1957 Mar # Baku Time @@ -1581,23 +1586,6 @@ Zone Asia/Amman 2:23:44 - LMT 1931 # Kazakhstan -# From Paul Eggert (1996-11-22): -# Andrew Evtichov (1996-04-13) writes that Kazakhstan -# stayed in sync with Moscow after 1990, and that Aqtobe (formerly Aktyubinsk) -# and Aqtau (formerly Shevchenko) are the largest cities in their zones. -# Guess that Aqtau and Aqtobe diverged in 1995, since that's the first time -# IATA SSIM mentions a third time zone in Kazakhstan. - -# From Paul Eggert (2006-03-22): -# German Iofis, ELSI, Almaty (2001-10-09) reports that Kazakhstan uses -# RussiaAsia rules, instead of switching at 00:00 as the IATA has it. -# Go with Shanks & Pottenger, who have them always using RussiaAsia rules. -# Also go with the following claims of Shanks & Pottenger: -# -# - Kazakhstan did not observe DST in 1991. -# - Qyzylorda switched from +5:00 to +6:00 on 1992-01-19 02:00. -# - Oral switched from +5:00 to +4:00 in spring 1989. - # From Kazakhstan Embassy's News Bulletin No. 11 # (2005-03-21): # The Government of Kazakhstan passed a resolution March 15 abolishing @@ -1614,61 +1602,232 @@ Zone Asia/Amman 2:23:44 - LMT 1931 # everything else.... I guess that would make Kazakhstan time zones # de jure UTC+5 and UTC+6 respectively. +# From Stepan Golosunov (2016-03-27) ([*] means see later comments below): +# Review of the linked documents from http://adilet.zan.kz/ +# produced the following data for post-1991 Kazakhstan: +# +# 0. Act of the Cabinet of Ministers of the USSR +# from 1991-02-04 No. 20 +# http://pravo.gov.ru/proxy/ips/?docbody=&nd=102010545 +# removed the extra hour ("decree time") on the territory of the USSR +# starting with the last Sunday of March 1991. +# It also allowed (but not mandated) Kazakh SSR, Kirghiz SSR, Tajik SSR, +# Turkmen SSR and Uzbek SSR to not have "summer" time. +# +# The 1992-01-13 act also refers to the act of the Cabinet of Ministers +# of the Kazakh SSR from 1991-03-20 No. 170 "About the act of the Cabinet +# of Ministers of the USSR from 1991-02-04 No. 20" but I didn't found its +# text. +# +# According to Izvestia newspaper No. 68 (23334) from 1991-03-20 +# (page 6; available at http://libinfo.org/newsr/newsr2574.djvu via +# http://libinfo.org/index.php?id=58564) on 1991-03-31 at 2:00 during +# transition to "summer" time: +# Republic of Georgia, Latvian SSR, Lithuanian SSR, SSR Moldova, +# Estonian SSR; Komi ASSR; Kaliningrad oblast; Nenets autonomous okrug +# were to move clocks 1 hour forward. +# Kazakh SSR (excluding Uralsk oblast); Republic of Kyrgyzstan, Tajik +# SSR; Andijan, Jizzakh, Namangan, Sirdarya, Tashkent, Fergana oblasts +# of the Uzbek SSR were to move clocks 1 hour backwards. +# Other territories were to not move clocks. +# When the "summer" time would end on 1991-09-29, clocks were to be +# moved 1 hour backwards on the territory of the USSR excluding +# Kazakhstan, Kirghizia, Uzbekistan, Turkmenia, Tajikistan. +# +# Apparently there were last minute changes. Apparently Kazakh act No. 170 +# was one of such changes. +# +# https://ru.wikipedia.org/wiki/Декретное время +# claims that Sovetskaya Rossiya newspaper on 1991-03-29 published that +# Nenets autonomous okrug, Komi and Kazakhstan (excluding Uralsk oblast) +# were to not move clocks and Uralsk oblast was to move clocks +# forward; on 1991-09-29 Kazakhstan was to move clocks backwards. +# (Probably there were changes even after that publication. There is an +# article claiming that Kaliningrad oblast decided on 1991-03-29 to not +# move clocks.) +# +# This implies that on 1991-03-31 Asia/Oral remained on +04/+05 while +# the rest of Kazakhstan switched from +06/+07 to +05/06 or from +05/06 +# to +04/+05. It's unclear how Kzyl-Orda oblast moved into the fifth +# time belt. (By switching from +04/+05 to +05/+06 on 1991-09-29?) ... +# +# 1. Act of the Cabinet of Ministers of the Republic of Kazakhstan +# from 1992-01-13 No. 28 +# http://adilet.zan.kz/rus/docs/P920000028_ +# (text includes modification from the 1996 act) +# introduced new rules for calculation of time, mirroring Russian +# 1992-01-08 act. It specified that time would be calculated +# according to time belts plus extra hour ("decree time"), moved clocks +# on the whole territory of Kazakhstan 1 hour forward on 1992-01-19 at +# 2:00, specified DST rules. It acknowledged that Kazakhstan was +# located in the fourth and the fifth time belts and specified the +# border between them to be located east of Kustanay and Aktyubinsk +# oblasts (notably including Turgai and Kzyl-Orda oblasts into the fifth +# time belt). +# +# This means switch on 1992-01-19 at 2:00 from +04/+05 to +05/+06 for +# Asia/Aqtau, Asia/Aqtobe, Asia/Oral, Atyrau and Kustanay oblasts; from +# +05/+06 to +06/+07 for Asia/Almaty and Asia/Qyzylorda (and Arkalyk) [*].... +# +# 2. Act of the Cabinet of Ministers of the Republic of Kazakhstan +# from 1992-03-27 No. 284 +# http://adilet.zan.kz/rus/docs/P920000284_ +# cancels extra hour ("decree time") for Uralsk and Kzyl-Orda oblasts +# since the last Sunday of March 1992, while keeping them in the fourth +# and the fifth time belts respectively. +# +# 3. Order of the Prime Minister of the Republic of Kazakhstan +# from 1994-09-23 No. 384 +# http://adilet.zan.kz/rus/docs/R940000384_ +# cancels the extra hour ("decree time") on the territory of Mangystau +# oblast since the last Sunday of September 1994 (saying that time on +# the territory would correspond to the third time belt as a +# result).... +# +# 4. Act of the Government of the Republic of Kazakhstan +# from 1996-05-08 No. 575 +# http://adilet.zan.kz/rus/docs/P960000575_ +# amends the 1992-01-13 act to end summer time in October instead +# of September, mirroring identical Russian change from 1996-04-23 act. +# +# 5. Act of the Government of the Republic of Kazakhstan +# from 1999-03-26 No. 305 +# http://adilet.zan.kz/rus/docs/P990000305_ +# cancels the extra hour ("decree time") for Atyrau oblast since the +# last Sunday of March 1999 while retaining the oblast in the fourth +# time belt. +# +# This means change from +05/+06 to +04/+05. +# +# There is no zone for Atyrau currently (listed under Asia/Aqtau in +# zone1970.tab).[*] +# +# 6. Act of the Government of the Republic of Kazakhstan +# from 2000-11-23 No. 1749 +# http://adilet.zan.kz/rus/archive/docs/P000001749_/23.11.2000 +# replaces the previous five documents. +# +# The only changes I noticed are in definition of the border between the +# fourth and the fifth time belts. They account for changes in spelling +# and administrative division (splitting of Turgai oblast in 1997 +# probably changed time in territories incorporated into Kostanay oblast +# (including Arkalyk) from +06/+07 to +05/+06) and move Kyzylorda oblast +# from being in the fifth time belt and not using decree time into the +# fourth time belt (no change in practice).[*] +# +# 7. Act of the Government of the Republic of Kazakhstan +# from 2003-12-29 No. 1342 +# http://adilet.zan.kz/rus/docs/P030001342_ +# modified the 2000-11-23 act. No relevant changes, apparently. +# +# 8. Act of the Government of the Republic of Kazakhstan +# from 2004-07-20 No. 775 +# http://adilet.zan.kz/rus/archive/docs/P040000775_/20.07.2004 +# modified the 2000-11-23 act to move Kostanay and Kyzylorda oblasts into +# the fifth time belt and add Aktobe oblast to the list of regions not +# using extra hour ("decree time"), leaving Kazakhstan with only 2 time +# zones (+04/+05 and +06/+07). The changes were to be implemented +# during DST transitions in 2004 and 2005 but the acts got radically +# amended before implementation happened. +# +# 9. Act of the Government of the Republic of Kazakhstan +# from 2004-09-15 No. 1059 +# http://adilet.zan.kz/rus/docs/P040001059_ +# modified the 2000-11-23 act to remove exceptions from the "decree time" +# (leaving Kazakhstan in +05/+06 and +06/+07 zones), amended the +# 2004-07-20 act to implement changes for Atyrau, West Kazakhstan, +# Kostanay, Kyzylorda and Mangystau oblasts by not moving clocks +# during the 2014 transition to "winter" time. +# +# This means transition from +04/+05 to +05/+06 for Atyrau oblast (no +# zone currently), Asia/Oral, Asia/Aqtau and transition from +05/+06 to +# +06/+07 for Kostanay oblast (Kostanay and Arkalyk, no zones currently) +# and Asia/Qyzylorda on 2004-10-31 at 3:00....[*] +# +# 10. Act of the Government of the Republic of Kazakhstan +# from 2005-03-15 No. 231 +# http://adilet.zan.kz/rus/docs/P050000231_ +# removes DST provisions from the 2000-11-23 act, removes most of the +# (already implemented) provisions from the 2004-07-20 and 2004-09-15 +# acts, comes into effect 10 days after official publication. +# The only practical effect seems to be the abolition of the summer +# time. +# +# Unamended version of the act of the Government of the Russian Federation +# No. 23 from 1992-01-08 [See 'europe' file for details]. +# Kazakh 1992-01-13 act appears to provide the same rules and 1992-03-27 +# act was to be enacted on the last Sunday of March 1992. + +# From Paul Eggert (2016-04-15): +# The tables below should reflect Stepan Golosunov's remarks above, +# except for the items marked "[*]" which I haven't gotten to yet. +# It looks like we will need new zones Asia/Atyrau and Asia/Qostanay +# to handle changes from 1992 through 2004 that we did not previously +# know about. + # # Zone NAME GMTOFF RULES FORMAT [UNTIL] # # Almaty (formerly Alma-Ata), representing most locations in Kazakhstan +# This includes KZ-AKM, KZ-ALA, KZ-ALM, KZ-AST, KZ-BAY, KZ-VOS, KZ-ZHA, +# KZ-KAR, KZ-SEV, KZ-PAV, and KZ-YUZ. Zone Asia/Almaty 5:07:48 - LMT 1924 May 2 # or Alma-Ata - 5:00 - ALMT 1930 Jun 21 # Alma-Ata Time - 6:00 RussiaAsia ALM%sT 1991 - 6:00 - ALMT 1992 - 6:00 RussiaAsia ALM%sT 2005 Mar 15 - 6:00 - ALMT -# Qyzylorda (aka Kyzylorda, Kizilorda, Kzyl-Orda, etc.) + 5:00 - +05 1930 Jun 21 + 6:00 RussiaAsia +06/+07 1991 Mar 31 2:00s + 5:00 RussiaAsia +05/+06 1992 Jan 19 2:00s + 6:00 RussiaAsia +06/+07 2004 Oct 31 2:00s + 6:00 - +06 +# Qyzylorda (aka Kyzylorda, Kizilorda, Kzyl-Orda, etc.) (KZ-KZY) Zone Asia/Qyzylorda 4:21:52 - LMT 1924 May 2 - 4:00 - KIZT 1930 Jun 21 # Kizilorda Time - 5:00 - KIZT 1981 Apr 1 - 5:00 1:00 KIZST 1981 Oct 1 - 6:00 - KIZT 1982 Apr 1 - 5:00 RussiaAsia KIZ%sT 1991 - 5:00 - KIZT 1991 Dec 16 # independence - 5:00 - QYZT 1992 Jan 19 2:00 - 6:00 RussiaAsia QYZ%sT 2005 Mar 15 - 6:00 - QYZT -# Aqtobe (aka Aktobe, formerly Aktyubinsk) + 4:00 - +04 1930 Jun 21 + 5:00 - +05 1981 Apr 1 + 5:00 1:00 +06 1981 Oct 1 + 6:00 - +06 1982 Apr 1 + 5:00 RussiaAsia +05/+06 1991 Mar 31 2:00s + 4:00 RussiaAsia +04/+05 1991 Sep 29 2:00s + 5:00 RussiaAsia +05/+06 1992 Jan 19 2:00s + 6:00 RussiaAsia +06/+07 1992 Mar 29 2:00s + 5:00 RussiaAsia +05/+06 2004 Oct 31 2:00s + 6:00 - +06 +# Aqtobe (aka Aktobe, formerly Aktyubinsk) (KZ-AKT) Zone Asia/Aqtobe 3:48:40 - LMT 1924 May 2 - 4:00 - AKTT 1930 Jun 21 # Aktyubinsk Time - 5:00 - AKTT 1981 Apr 1 - 5:00 1:00 AKTST 1981 Oct 1 - 6:00 - AKTT 1982 Apr 1 - 5:00 RussiaAsia AKT%sT 1991 - 5:00 - AKTT 1991 Dec 16 # independence - 5:00 RussiaAsia AQT%sT 2005 Mar 15 # Aqtobe Time - 5:00 - AQTT -# Mangghystau + 4:00 - +04 1930 Jun 21 + 5:00 - +05 1981 Apr 1 + 5:00 1:00 +06 1981 Oct 1 + 6:00 - +06 1982 Apr 1 + 5:00 RussiaAsia +05/+06 1991 Mar 31 2:00s + 4:00 RussiaAsia +04/+05 1992 Jan 19 2:00s + 5:00 RussiaAsia +05/+06 2004 Oct 31 2:00s + 5:00 - +05 +# Qostanay (KZ-KUS) + +# Mangghystau (KZ-MAN) # Aqtau was not founded until 1963, but it represents an inhabited region, # so include time stamps before 1963. Zone Asia/Aqtau 3:21:04 - LMT 1924 May 2 - 4:00 - FORT 1930 Jun 21 # Fort Shevchenko T - 5:00 - FORT 1963 - 5:00 - SHET 1981 Oct 1 # Shevchenko Time - 6:00 - SHET 1982 Apr 1 - 5:00 RussiaAsia SHE%sT 1991 - 5:00 - SHET 1991 Dec 16 # independence - 5:00 RussiaAsia AQT%sT 1995 Mar lastSun 2:00 # Aqtau Time - 4:00 RussiaAsia AQT%sT 2005 Mar 15 - 5:00 - AQTT -# West Kazakhstan + 4:00 - +04 1930 Jun 21 + 5:00 - +05 1963 + 5:00 - +05 1981 Oct 1 + 6:00 - +06 1982 Apr 1 + 5:00 RussiaAsia +05/+06 1991 Mar 31 2:00s + 4:00 RussiaAsia +04/+05 1992 Jan 19 2:00s + 5:00 RussiaAsia +05/+06 1994 Sep 25 2:00s + 4:00 RussiaAsia +04/+05 2004 Oct 31 2:00s + 5:00 - +05 + +# West Kazakhstan (KZ-ZAP) +# From Paul Eggert (2016-03-18): +# The 1989 transition is from USSR act No. 227 (1989-03-14). Zone Asia/Oral 3:25:24 - LMT 1924 May 2 # or Ural'sk - 4:00 - URAT 1930 Jun 21 # Ural'sk time - 5:00 - URAT 1981 Apr 1 - 5:00 1:00 URAST 1981 Oct 1 - 6:00 - URAT 1982 Apr 1 - 5:00 RussiaAsia URA%sT 1989 Mar 26 2:00 - 4:00 RussiaAsia URA%sT 1991 - 4:00 - URAT 1991 Dec 16 # independence - 4:00 RussiaAsia ORA%sT 2005 Mar 15 # Oral Time - 5:00 - ORAT + 4:00 - +04 1930 Jun 21 + 5:00 - +05 1981 Apr 1 + 5:00 1:00 +06 1981 Oct 1 + 6:00 - +06 1982 Apr 1 + 5:00 RussiaAsia +05/+06 1989 Mar 26 2:00s + 4:00 RussiaAsia +04/+05 1992 Jan 19 2:00s + 5:00 RussiaAsia +05/+06 1992 Mar 29 2:00s + 4:00 RussiaAsia +04/+05 2004 Oct 31 2:00s + 5:00 - +05 # Kyrgyzstan (Kirgizstan) # Transitions through 1991 are from Shanks & Pottenger. @@ -2419,6 +2578,16 @@ Zone Asia/Karachi 4:28:12 - LMT 1907 # http://www.timeanddate.com/time/change/gaza-strip/gaza # http://www.timeanddate.com/time/change/west-bank/hebron +# From Hannah Kreitem (2016-03-09): +# http://www.palestinecabinet.gov.ps/WebSite/ar/ViewDetails?ID=31728 +# [Google translation]: "The Council also decided to start daylight +# saving in Palestine as of one o'clock on Saturday morning, +# 2016-03-26, to provide the clock 60 minutes ahead." +# +# From Paul Eggert (2016-03-12): +# Predict spring transitions on March's last Saturday at 01:00 from now on. +# Leave fall predictions alone for now. + # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule EgyptAsia 1957 only - May 10 0:00 1:00 S Rule EgyptAsia 1957 1958 - Oct 1 0:00 0 - @@ -2447,7 +2616,8 @@ Rule Palestine 2012 2014 - Mar lastThu 24:00 1:00 S Rule Palestine 2012 only - Sep 21 1:00 0 - Rule Palestine 2013 only - Sep Fri>=21 0:00 0 - Rule Palestine 2014 max - Oct Fri>=21 0:00 0 - -Rule Palestine 2015 max - Mar lastFri 24:00 1:00 S +Rule Palestine 2015 only - Mar lastFri 24:00 1:00 S +Rule Palestine 2016 max - Mar lastSat 1:00 1:00 S # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Asia/Gaza 2:17:52 - LMT 1900 Oct diff --git a/make/data/tzdata/australasia b/make/data/tzdata/australasia index 09afef2d401ad5f82d941372fd5d9952321467eb..929124cc04880f01d14bc2b6910ac0bc4b26a966 100644 --- a/make/data/tzdata/australasia +++ b/make/data/tzdata/australasia @@ -83,6 +83,14 @@ Zone Australia/Eucla 8:35:28 - LMT 1895 Dec # Hamilton is the largest, but there is also a Hamilton in Victoria, # so use Lindeman. # +# From J William Piggott (2016-02-20): +# There is no location named Holiday Islands in Queensland Australia; holiday +# islands is a colloquial term used globally. Hayman and Lindeman are at the +# north and south extremes of the Whitsunday Islands archipelago, and +# Hamilton is in between; it is reasonable to believe that this time zone +# applies to all of the Whitsundays. +# http://www.australia.gov.au/about-australia/australian-story/austn-islands +# # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule AQ 1971 only - Oct lastSun 2:00s 1:00 D Rule AQ 1972 only - Feb lastSun 2:00s 0 S diff --git a/make/data/tzdata/europe b/make/data/tzdata/europe index 267992150ce26d19f1c92123af4a9bd36491a9d1..00a9fffa39da5ba11ccb236831b010aa87673794 100644 --- a/make/data/tzdata/europe +++ b/make/data/tzdata/europe @@ -623,16 +623,40 @@ Rule Russia 1981 1984 - Apr 1 0:00 1:00 S Rule Russia 1981 1983 - Oct 1 0:00 0 - # Act No. 967 of the Council of Ministers of the USSR (1984-09-13), repeated in # Act No. 227 of the Council of Ministers of the USSR (1989-03-14): -Rule Russia 1984 1991 - Sep lastSun 2:00s 0 - -Rule Russia 1985 1991 - Mar lastSun 2:00s 1:00 S +Rule Russia 1984 1995 - Sep lastSun 2:00s 0 - +Rule Russia 1985 2010 - Mar lastSun 2:00s 1:00 S # -Rule Russia 1992 only - Mar lastSat 23:00 1:00 S -Rule Russia 1992 only - Sep lastSat 23:00 0 - -Rule Russia 1993 2010 - Mar lastSun 2:00s 1:00 S -Rule Russia 1993 1995 - Sep lastSun 2:00s 0 - Rule Russia 1996 2010 - Oct lastSun 2:00s 0 - # As described below, Russia's 2014 change affects Zone data, not Rule data. +# From Stepan Golosunov (2016-03-07): +# Wikipedia and other sources refer to the Act of the Council of +# Ministers of the USSR from 1988-01-04 No. 5 and the Act of the +# Council of Ministers of the USSR from 1989-03-14 No. 227. +# +# I did not find full texts of these acts. For the 1989 one we have +# title at http://base.garant.ru/70754136/ : +# "About change in calculation of time on the territories of +# Lithuanian SSR, Latvian SSR and Estonian SSR, Astrakhan, +# Kaliningrad, Kirov, Kuybyshev, Ulyanovsk and Uralsk oblasts". +# And http://astrozet.net/files/Zones/DOC/RU/1980-925.txt appears to +# contain quotes from both acts: Since last Sunday of March 1988 rules +# of the second time belt are installed in Volgograd and Saratov +# oblasts. Since last Sunday of March 1989: +# a) Lithuanian SSR, Latvian SSR, Estonian SSR, Kaliningrad oblast: +# second time belt rules without extra hour (Moscow-1); +# b) Astrakhan, Kirov, Kuybyshev, Ulyanovsk oblasts: second time belt +# rules (Moscow time) +# c) Uralsk oblast: third time belt rules (Moscow+1). + +# From Stepan Golosunov (2016-03-27): +# Unamended version of the act of the +# Government of the Russian Federation No. 23 from 08.01.1992 +# http://pravo.gov.ru/proxy/ips/?docbody=&nd=102014034&rdk=0 +# says that every year clocks were to be moved forward on last Sunday +# of March at 2 hours and moved backwards on last Sunday of September +# at 3 hours. It was amended in 1996 to replace September with October. + # From Alexander Krivenyshev (2011-06-14): # According to Kremlin press service, Russian President Dmitry Medvedev # signed a federal law "On calculation of time" on June 9, 2011. @@ -1028,6 +1052,12 @@ Zone Atlantic/Faroe -0:27:04 - LMT 1908 Jan 11 # Tórshavn # startkart.no says Thule does not observe DST, but this is clearly an error, # so go with Shanks & Pottenger for Thule transitions until this year. # For 2007 on assume Thule will stay in sync with US DST rules. + +# From J William Piggott (2016-02-20): +# "Greenland north of the community of Scoresbysund" is officially named +# "National Park" by Executive Order: +# http://naalakkersuisut.gl/~/media/Nanoq/Files/Attached%20Files/Engelske-tekster/Legislation/Executive%20Order%20National%20Park.rtf +# It is their only National Park. # # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Thule 1991 1992 - Mar lastSun 2:00 1:00 D @@ -1053,6 +1083,10 @@ Zone America/Thule -4:35:08 - LMT 1916 Jul 28 # Pituffik air base -4:00 Thule A%sT # Estonia +# +# From Paul Eggert (2016-03-18): +# The 1989 transition is from USSR act No. 227 (1989-03-14). +# # From Peter Ilieve (1994-10-15): # A relative in Tallinn confirms the accuracy of the data for 1989 onwards # [through 1994] and gives the legal authority for it, @@ -1646,6 +1680,9 @@ Link Europe/Zurich Europe/Vaduz # Lithuania +# From Paul Eggert (2016-03-18): +# The 1989 transition is from USSR act No. 227 (1989-03-14). + # From Paul Eggert (1996-11-22): # IATA SSIM (1992/1996) says Lithuania uses W-Eur rules, but since it is # known to be wrong about Estonia and Latvia, assume it's wrong here too. @@ -1685,8 +1722,8 @@ Zone Europe/Vilnius 1:41:16 - LMT 1880 1:00 - CET 1940 Aug 3 3:00 - MSK 1941 Jun 24 1:00 C-Eur CE%sT 1944 Aug - 3:00 Russia MSK/MSD 1991 Mar 31 2:00s - 2:00 1:00 EEST 1991 Sep 29 2:00s + 3:00 Russia MSK/MSD 1989 Mar 26 2:00s + 2:00 Russia EE%sT 1991 Sep 29 2:00s 2:00 C-Eur EE%sT 1998 2:00 - EET 1998 Mar 29 1:00u 1:00 EU CE%sT 1999 Oct 31 1:00u @@ -1751,6 +1788,16 @@ Zone Europe/Malta 0:58:04 - LMT 1893 Nov 2 0:00s # Valletta # Moldova +# From Stepan Golosunov (2016-03-07): +# the act of the government of the Republic of Moldova Nr. 132 from 1990-05-04 +# http://lex.justice.md/viewdoc.php?action=view&view=doc&id=298782&lang=2 +# ... says that since 1990-05-06 on the territory of the Moldavian SSR +# time would be calculated as the standard time of the second time belt +# plus one hour of the "summer" time. To implement that clocks would be +# adjusted one hour backwards at 1990-05-06 2:00. After that "summer" +# time would be cancelled last Sunday of September at 3:00 and +# reintroduced last Sunday of March at 2:00. + # From Paul Eggert (2006-03-22): # A previous version of this database followed Shanks & Pottenger, who write # that Tiraspol switched to Moscow time on 1992-01-19 at 02:00. @@ -1809,9 +1856,7 @@ Zone Europe/Chisinau 1:55:20 - LMT 1880 2:00 Romania EE%sT 1940 Aug 15 2:00 1:00 EEST 1941 Jul 17 1:00 C-Eur CE%sT 1944 Aug 24 - 3:00 Russia MSK/MSD 1990 - 3:00 - MSK 1990 May 6 - 2:00 - EET 1991 + 3:00 Russia MSK/MSD 1990 May 6 2:00 2:00 Russia EE%sT 1992 2:00 E-Eur EE%sT 1997 # See Romania commentary for the guessed 1997 transition to EU rules. @@ -2289,16 +2334,32 @@ Zone Europe/Bucharest 1:44:24 - LMT 1891 Oct # Europe/Kaliningrad covers... # 39 RU-KGD Kaliningrad Oblast +# From Paul Eggert (2016-03-18): +# The 1989 transition is from USSR act No. 227 (1989-03-14). + +# From Stepan Golosunov (2016-03-07): +# http://www.rgo.ru/ru/kaliningradskoe-oblastnoe-otdelenie/ob-otdelenii/publikacii/kak-nam-zhilos-bez-letnego-vremeni +# confirms that the 1989 change to Moscow-1 was implemented. +# (The article, though, is misattributed to 1990 while saying that +# summer->winter transition would be done on the 24 of September. But +# 1990-09-24 was Monday, while 1989-09-24 was Sunday as expected.) +# ... +# http://www.kaliningradka.ru/site_pc/cherez/index.php?ELEMENT_ID=40091 +# says that Kaliningrad switched to Moscow-1 on 1989-03-26, avoided +# at the last moment switch to Moscow-1 on 1991-03-31, switched to +# Moscow on 1991-11-03, switched to Moscow-1 on 1992-01-19. + Zone Europe/Kaliningrad 1:22:00 - LMT 1893 Apr 1:00 C-Eur CE%sT 1945 2:00 Poland CE%sT 1946 - 3:00 Russia MSK/MSD 1991 Mar 31 2:00s + 3:00 Russia MSK/MSD 1989 Mar 26 2:00s 2:00 Russia EE%sT 2011 Mar 27 2:00s 3:00 - FET 2014 Oct 26 2:00s 2:00 - EET -# From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2001-08-25): +# From Paul Eggert (2016-02-21), per Tim Parenti (2014-07-03) and +# Oscar van Vlijmen (2001-08-25): # Europe/Moscow covers... # 01 RU-AD Adygea, Republic of # 05 RU-DA Dagestan, Republic of @@ -2341,12 +2402,92 @@ Zone Europe/Kaliningrad 1:22:00 - LMT 1893 Apr # 68 RU-TAM Tambov Oblast # 69 RU-TVE Tver Oblast # 71 RU-TUL Tula Oblast -# 73 RU-ULY Ulyanovsk Oblast # 76 RU-YAR Yaroslavl Oblast # 77 RU-MOW Moscow # 78 RU-SPE Saint Petersburg # 83 RU-NEN Nenets Autonomous Okrug +# From Stepan Golosunov (2016-03-07): +# 11. Regions-violators, 1981-1982. +# Wikipedia refers to +# http://maps.monetonos.ru/maps/raznoe/Old_Maps/Old_Maps/Articles/022/3_1981.html +# http://besp.narod.ru/nauka_1981_3.htm +# +# The second link provides two articles scanned from the Nauka i Zhizn +# magazine No. 3, 1981 and a scan of the short article attributed to +# the Trud newspaper from February 1982. The first link provides the +# same Nauka i Zhizn articles converted to the text form (but misses +# time belt changes map). +# +# The second Nauka i Zhizn article says that in addition to +# introduction of summer time on 1981-04-01 there are some time belt +# border changes on 1981-10-01, mostly affecting Nenets Autonomous +# Okrug, Krasnoyarsk Krai, Yakutia, Magadan Oblast and Chukotka +# according to the provided map (colored one). In addition to that +# "time violators" (regions which were not using rules of the time +# belts in which they were located) would not be moving off the DST on +# 1981-10-01 to restore the decree time usage. (Komi ASSR was +# supposed to repeat that move in October 1982 to account for the 2 +# hour difference.) Map depicting "time violators" before 1981-10-01 +# is also provided. +# +# The article from Trud says that 1981-10-01 changes caused problems +# and some territories would be moved to pre-1981-10-01 time by not +# moving to summer time on 1982-04-01. Namely: Dagestan, +# Kabardino-Balkar, Kalmyk, Komi, Mari, Mordovian, North Ossetian, +# Tatar, Chechen-Ingush and Chuvash ASSR, Krasnodar and Stavropol +# krais, Arkhangelsk, Vladimir, Vologda, Voronezh, Gorky, Ivanovo, +# Kostroma, Lipetsk, Penza, Rostov, Ryazan, Tambov, Tyumen and +# Yaroslavl oblasts, Nenets and Evenk autonomous okrugs, Khatangsky +# district of Taymyr Autonomous Okrug. As a result Evenk Autonomous +# Okrug and Khatangsky district of Taymyr Autonomous Okrug would end +# up on Moscow+4, Tyumen Oblast on Moscow+2 and the rest on Moscow +# time. +# +# http://astrozet.net/files/Zones/DOC/RU/1980-925.txt +# attributes the 1982 changes to the Act of the Council of Ministers +# of the USSR No. 126 from 18.02.1982. 1980-925.txt also adds +# Udmurtia to the list of affected territories and lists Khatangsky +# district separately from Taymyr Autonomous Okurg. Probably erroneously. +# +# The affected territories are currently listed under Europe/Moscow, +# Asia/Yekaterinburg and Asia/Krasnoyarsk. +# +# 12. Udmurtia +# The fact that Udmurtia is depicted as a violator in the Nauka i +# Zhizn article hints at Izhevsk being on different time from +# Kuybyshev before 1981-10-01. Udmurtia is not mentioned in the 1989 act. +# http://astrozet.net/files/Zones/DOC/RU/1980-925.txt +# implies Udmurtia was on Moscow time after 1982-04-01. +# Wikipedia implies Udmurtia being on Moscow+1 until 1991. +# +# ... +# +# All Russian zones are supposed to have by default a -1 change at +# 1991-03-31 2:00 (cancellation of the decree time in the USSR) and a +1 +# change at 1992-01-19 2:00 (restoration of the decree time in Russia). +# +# There were some exceptions, though. +# Wikipedia says newspapers listed Astrakhan, Saratov, Kirov, Volgograd, +# Izhevsk, Grozny, Kazan and Samara as such exceptions for the 1992 +# change. (Different newspapers providing different lists. And some +# lists found in the internet are quite wild.) +# +# And apparently some exceptions were reverted in the last moment. +# http://www.kaliningradka.ru/site_pc/cherez/index.php?ELEMENT_ID=40091 +# says that Kaliningrad decided not to be an exception 2 days before the +# 1991-03-31 switch and one person at +# http://izhevsk.ru/forum_light_message/50/682597-m8369040.html +# says he remembers that Samara opted out of the 1992-01-19 exception +# 2 days before the switch. +# +# +# From Paul Eggert (2016-03-18): +# Given the above, we appear to be missing some Zone entries for the +# chaotic early 1980s in Russia. It's not clear what these entries +# should be. For now, sweep this under the rug and just document the +# time in Moscow. + # From Vladimir Karpinsky (2014-07-08): # LMT in Moscow (before Jul 3, 1916) is 2:30:17, that was defined by Moscow # Observatory (coordinates: 55 deg. 45'29.70", 37 deg. 34'05.30").... @@ -2420,47 +2561,102 @@ Zone Europe/Simferopol 2:16:24 - LMT 1880 3:00 - MSK -# From Tim Parenti (2014-07-03): -# Europe/Volgograd covers... +# From Paul Eggert (2016-03-18): +# Europe/Astrakhan covers: # 30 RU-AST Astrakhan Oblast +# +# The 1989 transition is from USSR act No. 227 (1989-03-14). + +# From Alexander Krivenyshev (2016-01-12): +# On February 10, 2016 Astrakhan Oblast got approval by the Federation +# Council to change its time zone to UTC+4 (from current UTC+3 Moscow time).... +# This Federal Law shall enter into force on 27 March 2016 at 02:00. +# From Matt Johnson (2016-03-09): +# http://publication.pravo.gov.ru/Document/View/0001201602150056 + +Zone Europe/Astrakhan 3:12:12 - LMT 1924 May + 3:00 - +03 1930 Jun 21 + 4:00 Russia +04/+05 1989 Mar 26 2:00s + 3:00 Russia +03/+04 1991 Mar 31 2:00s + 4:00 - +04 1992 Mar 29 2:00s + 3:00 Russia +03/+04 2011 Mar 27 2:00s + 4:00 - +04 2014 Oct 26 2:00s + 3:00 - +03 2016 Mar 27 2:00s + 4:00 - +04 + +# From Paul Eggert (2016-03-18): +# Europe/Volgograd covers: # 34 RU-VGG Volgograd Oblast -# 43 RU-KIR Kirov Oblast # 64 RU-SAR Saratov Oblast - -# From Paul Eggert (2006-05-09): -# Shanks & Pottenger say Kirov is still at +0400 but Wikipedia says +0300. -# Perhaps it switched after the others? But we have no data. +# The 1988 transition is from USSR act No. 5 (1988-01-04). Zone Europe/Volgograd 2:57:40 - LMT 1920 Jan 3 3:00 - TSAT 1925 Apr 6 # Tsaritsyn Time 3:00 - STAT 1930 Jun 21 # Stalingrad Time 4:00 - STAT 1961 Nov 11 - 4:00 Russia VOL%sT 1989 Mar 26 2:00s # Volgograd T + 4:00 Russia VOL%sT 1988 Mar 27 2:00s # Volgograd T 3:00 Russia VOL%sT 1991 Mar 31 2:00s 4:00 - VOLT 1992 Mar 29 2:00s 3:00 Russia MSK/MSD 2011 Mar 27 2:00s 4:00 - MSK 2014 Oct 26 2:00s 3:00 - MSK +# From Paul Eggert (2016-03-18): +# Europe/Kirov covers: +# 43 RU-KIR Kirov Oblast +# The 1989 transition is from USSR act No. 227 (1989-03-14). +# +Zone Europe/Kirov 3:18:48 - LMT 1919 Jul 1 2:00 + 3:00 - +03 1930 Jun 21 + 4:00 Russia +04/+05 1989 Mar 26 2:00s + 3:00 Russia +03/+04 1991 Mar 31 2:00s + 4:00 - +04 1992 Mar 29 2:00s + 3:00 Russia +03/+04 2011 Mar 27 2:00s + 4:00 - +04 2014 Oct 26 2:00s + 3:00 - +03 # From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2001-08-25): # Europe/Samara covers... # 18 RU-UD Udmurt Republic # 63 RU-SAM Samara Oblast +# From Paul Eggert (2016-03-18): # Byalokoz 1919 says Samara was 3:20:20. +# The 1989 transition is from USSR act No. 227 (1989-03-14). Zone Europe/Samara 3:20:20 - LMT 1919 Jul 1 2:00 - 3:00 - SAMT 1930 Jun 21 + 3:00 - SAMT 1930 Jun 21 # Samara Time 4:00 - SAMT 1935 Jan 27 4:00 Russia KUY%sT 1989 Mar 26 2:00s # Kuybyshev 3:00 Russia MSK/MSD 1991 Mar 31 2:00s 2:00 Russia EE%sT 1991 Sep 29 2:00s - 3:00 - KUYT 1991 Oct 20 3:00 - 4:00 Russia SAM%sT 2010 Mar 28 2:00s # Samara Time + 3:00 - SAMT 1991 Oct 20 3:00 + 4:00 Russia SAM%sT 2010 Mar 28 2:00s 3:00 Russia SAM%sT 2011 Mar 27 2:00s 4:00 - SAMT +# From Paul Eggert (2016-03-18): +# Europe/Ulyanovsk covers: +# 73 RU-ULY Ulyanovsk Oblast + +# The 1989 transition is from USSR act No. 227 (1989-03-14). + +# From Alexander Krivenyshev (2016-02-17): +# Ulyanovsk ... on their way to change time zones by March 27, 2016 at 2am. +# Ulyanovsk Oblast ... from MSK to MSK+1 (UTC+3 to UTC+4) ... +# 920582-6 ... 02/17/2016 The State Duma passed the bill in the first reading. +# From Matt Johnson (2016-03-09): +# http://publication.pravo.gov.ru/Document/View/0001201603090051 + +Zone Europe/Ulyanovsk 3:13:36 - LMT 1919 Jul 1 2:00 + 3:00 - +03 1930 Jun 21 + 4:00 Russia +04/+05 1989 Mar 26 2:00s + 3:00 Russia +03/+04 1991 Mar 31 2:00s + 2:00 Russia +02/+03 1992 Jan 19 2:00s + 3:00 Russia +03/+04 2011 Mar 27 2:00s + 4:00 - +04 2014 Oct 26 2:00s + 3:00 - +03 2016 Mar 27 2:00s + 4:00 - +04 # From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2001-08-25): # Asia/Yekaterinburg covers... @@ -2494,8 +2690,6 @@ Zone Asia/Yekaterinburg 4:02:33 - LMT 1916 Jul 3 # From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2001-08-25): # Asia/Omsk covers... -# 04 RU-AL Altai Republic -# 22 RU-ALT Altai Krai # 55 RU-OMS Omsk Oblast # Byalokoz 1919 says Omsk was 4:53:30. @@ -2508,14 +2702,49 @@ Zone Asia/Omsk 4:53:30 - LMT 1919 Nov 14 7:00 - OMST 2014 Oct 26 2:00s 6:00 - OMST +# From Paul Eggert (2016-02-22): +# Asia/Barnaul covers: +# 04 RU-AL Altai Republic +# 22 RU-ALT Altai Krai -# From Tim Parenti (2014-07-03): -# Asia/Novosibirsk covers... +# Data before 1991 are from Shanks & Pottenger. + +# From Stepan Golosunov (2016-03-07): +# Letter of Bank of Russia from 1995-05-25 +# http://www.bestpravo.ru/rossijskoje/lj-akty/y3a.htm +# suggests that Altai Republic transitioned to Moscow+3 on +# 1995-05-28. +# +# http://regnum.ru/news/society/1957270.html +# has some historical data for Altai Krai: +# before 1957: west part on UTC+6, east on UTC+7 +# after 1957: UTC+7 +# since 1995: UTC+6 +# http://barnaul.rusplt.ru/index/pochemu_altajskij_kraj_okazalsja_v_neprivychnom_chasovom_pojase-17648.html +# confirms that and provides more details including 1995-05-28 transition date. + +# From Alexander Krivenyshev (2016-02-17): +# Altai Krai and Altai Republic on their way to change time zones +# by March 27, 2016 at 2am.... +# Altai Republic / Gorno-Altaysk MSK+3 to MSK+4 (UTC+6 to UTC+7) ... +# Altai Krai / Barnaul MSK+3 to MSK+4 (UTC+6 to UTC+7) +# From Matt Johnson (2016-03-09): +# http://publication.pravo.gov.ru/Document/View/0001201603090043 +# http://publication.pravo.gov.ru/Document/View/0001201603090038 + +Zone Asia/Barnaul 5:35:00 - LMT 1919 Dec 10 + 6:00 - +06 1930 Jun 21 + 7:00 Russia +07/+08 1991 Mar 31 2:00s + 6:00 Russia +06/+07 1992 Jan 19 2:00s + 7:00 Russia +07/+08 1995 May 28 + 6:00 Russia +06/+07 2011 Mar 27 2:00s + 7:00 - +07 2014 Oct 26 2:00s + 6:00 - +06 2016 Mar 27 2:00s + 7:00 - +07 + +# From Paul Eggert (2016-03-18): +# Asia/Novosibirsk covers: # 54 RU-NVS Novosibirsk Oblast -# 70 RU-TOM Tomsk Oblast - -# From Paul Eggert (2006-08-19): I'm guessing about Tomsk here; it's -# not clear when it switched from +7 to +6. Zone Asia/Novosibirsk 5:31:40 - LMT 1919 Dec 14 6:00 6:00 - NOVT 1930 Jun 21 # Novosibirsk Time @@ -2526,6 +2755,55 @@ Zone Asia/Novosibirsk 5:31:40 - LMT 1919 Dec 14 6:00 7:00 - NOVT 2014 Oct 26 2:00s 6:00 - NOVT +# From Paul Eggert (2016-03-18): +# Asia/Tomsk covers: +# 70 RU-TOM Tomsk Oblast + +# From Stepan Golosunov (2016-03-24): +# Byalokoz listed Tomsk at 5:39:51. + +# From Stanislaw A. Kuzikowski (1994-06-29): +# Tomsk is still 4 hours ahead of Moscow. + +# From Stepan Golosunov (2016-03-19): +# http://pravo.gov.ru/proxy/ips/?docbody=&nd=102075743 +# (fifth time belt being UTC+5+1(decree time) +# / UTC+5+1(decree time)+1(summer time)) ... +# Note that time belts (numbered from 2 (Moscow) to 12 according to their +# GMT/UTC offset and having too many exceptions like regions formally +# belonging to one belt but using time from another) were replaced +# with time zones in 2011 with different numberings (there was a +# 2-hour gap between second and third zones in 2011-2014). + +# From Stepan Golosunov (2016-04-12): +# http://asozd2.duma.gov.ru/main.nsf/(SpravkaNew)?OpenAgent&RN=1006865-6 +# This bill was approved in the first reading today. It moves Tomsk oblast +# from UTC+6 to UTC+7 and is supposed to come into effect on 2016-05-29 at +# 2:00. The bill needs to be approved in the second and the third readings by +# the State Duma, approved by the Federation Council, signed by the President +# and published to become a law. Minor changes in the text are to be expected +# before the second reading (references need to be updated to account for the +# recent changes). +# +# Judging by the ultra-short one-day amendments period, recent similar laws, +# the State Duma schedule and the Federation Council schedule +# http://www.duma.gov.ru/legislative/planning/day-shedule/por_vesna_2016/ +# http://council.gov.ru/activity/meetings/schedule/63303 +# I speculate that the final text of the bill will be proposed tomorrow, the +# bill will be approved in the second and the third readings on Friday, +# approved by the Federation Council on 2016-04-20, signed by the President and +# published as a law around 2016-04-26. + +Zone Asia/Tomsk 5:39:51 - LMT 1919 Dec 22 + 6:00 - +06 1930 Jun 21 + 7:00 Russia +07/+08 1991 Mar 31 2:00s + 6:00 Russia +06/+07 1992 Jan 19 2:00s + 7:00 Russia +07/+08 2002 May 1 3:00 + 6:00 Russia +06/+07 2011 Mar 27 2:00s + 7:00 - +07 2014 Oct 26 2:00s + 6:00 - +06 2016 May 29 2:00s + 7:00 - +07 + # From Tim Parenti (2014-07-03): # Asia/Novokuznetsk covers... @@ -2549,9 +2827,6 @@ Zone Asia/Novosibirsk 5:31:40 - LMT 1919 Dec 14 6:00 # # Thus, when Russia will switch to DST on the night of March 28, 2010 # Kemerovo region (Kemerovo oblast') will not change the clock. -# -# As a result, Kemerovo oblast' will be in the same time zone as -# Novosibirsk, Omsk, Tomsk, Barnaul and Altai Republic. # From Tim Parenti (2014-07-02), per Alexander Krivenyshev (2014-07-02): # The Kemerovo region will remain at UTC+7 through the 2014-10-26 change, thus @@ -2620,7 +2895,7 @@ Zone Asia/Irkutsk 6:57:05 - LMT 1880 # [The] time zone in the Trans-Baikal Territory (Zabaykalsky Krai) - # Asia/Chita [is changing] from UTC+8 to UTC+9. Effective date will # be March 27, 2016 at 2:00am.... -# http://publication.pravo.gov.ru/Document/View/000120151230010 +# http://publication.pravo.gov.ru/Document/View/0001201512300107 Zone Asia/Chita 7:33:52 - LMT 1919 Dec 15 8:00 - YAKT 1930 Jun 21 # Yakutsk Time @@ -2731,6 +3006,11 @@ Zone Asia/Khandyga 9:02:13 - LMT 1919 Dec 15 # ...with the exception of: # 65-11 **** Severo-Kurilsky District (North Kuril Islands) +# From Matt Johnson (2016-02-22): +# Asia/Sakhalin is moving (in entirety) from UTC+10 to UTC+11 ... +# (2016-03-09): +# http://publication.pravo.gov.ru/Document/View/0001201603090044 + # The Zone name should be Asia/Yuzhno-Sakhalinsk, but that's too long. Zone Asia/Sakhalin 9:30:48 - LMT 1905 Aug 23 9:00 - JCST 1937 Oct 1 @@ -2740,7 +3020,8 @@ Zone Asia/Sakhalin 9:30:48 - LMT 1905 Aug 23 11:00 Russia SAK%sT 1997 Mar lastSun 2:00s 10:00 Russia SAK%sT 2011 Mar 27 2:00s 11:00 - SAKT 2014 Oct 26 2:00s - 10:00 - SAKT + 10:00 - SAKT 2016 Mar 27 2:00s + 11:00 - SAKT # From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2009-11-29): @@ -2754,13 +3035,22 @@ Zone Asia/Sakhalin 9:30:48 - LMT 1905 Aug 23 # until now by Asia/Magadan, will instead move to UTC+11. These regions will # need their own zone. +# From Alexander Krivenyshev (2016-03-27): +# ... draft bill 948300-6 to change its time zone from UTC+10 to UTC+11 ... +# will take ... effect ... on April 24, 2016 at 2 o'clock +# +# From Matt Johnson (2016-04-05): +# ... signed by the President today ... +# http://publication.pravo.gov.ru/Document/View/0001201604050038 + Zone Asia/Magadan 10:03:12 - LMT 1924 May 2 10:00 - MAGT 1930 Jun 21 # Magadan Time 11:00 Russia MAG%sT 1991 Mar 31 2:00s 10:00 Russia MAG%sT 1992 Jan 19 2:00s 11:00 Russia MAG%sT 2011 Mar 27 2:00s 12:00 - MAGT 2014 Oct 26 2:00s - 10:00 - MAGT + 10:00 - MAGT 2016 Apr 24 2:00s + 11:00 - MAGT # From Tim Parenti (2014-07-06): diff --git a/make/data/tzdata/iso3166.tab b/make/data/tzdata/iso3166.tab index 7fb307326fff9d3149d5257e4f81fba1d671c726..e47eefe122743bd803dd597a2feef85eab7a2900 100644 --- a/make/data/tzdata/iso3166.tab +++ b/make/data/tzdata/iso3166.tab @@ -75,7 +75,7 @@ BL St Barthelemy BM Bermuda BN Brunei BO Bolivia -BQ Caribbean Netherlands +BQ Caribbean NL BR Brazil BS Bahamas BT Bhutan @@ -186,7 +186,7 @@ MA Morocco MC Monaco MD Moldova ME Montenegro -MF St Martin (French part) +MF St Martin (French) MG Madagascar MH Marshall Islands MK Macedonia @@ -256,7 +256,7 @@ SR Suriname SS South Sudan ST Sao Tome & Principe SV El Salvador -SX St Maarten (Dutch part) +SX St Maarten (Dutch) SY Syria SZ Swaziland TC Turks & Caicos Is diff --git a/make/data/tzdata/leapseconds b/make/data/tzdata/leapseconds index de698eaa562657a5dd2927edfb47cfbeab260320..a08fbc7b20b59df710a8219023d844551b5c0eb6 100644 --- a/make/data/tzdata/leapseconds +++ b/make/data/tzdata/leapseconds @@ -29,6 +29,7 @@ # leap-seconds.list file available from most NIST time servers. # If the URL does not work, # you should be able to pick up leap-seconds.list from a secondary NIST server. +# See for a list of secondary servers. # For more about leap-seconds.list, please see # The NTP Timescale and Leap Seconds # http://www.eecis.udel.edu/~mills/leap.html @@ -79,5 +80,5 @@ Leap 2008 Dec 31 23:59:60 + S Leap 2012 Jun 30 23:59:60 + S Leap 2015 Jun 30 23:59:60 + S -# Updated through IERS Bulletin C50 -# File expires on: 28 June 2016 +# Updated through IERS Bulletin C51 +# File expires on: 28 December 2016 diff --git a/make/data/tzdata/northamerica b/make/data/tzdata/northamerica index e56fd895d10cc089c320b98335ec35a4d899e1ce..2124401edaf4a0d39d34eb88705e4dab71095c46 100644 --- a/make/data/tzdata/northamerica +++ b/make/data/tzdata/northamerica @@ -2498,13 +2498,22 @@ Zone America/Merida -5:58:28 - LMT 1922 Jan 1 0:01:32 -6:00 - CST 1981 Dec 23 -5:00 - EST 1982 Dec 2 -6:00 Mexico C%sT -# Coahuila, Durango, Nuevo León, Tamaulipas (near US border) +# Coahuila, Nuevo León, Tamaulipas (near US border) +# This includes the following municipalities: +# in Coahuila: Ocampo, Acuña, Zaragoza, Jiménez, Piedras Negras, Nava, +# Guerrero, Hidalgo. +# in Nuevo León: Anáhuac, Los Aldama. +# in Tamaulipas: Nuevo Laredo, Guerrero, Mier, Miguel Alemán, Camargo, +# Gustavo Díaz Ordaz, Reynosa, Río Bravo, Valle Hermoso, Matamoros. +# See: Inicia mañana Horario de Verano en zona fronteriza, El Universal, +# 2016-03-12 +# http://www.eluniversal.com.mx/articulo/estados/2016/03/12/inicia-manana-horario-de-verano-en-zona-fronteriza Zone America/Matamoros -6:40:00 - LMT 1921 Dec 31 23:20:00 -6:00 - CST 1988 -6:00 US C%sT 1989 -6:00 Mexico C%sT 2010 -6:00 US C%sT -# Coahuila, Durango, Nuevo León, Tamaulipas (away from US border) +# Durango; Coahuila, Nuevo León, Tamaulipas (away from US border) Zone America/Monterrey -6:41:16 - LMT 1921 Dec 31 23:18:44 -6:00 - CST 1988 -6:00 US C%sT 1989 @@ -2520,6 +2529,9 @@ Zone America/Mexico_City -6:36:36 - LMT 1922 Jan 1 0:23:24 -6:00 - CST 2002 Feb 20 -6:00 Mexico C%sT # Chihuahua (near US border) +# This includes the municipalities of Janos, Ascensión, Juárez, Guadalupe, +# Práxedis G Guerrero, Coyame del Sotol, Ojinaga, and Manuel Benavides. +# (See the 2016-03-12 El Universal source mentioned above.) Zone America/Ojinaga -6:57:40 - LMT 1922 Jan 1 0:02:20 -7:00 - MST 1927 Jun 10 23:00 -6:00 - CST 1930 Nov 15 @@ -2607,7 +2619,7 @@ Zone America/Bahia_Banderas -7:01:00 - LMT 1921 Dec 31 23:59:00 -7:00 Mexico M%sT 2010 Apr 4 2:00 -6:00 Mexico C%sT -# Baja California (near US border) +# Baja California Zone America/Tijuana -7:48:04 - LMT 1922 Jan 1 0:11:56 -7:00 - MST 1924 -8:00 - PST 1927 Jun 10 23:00 @@ -3083,6 +3095,13 @@ Zone America/Guatemala -6:02:04 - LMT 1918 Oct 5 # http://radiovision2000haiti.net/public/haiti-avis-changement-dheure-dimanche/ # http://www.canalplushaiti.net/?p=6714 +# From Steffen Thorsen (2016-03-12): +# Jean Antoine, editor of www.haiti-reference.com informed us that Haiti +# are not going on DST this year. Several other resources confirm this: ... +# http://www.radiotelevisioncaraibes.com/presse/heure_d_t_pas_de_changement_d_heure_pr_vu_pour_cet_ann_e.html +# http://www.vantbefinfo.com/changement-dheure-pas-pour-haiti/ +# http://news.anmwe.com/haiti-lheure-nationale-ne-sera-ni-avancee-ni-reculee-cette-annee/ + # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Haiti 1983 only - May 8 0:00 1:00 D Rule Haiti 1984 1987 - Apr lastSun 0:00 1:00 D @@ -3093,8 +3112,8 @@ Rule Haiti 1988 1997 - Apr Sun>=1 1:00s 1:00 D Rule Haiti 1988 1997 - Oct lastSun 1:00s 0 S Rule Haiti 2005 2006 - Apr Sun>=1 0:00 1:00 D Rule Haiti 2005 2006 - Oct lastSun 0:00 0 S -Rule Haiti 2012 max - Mar Sun>=8 2:00 1:00 D -Rule Haiti 2012 max - Nov Sun>=1 2:00 0 S +Rule Haiti 2012 2015 - Mar Sun>=8 2:00 1:00 D +Rule Haiti 2012 2015 - Nov Sun>=1 2:00 0 S # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone America/Port-au-Prince -4:49:20 - LMT 1890 -4:49 - PPMT 1917 Jan 24 12:00 # P-a-P MT diff --git a/make/data/tzdata/southamerica b/make/data/tzdata/southamerica index 082018691d69d5861a74d23742b8ace6a884ee6b..b9090896d8b732a371a61db601ea26fbff55619b 100644 --- a/make/data/tzdata/southamerica +++ b/make/data/tzdata/southamerica @@ -1244,6 +1244,20 @@ Zone America/Rio_Branco -4:31:12 - LMT 1914 # From Paul Eggert (2015-03-03): # For now, assume that the extension will persist indefinitely. +# From Juan Correa (2016-03-18): +# The decree regarding DST has been published in today's Official Gazette: +# http://www.diariooficial.interior.gob.cl/versiones-anteriores/do/20160318/ +# http://www.leychile.cl/Navegar?idNorma=1088502 +# It does consider the second Saturday of May and August as the dates +# for the transition; and it lists DST dates until 2019, but I think +# this scheme will stick. +# +# From Paul Eggert (2016-03-18): +# For now, assume the pattern holds for the indefinite future. +# The decree says transitions occur at 24:00; in practice this appears +# to mean 24:00 mainland time, not 24:00 local time, so that Easter +# Island is always two hours behind the mainland. + # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Chile 1927 1931 - Sep 1 0:00 1:00 S Rule Chile 1928 1932 - Apr 1 0:00 0 - @@ -1275,8 +1289,10 @@ Rule Chile 2009 only - Mar Sun>=9 3:00u 0 - Rule Chile 2010 only - Apr Sun>=1 3:00u 0 - Rule Chile 2011 only - May Sun>=2 3:00u 0 - Rule Chile 2011 only - Aug Sun>=16 4:00u 1:00 S -Rule Chile 2012 2015 - Apr Sun>=23 3:00u 0 - +Rule Chile 2012 2014 - Apr Sun>=23 3:00u 0 - Rule Chile 2012 2014 - Sep Sun>=2 4:00u 1:00 S +Rule Chile 2016 max - May Sun>=9 3:00u 0 - +Rule Chile 2016 max - Aug Sun>=9 4:00u 1:00 S # IATA SSIM anomalies: (1992-02) says 1992-03-14; # (1996-09) says 1998-03-08. Ignore these. # Zone NAME GMTOFF RULES FORMAT [UNTIL] @@ -1293,13 +1309,11 @@ Zone America/Santiago -4:42:46 - LMT 1890 -4:00 1:00 CLST 1946 Sep 1 # central Chile -4:00 - CLT 1947 Apr 1 -5:00 - CLT 1947 May 21 23:00 - -4:00 Chile CL%sT 2015 Apr 26 3:00u - -3:00 - CLT + -4:00 Chile CL%sT Zone Pacific/Easter -7:17:28 - LMT 1890 -7:17:28 - EMT 1932 Sep # Easter Mean Time -7:00 Chile EAS%sT 1982 Mar 14 3:00u # Easter Time - -6:00 Chile EAS%sT 2015 Apr 26 3:00u - -5:00 - EAST + -6:00 Chile EAS%sT # # Salas y Gómez Island is uninhabited. # Other Chilean locations, including Juan Fernández Is, Desventuradas Is, @@ -1321,8 +1335,7 @@ Zone Pacific/Easter -7:17:28 - LMT 1890 Zone Antarctica/Palmer 0 - zzz 1965 -4:00 Arg AR%sT 1969 Oct 5 -3:00 Arg AR%sT 1982 May - -4:00 Chile CL%sT 2015 Apr 26 3:00u - -3:00 - CLT + -4:00 Chile CL%sT # Colombia @@ -1765,9 +1778,25 @@ Zone America/Montevideo -3:44:44 - LMT 1898 Jun 28 # resolution publication) # http://www.globovision.com/news.php?nid=72208 +# From Alexander Krivenyshev (2016-04-15): +# https://actualidad.rt.com/actualidad/204758-venezuela-modificar-huso-horario-sequia-elnino +# +# From Paul Eggert (2016-04-15): +# Clocks advance 30 minutes on 2016-05-01 at 02:30. See: +# Barboza AD. Huso horario en Venezuela volverá a 4 horas menos con +# respecto al "Greenwich". Panorama 2016-04-15 12:20 -0430. +# http://www.panorama.com.ve/ciudad/Huso-horario-en-Venezuela-volvera-a-4-horas-menos-con-respecto-al-Greenwich-20160415-0032.html +# +# "'Venezuela's new time-zone: hours without light, hours without water, +# hours of presidential broadcasts, hours of lines," quipped comedian +# Jean Mary Curro ...". See: Cawthorne A, Kai D. Venezuela scraps +# half-hour time difference set by Chavez. Reuters 2016-04-15 14:50 -0400 +# http://www.reuters.com/article/us-venezuela-timezone-idUSKCN0XC2BE + # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone America/Caracas -4:27:44 - LMT 1890 -4:27:40 - CMT 1912 Feb 12 # Caracas Mean Time? -4:30 - VET 1965 Jan 1 0:00 # Venezuela T. -4:00 - VET 2007 Dec 9 3:00 - -4:30 - VET + -4:30 - VET 2016 May 1 2:30 + -4:00 - VET diff --git a/make/data/tzdata/zone.tab b/make/data/tzdata/zone.tab index 51aaf775dee42b924011249105a9a3febfab29cc..5649691ac03f55687f785dd8630b5f22767cfee9 100644 --- a/make/data/tzdata/zone.tab +++ b/make/data/tzdata/zone.tab @@ -53,22 +53,22 @@ AI +1812-06304 America/Anguilla AL +4120+01950 Europe/Tirane AM +4011+04430 Asia/Yerevan AO -0848+01314 Africa/Luanda -AQ -7750+16636 Antarctica/McMurdo McMurdo, South Pole, Scott (New Zealand time) -AQ -6734-06808 Antarctica/Rothera Rothera Station, Adelaide Island -AQ -6448-06406 Antarctica/Palmer Palmer Station, Anvers Island -AQ -6736+06253 Antarctica/Mawson Mawson Station, Holme Bay -AQ -6835+07758 Antarctica/Davis Davis Station, Vestfold Hills -AQ -6617+11031 Antarctica/Casey Casey Station, Bailey Peninsula -AQ -7824+10654 Antarctica/Vostok Vostok Station, Lake Vostok -AQ -6640+14001 Antarctica/DumontDUrville Dumont-d'Urville Station, Adelie Land -AQ -690022+0393524 Antarctica/Syowa Syowa Station, E Ongul I -AQ -720041+0023206 Antarctica/Troll Troll Station, Queen Maud Land +AQ -7750+16636 Antarctica/McMurdo New Zealand time - McMurdo, South Pole +AQ -6617+11031 Antarctica/Casey Casey +AQ -6835+07758 Antarctica/Davis Davis +AQ -6640+14001 Antarctica/DumontDUrville Dumont-d'Urville +AQ -6736+06253 Antarctica/Mawson Mawson +AQ -6448-06406 Antarctica/Palmer Palmer +AQ -6734-06808 Antarctica/Rothera Rothera +AQ -690022+0393524 Antarctica/Syowa Syowa +AQ -720041+0023206 Antarctica/Troll Troll +AQ -7824+10654 Antarctica/Vostok Vostok AR -3436-05827 America/Argentina/Buenos_Aires Buenos Aires (BA, CF) -AR -3124-06411 America/Argentina/Cordoba most locations (CB, CC, CN, ER, FM, MN, SE, SF) -AR -2447-06525 America/Argentina/Salta (SA, LP, NQ, RN) +AR -3124-06411 America/Argentina/Cordoba Argentina (most areas: CB, CC, CN, ER, FM, MN, SE, SF) +AR -2447-06525 America/Argentina/Salta Salta (SA, LP, NQ, RN) AR -2411-06518 America/Argentina/Jujuy Jujuy (JY) AR -2649-06513 America/Argentina/Tucuman Tucuman (TM) -AR -2828-06547 America/Argentina/Catamarca Catamarca (CT), Chubut (CH) +AR -2828-06547 America/Argentina/Catamarca Catamarca (CT); Chubut (CH) AR -2926-06651 America/Argentina/La_Rioja La Rioja (LR) AR -3132-06831 America/Argentina/San_Juan San Juan (SJ) AR -3253-06849 America/Argentina/Mendoza Mendoza (MZ) @@ -79,17 +79,17 @@ AS -1416-17042 Pacific/Pago_Pago AT +4813+01620 Europe/Vienna AU -3133+15905 Australia/Lord_Howe Lord Howe Island AU -5430+15857 Antarctica/Macquarie Macquarie Island -AU -4253+14719 Australia/Hobart Tasmania - most locations -AU -3956+14352 Australia/Currie Tasmania - King Island +AU -4253+14719 Australia/Hobart Tasmania (most areas) +AU -3956+14352 Australia/Currie Tasmania (King Island) AU -3749+14458 Australia/Melbourne Victoria -AU -3352+15113 Australia/Sydney New South Wales - most locations -AU -3157+14127 Australia/Broken_Hill New South Wales - Yancowinna -AU -2728+15302 Australia/Brisbane Queensland - most locations -AU -2016+14900 Australia/Lindeman Queensland - Holiday Islands +AU -3352+15113 Australia/Sydney New South Wales (most areas) +AU -3157+14127 Australia/Broken_Hill New South Wales (Yancowinna) +AU -2728+15302 Australia/Brisbane Queensland (most areas) +AU -2016+14900 Australia/Lindeman Queensland (Whitsunday Islands) AU -3455+13835 Australia/Adelaide South Australia AU -1228+13050 Australia/Darwin Northern Territory -AU -3157+11551 Australia/Perth Western Australia - most locations -AU -3143+12852 Australia/Eucla Western Australia - Eucla area +AU -3157+11551 Australia/Perth Western Australia (most areas) +AU -3143+12852 Australia/Eucla Western Australia (Eucla) AW +1230-06958 America/Aruba AX +6006+01957 Europe/Mariehamn AZ +4023+04951 Asia/Baku @@ -108,63 +108,63 @@ BN +0456+11455 Asia/Brunei BO -1630-06809 America/La_Paz BQ +120903-0681636 America/Kralendijk BR -0351-03225 America/Noronha Atlantic islands -BR -0127-04829 America/Belem Amapa, E Para -BR -0343-03830 America/Fortaleza NE Brazil (MA, PI, CE, RN, PB) +BR -0127-04829 America/Belem Para (east); Amapa +BR -0343-03830 America/Fortaleza Brazil (northeast: MA, PI, CE, RN, PB) BR -0803-03454 America/Recife Pernambuco BR -0712-04812 America/Araguaina Tocantins BR -0940-03543 America/Maceio Alagoas, Sergipe BR -1259-03831 America/Bahia Bahia -BR -2332-04637 America/Sao_Paulo S & SE Brazil (GO, DF, MG, ES, RJ, SP, PR, SC, RS) +BR -2332-04637 America/Sao_Paulo Brazil (southeast: GO, DF, MG, ES, RJ, SP, PR, SC, RS) BR -2027-05437 America/Campo_Grande Mato Grosso do Sul BR -1535-05605 America/Cuiaba Mato Grosso -BR -0226-05452 America/Santarem W Para +BR -0226-05452 America/Santarem Para (west) BR -0846-06354 America/Porto_Velho Rondonia BR +0249-06040 America/Boa_Vista Roraima -BR -0308-06001 America/Manaus E Amazonas -BR -0640-06952 America/Eirunepe W Amazonas +BR -0308-06001 America/Manaus Amazonas (east) +BR -0640-06952 America/Eirunepe Amazonas (west) BR -0958-06748 America/Rio_Branco Acre BS +2505-07721 America/Nassau BT +2728+08939 Asia/Thimphu BW -2439+02555 Africa/Gaborone BY +5354+02734 Europe/Minsk BZ +1730-08812 America/Belize -CA +4734-05243 America/St_Johns Newfoundland Time, including SE Labrador -CA +4439-06336 America/Halifax Atlantic Time - Nova Scotia (peninsula), PEI -CA +4612-05957 America/Glace_Bay Atlantic Time - Nova Scotia (Cape Breton) -CA +4606-06447 America/Moncton Atlantic Time - New Brunswick -CA +5320-06025 America/Goose_Bay Atlantic Time - Labrador - most locations -CA +5125-05707 America/Blanc-Sablon Atlantic Standard Time - Quebec - Lower North Shore -CA +4339-07923 America/Toronto Eastern Time - Ontario & Quebec - most locations -CA +4901-08816 America/Nipigon Eastern Time - Ontario & Quebec - places that did not observe DST 1967-1973 -CA +4823-08915 America/Thunder_Bay Eastern Time - Thunder Bay, Ontario -CA +6344-06828 America/Iqaluit Eastern Time - east Nunavut - most locations -CA +6608-06544 America/Pangnirtung Eastern Time - Pangnirtung, Nunavut -CA +744144-0944945 America/Resolute Central Time - Resolute, Nunavut -CA +484531-0913718 America/Atikokan Eastern Standard Time - Atikokan, Ontario and Southampton I, Nunavut -CA +624900-0920459 America/Rankin_Inlet Central Time - central Nunavut -CA +4953-09709 America/Winnipeg Central Time - Manitoba & west Ontario -CA +4843-09434 America/Rainy_River Central Time - Rainy River & Fort Frances, Ontario -CA +5024-10439 America/Regina Central Standard Time - Saskatchewan - most locations -CA +5017-10750 America/Swift_Current Central Standard Time - Saskatchewan - midwest -CA +5333-11328 America/Edmonton Mountain Time - Alberta, east British Columbia & west Saskatchewan -CA +690650-1050310 America/Cambridge_Bay Mountain Time - west Nunavut -CA +6227-11421 America/Yellowknife Mountain Time - central Northwest Territories -CA +682059-1334300 America/Inuvik Mountain Time - west Northwest Territories -CA +4906-11631 America/Creston Mountain Standard Time - Creston, British Columbia -CA +5946-12014 America/Dawson_Creek Mountain Standard Time - Dawson Creek & Fort Saint John, British Columbia -CA +5848-12242 America/Fort_Nelson Mountain Standard Time - Fort Nelson, British Columbia -CA +4916-12307 America/Vancouver Pacific Time - west British Columbia -CA +6043-13503 America/Whitehorse Pacific Time - south Yukon -CA +6404-13925 America/Dawson Pacific Time - north Yukon +CA +4734-05243 America/St_Johns Newfoundland; Labrador (southeast) +CA +4439-06336 America/Halifax Atlantic - NS (most areas); PE +CA +4612-05957 America/Glace_Bay Atlantic - NS (Cape Breton) +CA +4606-06447 America/Moncton Atlantic - New Brunswick +CA +5320-06025 America/Goose_Bay Atlantic - Labrador (most areas) +CA +5125-05707 America/Blanc-Sablon AST - QC (Lower North Shore) +CA +4339-07923 America/Toronto Eastern - ON, QC (most areas) +CA +4901-08816 America/Nipigon Eastern - ON, QC (no DST 1967-73) +CA +4823-08915 America/Thunder_Bay Eastern - ON (Thunder Bay) +CA +6344-06828 America/Iqaluit Eastern - NU (most east areas) +CA +6608-06544 America/Pangnirtung Eastern - NU (Pangnirtung) +CA +484531-0913718 America/Atikokan EST - ON (Atikokan); NU (Coral H) +CA +4953-09709 America/Winnipeg Central - ON (west); Manitoba +CA +4843-09434 America/Rainy_River Central - ON (Rainy R, Ft Frances) +CA +744144-0944945 America/Resolute Central - NU (Resolute) +CA +624900-0920459 America/Rankin_Inlet Central - NU (central) +CA +5024-10439 America/Regina CST - SK (most areas) +CA +5017-10750 America/Swift_Current CST - SK (midwest) +CA +5333-11328 America/Edmonton Mountain - AB; BC (E); SK (W) +CA +690650-1050310 America/Cambridge_Bay Mountain - NU (west) +CA +6227-11421 America/Yellowknife Mountain - NT (central) +CA +682059-1334300 America/Inuvik Mountain - NT (west) +CA +4906-11631 America/Creston MST - BC (Creston) +CA +5946-12014 America/Dawson_Creek MST - BC (Dawson Cr, Ft St John) +CA +5848-12242 America/Fort_Nelson MST - BC (Ft Nelson) +CA +4916-12307 America/Vancouver Pacific - BC (most areas) +CA +6043-13503 America/Whitehorse Pacific - Yukon (south) +CA +6404-13925 America/Dawson Pacific - Yukon (north) CC -1210+09655 Indian/Cocos -CD -0418+01518 Africa/Kinshasa west Dem. Rep. of Congo -CD -1140+02728 Africa/Lubumbashi east Dem. Rep. of Congo +CD -0418+01518 Africa/Kinshasa Dem. Rep. of Congo (west) +CD -1140+02728 Africa/Lubumbashi Dem. Rep. of Congo (east) CF +0422+01835 Africa/Bangui CG -0416+01517 Africa/Brazzaville CH +4723+00832 Europe/Zurich CI +0519-00402 Africa/Abidjan CK -2114-15946 Pacific/Rarotonga -CL -3327-07040 America/Santiago most locations +CL -3327-07040 America/Santiago Chile (most areas) CL -2709-10926 Pacific/Easter Easter Island CM +0403+00942 Africa/Douala CN +3114+12128 Asia/Shanghai Beijing Time @@ -177,28 +177,28 @@ CW +1211-06900 America/Curacao CX -1025+10543 Indian/Christmas CY +3510+03322 Asia/Nicosia CZ +5005+01426 Europe/Prague -DE +5230+01322 Europe/Berlin most locations +DE +5230+01322 Europe/Berlin Germany (most areas) DE +4742+00841 Europe/Busingen Busingen DJ +1136+04309 Africa/Djibouti DK +5540+01235 Europe/Copenhagen DM +1518-06124 America/Dominica DO +1828-06954 America/Santo_Domingo DZ +3647+00303 Africa/Algiers -EC -0210-07950 America/Guayaquil mainland +EC -0210-07950 America/Guayaquil Ecuador (mainland) EC -0054-08936 Pacific/Galapagos Galapagos Islands EE +5925+02445 Europe/Tallinn EG +3003+03115 Africa/Cairo EH +2709-01312 Africa/El_Aaiun ER +1520+03853 Africa/Asmara -ES +4024-00341 Europe/Madrid mainland -ES +3553-00519 Africa/Ceuta Ceuta & Melilla +ES +4024-00341 Europe/Madrid Spain (mainland) +ES +3553-00519 Africa/Ceuta Ceuta, Melilla ES +2806-01524 Atlantic/Canary Canary Islands ET +0902+03842 Africa/Addis_Ababa FI +6010+02458 Europe/Helsinki FJ -1808+17825 Pacific/Fiji FK -5142-05751 Atlantic/Stanley -FM +0725+15147 Pacific/Chuuk Chuuk (Truk) and Yap -FM +0658+15813 Pacific/Pohnpei Pohnpei (Ponape) +FM +0725+15147 Pacific/Chuuk Chuuk/Truk, Yap +FM +0658+15813 Pacific/Pohnpei Pohnpei/Ponape FM +0519+16259 Pacific/Kosrae Kosrae FO +6201-00646 Atlantic/Faroe FR +4852+00220 Europe/Paris @@ -210,10 +210,10 @@ GF +0456-05220 America/Cayenne GG +4927-00232 Europe/Guernsey GH +0533-00013 Africa/Accra GI +3608-00521 Europe/Gibraltar -GL +6411-05144 America/Godthab most locations -GL +7646-01840 America/Danmarkshavn east coast, north of Scoresbysund -GL +7029-02158 America/Scoresbysund Scoresbysund / Ittoqqortoormiit -GL +7634-06847 America/Thule Thule / Pituffik +GL +6411-05144 America/Godthab Greenland (most areas) +GL +7646-01840 America/Danmarkshavn National Park (east coast) +GL +7029-02158 America/Scoresbysund Scoresbysund/Ittoqqortoormiit +GL +7634-06847 America/Thule Thule/Pituffik GM +1328-01639 Africa/Banjul GN +0931-01343 Africa/Conakry GP +1614-06132 America/Guadeloupe @@ -229,10 +229,10 @@ HN +1406-08713 America/Tegucigalpa HR +4548+01558 Europe/Zagreb HT +1832-07220 America/Port-au-Prince HU +4730+01905 Europe/Budapest -ID -0610+10648 Asia/Jakarta Java & Sumatra -ID -0002+10920 Asia/Pontianak west & central Borneo -ID -0507+11924 Asia/Makassar east & south Borneo, Sulawesi (Celebes), Bali, Nusa Tengarra, west Timor -ID -0232+14042 Asia/Jayapura west New Guinea (Irian Jaya) & Malukus (Moluccas) +ID -0610+10648 Asia/Jakarta Java, Sumatra +ID -0002+10920 Asia/Pontianak Borneo (west, central) +ID -0507+11924 Asia/Makassar Borneo (east, south); Sulawesi/Celebes, Bali, Nusa Tengarra; Timor (west) +ID -0232+14042 Asia/Jayapura New Guinea (West Papua / Irian Jaya); Malukus/Moluccas IE +5320-00615 Europe/Dublin IL +314650+0351326 Asia/Jerusalem IM +5409-00428 Europe/Isle_of_Man @@ -258,10 +258,10 @@ KP +3901+12545 Asia/Pyongyang KR +3733+12658 Asia/Seoul KW +2920+04759 Asia/Kuwait KY +1918-08123 America/Cayman -KZ +4315+07657 Asia/Almaty most locations -KZ +4448+06528 Asia/Qyzylorda Qyzylorda (Kyzylorda, Kzyl-Orda) -KZ +5017+05710 Asia/Aqtobe Aqtobe (Aktobe) -KZ +4431+05016 Asia/Aqtau Atyrau (Atirau, Gur'yev), Mangghystau (Mankistau) +KZ +4315+07657 Asia/Almaty Kazakhstan (most areas) +KZ +4448+06528 Asia/Qyzylorda Qyzylorda/Kyzylorda/Kzyl-Orda +KZ +5017+05710 Asia/Aqtobe Aqtobe/Aktobe +KZ +4431+05016 Asia/Aqtau Atyrau/Atirau/Gur'yev, Mangghystau/Mankistau KZ +5113+05121 Asia/Oral West Kazakhstan LA +1758+10236 Asia/Vientiane LB +3353+03530 Asia/Beirut @@ -280,12 +280,12 @@ MD +4700+02850 Europe/Chisinau ME +4226+01916 Europe/Podgorica MF +1804-06305 America/Marigot MG -1855+04731 Indian/Antananarivo -MH +0709+17112 Pacific/Majuro most locations +MH +0709+17112 Pacific/Majuro Marshall Islands (most areas) MH +0905+16720 Pacific/Kwajalein Kwajalein MK +4159+02126 Europe/Skopje ML +1239-00800 Africa/Bamako MM +1647+09610 Asia/Rangoon -MN +4755+10653 Asia/Ulaanbaatar most locations +MN +4755+10653 Asia/Ulaanbaatar Mongolia (most areas) MN +4801+09139 Asia/Hovd Bayan-Olgiy, Govi-Altai, Hovd, Uvs, Zavkhan MN +4804+11430 Asia/Choibalsan Dornod, Sukhbaatar MO +2214+11335 Asia/Macau @@ -297,19 +297,19 @@ MT +3554+01431 Europe/Malta MU -2010+05730 Indian/Mauritius MV +0410+07330 Indian/Maldives MW -1547+03500 Africa/Blantyre -MX +1924-09909 America/Mexico_City Central Time - most locations +MX +1924-09909 America/Mexico_City Central Time MX +2105-08646 America/Cancun Eastern Standard Time - Quintana Roo MX +2058-08937 America/Merida Central Time - Campeche, Yucatan -MX +2540-10019 America/Monterrey Mexican Central Time - Coahuila, Durango, Nuevo Leon, Tamaulipas away from US border -MX +2550-09730 America/Matamoros US Central Time - Coahuila, Durango, Nuevo Leon, Tamaulipas near US border -MX +2313-10625 America/Mazatlan Mountain Time - S Baja, Nayarit, Sinaloa -MX +2838-10605 America/Chihuahua Mexican Mountain Time - Chihuahua away from US border -MX +2934-10425 America/Ojinaga US Mountain Time - Chihuahua near US border +MX +2540-10019 America/Monterrey Central Time - Durango; Coahuila, Nuevo Leon, Tamaulipas (most areas) +MX +2550-09730 America/Matamoros Central Time US - Coahuila, Nuevo Leon, Tamaulipas (US border) +MX +2313-10625 America/Mazatlan Mountain Time - Baja California Sur, Nayarit, Sinaloa +MX +2838-10605 America/Chihuahua Mountain Time - Chihuahua (most areas) +MX +2934-10425 America/Ojinaga Mountain Time US - Chihuahua (US border) MX +2904-11058 America/Hermosillo Mountain Standard Time - Sonora -MX +3232-11701 America/Tijuana US Pacific Time - Baja California state -MX +2048-10515 America/Bahia_Banderas Mexican Central Time - Bahia de Banderas -MY +0310+10142 Asia/Kuala_Lumpur peninsular Malaysia -MY +0133+11020 Asia/Kuching Sabah & Sarawak +MX +3232-11701 America/Tijuana Pacific Time US - Baja California +MX +2048-10515 America/Bahia_Banderas Central Time - Bahia de Banderas +MY +0310+10142 Asia/Kuala_Lumpur Malaysia (peninsula) +MY +0133+11020 Asia/Kuching Sabah, Sarawak MZ -2558+03235 Africa/Maputo NA -2234+01706 Africa/Windhoek NC -2216+16627 Pacific/Noumea @@ -322,7 +322,7 @@ NO +5955+01045 Europe/Oslo NP +2743+08519 Asia/Kathmandu NR -0031+16655 Pacific/Nauru NU -1901-16955 Pacific/Niue -NZ -3652+17446 Pacific/Auckland most locations +NZ -3652+17446 Pacific/Auckland New Zealand (most areas) NZ -4357-17633 Pacific/Chatham Chatham Islands OM +2336+05835 Asia/Muscat PA +0858-07932 America/Panama @@ -330,7 +330,7 @@ PE -1203-07703 America/Lima PF -1732-14934 Pacific/Tahiti Society Islands PF -0900-13930 Pacific/Marquesas Marquesas Islands PF -2308-13457 Pacific/Gambier Gambier Islands -PG -0930+14710 Pacific/Port_Moresby most locations +PG -0930+14710 Pacific/Port_Moresby Papua New Guinea (most areas) PG -0613+15534 Pacific/Bougainville Bougainville PH +1435+12100 Asia/Manila PK +2452+06703 Asia/Karachi @@ -340,7 +340,7 @@ PN -2504-13005 Pacific/Pitcairn PR +182806-0660622 America/Puerto_Rico PS +3130+03428 Asia/Gaza Gaza Strip PS +313200+0350542 Asia/Hebron West Bank -PT +3843-00908 Europe/Lisbon mainland +PT +3843-00908 Europe/Lisbon Portugal (mainland) PT +3238-01654 Atlantic/Madeira Madeira Islands PT +3744-02540 Atlantic/Azores Azores PW +0720+13429 Pacific/Palau @@ -349,27 +349,32 @@ QA +2517+05132 Asia/Qatar RE -2052+05528 Indian/Reunion RO +4426+02606 Europe/Bucharest RS +4450+02030 Europe/Belgrade -RU +5443+02030 Europe/Kaliningrad Moscow-01 - Kaliningrad -RU +554521+0373704 Europe/Moscow Moscow+00 - west Russia -RU +4457+03406 Europe/Simferopol Moscow+00 - Crimea -RU +4844+04425 Europe/Volgograd Moscow+00 - Caspian Sea -RU +5312+05009 Europe/Samara Moscow+00 (Moscow+01 after 2014-10-26) - Samara, Udmurtia -RU +5651+06036 Asia/Yekaterinburg Moscow+02 - Urals -RU +5500+07324 Asia/Omsk Moscow+03 - west Siberia -RU +5502+08255 Asia/Novosibirsk Moscow+03 - Novosibirsk -RU +5345+08707 Asia/Novokuznetsk Moscow+03 (Moscow+04 after 2014-10-26) - Kemerovo -RU +5601+09250 Asia/Krasnoyarsk Moscow+04 - Yenisei River -RU +5216+10420 Asia/Irkutsk Moscow+05 - Lake Baikal -RU +5203+11328 Asia/Chita Moscow+06 (Moscow+05 after 2014-10-26) - Zabaykalsky -RU +6200+12940 Asia/Yakutsk Moscow+06 - Lena River -RU +623923+1353314 Asia/Khandyga Moscow+06 - Tomponsky, Ust-Maysky -RU +4310+13156 Asia/Vladivostok Moscow+07 - Amur River -RU +4658+14242 Asia/Sakhalin Moscow+07 - Sakhalin Island -RU +643337+1431336 Asia/Ust-Nera Moscow+07 - Oymyakonsky -RU +5934+15048 Asia/Magadan Moscow+08 (Moscow+07 after 2014-10-26) - Magadan -RU +6728+15343 Asia/Srednekolymsk Moscow+08 - E Sakha, N Kuril Is -RU +5301+15839 Asia/Kamchatka Moscow+08 (Moscow+09 after 2014-10-26) - Kamchatka -RU +6445+17729 Asia/Anadyr Moscow+08 (Moscow+09 after 2014-10-26) - Bering Sea +RU +5443+02030 Europe/Kaliningrad MSK-01 - Kaliningrad +RU +554521+0373704 Europe/Moscow MSK+00 - Moscow area +RU +4457+03406 Europe/Simferopol MSK+00 - Crimea +RU +4844+04425 Europe/Volgograd MSK+00 - Volgograd, Saratov +RU +5836+04939 Europe/Kirov MSK+00 - Kirov +RU +4621+04803 Europe/Astrakhan MSK+01 - Astrakhan +RU +5312+05009 Europe/Samara MSK+01 - Samara, Udmurtia +RU +5420+04824 Europe/Ulyanovsk MSK+01 - Ulyanovsk +RU +5651+06036 Asia/Yekaterinburg MSK+02 - Urals +RU +5500+07324 Asia/Omsk MSK+03 - Omsk +RU +5502+08255 Asia/Novosibirsk MSK+03 - Novosibirsk +RU +5322+08345 Asia/Barnaul MSK+04 - Altai +RU +5630+08458 Asia/Tomsk MSK+04 - Tomsk +RU +5345+08707 Asia/Novokuznetsk MSK+04 - Kemerovo +RU +5601+09250 Asia/Krasnoyarsk MSK+04 - Krasnoyarsk area +RU +5216+10420 Asia/Irkutsk MSK+05 - Irkutsk, Buryatia +RU +5203+11328 Asia/Chita MSK+06 - Zabaykalsky +RU +6200+12940 Asia/Yakutsk MSK+06 - Lena River +RU +623923+1353314 Asia/Khandyga MSK+06 - Tomponsky, Ust-Maysky +RU +4310+13156 Asia/Vladivostok MSK+07 - Amur River +RU +643337+1431336 Asia/Ust-Nera MSK+07 - Oymyakonsky +RU +5934+15048 Asia/Magadan MSK+08 - Magadan +RU +4658+14242 Asia/Sakhalin MSK+08 - Sakhalin Island +RU +6728+15343 Asia/Srednekolymsk MSK+08 - Sakha (E); North Kuril Is +RU +5301+15839 Asia/Kamchatka MSK+09 - Kamchatka +RU +6445+17729 Asia/Anadyr MSK+09 - Bering Sea RW -0157+03004 Africa/Kigali SA +2438+04643 Asia/Riyadh SB -0932+16012 Pacific/Guadalcanal @@ -408,45 +413,45 @@ TT +1039-06131 America/Port_of_Spain TV -0831+17913 Pacific/Funafuti TW +2503+12130 Asia/Taipei TZ -0648+03917 Africa/Dar_es_Salaam -UA +5026+03031 Europe/Kiev most locations +UA +5026+03031 Europe/Kiev Ukraine (most areas) UA +4837+02218 Europe/Uzhgorod Ruthenia -UA +4750+03510 Europe/Zaporozhye Zaporozh'ye, E Lugansk / Zaporizhia, E Luhansk +UA +4750+03510 Europe/Zaporozhye Zaporozh'ye/Zaporizhia; Lugansk/Luhansk (east) UG +0019+03225 Africa/Kampala UM +1645-16931 Pacific/Johnston Johnston Atoll UM +2813-17722 Pacific/Midway Midway Islands UM +1917+16637 Pacific/Wake Wake Island -US +404251-0740023 America/New_York Eastern Time -US +421953-0830245 America/Detroit Eastern Time - Michigan - most locations -US +381515-0854534 America/Kentucky/Louisville Eastern Time - Kentucky - Louisville area -US +364947-0845057 America/Kentucky/Monticello Eastern Time - Kentucky - Wayne County -US +394606-0860929 America/Indiana/Indianapolis Eastern Time - Indiana - most locations -US +384038-0873143 America/Indiana/Vincennes Eastern Time - Indiana - Daviess, Dubois, Knox & Martin Counties -US +410305-0863611 America/Indiana/Winamac Eastern Time - Indiana - Pulaski County -US +382232-0862041 America/Indiana/Marengo Eastern Time - Indiana - Crawford County -US +382931-0871643 America/Indiana/Petersburg Eastern Time - Indiana - Pike County -US +384452-0850402 America/Indiana/Vevay Eastern Time - Indiana - Switzerland County -US +415100-0873900 America/Chicago Central Time -US +375711-0864541 America/Indiana/Tell_City Central Time - Indiana - Perry County -US +411745-0863730 America/Indiana/Knox Central Time - Indiana - Starke County -US +450628-0873651 America/Menominee Central Time - Michigan - Dickinson, Gogebic, Iron & Menominee Counties -US +470659-1011757 America/North_Dakota/Center Central Time - North Dakota - Oliver County -US +465042-1012439 America/North_Dakota/New_Salem Central Time - North Dakota - Morton County (except Mandan area) -US +471551-1014640 America/North_Dakota/Beulah Central Time - North Dakota - Mercer County -US +394421-1045903 America/Denver Mountain Time -US +433649-1161209 America/Boise Mountain Time - south Idaho & east Oregon -US +332654-1120424 America/Phoenix Mountain Standard Time - Arizona (except Navajo) -US +340308-1181434 America/Los_Angeles Pacific Time -US +611305-1495401 America/Anchorage Alaska Time -US +581807-1342511 America/Juneau Alaska Time - Alaska panhandle -US +571035-1351807 America/Sitka Alaska Time - southeast Alaska panhandle -US +550737-1313435 America/Metlakatla Alaska Time - Annette Island -US +593249-1394338 America/Yakutat Alaska Time - Alaska panhandle neck -US +643004-1652423 America/Nome Alaska Time - west Alaska +US +404251-0740023 America/New_York Eastern (most areas) +US +421953-0830245 America/Detroit Eastern - MI (most areas) +US +381515-0854534 America/Kentucky/Louisville Eastern - KY (Louisville area) +US +364947-0845057 America/Kentucky/Monticello Eastern - KY (Wayne) +US +394606-0860929 America/Indiana/Indianapolis Eastern - IN (most areas) +US +384038-0873143 America/Indiana/Vincennes Eastern - IN (Da, Du, K, Mn) +US +410305-0863611 America/Indiana/Winamac Eastern - IN (Pulaski) +US +382232-0862041 America/Indiana/Marengo Eastern - IN (Crawford) +US +382931-0871643 America/Indiana/Petersburg Eastern - IN (Pike) +US +384452-0850402 America/Indiana/Vevay Eastern - IN (Switzerland) +US +415100-0873900 America/Chicago Central (most areas) +US +375711-0864541 America/Indiana/Tell_City Central - IN (Perry) +US +411745-0863730 America/Indiana/Knox Central - IN (Starke) +US +450628-0873651 America/Menominee Central - MI (Wisconsin border) +US +470659-1011757 America/North_Dakota/Center Central - ND (Oliver) +US +465042-1012439 America/North_Dakota/New_Salem Central - ND (Morton rural) +US +471551-1014640 America/North_Dakota/Beulah Central - ND (Mercer) +US +394421-1045903 America/Denver Mountain (most areas) +US +433649-1161209 America/Boise Mountain - ID (south); OR (east) +US +332654-1120424 America/Phoenix MST - Arizona (except Navajo) +US +340308-1181434 America/Los_Angeles Pacific +US +611305-1495401 America/Anchorage Alaska (most areas) +US +581807-1342511 America/Juneau Alaska - Juneau area +US +571035-1351807 America/Sitka Alaska - Sitka area +US +550737-1313435 America/Metlakatla Alaska - Annette Island +US +593249-1394338 America/Yakutat Alaska - Yakutat +US +643004-1652423 America/Nome Alaska (west) US +515248-1763929 America/Adak Aleutian Islands US +211825-1575130 Pacific/Honolulu Hawaii UY -3453-05611 America/Montevideo -UZ +3940+06648 Asia/Samarkand west Uzbekistan -UZ +4120+06918 Asia/Tashkent east Uzbekistan +UZ +3940+06648 Asia/Samarkand Uzbekistan (west) +UZ +4120+06918 Asia/Tashkent Uzbekistan (east) VA +415408+0122711 Europe/Vatican VC +1309-06114 America/St_Vincent VE +1030-06656 America/Caracas diff --git a/make/src/classes/build/tools/cldrconverter/ResourceBundleGenerator.java b/make/src/classes/build/tools/cldrconverter/ResourceBundleGenerator.java index b905f75290a59ae224a26313d5cd46451916e4a2..d5eecf25ee816c399b98fa786e55269e1bbd7a73 100644 --- a/make/src/classes/build/tools/cldrconverter/ResourceBundleGenerator.java +++ b/make/src/classes/build/tools/cldrconverter/ResourceBundleGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2016, 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 @@ -30,11 +30,37 @@ import java.io.IOException; import java.io.PrintWriter; import java.util.Formatter; import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; import java.util.SortedSet; class ResourceBundleGenerator implements BundleGenerator { + // preferred timezones - keeping compatibility with JDK1.1 3 letter abbreviations + private static final String[] preferredTZIDs = { + "America/Los_Angeles", + "America/Denver", + "America/Phoenix", + "America/Chicago", + "America/New_York", + "America/Indianapolis", + "Pacific/Honolulu", + "America/Anchorage", + "America/Halifax", + "America/Sitka", + "America/St_Johns", + "Europe/Paris", + // Although CLDR does not support abbreviated zones, handle "GMT" as a + // special case here, as it is specified in the javadoc. + "GMT", + "Africa/Casablanca", + "Asia/Jerusalem", + "Asia/Tokyo", + "Europe/Bucharest", + "Asia/Shanghai", + "UTC", + }; + @Override public void generateBundle(String packageName, String baseName, String localeID, boolean useJava, Map map, BundleType type) throws IOException { @@ -89,6 +115,19 @@ class ResourceBundleGenerator implements BundleGenerator { for (String key : metaKeys) { map.remove(key); } + + // Make it preferred ordered + LinkedHashMap newMap = new LinkedHashMap<>(); + for (String preferred : preferredTZIDs) { + if (map.containsKey(preferred)) { + newMap.put(preferred, map.remove(preferred)); + } else if (("GMT".equals(preferred) || "UTC".equals(preferred)) && + metaKeys.contains(CLDRConverter.METAZONE_ID_PREFIX+preferred)) { + newMap.put(preferred, preferred); + } + } + newMap.putAll(map); + map = newMap; } try (PrintWriter out = new PrintWriter(file, encoding)) { diff --git a/src/share/classes/com/sun/accessibility/internal/resources/accessibility_ko.properties b/src/share/classes/com/sun/accessibility/internal/resources/accessibility_ko.properties index 530caa689994e60cee4ce6ede0f8cb0217626af8..51de7a1034ffdc4e5b0a916132b1186cd43d1a6f 100644 --- a/src/share/classes/com/sun/accessibility/internal/resources/accessibility_ko.properties +++ b/src/share/classes/com/sun/accessibility/internal/resources/accessibility_ko.properties @@ -15,13 +15,13 @@ # alert=\uACBD\uBCF4 awtcomponent=AWT \uAD6C\uC131 \uC694\uC18C -checkbox=\uCCB4\uD06C \uBC15\uC2A4 +checkbox=\uCCB4\uD06C\uBC15\uC2A4 colorchooser=\uC0C9\uC0C1 \uC120\uD0DD\uAE30 columnheader=\uC5F4 \uBA38\uB9AC\uAE00 combobox=\uCF64\uBCF4 \uC0C1\uC790 canvas=\uCE94\uBC84\uC2A4 -desktopicon=\uBC14\uD0D5 \uD654\uBA74 \uC544\uC774\uCF58 -desktoppane=\uBC14\uD0D5 \uD654\uBA74 \uCC3D +desktopicon=\uBC14\uD0D5\uD654\uBA74 \uC544\uC774\uCF58 +desktoppane=\uBC14\uD0D5\uD654\uBA74 \uCC3D dialog=\uB300\uD654\uC0C1\uC790 directorypane=\uB514\uB809\uD1A0\uB9AC \uCC3D glasspane=\uAE00\uB798\uC2A4 \uCC3D diff --git a/src/share/classes/com/sun/jndi/ldap/LdapCtx.java b/src/share/classes/com/sun/jndi/ldap/LdapCtx.java index e5821adea6e259d10bbfdddc123d9b732d9fca21..79630f53e1d721f784e58ed212d7424316ae1b93 100644 --- a/src/share/classes/com/sun/jndi/ldap/LdapCtx.java +++ b/src/share/classes/com/sun/jndi/ldap/LdapCtx.java @@ -2975,7 +2975,8 @@ final public class LdapCtx extends ComponentDirContext r = new LdapReferralException(resolvedName, resolvedObj, remainName, msg, envprops, fullDN, handleReferrals, reqCtls); // only one set of URLs is present - r.setReferralInfo(res.referrals.elementAt(0), false); + r.setReferralInfo(res.referrals == null ? null : + res.referrals.elementAt(0), false); if (hopCount > 1) { r.setHopCount(hopCount); @@ -3044,7 +3045,7 @@ final public class LdapCtx extends ComponentDirContext * assume name resolution has not yet completed. */ if (((res.entries == null) || (res.entries.isEmpty())) && - (res.referrals.size() == 1)) { + ((res.referrals != null) && (res.referrals.size() == 1))) { r.setReferralInfo(res.referrals, false); diff --git a/src/share/classes/com/sun/jndi/ldap/LdapReferralContext.java b/src/share/classes/com/sun/jndi/ldap/LdapReferralContext.java index 0a09e0fda690a3e3388bb3faf39f098821053401..0b82340df537f1eac2db1721383cb5478563aa54 100644 --- a/src/share/classes/com/sun/jndi/ldap/LdapReferralContext.java +++ b/src/share/classes/com/sun/jndi/ldap/LdapReferralContext.java @@ -92,7 +92,12 @@ final class LdapReferralContext implements DirContext, LdapContext { try { referral = refEx.getNextReferral(); if (referral == null) { - throw (NamingException)(previousEx.fillInStackTrace()); + if (previousEx != null) { + throw (NamingException)(previousEx.fillInStackTrace()); + } else { + throw new NamingException( + "Illegal encoding: referral is empty"); + } } } catch (LdapReferralException e) { diff --git a/src/share/classes/com/sun/jndi/ldap/LdapReferralException.java b/src/share/classes/com/sun/jndi/ldap/LdapReferralException.java index 53783adace4e5f26631042d94257c4b33c172f71..1058d9dd92433834c0f23cfbcdcca7ff68796eb8 100644 --- a/src/share/classes/com/sun/jndi/ldap/LdapReferralException.java +++ b/src/share/classes/com/sun/jndi/ldap/LdapReferralException.java @@ -217,13 +217,15 @@ final public class LdapReferralException extends System.out.println("LdapReferralException.setReferralInfo"); this.referrals = referrals; - if (referrals != null) { - referralCount = referrals.size(); - } + referralCount = (referrals == null) ? 0 : referrals.size(); if (debug) { - for (int i = 0; i < referralCount; i++) { - System.out.println(" [" + i + "] " + referrals.elementAt(i)); + if (referrals != null) { + for (int i = 0; i < referralCount; i++) { + System.out.println(" [" + i + "] " + referrals.elementAt(i)); + } + } else { + System.out.println("setReferralInfo : referrals == null"); } } } diff --git a/src/share/classes/com/sun/media/sound/SoftSynthesizer.java b/src/share/classes/com/sun/media/sound/SoftSynthesizer.java index 9b1ff67a20ba9703e188f449ead810b6df9b326c..8464e5aef67d3f72db1a9bfa49758114c64d3ab0 100644 --- a/src/share/classes/com/sun/media/sound/SoftSynthesizer.java +++ b/src/share/classes/com/sun/media/sound/SoftSynthesizer.java @@ -666,6 +666,40 @@ public final class SoftSynthesizer implements AudioSynthesizer, } }); + actions.add(new PrivilegedAction() { + public InputStream run() { + if (System.getProperties().getProperty("os.name") + .startsWith("Linux")) { + + File[] systemSoundFontsDir = new File[] { + /* Arch, Fedora, Mageia */ + new File("/usr/share/soundfonts/"), + new File("/usr/local/share/soundfonts/"), + /* Debian, Gentoo, OpenSUSE, Ubuntu */ + new File("/usr/share/sounds/sf2/"), + new File("/usr/local/share/sounds/sf2/"), + }; + + /* + * Look for a default.sf2 + */ + for (File systemSoundFontDir : systemSoundFontsDir) { + if (systemSoundFontDir.exists()) { + File defaultSoundFont = new File(systemSoundFontDir, "default.sf2"); + if (defaultSoundFont.exists()) { + try { + return new FileInputStream(defaultSoundFont); + } catch (IOException e) { + // continue with lookup + } + } + } + } + } + return null; + } + }); + actions.add(new PrivilegedAction() { public InputStream run() { if (System.getProperties().getProperty("os.name") diff --git a/src/share/classes/com/sun/tools/hat/internal/parser/HprofReader.java b/src/share/classes/com/sun/tools/hat/internal/parser/HprofReader.java index 33cdb3aa3e1e6e13ea392ed0d95cba7c5a2ac5da..a5b20bd7e4ff7b918e1f93daf4aae12b2cae41b2 100644 --- a/src/share/classes/com/sun/tools/hat/internal/parser/HprofReader.java +++ b/src/share/classes/com/sun/tools/hat/internal/parser/HprofReader.java @@ -354,7 +354,14 @@ public class HprofReader extends Reader /* imports */ implements ArrayTypeCodes } private void skipBytes(long length) throws IOException { - in.skipBytes((int)length); + while (length > 0) { + long skipped = in.skip(length); + length -= skipped; + if (skipped == 0) { + // EOF or other problem, throw exception + throw new EOFException("Couldn't skip enough bytes"); + } + } } private int readVersionHeader() throws IOException { @@ -486,12 +493,12 @@ public class HprofReader extends Reader /* imports */ implements ArrayTypeCodes break; } case HPROF_GC_OBJ_ARRAY_DUMP: { - int bytesRead = readArray(false); + long bytesRead = readArray(false); bytesLeft -= bytesRead; break; } case HPROF_GC_PRIM_ARRAY_DUMP: { - int bytesRead = readArray(true); + long bytesRead = readArray(true); bytesLeft -= bytesRead; break; } @@ -743,12 +750,12 @@ public class HprofReader extends Reader /* imports */ implements ArrayTypeCodes // Handle a HPROF_GC_OBJ_ARRAY_DUMP or HPROF_GC_PRIM_ARRAY_DUMP // Return number of bytes read // - private int readArray(boolean isPrimitive) throws IOException { + private long readArray(boolean isPrimitive) throws IOException { long start = in.position(); long id = readID(); StackTrace stackTrace = getStackTraceFromSerial(in.readInt()); int num = in.readInt(); - int bytesRead = identifierSize + 8; + long bytesRead = identifierSize + 8; long elementClassID; if (isPrimitive) { elementClassID = in.readByte(); @@ -810,14 +817,14 @@ public class HprofReader extends Reader /* imports */ implements ArrayTypeCodes } } if (primitiveSignature != 0x00) { - int size = elSize * num; + long size = elSize * (long)num; bytesRead += size; JavaValueArray va = new JavaValueArray(primitiveSignature, start); skipBytes(size); snapshot.addHeapObject(id, va); snapshot.setSiteTrace(va, stackTrace); } else { - int sz = num * identifierSize; + long sz = (long)num * identifierSize; bytesRead += sz; JavaObjectArray arr = new JavaObjectArray(elementClassID, start); skipBytes(sz); diff --git a/src/share/classes/com/sun/tools/jdi/ArrayTypeImpl.java b/src/share/classes/com/sun/tools/jdi/ArrayTypeImpl.java index 0c83e4d6686f6b4445f747d187b8dbeb5880e06b..3449a45fb714bd61830eae79130ef1bd45ef2a68 100644 --- a/src/share/classes/com/sun/tools/jdi/ArrayTypeImpl.java +++ b/src/share/classes/com/sun/tools/jdi/ArrayTypeImpl.java @@ -200,4 +200,9 @@ public class ArrayTypeImpl extends ReferenceTypeImpl * Defined always to be true for arrays */ public boolean isFinal() { return true; } + + /* + * Defined always to be false for arrays + */ + public boolean isStatic() { return false; } } diff --git a/src/share/classes/java/lang/AbstractStringBuilder.java b/src/share/classes/java/lang/AbstractStringBuilder.java index 3cde60d643792aabdc36ea8b46a9b794266bba72..4c31e2384011f52482e9371b22c99ac255b007f7 100644 --- a/src/share/classes/java/lang/AbstractStringBuilder.java +++ b/src/share/classes/java/lang/AbstractStringBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, 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 @@ -112,29 +112,56 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { } /** - * This method has the same contract as ensureCapacity, but is - * never synchronized. + * For positive values of {@code minimumCapacity}, this method + * behaves like {@code ensureCapacity}, however it is never + * synchronized. + * If {@code minimumCapacity} is non positive due to numeric + * overflow, this method throws {@code OutOfMemoryError}. */ private void ensureCapacityInternal(int minimumCapacity) { // overflow-conscious code - if (minimumCapacity - value.length > 0) - expandCapacity(minimumCapacity); + if (minimumCapacity - value.length > 0) { + value = Arrays.copyOf(value, + newCapacity(minimumCapacity)); + } } /** - * This implements the expansion semantics of ensureCapacity with no - * size check or synchronization. + * The maximum size of array to allocate (unless necessary). + * Some VMs reserve some header words in an array. + * Attempts to allocate larger arrays may result in + * OutOfMemoryError: Requested array size exceeds VM limit + */ + private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; + + /** + * Returns a capacity at least as large as the given minimum capacity. + * Returns the current capacity increased by the same amount + 2 if + * that suffices. + * Will not return a capacity greater than {@code MAX_ARRAY_SIZE} + * unless the given minimum capacity is greater than that. + * + * @param minCapacity the desired minimum capacity + * @throws OutOfMemoryError if minCapacity is less than zero or + * greater than Integer.MAX_VALUE */ - void expandCapacity(int minimumCapacity) { - int newCapacity = value.length * 2 + 2; - if (newCapacity - minimumCapacity < 0) - newCapacity = minimumCapacity; - if (newCapacity < 0) { - if (minimumCapacity < 0) // overflow - throw new OutOfMemoryError(); - newCapacity = Integer.MAX_VALUE; + private int newCapacity(int minCapacity) { + // overflow-conscious code + int newCapacity = (value.length << 1) + 2; + if (newCapacity - minCapacity < 0) { + newCapacity = minCapacity; + } + return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0) + ? hugeCapacity(minCapacity) + : newCapacity; + } + + private int hugeCapacity(int minCapacity) { + if (Integer.MAX_VALUE - minCapacity < 0) { // overflow + throw new OutOfMemoryError(); } - value = Arrays.copyOf(value, newCapacity); + return (minCapacity > MAX_ARRAY_SIZE) + ? minCapacity : MAX_ARRAY_SIZE; } /** diff --git a/src/share/classes/java/lang/StringBuffer.java b/src/share/classes/java/lang/StringBuffer.java index 9bc8f3ba10fd7b55f4d704cc2179ea8cb1e57e07..1638f30054176560d088ead29f0a5ff6e59e1052 100644 --- a/src/share/classes/java/lang/StringBuffer.java +++ b/src/share/classes/java/lang/StringBuffer.java @@ -171,9 +171,7 @@ import java.util.Arrays; @Override public synchronized void ensureCapacity(int minimumCapacity) { - if (minimumCapacity > value.length) { - expandCapacity(minimumCapacity); - } + super.ensureCapacity(minimumCapacity); } /** diff --git a/src/share/classes/java/lang/Thread.java b/src/share/classes/java/lang/Thread.java index 274801cea6c585a9f7b9f5ebd30298868ac4fa0f..7c8e83ef2b92681121cc35c63b6453d2c504645d 100644 --- a/src/share/classes/java/lang/Thread.java +++ b/src/share/classes/java/lang/Thread.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2016, 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 @@ -145,7 +145,7 @@ class Thread implements Runnable { registerNatives(); } - private volatile char name[]; + private volatile String name; private int priority; private Thread threadQ; private long eetop; @@ -366,7 +366,7 @@ class Thread implements Runnable { throw new NullPointerException("name cannot be null"); } - this.name = name.toCharArray(); + this.name = name; Thread parent = currentThread(); SecurityManager security = System.getSecurityManager(); @@ -1119,7 +1119,11 @@ class Thread implements Runnable { */ public final synchronized void setName(String name) { checkAccess(); - this.name = name.toCharArray(); + if (name == null) { + throw new NullPointerException("name cannot be null"); + } + + this.name = name; if (threadStatus != 0) { setNativeName(name); } @@ -1132,7 +1136,7 @@ class Thread implements Runnable { * @see #setName(String) */ public final String getName() { - return new String(name, true); + return name; } /** diff --git a/src/share/classes/java/lang/invoke/DirectMethodHandle.java b/src/share/classes/java/lang/invoke/DirectMethodHandle.java index cabd0716341678ae1b0fbe9f8471669e2d09c8e9..df3c2be141952fc9fc76d9069884d444333a7344 100644 --- a/src/share/classes/java/lang/invoke/DirectMethodHandle.java +++ b/src/share/classes/java/lang/invoke/DirectMethodHandle.java @@ -158,7 +158,7 @@ class DirectMethodHandle extends MethodHandle { private static LambdaForm preparedLambdaForm(MemberName m) { assert(m.isInvocable()) : m; // call preparedFieldLambdaForm instead MethodType mtype = m.getInvocationType().basicType(); - assert(!m.isMethodHandleInvoke() || "invokeBasic".equals(m.getName())) : m; + assert(!m.isMethodHandleInvoke()) : m; int which; switch (m.getReferenceKind()) { case REF_invokeVirtual: which = LF_INVVIRTUAL; break; diff --git a/src/share/classes/java/lang/invoke/LambdaForm.java b/src/share/classes/java/lang/invoke/LambdaForm.java index 09a742f55ec01069cbc5bac896c9aca36275c330..9420d3b042e847c7e238d141cdcc46d6daf4f8d2 100644 --- a/src/share/classes/java/lang/invoke/LambdaForm.java +++ b/src/share/classes/java/lang/invoke/LambdaForm.java @@ -1034,7 +1034,7 @@ class LambdaForm { this.member = member; this.resolvedHandle = resolvedHandle; // The following assert is almost always correct, but will fail for corner cases, such as PrivateInvokeTest. - //assert(!isInvokeBasic()); + //assert(!isInvokeBasic(member)); } NamedFunction(MethodType basicInvokerType) { assert(basicInvokerType == basicInvokerType.basicType()) : basicInvokerType; @@ -1045,13 +1045,13 @@ class LambdaForm { // necessary to pass BigArityTest this.member = Invokers.invokeBasicMethod(basicInvokerType); } - assert(isInvokeBasic()); + assert(isInvokeBasic(member)); } - private boolean isInvokeBasic() { + private static boolean isInvokeBasic(MemberName member) { return member != null && - member.isMethodHandleInvoke() && - "invokeBasic".equals(member.getName()); + member.getDeclaringClass() == MethodHandle.class && + "invokeBasic".equals(member.getName()); } // The next 3 constructors are used to break circular dependencies on MH.invokeStatic, etc. @@ -1191,7 +1191,7 @@ class LambdaForm { assert(mh.type().basicType() == MethodType.genericMethodType(arity).changeReturnType(rtype)) : Arrays.asList(mh, rtype, arity); MemberName member = mh.internalMemberName(); - if (member != null && member.getName().equals("invokeBasic") && member.isMethodHandleInvoke()) { + if (isInvokeBasic(member)) { assert(arity > 0); assert(a[0] instanceof MethodHandle); MethodHandle mh2 = (MethodHandle) a[0]; diff --git a/src/share/classes/java/lang/invoke/MemberName.java b/src/share/classes/java/lang/invoke/MemberName.java index bcc08e71d912373b3d0aecd408c86de8c7cc5040..b2fc757390e8df67231b8783d48de96911d57370 100644 --- a/src/share/classes/java/lang/invoke/MemberName.java +++ b/src/share/classes/java/lang/invoke/MemberName.java @@ -341,7 +341,6 @@ import java.util.Objects; } /** Utility method to query if this member is a method handle invocation (invoke or invokeExact). - * Also returns true for the non-public MH.invokeBasic. */ public boolean isMethodHandleInvoke() { final int bits = MH_INVOKE_MODS &~ Modifier.PUBLIC; @@ -356,7 +355,6 @@ import java.util.Objects; switch (name) { case "invoke": case "invokeExact": - case "invokeBasic": // internal sig-poly method return true; default: return false; diff --git a/src/share/classes/java/lang/invoke/MethodHandles.java b/src/share/classes/java/lang/invoke/MethodHandles.java index 85118904818e28d50d6ed615b3ca4987697457a4..dfd86288727e150ddf38e5b1fd8809bcb3a1fcc5 100644 --- a/src/share/classes/java/lang/invoke/MethodHandles.java +++ b/src/share/classes/java/lang/invoke/MethodHandles.java @@ -28,6 +28,7 @@ package java.lang.invoke; import java.lang.reflect.*; import java.util.BitSet; import java.util.List; +import java.util.ArrayList; import java.util.Arrays; import sun.invoke.util.ValueConversions; @@ -864,8 +865,6 @@ assertEquals("", (String) MH_newString.invokeExact()); return invoker(type); if ("invokeExact".equals(name)) return exactInvoker(type); - if ("invokeBasic".equals(name)) - return basicInvoker(type); assert(!MemberName.isMethodHandleInvokeName(name)); return null; } @@ -2447,6 +2446,7 @@ assertEquals("yz", (String) d0.invokeExact(123, "x", "y", "z")); */ public static MethodHandle dropArguments(MethodHandle target, int pos, List> valueTypes) { + valueTypes = copyTypes(valueTypes); MethodType oldType = target.type(); // get NPE int dropped = dropArgumentChecks(oldType, pos, valueTypes); MethodType newType = oldType.insertParameterTypes(pos, valueTypes); @@ -2461,6 +2461,11 @@ assertEquals("yz", (String) d0.invokeExact(123, "x", "y", "z")); return result; } + private static List> copyTypes(List> types) { + Object[] a = types.toArray(); + return Arrays.asList(Arrays.copyOf(a, a.length, Class[].class)); + } + private static int dropArgumentChecks(MethodType oldType, int pos, List> valueTypes) { int dropped = valueTypes.size(); MethodType.checkSlotCount(dropped); @@ -2842,7 +2847,7 @@ System.out.println((int) f0.invokeExact("x", "y")); // 2 int filterValues = filterType.parameterCount(); if (filterValues == 0 ? (rtype != void.class) - : (rtype != filterType.parameterType(0))) + : (rtype != filterType.parameterType(0) || filterValues != 1)) throw newIllegalArgumentException("target and filter types do not match", targetType, filterType); } diff --git a/src/share/classes/java/net/URLConnection.java b/src/share/classes/java/net/URLConnection.java index dd66ed26c547a43011f997572511cb1ebdc9e137..7f7f43d94be32ab6687d0a56b96c15122ffce187 100644 --- a/src/share/classes/java/net/URLConnection.java +++ b/src/share/classes/java/net/URLConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2016, 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 @@ -1515,7 +1515,7 @@ public abstract class URLConnection { } if (c1 == 0xFF && c2 == 0xD8 && c3 == 0xFF) { - if (c4 == 0xE0) { + if (c4 == 0xE0 || c4 == 0xEE) { return "image/jpeg"; } @@ -1530,10 +1530,6 @@ public abstract class URLConnection { c11 == 0)) { return "image/jpeg"; } - - if (c4 == 0xEE) { - return "image/jpg"; - } } if (c1 == 0xD0 && c2 == 0xCF && c3 == 0x11 && c4 == 0xE0 && diff --git a/src/share/classes/java/net/URLPermission.java b/src/share/classes/java/net/URLPermission.java index 78373e1087f76a30dab7bcd22d5408c30d442001..e188c81d73b03c5763470f8bd9a427f99c7fcd94 100644 --- a/src/share/classes/java/net/URLPermission.java +++ b/src/share/classes/java/net/URLPermission.java @@ -170,7 +170,8 @@ public final class URLPermission extends Permission { parseURI(getName()); int colon = actions.indexOf(':'); if (actions.lastIndexOf(':') != colon) { - throw new IllegalArgumentException("invalid actions string"); + throw new IllegalArgumentException( + "Invalid actions string: \"" + actions + "\""); } String methods, headers; @@ -371,7 +372,8 @@ public final class URLPermission extends Permission { l.add(s); b = new StringBuilder(); } else if (c == ' ' || c == '\t') { - throw new IllegalArgumentException("white space not allowed"); + throw new IllegalArgumentException( + "White space not allowed in methods: \"" + methods + "\""); } else { if (c >= 'a' && c <= 'z') { c += 'A' - 'a'; @@ -398,7 +400,8 @@ public final class URLPermission extends Permission { } b.append(c); } else if (c == ' ' || c == '\t') { - throw new IllegalArgumentException("white space not allowed"); + throw new IllegalArgumentException( + "White space not allowed in headers: \"" + headers + "\""); } else if (c == '-') { capitalizeNext = true; b.append(c); @@ -423,14 +426,16 @@ public final class URLPermission extends Permission { int len = url.length(); int delim = url.indexOf(':'); if (delim == -1 || delim + 1 == len) { - throw new IllegalArgumentException("invalid URL string"); + throw new IllegalArgumentException( + "Invalid URL string: \"" + url + "\""); } scheme = url.substring(0, delim).toLowerCase(); this.ssp = url.substring(delim + 1); if (!ssp.startsWith("//")) { if (!ssp.equals("*")) { - throw new IllegalArgumentException("invalid URL string"); + throw new IllegalArgumentException( + "Invalid URL string: \"" + url + "\""); } this.authority = new Authority(scheme, "*"); return; diff --git a/src/share/classes/java/text/DateFormatSymbols.java b/src/share/classes/java/text/DateFormatSymbols.java index c1f951d5bf80bd3fee042e8b64de6f02dc880224..4fcde4eabb47eb500843b59a0946cf1737e3e095 100644 --- a/src/share/classes/java/text/DateFormatSymbols.java +++ b/src/share/classes/java/text/DateFormatSymbols.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2016, 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 @@ -47,7 +47,6 @@ import java.util.Arrays; import java.util.Locale; import java.util.Objects; import java.util.ResourceBundle; -import java.util.TimeZone; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import sun.util.locale.provider.LocaleProviderAdapter; @@ -146,6 +145,12 @@ public class DateFormatSymbols implements Serializable, Cloneable { initializeData(locale); } + /** + * Constructs an uninitialized DateFormatSymbols. + */ + private DateFormatSymbols(boolean flag) { + } + /** * Era strings. For example: "AD" and "BC". An array of 2 strings, * indexed by Calendar.BC and Calendar.AD. @@ -677,54 +682,80 @@ public class DateFormatSymbols implements Serializable, Cloneable { */ transient volatile int cachedHashCode = 0; - private void initializeData(Locale desiredLocale) { - locale = desiredLocale; - - // Copy values of a cached instance if any. + /** + * Initializes this DateFormatSymbols with the locale data. This method uses + * a cached DateFormatSymbols instance for the given locale if available. If + * there's no cached one, this method creates an uninitialized instance and + * populates its fields from the resource bundle for the locale, and caches + * the instance. Note: zoneStrings isn't initialized in this method. + */ + private void initializeData(Locale locale) { SoftReference ref = cachedInstances.get(locale); DateFormatSymbols dfs; - if (ref != null && (dfs = ref.get()) != null) { - copyMembers(dfs, this); - return; - } - - // Initialize the fields from the ResourceBundle for locale. - LocaleProviderAdapter adapter = LocaleProviderAdapter.getAdapter(DateFormatSymbolsProvider.class, locale); - // Avoid any potential recursions - if (!(adapter instanceof ResourceBundleBasedAdapter)) { - adapter = LocaleProviderAdapter.getResourceBundleBased(); - } - ResourceBundle resource = ((ResourceBundleBasedAdapter)adapter).getLocaleData().getDateFormatData(locale); - - // JRE and CLDR use different keys - // JRE: Eras, short.Eras and narrow.Eras - // CLDR: long.Eras, Eras and narrow.Eras - if (resource.containsKey("Eras")) { - eras = resource.getStringArray("Eras"); - } else if (resource.containsKey("long.Eras")) { - eras = resource.getStringArray("long.Eras"); - } else if (resource.containsKey("short.Eras")) { - eras = resource.getStringArray("short.Eras"); - } - months = resource.getStringArray("MonthNames"); - shortMonths = resource.getStringArray("MonthAbbreviations"); - ampms = resource.getStringArray("AmPmMarkers"); - localPatternChars = resource.getString("DateTimePatternChars"); - - // Day of week names are stored in a 1-based array. - weekdays = toOneBasedArray(resource.getStringArray("DayNames")); - shortWeekdays = toOneBasedArray(resource.getStringArray("DayAbbreviations")); - - // Put a clone in the cache - ref = new SoftReference<>((DateFormatSymbols)this.clone()); - SoftReference x = cachedInstances.putIfAbsent(locale, ref); - if (x != null) { - DateFormatSymbols y = x.get(); - if (y == null) { - // Replace the empty SoftReference with ref. - cachedInstances.put(locale, ref); + if (ref == null || (dfs = ref.get()) == null) { + if (ref != null) { + // Remove the empty SoftReference + cachedInstances.remove(locale, ref); + } + dfs = new DateFormatSymbols(false); + + // Initialize the fields from the ResourceBundle for locale. + LocaleProviderAdapter adapter + = LocaleProviderAdapter.getAdapter(DateFormatSymbolsProvider.class, locale); + // Avoid any potential recursions + if (!(adapter instanceof ResourceBundleBasedAdapter)) { + adapter = LocaleProviderAdapter.getResourceBundleBased(); + } + ResourceBundle resource + = ((ResourceBundleBasedAdapter)adapter).getLocaleData().getDateFormatData(locale); + + dfs.locale = locale; + // JRE and CLDR use different keys + // JRE: Eras, short.Eras and narrow.Eras + // CLDR: long.Eras, Eras and narrow.Eras + if (resource.containsKey("Eras")) { + dfs.eras = resource.getStringArray("Eras"); + } else if (resource.containsKey("long.Eras")) { + dfs.eras = resource.getStringArray("long.Eras"); + } else if (resource.containsKey("short.Eras")) { + dfs.eras = resource.getStringArray("short.Eras"); + } + dfs.months = resource.getStringArray("MonthNames"); + dfs.shortMonths = resource.getStringArray("MonthAbbreviations"); + dfs.ampms = resource.getStringArray("AmPmMarkers"); + dfs.localPatternChars = resource.getString("DateTimePatternChars"); + + // Day of week names are stored in a 1-based array. + dfs.weekdays = toOneBasedArray(resource.getStringArray("DayNames")); + dfs.shortWeekdays = toOneBasedArray(resource.getStringArray("DayAbbreviations")); + + // Put dfs in the cache + ref = new SoftReference<>(dfs); + SoftReference x = cachedInstances.putIfAbsent(locale, ref); + if (x != null) { + DateFormatSymbols y = x.get(); + if (y == null) { + // Replace the empty SoftReference with ref. + cachedInstances.replace(locale, x, ref); + } else { + ref = x; + dfs = y; + } + } + // If the bundle's locale isn't the target locale, put another cache + // entry for the bundle's locale. + Locale bundleLocale = resource.getLocale(); + if (!bundleLocale.equals(locale)) { + SoftReference z + = cachedInstances.putIfAbsent(bundleLocale, ref); + if (z != null && z.get() == null) { + cachedInstances.replace(bundleLocale, z, ref); + } } } + + // Copy the field values from dfs to this instance. + copyMembers(dfs, this); } private static String[] toOneBasedArray(String[] src) { @@ -806,12 +837,14 @@ public class DateFormatSymbols implements Serializable, Cloneable { /** * Clones all the data members from the source DateFormatSymbols to - * the target DateFormatSymbols. This is only for subclasses. + * the target DateFormatSymbols. + * * @param src the source DateFormatSymbols. * @param dst the target DateFormatSymbols. */ private void copyMembers(DateFormatSymbols src, DateFormatSymbols dst) { + dst.locale = src.locale; dst.eras = Arrays.copyOf(src.eras, src.eras.length); dst.months = Arrays.copyOf(src.months, src.months.length); dst.shortMonths = Arrays.copyOf(src.shortMonths, src.shortMonths.length); diff --git a/src/share/classes/java/util/Hashtable.java b/src/share/classes/java/util/Hashtable.java index 6ee87cbb3bd011206d90335a8f3f0efa2afd1f54..c7e92515d197446315ad49cdc6b80d5b877a9185 100644 --- a/src/share/classes/java/util/Hashtable.java +++ b/src/share/classes/java/util/Hashtable.java @@ -1132,10 +1132,10 @@ public class Hashtable Entry entryStack = null; synchronized (this) { - // Write out the length, threshold, loadfactor + // Write out the threshold and loadFactor s.defaultWriteObject(); - // Write out length, count of elements + // Write out the length and count of elements s.writeInt(table.length); s.writeInt(count); @@ -1165,22 +1165,33 @@ public class Hashtable private void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException { - // Read in the length, threshold, and loadfactor + // Read in the threshold and loadFactor s.defaultReadObject(); + // Validate loadFactor (ignore threshold - it will be re-computed) + if (loadFactor <= 0 || Float.isNaN(loadFactor)) + throw new StreamCorruptedException("Illegal Load: " + loadFactor); + // Read the original length of the array and number of elements int origlength = s.readInt(); int elements = s.readInt(); - // Compute new size with a bit of room 5% to grow but - // no larger than the original size. Make the length + // Validate # of elements + if (elements < 0) + throw new StreamCorruptedException("Illegal # of Elements: " + elements); + + // Clamp original length to be more than elements / loadFactor + // (this is the invariant enforced with auto-growth) + origlength = Math.max(origlength, (int)(elements / loadFactor) + 1); + + // Compute new length with a bit of room 5% + 3 to grow but + // no larger than the clamped original length. Make the length // odd if it's large enough, this helps distribute the entries. // Guard against the length ending up zero, that's not valid. - int length = (int)(elements * loadFactor) + (elements / 20) + 3; + int length = (int)((elements + elements / 20) / loadFactor) + 3; if (length > elements && (length & 1) == 0) length--; - if (origlength > 0 && length > origlength) - length = origlength; + length = Math.min(length, origlength); table = new Entry[length]; threshold = (int)Math.min(length * loadFactor, MAX_ARRAY_SIZE + 1); count = 0; @@ -1191,7 +1202,7 @@ public class Hashtable K key = (K)s.readObject(); @SuppressWarnings("unchecked") V value = (V)s.readObject(); - // synch could be eliminated for performance + // sync is eliminated for performance reconstitutionPut(table, key, value); } } @@ -1203,9 +1214,9 @@ public class Hashtable * *

This differs from the regular put method in several ways. No * checking for rehashing is necessary since the number of elements - * initially in the table is known. The modCount is not incremented - * because we are creating a new instance. Also, no return value - * is needed. + * initially in the table is known. The modCount is not incremented and + * there's no synchronization because we are creating a new instance. + * Also, no return value is needed. */ private void reconstitutionPut(Entry[] tab, K key, V value) throws StreamCorruptedException diff --git a/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java b/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java index 62512ac41dcd6508f280abaa2d54c90fc558b3ef..15c4c9c0f6910ea9a263d102fcbda2109c0d5c73 100644 --- a/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java +++ b/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java @@ -485,19 +485,25 @@ public class ConcurrentLinkedQueue extends AbstractQueue * @return {@code true} if this queue changed as a result of the call */ public boolean remove(Object o) { - if (o == null) return false; - Node pred = null; - for (Node p = first(); p != null; p = succ(p)) { - E item = p.item; - if (item != null && - o.equals(item) && - p.casItem(item, null)) { - Node next = succ(p); - if (pred != null && next != null) + if (o != null) { + Node next, pred = null; + for (Node p = first(); p != null; pred = p, p = next) { + boolean removed = false; + E item = p.item; + if (item != null) { + if (!o.equals(item)) { + next = succ(p); + continue; + } + removed = p.casItem(item, null); + } + + next = succ(p); + if (pred != null && next != null) // unlink pred.casNext(p, next); - return true; + if (removed) + return true; } - pred = p; } return false; } diff --git a/src/share/classes/java/util/logging/Logger.java b/src/share/classes/java/util/logging/Logger.java index 4629320c1fdedc3a94dbf1766f802e87b8c00091..61bbe4e3df975ef895acf3671e5b6cad07e594f0 100644 --- a/src/share/classes/java/util/logging/Logger.java +++ b/src/share/classes/java/util/logging/Logger.java @@ -800,6 +800,7 @@ public class Logger { * @param level One of the message level identifiers, e.g., SEVERE * @param msgSupplier A function, which when called, produces the * desired log message + * @since 1.8 */ public void log(Level level, Supplier msgSupplier) { if (!isLoggable(level)) { diff --git a/src/share/classes/javax/crypto/JceSecurity.java b/src/share/classes/javax/crypto/JceSecurity.java index fb7052d244d20da01ce96f66be79ce1815fcd9bb..29823e77360a75b372235d10d6e5f120314b026f 100644 --- a/src/share/classes/javax/crypto/JceSecurity.java +++ b/src/share/classes/javax/crypto/JceSecurity.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, 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 @@ -64,8 +64,7 @@ final class JceSecurity { private final static Map verifyingProviders = new IdentityHashMap<>(); - // Set the default value. May be changed in the static initializer. - private static boolean isRestricted = true; + private static final boolean isRestricted; /* * Don't let anyone instantiate this. diff --git a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java index bf4e28b6738c76c3e8248cab8bbe3b3f3f3b5078..209de6647162f2c8929dde947c258cd7395685a3 100644 --- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java +++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java @@ -21,7 +21,7 @@ * under the License. */ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. */ /* * $Id: DOMURIDereferencer.java 1231033 2012-01-13 12:12:12Z coheigea $ @@ -111,7 +111,8 @@ public class DOMURIDereferencer implements URIDereferencer { try { ResourceResolver apacheResolver = ResourceResolver.getInstance(uriAttr, baseURI, secVal); - XMLSignatureInput in = apacheResolver.resolve(uriAttr, baseURI); + XMLSignatureInput in = apacheResolver.resolve(uriAttr, + baseURI, secVal); if (in.isOctetStream()) { return new ApacheOctetStreamData(in); } else { diff --git a/src/share/classes/sun/awt/datatransfer/DataTransferer.java b/src/share/classes/sun/awt/datatransfer/DataTransferer.java index 79c2792800fb7d250c0b1dcd8e0da661258d63fc..a5bd0f559ec1ee163346a75e44241baaf8b012c4 100644 --- a/src/share/classes/sun/awt/datatransfer/DataTransferer.java +++ b/src/share/classes/sun/awt/datatransfer/DataTransferer.java @@ -2898,13 +2898,7 @@ search: return comp; } } else { - // First, prefer application types. - comp = compareIndices(primaryTypes, primaryType1, primaryType2, - UNKNOWN_OBJECT_LOSES); - if (comp != 0) { - return comp; - } - + // First, prefer text types if (flavor1.isFlavorTextType()) { return 1; } @@ -2913,6 +2907,13 @@ search: return -1; } + // Next, prefer application types. + comp = compareIndices(primaryTypes, primaryType1, primaryType2, + UNKNOWN_OBJECT_LOSES); + if (comp != 0) { + return comp; + } + // Next, look for application/x-java-* types. Prefer unknown // MIME types because if the user provides his own data flavor, // it will likely be the most descriptive one. diff --git a/src/share/classes/sun/invoke/anon/AnonymousClassLoader.java b/src/share/classes/sun/invoke/anon/AnonymousClassLoader.java deleted file mode 100644 index 32624b40f97760719159031009f43824d5d5790d..0000000000000000000000000000000000000000 --- a/src/share/classes/sun/invoke/anon/AnonymousClassLoader.java +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.invoke.anon; - -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import sun.misc.IOUtils; - -/** - * Anonymous class loader. Will load any valid classfile, producing - * a {@link Class} metaobject, without installing that class in the - * system dictionary. Therefore, {@link Class#forName(String)} will never - * produce a reference to an anonymous class. - *

- * The access permissions of the anonymous class are borrowed from - * a host class. The new class behaves as if it were an - * inner class of the host class. It can access the host's private - * members, if the creator of the class loader has permission to - * do so (or to create accessible reflective objects). - *

- * When the anonymous class is loaded, elements of its constant pool - * can be patched to new values. This provides a hook to pre-resolve - * named classes in the constant pool to other classes, including - * anonymous ones. Also, string constants can be pre-resolved to - * any reference. (The verifier treats non-string, non-class reference - * constants as plain objects.) - *

- * Why include the patching function? It makes some use cases much easier. - * Second, the constant pool needed some internal patching anyway, - * to anonymize the loaded class itself. Finally, if you are going - * to use this seriously, you'll want to build anonymous classes - * on top of pre-existing anonymous classes, and that requires patching. - * - *

%%% TO-DO: - *

    - *
  • needs better documentation
  • - *
  • needs more security work (for safe delegation)
  • - *
  • needs a clearer story about error processing
  • - *
  • patch member references also (use ';' as delimiter char)
  • - *
  • patch method references to (conforming) method handles
  • - *
- * - * @author jrose - * @author Remi Forax - * @see - * http://blogs.sun.com/jrose/entry/anonymous_classes_in_the_vm - */ - -public class AnonymousClassLoader { - final Class hostClass; - - // Privileged constructor. - private AnonymousClassLoader(Class hostClass) { - this.hostClass = hostClass; - } - - public static AnonymousClassLoader make(sun.misc.Unsafe unsafe, Class hostClass) { - if (unsafe == null) throw new NullPointerException(); - return new AnonymousClassLoader(hostClass); - } - - public Class loadClass(byte[] classFile) { - if (defineAnonymousClass == null) { - // no JVM support; try to fake an approximation - try { - return fakeLoadClass(new ConstantPoolParser(classFile).createPatch()); - } catch (InvalidConstantPoolFormatException ee) { - throw new IllegalArgumentException(ee); - } - } - return loadClass(classFile, null); - } - - public Class loadClass(ConstantPoolPatch classPatch) { - if (defineAnonymousClass == null) { - // no JVM support; try to fake an approximation - return fakeLoadClass(classPatch); - } - Object[] patches = classPatch.patchArray; - // Convert class names (this late in the game) - // to use slash '/' instead of dot '.'. - // Java likes dots, but the JVM likes slashes. - for (int i = 0; i < patches.length; i++) { - Object value = patches[i]; - if (value != null) { - byte tag = classPatch.getTag(i); - switch (tag) { - case ConstantPoolVisitor.CONSTANT_Class: - if (value instanceof String) { - if (patches == classPatch.patchArray) - patches = patches.clone(); - patches[i] = ((String)value).replace('.', '/'); - } - break; - case ConstantPoolVisitor.CONSTANT_Fieldref: - case ConstantPoolVisitor.CONSTANT_Methodref: - case ConstantPoolVisitor.CONSTANT_InterfaceMethodref: - case ConstantPoolVisitor.CONSTANT_NameAndType: - // When/if the JVM supports these patches, - // we'll probably need to reformat them also. - // Meanwhile, let the class loader create the error. - break; - } - } - } - return loadClass(classPatch.outer.classFile, classPatch.patchArray); - } - - private Class loadClass(byte[] classFile, Object[] patchArray) { - try { - return (Class) - defineAnonymousClass.invoke(unsafe, - hostClass, classFile, patchArray); - } catch (Exception ex) { - throwReflectedException(ex); - throw new RuntimeException("error loading into "+hostClass, ex); - } - } - - private static void throwReflectedException(Exception ex) { - if (ex instanceof InvocationTargetException) { - Throwable tex = ((InvocationTargetException)ex).getTargetException(); - if (tex instanceof Error) - throw (Error) tex; - ex = (Exception) tex; - } - if (ex instanceof RuntimeException) { - throw (RuntimeException) ex; - } - } - - private Class fakeLoadClass(ConstantPoolPatch classPatch) { - // Implementation: - // 1. Make up a new name nobody has used yet. - // 2. Inspect the tail-header of the class to find the this_class index. - // 3. Patch the CONSTANT_Class for this_class to the new name. - // 4. Add other CP entries required by (e.g.) string patches. - // 5. Flatten Class constants down to their names, making sure that - // the host class loader can pick them up again accurately. - // 6. Generate the edited class file bytes. - // - // Potential limitations: - // * The class won't be truly anonymous, and may interfere with others. - // * Flattened class constants might not work, because of loader issues. - // * Pseudo-string constants will not flatten down to real strings. - // * Method handles will (of course) fail to flatten to linkage strings. - if (true) throw new UnsupportedOperationException("NYI"); - Object[] cpArray; - try { - cpArray = classPatch.getOriginalCP(); - } catch (InvalidConstantPoolFormatException ex) { - throw new RuntimeException(ex); - } - int thisClassIndex = classPatch.getParser().getThisClassIndex(); - String thisClassName = (String) cpArray[thisClassIndex]; - synchronized (AnonymousClassLoader.class) { - thisClassName = thisClassName+"\\|"+(++fakeNameCounter); - } - classPatch.putUTF8(thisClassIndex, thisClassName); - byte[] classFile = null; - return unsafe.defineClass(null, classFile, 0, classFile.length, - hostClass.getClassLoader(), - hostClass.getProtectionDomain()); - } - private static int fakeNameCounter = 99999; - - // ignore two warnings on this line: - private static sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe(); - // preceding line requires that this class be on the boot class path - - static private final Method defineAnonymousClass; - static { - Method dac = null; - Class unsafeClass = unsafe.getClass(); - try { - dac = unsafeClass.getMethod("defineAnonymousClass", - Class.class, - byte[].class, - Object[].class); - } catch (Exception ee) { - dac = null; - } - defineAnonymousClass = dac; - } - - private static void noJVMSupport() { - throw new UnsupportedOperationException("no JVM support for anonymous classes"); - } - - - private static native Class loadClassInternal(Class hostClass, - byte[] classFile, - Object[] patchArray); - - public static byte[] readClassFile(Class templateClass) throws IOException { - String templateName = templateClass.getName(); - int lastDot = templateName.lastIndexOf('.'); - java.net.URL url = templateClass.getResource(templateName.substring(lastDot+1)+".class"); - java.net.URLConnection connection = url.openConnection(); - int contentLength = connection.getContentLength(); - if (contentLength < 0) - throw new IOException("invalid content length "+contentLength); - - return IOUtils.readFully(connection.getInputStream(), contentLength, true); - } -} diff --git a/src/share/classes/sun/invoke/anon/ConstantPoolParser.java b/src/share/classes/sun/invoke/anon/ConstantPoolParser.java deleted file mode 100644 index 441ba9573365b0b1961f84ae297f8fc09c948b87..0000000000000000000000000000000000000000 --- a/src/share/classes/sun/invoke/anon/ConstantPoolParser.java +++ /dev/null @@ -1,368 +0,0 @@ -/* - * Copyright (c) 2008, 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.invoke.anon; - -import java.io.IOException; -import java.io.OutputStream; -import java.nio.BufferUnderflowException; -import java.nio.ByteBuffer; - -import static sun.invoke.anon.ConstantPoolVisitor.*; - -/** A constant pool parser. - */ -public class ConstantPoolParser { - final byte[] classFile; - final byte[] tags; - final char[] firstHeader; // maghi, maglo, minor, major, cplen - - // these are filled in on first parse: - int endOffset; - char[] secondHeader; // flags, this_class, super_class, intlen - - // used to decode UTF8 array - private char[] charArray = new char[80]; - - /** Creates a constant pool parser. - * @param classFile an array of bytes containing a class. - * @throws InvalidConstantPoolFormatException if the header of the class has errors. - */ - public ConstantPoolParser(byte[] classFile) throws InvalidConstantPoolFormatException { - this.classFile = classFile; - this.firstHeader = parseHeader(classFile); - this.tags = new byte[firstHeader[4]]; - } - - /** Create a constant pool parser by loading the bytecodes of the - * class taken as argument. - * - * @param templateClass the class to parse. - * - * @throws IOException raised if an I/O occurs when loading - * the bytecode of the template class. - * @throws InvalidConstantPoolFormatException if the header of the class has errors. - * - * @see #ConstantPoolParser(byte[]) - * @see AnonymousClassLoader#readClassFile(Class) - */ - public ConstantPoolParser(Class templateClass) throws IOException, InvalidConstantPoolFormatException { - this(AnonymousClassLoader.readClassFile(templateClass)); - } - - /** Creates an empty patch to patch the class file - * used by the current parser. - * @return a new class patch. - */ - public ConstantPoolPatch createPatch() { - return new ConstantPoolPatch(this); - } - - /** Report the tag of the indicated CP entry. - * @param index - * @return one of {@link ConstantPoolVisitor#CONSTANT_Utf8}, etc. - */ - public byte getTag(int index) { - getEndOffset(); // trigger an exception if we haven't parsed yet - return tags[index]; - } - - /** Report the length of the constant pool. */ - public int getLength() { - return firstHeader[4]; - } - - /** Report the offset, within the class file, of the start of the constant pool. */ - public int getStartOffset() { - return firstHeader.length * 2; - } - - /** Report the offset, within the class file, of the end of the constant pool. */ - public int getEndOffset() { - if (endOffset == 0) - throw new IllegalStateException("class file has not yet been parsed"); - return endOffset; - } - - /** Report the CP index of this class's own name. */ - public int getThisClassIndex() { - getEndOffset(); // provoke exception if not yet parsed - return secondHeader[1]; - } - - /** Report the total size of the class file. */ - public int getTailLength() { - return classFile.length - getEndOffset(); - } - - /** Write the head (header plus constant pool) - * of the class file to the indicated stream. - */ - public void writeHead(OutputStream out) throws IOException { - out.write(classFile, 0, getEndOffset()); - } - - /** Write the head (header plus constant pool) - * of the class file to the indicated stream, - * incorporating the non-null entries of the given array - * as patches. - */ - void writePatchedHead(OutputStream out, Object[] patchArray) { - // this will be useful to partially emulate the class loader on old JVMs - throw new UnsupportedOperationException("Not yet implemented"); - } - - /** Write the tail (everything after the constant pool) - * of the class file to the indicated stream. - */ - public void writeTail(OutputStream out) throws IOException { - out.write(classFile, getEndOffset(), getTailLength()); - } - - private static char[] parseHeader(byte[] classFile) throws InvalidConstantPoolFormatException { - char[] result = new char[5]; - ByteBuffer buffer = ByteBuffer.wrap(classFile); - for (int i = 0; i < result.length; i++) - result[i] = (char) getUnsignedShort(buffer); - int magic = result[0] << 16 | result[1] << 0; - if (magic != 0xCAFEBABE) - throw new InvalidConstantPoolFormatException("invalid magic number "+magic); - // skip major, minor version - int len = result[4]; - if (len < 1) - throw new InvalidConstantPoolFormatException("constant pool length < 1"); - return result; - } - - /** Parse the constant pool of the class - * calling a method visit* each time a constant pool entry is parsed. - * - * The order of the calls to visit* is not guaranteed to be the same - * than the order of the constant pool entry in the bytecode array. - * - * @param visitor - * @throws InvalidConstantPoolFormatException - */ - public void parse(ConstantPoolVisitor visitor) throws InvalidConstantPoolFormatException { - ByteBuffer buffer = ByteBuffer.wrap(classFile); - buffer.position(getStartOffset()); //skip header - - Object[] values = new Object[getLength()]; - try { - parseConstantPool(buffer, values, visitor); - } catch(BufferUnderflowException e) { - throw new InvalidConstantPoolFormatException(e); - } - if (endOffset == 0) { - endOffset = buffer.position(); - secondHeader = new char[4]; - for (int i = 0; i < secondHeader.length; i++) { - secondHeader[i] = (char) getUnsignedShort(buffer); - } - } - resolveConstantPool(values, visitor); - } - - private char[] getCharArray(int utfLength) { - if (utfLength <= charArray.length) - return charArray; - return charArray = new char[utfLength]; - } - - private void parseConstantPool(ByteBuffer buffer, Object[] values, ConstantPoolVisitor visitor) throws InvalidConstantPoolFormatException { - for (int i = 1; i < tags.length; ) { - byte tag = (byte) getUnsignedByte(buffer); - assert(tags[i] == 0 || tags[i] == tag); - tags[i] = tag; - switch (tag) { - case CONSTANT_Utf8: - int utfLen = getUnsignedShort(buffer); - String value = getUTF8(buffer, utfLen, getCharArray(utfLen)); - visitor.visitUTF8(i, CONSTANT_Utf8, value); - tags[i] = tag; - values[i++] = value; - break; - case CONSTANT_Integer: - visitor.visitConstantValue(i, tag, buffer.getInt()); - i++; - break; - case CONSTANT_Float: - visitor.visitConstantValue(i, tag, buffer.getFloat()); - i++; - break; - case CONSTANT_Long: - visitor.visitConstantValue(i, tag, buffer.getLong()); - i+=2; - break; - case CONSTANT_Double: - visitor.visitConstantValue(i, tag, buffer.getDouble()); - i+=2; - break; - - case CONSTANT_Class: // fall through: - case CONSTANT_String: - tags[i] = tag; - values[i++] = new int[] { getUnsignedShort(buffer) }; - break; - - case CONSTANT_Fieldref: // fall through: - case CONSTANT_Methodref: // fall through: - case CONSTANT_InterfaceMethodref: // fall through: - case CONSTANT_NameAndType: - tags[i] = tag; - values[i++] = new int[] { getUnsignedShort(buffer), getUnsignedShort(buffer) }; - break; - default: - throw new AssertionError("invalid constant "+tag); - } - } - } - - private void resolveConstantPool(Object[] values, ConstantPoolVisitor visitor) { - // clean out the int[] values, which are temporary - for (int beg = 1, end = values.length-1, beg2, end2; - beg <= end; - beg = beg2, end = end2) { - beg2 = end; end2 = beg-1; - //System.out.println("CP resolve pass: "+beg+".."+end); - for (int i = beg; i <= end; i++) { - Object value = values[i]; - if (!(value instanceof int[])) - continue; - int[] array = (int[]) value; - byte tag = tags[i]; - switch (tag) { - case CONSTANT_String: - String stringBody = (String) values[array[0]]; - visitor.visitConstantString(i, tag, stringBody, array[0]); - values[i] = null; - break; - case CONSTANT_Class: { - String className = (String) values[array[0]]; - // use the external form favored by Class.forName: - className = className.replace('/', '.'); - visitor.visitConstantString(i, tag, className, array[0]); - values[i] = className; - break; - } - case CONSTANT_NameAndType: { - String memberName = (String) values[array[0]]; - String signature = (String) values[array[1]]; - visitor.visitDescriptor(i, tag, memberName, signature, - array[0], array[1]); - values[i] = new String[] {memberName, signature}; - break; - } - case CONSTANT_Fieldref: // fall through: - case CONSTANT_Methodref: // fall through: - case CONSTANT_InterfaceMethodref: { - Object className = values[array[0]]; - Object nameAndType = values[array[1]]; - if (!(className instanceof String) || - !(nameAndType instanceof String[])) { - // one more pass is needed - if (beg2 > i) beg2 = i; - if (end2 < i) end2 = i; - continue; - } - String[] nameAndTypeArray = (String[]) nameAndType; - visitor.visitMemberRef(i, tag, - (String)className, - nameAndTypeArray[0], - nameAndTypeArray[1], - array[0], array[1]); - values[i] = null; - } - break; - default: - continue; - } - } - } - } - - private static int getUnsignedByte(ByteBuffer buffer) { - return buffer.get() & 0xFF; - } - - private static int getUnsignedShort(ByteBuffer buffer) { - int b1 = getUnsignedByte(buffer); - int b2 = getUnsignedByte(buffer); - return (b1 << 8) + (b2 << 0); - } - - private static String getUTF8(ByteBuffer buffer, int utfLen, char[] charArray) throws InvalidConstantPoolFormatException { - int utfLimit = buffer.position() + utfLen; - int index = 0; - while (buffer.position() < utfLimit) { - int c = buffer.get() & 0xff; - if (c > 127) { - buffer.position(buffer.position() - 1); - return getUTF8Extended(buffer, utfLimit, charArray, index); - } - charArray[index++] = (char)c; - } - return new String(charArray, 0, index); - } - - private static String getUTF8Extended(ByteBuffer buffer, int utfLimit, char[] charArray, int index) throws InvalidConstantPoolFormatException { - int c, c2, c3; - while (buffer.position() < utfLimit) { - c = buffer.get() & 0xff; - switch (c >> 4) { - case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: - /* 0xxxxxxx*/ - charArray[index++] = (char)c; - break; - case 12: case 13: - /* 110x xxxx 10xx xxxx*/ - c2 = buffer.get(); - if ((c2 & 0xC0) != 0x80) - throw new InvalidConstantPoolFormatException( - "malformed input around byte " + buffer.position()); - charArray[index++] = (char)(((c & 0x1F) << 6) | - (c2 & 0x3F)); - break; - case 14: - /* 1110 xxxx 10xx xxxx 10xx xxxx */ - c2 = buffer.get(); - c3 = buffer.get(); - if (((c2 & 0xC0) != 0x80) || ((c3 & 0xC0) != 0x80)) - throw new InvalidConstantPoolFormatException( - "malformed input around byte " + (buffer.position())); - charArray[index++] = (char)(((c & 0x0F) << 12) | - ((c2 & 0x3F) << 6) | - ((c3 & 0x3F) << 0)); - break; - default: - /* 10xx xxxx, 1111 xxxx */ - throw new InvalidConstantPoolFormatException( - "malformed input around byte " + buffer.position()); - } - } - // The number of chars produced may be less than utflen - return new String(charArray, 0, index); - } -} diff --git a/src/share/classes/sun/invoke/anon/ConstantPoolPatch.java b/src/share/classes/sun/invoke/anon/ConstantPoolPatch.java deleted file mode 100644 index d83c2a6d61a3bbd99d9008a581b4bde95632a17b..0000000000000000000000000000000000000000 --- a/src/share/classes/sun/invoke/anon/ConstantPoolPatch.java +++ /dev/null @@ -1,503 +0,0 @@ -/* - * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * 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.invoke.anon; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.Arrays; -import java.util.HashSet; -import java.util.IdentityHashMap; -import java.util.Map; - -import static sun.invoke.anon.ConstantPoolVisitor.*; - -/** A class and its patched constant pool. - * - * This class allow to modify (patch) a constant pool - * by changing the value of its entry. - * Entry are referenced using index that can be get - * by parsing the constant pool using - * {@link ConstantPoolParser#parse(ConstantPoolVisitor)}. - * - * @see ConstantPoolVisitor - * @see ConstantPoolParser#createPatch() - */ -public class ConstantPoolPatch { - final ConstantPoolParser outer; - final Object[] patchArray; - - ConstantPoolPatch(ConstantPoolParser outer) { - this.outer = outer; - this.patchArray = new Object[outer.getLength()]; - } - - /** Create a {@link ConstantPoolParser} and - * a {@link ConstantPoolPatch} in one step. - * Equivalent to {@code new ConstantPoolParser(classFile).createPatch()}. - * - * @param classFile an array of bytes containing a class. - * @see #ConstantPoolParser(Class) - */ - public ConstantPoolPatch(byte[] classFile) throws InvalidConstantPoolFormatException { - this(new ConstantPoolParser(classFile)); - } - - /** Create a {@link ConstantPoolParser} and - * a {@link ConstantPoolPatch} in one step. - * Equivalent to {@code new ConstantPoolParser(templateClass).createPatch()}. - * - * @param templateClass the class to parse. - * @see #ConstantPoolParser(Class) - */ - public ConstantPoolPatch(Class templateClass) throws IOException, InvalidConstantPoolFormatException { - this(new ConstantPoolParser(templateClass)); - } - - - /** Creates a patch from an existing patch. - * All changes are copied from that patch. - * @param patch a patch - * - * @see ConstantPoolParser#createPatch() - */ - public ConstantPoolPatch(ConstantPoolPatch patch) { - outer = patch.outer; - patchArray = patch.patchArray.clone(); - } - - /** Which parser built this patch? */ - public ConstantPoolParser getParser() { - return outer; - } - - /** Report the tag at the given index in the constant pool. */ - public byte getTag(int index) { - return outer.getTag(index); - } - - /** Report the current patch at the given index of the constant pool. - * Null means no patch will be made. - * To observe the unpatched entry at the given index, use - * {@link #getParser()}{@code .}@link ConstantPoolParser#parse(ConstantPoolVisitor)} - */ - public Object getPatch(int index) { - Object value = patchArray[index]; - if (value == null) return null; - switch (getTag(index)) { - case CONSTANT_Fieldref: - case CONSTANT_Methodref: - case CONSTANT_InterfaceMethodref: - if (value instanceof String) - value = stripSemis(2, (String) value); - break; - case CONSTANT_NameAndType: - if (value instanceof String) - value = stripSemis(1, (String) value); - break; - } - return value; - } - - /** Clear all patches. */ - public void clear() { - Arrays.fill(patchArray, null); - } - - /** Clear one patch. */ - public void clear(int index) { - patchArray[index] = null; - } - - /** Produce the patches as an array. */ - public Object[] getPatches() { - return patchArray.clone(); - } - - /** Produce the original constant pool as an array. */ - public Object[] getOriginalCP() throws InvalidConstantPoolFormatException { - return getOriginalCP(0, patchArray.length, -1); - } - - /** Walk the constant pool, applying patches using the given map. - * - * @param utf8Map Utf8 strings to modify, if encountered - * @param classMap Classes (or their names) to modify, if encountered - * @param valueMap Constant values to modify, if encountered - * @param deleteUsedEntries if true, delete map entries that are used - */ - public void putPatches(final Map utf8Map, - final Map classMap, - final Map valueMap, - boolean deleteUsedEntries) throws InvalidConstantPoolFormatException { - final HashSet usedUtf8Keys; - final HashSet usedClassKeys; - final HashSet usedValueKeys; - if (deleteUsedEntries) { - usedUtf8Keys = (utf8Map == null) ? null : new HashSet(); - usedClassKeys = (classMap == null) ? null : new HashSet(); - usedValueKeys = (valueMap == null) ? null : new HashSet(); - } else { - usedUtf8Keys = null; - usedClassKeys = null; - usedValueKeys = null; - } - - outer.parse(new ConstantPoolVisitor() { - - @Override - public void visitUTF8(int index, byte tag, String utf8) { - putUTF8(index, utf8Map.get(utf8)); - if (usedUtf8Keys != null) usedUtf8Keys.add(utf8); - } - - @Override - public void visitConstantValue(int index, byte tag, Object value) { - putConstantValue(index, tag, valueMap.get(value)); - if (usedValueKeys != null) usedValueKeys.add(value); - } - - @Override - public void visitConstantString(int index, byte tag, String name, int nameIndex) { - if (tag == CONSTANT_Class) { - putConstantValue(index, tag, classMap.get(name)); - if (usedClassKeys != null) usedClassKeys.add(name); - } else { - assert(tag == CONSTANT_String); - visitConstantValue(index, tag, name); - } - } - }); - if (usedUtf8Keys != null) utf8Map.keySet().removeAll(usedUtf8Keys); - if (usedClassKeys != null) classMap.keySet().removeAll(usedClassKeys); - if (usedValueKeys != null) valueMap.keySet().removeAll(usedValueKeys); - } - - Object[] getOriginalCP(final int startIndex, - final int endIndex, - final int tagMask) throws InvalidConstantPoolFormatException { - final Object[] cpArray = new Object[endIndex - startIndex]; - outer.parse(new ConstantPoolVisitor() { - - void show(int index, byte tag, Object value) { - if (index < startIndex || index >= endIndex) return; - if (((1 << tag) & tagMask) == 0) return; - cpArray[index - startIndex] = value; - } - - @Override - public void visitUTF8(int index, byte tag, String utf8) { - show(index, tag, utf8); - } - - @Override - public void visitConstantValue(int index, byte tag, Object value) { - assert(tag != CONSTANT_String); - show(index, tag, value); - } - - @Override - public void visitConstantString(int index, byte tag, - String value, int j) { - show(index, tag, value); - } - - @Override - public void visitMemberRef(int index, byte tag, - String className, String memberName, - String signature, - int j, int k) { - show(index, tag, new String[]{ className, memberName, signature }); - } - - @Override - public void visitDescriptor(int index, byte tag, - String memberName, String signature, - int j, int k) { - show(index, tag, new String[]{ memberName, signature }); - } - }); - return cpArray; - } - - /** Write the head (header plus constant pool) - * of the patched class file to the indicated stream. - */ - void writeHead(OutputStream out) throws IOException { - outer.writePatchedHead(out, patchArray); - } - - /** Write the tail (everything after the constant pool) - * of the patched class file to the indicated stream. - */ - void writeTail(OutputStream out) throws IOException { - outer.writeTail(out); - } - - private void checkConstantTag(byte tag, Object value) { - if (value == null) - throw new IllegalArgumentException( - "invalid null constant value"); - if (classForTag(tag) != value.getClass()) - throw new IllegalArgumentException( - "invalid constant value" - + (tag == CONSTANT_None ? "" - : " for tag "+tagName(tag)) - + " of class "+value.getClass()); - } - - private void checkTag(int index, byte putTag) { - byte tag = outer.tags[index]; - if (tag != putTag) - throw new IllegalArgumentException( - "invalid put operation" - + " for " + tagName(putTag) - + " at index " + index + " found " + tagName(tag)); - } - - private void checkTagMask(int index, int tagBitMask) { - byte tag = outer.tags[index]; - int tagBit = ((tag & 0x1F) == tag) ? (1 << tag) : 0; - if ((tagBit & tagBitMask) == 0) - throw new IllegalArgumentException( - "invalid put operation" - + " at index " + index + " found " + tagName(tag)); - } - - private static void checkMemberName(String memberName) { - if (memberName.indexOf(';') >= 0) - throw new IllegalArgumentException("memberName " + memberName + " contains a ';'"); - } - - /** Set the entry of the constant pool indexed by index to - * a new string. - * - * @param index an index to a constant pool entry containing a - * {@link ConstantPoolVisitor#CONSTANT_Utf8} value. - * @param utf8 a string - * - * @see ConstantPoolVisitor#visitUTF8(int, byte, String) - */ - public void putUTF8(int index, String utf8) { - if (utf8 == null) { clear(index); return; } - checkTag(index, CONSTANT_Utf8); - patchArray[index] = utf8; - } - - /** Set the entry of the constant pool indexed by index to - * a new value, depending on its dynamic type. - * - * @param index an index to a constant pool entry containing a - * one of the following structures: - * {@link ConstantPoolVisitor#CONSTANT_Integer}, - * {@link ConstantPoolVisitor#CONSTANT_Float}, - * {@link ConstantPoolVisitor#CONSTANT_Long}, - * {@link ConstantPoolVisitor#CONSTANT_Double}, - * {@link ConstantPoolVisitor#CONSTANT_String}, or - * {@link ConstantPoolVisitor#CONSTANT_Class} - * @param value a boxed int, float, long or double; or a string or class object - * @throws IllegalArgumentException if the type of the constant does not - * match the constant pool entry type, - * as reported by {@link #getTag(int)} - * - * @see #putConstantValue(int, byte, Object) - * @see ConstantPoolVisitor#visitConstantValue(int, byte, Object) - * @see ConstantPoolVisitor#visitConstantString(int, byte, String, int) - */ - public void putConstantValue(int index, Object value) { - if (value == null) { clear(index); return; } - byte tag = tagForConstant(value.getClass()); - checkConstantTag(tag, value); - checkTag(index, tag); - patchArray[index] = value; - } - - /** Set the entry of the constant pool indexed by index to - * a new value. - * - * @param index an index to a constant pool entry matching the given tag - * @param tag one of the following values: - * {@link ConstantPoolVisitor#CONSTANT_Integer}, - * {@link ConstantPoolVisitor#CONSTANT_Float}, - * {@link ConstantPoolVisitor#CONSTANT_Long}, - * {@link ConstantPoolVisitor#CONSTANT_Double}, - * {@link ConstantPoolVisitor#CONSTANT_String}, or - * {@link ConstantPoolVisitor#CONSTANT_Class} - * @param value a boxed number, string, or class object - * @throws IllegalArgumentException if the type of the constant does not - * match the constant pool entry type, or if a class name contains - * '/' or ';' - * - * @see #putConstantValue(int, Object) - * @see ConstantPoolVisitor#visitConstantValue(int, byte, Object) - * @see ConstantPoolVisitor#visitConstantString(int, byte, String, int) - */ - public void putConstantValue(int index, byte tag, Object value) { - if (value == null) { clear(index); return; } - checkTag(index, tag); - if (tag == CONSTANT_Class && value instanceof String) { - checkClassName((String) value); - } else if (tag == CONSTANT_String) { - // the JVM accepts any object as a patch for a string - } else { - // make sure the incoming value is the right type - checkConstantTag(tag, value); - } - checkTag(index, tag); - patchArray[index] = value; - } - - /** Set the entry of the constant pool indexed by index to - * a new {@link ConstantPoolVisitor#CONSTANT_NameAndType} value. - * - * @param index an index to a constant pool entry containing a - * {@link ConstantPoolVisitor#CONSTANT_NameAndType} value. - * @param memberName a memberName - * @param signature a signature - * @throws IllegalArgumentException if memberName contains the character ';' - * - * @see ConstantPoolVisitor#visitDescriptor(int, byte, String, String, int, int) - */ - public void putDescriptor(int index, String memberName, String signature) { - checkTag(index, CONSTANT_NameAndType); - checkMemberName(memberName); - patchArray[index] = addSemis(memberName, signature); - } - - /** Set the entry of the constant pool indexed by index to - * a new {@link ConstantPoolVisitor#CONSTANT_Fieldref}, - * {@link ConstantPoolVisitor#CONSTANT_Methodref}, or - * {@link ConstantPoolVisitor#CONSTANT_InterfaceMethodref} value. - * - * @param index an index to a constant pool entry containing a member reference - * @param className a class name - * @param memberName a field or method name - * @param signature a field or method signature - * @throws IllegalArgumentException if memberName contains the character ';' - * or signature is not a correct signature - * - * @see ConstantPoolVisitor#visitMemberRef(int, byte, String, String, String, int, int) - */ - public void putMemberRef(int index, byte tag, - String className, String memberName, String signature) { - checkTagMask(tag, CONSTANT_MemberRef_MASK); - checkTag(index, tag); - checkClassName(className); - checkMemberName(memberName); - if (signature.startsWith("(") == (tag == CONSTANT_Fieldref)) - throw new IllegalArgumentException("bad signature: "+signature); - patchArray[index] = addSemis(className, memberName, signature); - } - - static private final int CONSTANT_MemberRef_MASK = - CONSTANT_Fieldref - | CONSTANT_Methodref - | CONSTANT_InterfaceMethodref; - - private static final Map, Byte> CONSTANT_VALUE_CLASS_TAG - = new IdentityHashMap, Byte>(); - private static final Class[] CONSTANT_VALUE_CLASS = new Class[16]; - static { - Object[][] values = { - {Integer.class, CONSTANT_Integer}, - {Long.class, CONSTANT_Long}, - {Float.class, CONSTANT_Float}, - {Double.class, CONSTANT_Double}, - {String.class, CONSTANT_String}, - {Class.class, CONSTANT_Class} - }; - for (Object[] value : values) { - Class cls = (Class)value[0]; - Byte tag = (Byte) value[1]; - CONSTANT_VALUE_CLASS_TAG.put(cls, tag); - CONSTANT_VALUE_CLASS[(byte)tag] = cls; - } - } - - static Class classForTag(byte tag) { - if ((tag & 0xFF) >= CONSTANT_VALUE_CLASS.length) - return null; - return CONSTANT_VALUE_CLASS[tag]; - } - - static byte tagForConstant(Class cls) { - Byte tag = CONSTANT_VALUE_CLASS_TAG.get(cls); - return (tag == null) ? CONSTANT_None : (byte)tag; - } - - private static void checkClassName(String className) { - if (className.indexOf('/') >= 0 || className.indexOf(';') >= 0) - throw new IllegalArgumentException("invalid class name " + className); - } - - static String addSemis(String name, String... names) { - StringBuilder buf = new StringBuilder(name.length() * 5); - buf.append(name); - for (String name2 : names) { - buf.append(';').append(name2); - } - String res = buf.toString(); - assert(stripSemis(names.length, res)[0].equals(name)); - assert(stripSemis(names.length, res)[1].equals(names[0])); - assert(names.length == 1 || - stripSemis(names.length, res)[2].equals(names[1])); - return res; - } - - static String[] stripSemis(int count, String string) { - String[] res = new String[count+1]; - int pos = 0; - for (int i = 0; i < count; i++) { - int pos2 = string.indexOf(';', pos); - if (pos2 < 0) pos2 = string.length(); // yuck - res[i] = string.substring(pos, pos2); - pos = pos2; - } - res[count] = string.substring(pos); - return res; - } - - public String toString() { - StringBuilder buf = new StringBuilder(this.getClass().getName()); - buf.append("{"); - Object[] origCP = null; - for (int i = 0; i < patchArray.length; i++) { - if (patchArray[i] == null) continue; - if (origCP != null) { - buf.append(", "); - } else { - try { - origCP = getOriginalCP(); - } catch (InvalidConstantPoolFormatException ee) { - origCP = new Object[0]; - } - } - Object orig = (i < origCP.length) ? origCP[i] : "?"; - buf.append(orig).append("=").append(patchArray[i]); - } - buf.append("}"); - return buf.toString(); - } -} diff --git a/src/share/classes/sun/invoke/anon/ConstantPoolVisitor.java b/src/share/classes/sun/invoke/anon/ConstantPoolVisitor.java deleted file mode 100644 index dfec8b41151e22664f6d41c2932bae26c2301202..0000000000000000000000000000000000000000 --- a/src/share/classes/sun/invoke/anon/ConstantPoolVisitor.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright (c) 2008, 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.invoke.anon; - -/** - * A visitor called by {@link ConstantPoolParser#parse(ConstantPoolVisitor)} - * when a constant pool entry is parsed. - *

- * A visit* method is called when a constant pool entry is parsed. - * The first argument is always the constant pool index. - * The second argument is always the constant pool tag, - * even for methods like {@link #visitUTF8(int, byte, String)} which only apply to one tag. - * String arguments refer to Utf8 or NameAndType entries declared elsewhere, - * and are always accompanied by the indexes of those entries. - *

- * The order of the calls to the visit* methods is not necessarily related - * to the order of the entries in the constant pool. - * If one entry has a reference to another entry, the latter (lower-level) - * entry will be visited first. - *

- * The following table shows the relation between constant pool entry - * types and the corresponding visit* methods: - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
Tag(s)Method
{@link #CONSTANT_Utf8}{@link #visitUTF8(int, byte, String)}
{@link #CONSTANT_Integer}, {@link #CONSTANT_Float}, - * {@link #CONSTANT_Long}, {@link #CONSTANT_Double}{@link #visitConstantValue(int, byte, Object)}
{@link #CONSTANT_String}, {@link #CONSTANT_Class}{@link #visitConstantString(int, byte, String, int)}
{@link #CONSTANT_NameAndType}{@link #visitDescriptor(int, byte, String, String, int, int)}
{@link #CONSTANT_Fieldref}, - * {@link #CONSTANT_Methodref}, - * {@link #CONSTANT_InterfaceMethodref}{@link #visitMemberRef(int, byte, String, String, String, int, int)}
- * - * @see ConstantPoolPatch - * @author Remi Forax - * @author jrose - */ -public class ConstantPoolVisitor { - /** Called each time an UTF8 constant pool entry is found. - * @param index the constant pool index - * @param tag always {@link #CONSTANT_Utf8} - * @param utf8 string encoded in modified UTF-8 format passed as a {@code String} - * - * @see ConstantPoolPatch#putUTF8(int, String) - */ - public void visitUTF8(int index, byte tag, String utf8) { - // do nothing - } - - /** Called for each constant pool entry that encodes an integer, - * a float, a long, or a double. - * Constant strings and classes are not managed by this method but - * by {@link #visitConstantString(int, byte, String, int)}. - * - * @param index the constant pool index - * @param tag one of {@link #CONSTANT_Integer}, - * {@link #CONSTANT_Float}, - * {@link #CONSTANT_Long}, - * or {@link #CONSTANT_Double} - * @param value encoded value - * - * @see ConstantPoolPatch#putConstantValue(int, Object) - */ - public void visitConstantValue(int index, byte tag, Object value) { - // do nothing - } - - /** Called for each constant pool entry that encodes a string or a class. - * @param index the constant pool index - * @param tag one of {@link #CONSTANT_String}, - * {@link #CONSTANT_Class}, - * @param name string body or class name (using dot separator) - * @param nameIndex the index of the Utf8 string for the name - * - * @see ConstantPoolPatch#putConstantValue(int, byte, Object) - */ - public void visitConstantString(int index, byte tag, - String name, int nameIndex) { - // do nothing - } - - /** Called for each constant pool entry that encodes a name and type. - * @param index the constant pool index - * @param tag always {@link #CONSTANT_NameAndType} - * @param memberName a field or method name - * @param signature the member signature - * @param memberNameIndex index of the Utf8 string for the member name - * @param signatureIndex index of the Utf8 string for the signature - * - * @see ConstantPoolPatch#putDescriptor(int, String, String) - */ - public void visitDescriptor(int index, byte tag, - String memberName, String signature, - int memberNameIndex, int signatureIndex) { - // do nothing - } - - /** Called for each constant pool entry that encodes a field or method. - * @param index the constant pool index - * @param tag one of {@link #CONSTANT_Fieldref}, - * or {@link #CONSTANT_Methodref}, - * or {@link #CONSTANT_InterfaceMethodref} - * @param className the class name (using dot separator) - * @param memberName name of the field or method - * @param signature the field or method signature - * @param classNameIndex index of the Utf8 string for the class name - * @param descriptorIndex index of the NameAndType descriptor constant - * - * @see ConstantPoolPatch#putMemberRef(int, byte, String, String, String) - */ - public void visitMemberRef(int index, byte tag, - String className, String memberName, String signature, - int classNameIndex, int descriptorIndex) { - // do nothing - } - - public static final byte - CONSTANT_None = 0, - CONSTANT_Utf8 = 1, - //CONSTANT_Unicode = 2, /* unused */ - CONSTANT_Integer = 3, - CONSTANT_Float = 4, - CONSTANT_Long = 5, - CONSTANT_Double = 6, - CONSTANT_Class = 7, - CONSTANT_String = 8, - CONSTANT_Fieldref = 9, - CONSTANT_Methodref = 10, - CONSTANT_InterfaceMethodref = 11, - CONSTANT_NameAndType = 12; - - private static String[] TAG_NAMES = { - "Empty", - "Utf8", - null, //"Unicode", - "Integer", - "Float", - "Long", - "Double", - "Class", - "String", - "Fieldref", - "Methodref", - "InterfaceMethodref", - "NameAndType" - }; - - public static String tagName(byte tag) { - String name = null; - if ((tag & 0xFF) < TAG_NAMES.length) - name = TAG_NAMES[tag]; - if (name == null) - name = "Unknown#"+(tag&0xFF); - return name; - } -} diff --git a/src/share/classes/sun/launcher/resources/launcher_zh_TW.properties b/src/share/classes/sun/launcher/resources/launcher_zh_TW.properties index dc3bcfb01711bdc8cd6a0af278f929de825a1daa..949c138115189f0d323d39f0c048364afd145a53 100644 --- a/src/share/classes/sun/launcher/resources/launcher_zh_TW.properties +++ b/src/share/classes/sun/launcher/resources/launcher_zh_TW.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2007, 2016, 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 @@ -44,7 +44,7 @@ java.launcher.X.macosx.usage=\n\u4E0B\u5217\u662F Mac OS X \u7279\u5B9A\u9078\u9 java.launcher.cls.error1=\u932F\u8AA4: \u627E\u4E0D\u5230\u6216\u7121\u6CD5\u8F09\u5165\u4E3B\u8981\u985E\u5225 {0} java.launcher.cls.error2=\u932F\u8AA4: \u4E3B\u8981\u65B9\u6CD5\u4E0D\u662F\u985E\u5225 {1} \u4E2D\u7684 {0}\uFF0C\u8ACB\u5B9A\u7FA9\u4E3B\u8981\u65B9\u6CD5\u70BA:\n public static void main(String[] args) -java.launcher.cls.error3=\u932F\u8AA4: \u4E3B\u8981\u65B9\u6CD5\u5FC5\u9808\u50B3\u56DE\u985E\u5225 {0} \u4E2D void \u985E\u578B\u7684\u503C\uFF0C \n\u8ACB\u5B9A\u7FA9\u4E3B\u8981\u65B9\u6CD5\u70BA:\n public static void main(String[] args) +java.launcher.cls.error3=\u932F\u8AA4: \u4E3B\u8981\u65B9\u6CD5\u5FC5\u9808\u50B3\u56DE\u985E\u5225 {0} \u4E2D void \u985E\u578B\u7684\u503C\uFF0C\n\u8ACB\u5B9A\u7FA9\u4E3B\u8981\u65B9\u6CD5\u70BA:\n public static void main(String[] args) java.launcher.cls.error4=\u932F\u8AA4: \u5728\u985E\u5225 {0} \u4E2D\u627E\u4E0D\u5230\u4E3B\u8981\u65B9\u6CD5\uFF0C\u8ACB\u5B9A\u7FA9\u4E3B\u8981\u65B9\u6CD5\u70BA:\n public static void main(String[] args)\n\u6216\u8005 JavaFX \u61C9\u7528\u7A0B\u5F0F\u985E\u5225\u5FC5\u9808\u64F4\u5145 {1} java.launcher.cls.error5=\u932F\u8AA4: \u907A\u6F0F\u57F7\u884C\u6B64\u61C9\u7528\u7A0B\u5F0F\u6240\u9700\u7684 JavaFX \u7A0B\u5F0F\u5BE6\u969B\u57F7\u884C\u5143\u4EF6 java.launcher.jar.error1=\u932F\u8AA4: \u5617\u8A66\u958B\u555F\u6A94\u6848 {0} \u6642\u767C\u751F\u672A\u9810\u671F\u7684\u932F\u8AA4 diff --git a/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java b/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java index 3ff602b4aaaa67ebe9a9f939dc8fd66eec1da5e6..56287edbd0459f05cec8e2f459c4f55e3050f2dd 100644 --- a/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java +++ b/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java @@ -30,9 +30,12 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.io.Serializable; import java.lang.management.ManagementFactory; import java.net.InetAddress; import java.net.MalformedURLException; +import java.net.Socket; +import java.net.ServerSocket; import java.net.UnknownHostException; import java.rmi.NoSuchObjectException; import java.rmi.Remote; @@ -40,6 +43,7 @@ import java.rmi.RemoteException; import java.rmi.registry.Registry; import java.rmi.server.RMIClientSocketFactory; import java.rmi.server.RMIServerSocketFactory; +import java.rmi.server.RMISocketFactory; import java.rmi.server.RemoteObject; import java.rmi.server.UnicastRemoteObject; import java.security.KeyStore; @@ -59,6 +63,8 @@ import javax.management.remote.JMXServiceURL; import javax.management.remote.rmi.RMIConnectorServer; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManagerFactory; import javax.rmi.ssl.SslRMIClientSocketFactory; import javax.rmi.ssl.SslRMIServerSocketFactory; @@ -107,6 +113,8 @@ public final class ConnectorBootstrap { public static final String PORT = "com.sun.management.jmxremote.port"; + public static final String HOST = + "com.sun.management.jmxremote.host"; public static final String RMI_PORT = "com.sun.management.jmxremote.rmi.port"; public static final String CONFIG_FILE_NAME = @@ -424,10 +432,14 @@ public final class ConnectorBootstrap { checkAccessFile(accessFileName); } + final String bindAddress = + props.getProperty(PropertyNames.HOST); + if (log.debugOn()) { log.debug("startRemoteConnectorServer", Agent.getText("jmxremote.ConnectorBootstrap.starting") + "\n\t" + PropertyNames.PORT + "=" + port + + (bindAddress == null ? "" : "\n\t" + PropertyNames.HOST + "=" + bindAddress) + "\n\t" + PropertyNames.RMI_PORT + "=" + rmiPort + "\n\t" + PropertyNames.USE_SSL + "=" + useSsl + "\n\t" + PropertyNames.USE_REGISTRY_SSL + "=" + useRegistrySsl + @@ -458,7 +470,7 @@ public final class ConnectorBootstrap { sslConfigFileName, enabledCipherSuitesList, enabledProtocolsList, sslNeedClientAuth, useAuthentication, loginConfigName, - passwordFileName, accessFileName); + passwordFileName, accessFileName, bindAddress); cs = data.jmxConnectorServer; url = data.jmxRemoteURL; log.config("startRemoteConnectorServer", @@ -631,12 +643,13 @@ public final class ConnectorBootstrap { String sslConfigFileName, String[] enabledCipherSuites, String[] enabledProtocols, - boolean sslNeedClientAuth) { + boolean sslNeedClientAuth, + String bindAddress) { if (sslConfigFileName == null) { - return new SslRMIServerSocketFactory( + return new HostAwareSslSocketFactory( enabledCipherSuites, enabledProtocols, - sslNeedClientAuth); + sslNeedClientAuth, bindAddress); } else { checkRestrictedFile(sslConfigFileName); try { @@ -690,11 +703,11 @@ public final class ConnectorBootstrap { SSLContext ctx = SSLContext.getInstance("SSL"); ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); - return new SslRMIServerSocketFactory( + return new HostAwareSslSocketFactory( ctx, enabledCipherSuites, enabledProtocols, - sslNeedClientAuth); + sslNeedClientAuth, bindAddress); } catch (Exception e) { throw new AgentConfigurationError(AGENT_EXCEPTION, e, e.toString()); } @@ -714,7 +727,8 @@ public final class ConnectorBootstrap { boolean useAuthentication, String loginConfigName, String passwordFileName, - String accessFileName) + String accessFileName, + String bindAddress) throws IOException, MalformedURLException { /* Make sure we use non-guessable RMI object IDs. Otherwise @@ -722,7 +736,7 @@ public final class ConnectorBootstrap { * IDs. */ System.setProperty("java.rmi.server.randomIDs", "true"); - JMXServiceURL url = new JMXServiceURL("rmi", null, rmiPort); + JMXServiceURL url = new JMXServiceURL("rmi", bindAddress, rmiPort); Map env = new HashMap<>(); @@ -733,6 +747,8 @@ public final class ConnectorBootstrap { String[].class.getName(), String.class.getName() }); + boolean useSocketFactory = bindAddress != null && !useSsl; + if (useAuthentication) { if (loginConfigName != null) { env.put("jmx.remote.x.login.config", loginConfigName); @@ -757,7 +773,7 @@ public final class ConnectorBootstrap { csf = new SslRMIClientSocketFactory(); ssf = createSslRMIServerSocketFactory( sslConfigFileName, enabledCipherSuites, - enabledProtocols, sslNeedClientAuth); + enabledProtocols, sslNeedClientAuth, bindAddress); } if (useSsl) { @@ -767,6 +783,12 @@ public final class ConnectorBootstrap { ssf); } + if (useSocketFactory) { + ssf = new HostAwareSocketFactory(bindAddress); + env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, + ssf); + } + JMXConnectorServer connServer = null; try { connServer = @@ -786,6 +808,10 @@ public final class ConnectorBootstrap { registry = new SingleEntryRegistry(port, csf, ssf, "jmxrmi", exporter.firstExported); + } else if (useSocketFactory) { + registry = + new SingleEntryRegistry(port, csf, ssf, + "jmxrmi", exporter.firstExported); } else { registry = new SingleEntryRegistry(port, @@ -819,4 +845,172 @@ public final class ConnectorBootstrap { private static final ClassLogger log = new ClassLogger(ConnectorBootstrap.class.getPackage().getName(), "ConnectorBootstrap"); + + private static class HostAwareSocketFactory implements RMIServerSocketFactory { + + private final String bindAddress; + + private HostAwareSocketFactory(String bindAddress) { + this.bindAddress = bindAddress; + } + + @Override + public ServerSocket createServerSocket(int port) throws IOException { + if (bindAddress == null) { + return new ServerSocket(port); + } else { + try { + InetAddress addr = InetAddress.getByName(bindAddress); + return new ServerSocket(port, 0, addr); + } catch (UnknownHostException e) { + return new ServerSocket(port); + } + } + } + } + + private static class HostAwareSslSocketFactory extends SslRMIServerSocketFactory { + + private final String bindAddress; + private final String[] enabledCipherSuites; + private final String[] enabledProtocols; + private final boolean needClientAuth; + private final SSLContext context; + + private HostAwareSslSocketFactory(String[] enabledCipherSuites, + String[] enabledProtocols, + boolean sslNeedClientAuth, + String bindAddress) throws IllegalArgumentException { + this(null, enabledCipherSuites, enabledProtocols, sslNeedClientAuth, bindAddress); + } + + private HostAwareSslSocketFactory(SSLContext ctx, + String[] enabledCipherSuites, + String[] enabledProtocols, + boolean sslNeedClientAuth, + String bindAddress) throws IllegalArgumentException { + this.context = ctx; + this.bindAddress = bindAddress; + this.enabledProtocols = enabledProtocols; + this.enabledCipherSuites = enabledCipherSuites; + this.needClientAuth = sslNeedClientAuth; + checkValues(ctx, enabledCipherSuites, enabledProtocols); + } + + @Override + public ServerSocket createServerSocket(int port) throws IOException { + if (bindAddress != null) { + try { + InetAddress addr = InetAddress.getByName(bindAddress); + return new SslServerSocket(port, 0, addr, context, + enabledCipherSuites, enabledProtocols, needClientAuth); + } catch (UnknownHostException e) { + return new SslServerSocket(port, context, + enabledCipherSuites, enabledProtocols, needClientAuth); + } + } else { + return new SslServerSocket(port, context, + enabledCipherSuites, enabledProtocols, needClientAuth); + } + } + + private static void checkValues(SSLContext context, + String[] enabledCipherSuites, + String[] enabledProtocols) throws IllegalArgumentException { + // Force the initialization of the default at construction time, + // rather than delaying it to the first time createServerSocket() + // is called. + // + final SSLSocketFactory sslSocketFactory = + context == null ? + (SSLSocketFactory)SSLSocketFactory.getDefault() : context.getSocketFactory(); + SSLSocket sslSocket = null; + if (enabledCipherSuites != null || enabledProtocols != null) { + try { + sslSocket = (SSLSocket) sslSocketFactory.createSocket(); + } catch (Exception e) { + final String msg = "Unable to check if the cipher suites " + + "and protocols to enable are supported"; + throw (IllegalArgumentException) + new IllegalArgumentException(msg).initCause(e); + } + } + + // Check if all the cipher suites and protocol versions to enable + // are supported by the underlying SSL/TLS implementation and if + // true create lists from arrays. + // + if (enabledCipherSuites != null) { + sslSocket.setEnabledCipherSuites(enabledCipherSuites); + } + if (enabledProtocols != null) { + sslSocket.setEnabledProtocols(enabledProtocols); + } + } + } + + private static class SslServerSocket extends ServerSocket { + + private static SSLSocketFactory defaultSSLSocketFactory; + private final String[] enabledCipherSuites; + private final String[] enabledProtocols; + private final boolean needClientAuth; + private final SSLContext context; + + private SslServerSocket(int port, + SSLContext ctx, + String[] enabledCipherSuites, + String[] enabledProtocols, + boolean needClientAuth) throws IOException { + super(port); + this.enabledProtocols = enabledProtocols; + this.enabledCipherSuites = enabledCipherSuites; + this.needClientAuth = needClientAuth; + this.context = ctx; + } + + private SslServerSocket(int port, + int backlog, + InetAddress bindAddr, + SSLContext ctx, + String[] enabledCipherSuites, + String[] enabledProtocols, + boolean needClientAuth) throws IOException { + super(port, backlog, bindAddr); + this.enabledProtocols = enabledProtocols; + this.enabledCipherSuites = enabledCipherSuites; + this.needClientAuth = needClientAuth; + this.context = ctx; + } + + @Override + public Socket accept() throws IOException { + final SSLSocketFactory sslSocketFactory = + context == null ? + getDefaultSSLSocketFactory() : context.getSocketFactory(); + Socket socket = super.accept(); + SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket( + socket, socket.getInetAddress().getHostName(), + socket.getPort(), true); + sslSocket.setUseClientMode(false); + if (enabledCipherSuites != null) { + sslSocket.setEnabledCipherSuites(enabledCipherSuites); + } + if (enabledProtocols != null) { + sslSocket.setEnabledProtocols(enabledProtocols); + } + sslSocket.setNeedClientAuth(needClientAuth); + return sslSocket; + } + + private static synchronized SSLSocketFactory getDefaultSSLSocketFactory() { + if (defaultSSLSocketFactory == null) { + defaultSSLSocketFactory = (SSLSocketFactory)SSLSocketFactory.getDefault(); + return defaultSSLSocketFactory; + } else { + return defaultSSLSocketFactory; + } + } + + } } diff --git a/src/share/classes/sun/management/resources/agent_zh_TW.properties b/src/share/classes/sun/management/resources/agent_zh_TW.properties index e75cb6d6bb3cd83bfa29e8e66b50f78cbb7d02bc..5b2208b41d9f7aa15a783918a4ea8f64f0f787ca 100644 --- a/src/share/classes/sun/management/resources/agent_zh_TW.properties +++ b/src/share/classes/sun/management/resources/agent_zh_TW.properties @@ -1,6 +1,6 @@ # # -# Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2016, 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 @@ -31,10 +31,10 @@ agent.err.error = \u932F\u8AA4 agent.err.exception = \u4EE3\u7406\u7A0B\u5F0F\u767C\u751F\u7570\u5E38 agent.err.warning = \u8B66\u544A -agent.err.configfile.notfound = \u627E\u4E0D\u5230\u914D\u7F6E\u6A94\u6848 -agent.err.configfile.failed = \u7121\u6CD5\u8B80\u53D6\u914D\u7F6E\u6A94\u6848 -agent.err.configfile.closed.failed = \u7121\u6CD5\u95DC\u9589\u914D\u7F6E\u6A94\u6848 -agent.err.configfile.access.denied = \u5B58\u53D6\u914D\u7F6E\u6A94\u6848\u906D\u5230\u62D2\u7D55 +agent.err.configfile.notfound = \u627E\u4E0D\u5230\u7D44\u614B\u6A94\u6848 +agent.err.configfile.failed = \u7121\u6CD5\u8B80\u53D6\u7D44\u614B\u6A94\u6848 +agent.err.configfile.closed.failed = \u7121\u6CD5\u95DC\u9589\u7D44\u614B\u6A94\u6848 +agent.err.configfile.access.denied = \u5B58\u53D6\u7D44\u614B\u6A94\u6848\u906D\u5230\u62D2\u7D55 agent.err.exportaddress.failed = \u5C07 JMX \u9023\u63A5\u5668\u4F4D\u5740\u532F\u51FA\u81F3\u8A2D\u5099\u7DE9\u885D\u5340\u5931\u6557 diff --git a/src/share/classes/sun/nio/ch/Util.java b/src/share/classes/sun/nio/ch/Util.java index dca91d6e8b26532b254fccb97f23a5df314745f0..3c61f83b42237759aace854764aed80805278841 100644 --- a/src/share/classes/sun/nio/ch/Util.java +++ b/src/share/classes/sun/nio/ch/Util.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2016, 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 @@ -47,6 +47,9 @@ public class Util { // The number of temp buffers in our pool private static final int TEMP_BUF_POOL_SIZE = IOUtil.IOV_MAX; + // The max size allowed for a cached temp buffer, in bytes + private static final long MAX_CACHED_BUFFER_SIZE = getMaxCachedBufferSize(); + // Per-thread cache of temporary direct buffers private static ThreadLocal bufferCache = new ThreadLocal() @@ -57,6 +60,52 @@ public class Util { } }; + /** + * Returns the max size allowed for a cached temp buffers, in + * bytes. It defaults to Long.MAX_VALUE. It can be set with the + * jdk.nio.maxCachedBufferSize property. Even though + * ByteBuffer.capacity() returns an int, we're using a long here + * for potential future-proofing. + */ + private static long getMaxCachedBufferSize() { + String s = java.security.AccessController.doPrivileged( + new PrivilegedAction() { + @Override + public String run() { + return System.getProperty("jdk.nio.maxCachedBufferSize"); + } + }); + if (s != null) { + try { + long m = Long.parseLong(s); + if (m >= 0) { + return m; + } else { + // if it's negative, ignore the system property + } + } catch (NumberFormatException e) { + // if the string is not well formed, ignore the system property + } + } + return Long.MAX_VALUE; + } + + /** + * Returns true if a buffer of this size is too large to be + * added to the buffer cache, false otherwise. + */ + private static boolean isBufferTooLarge(int size) { + return size > MAX_CACHED_BUFFER_SIZE; + } + + /** + * Returns true if the buffer is too large to be added to the + * buffer cache, false otherwise. + */ + private static boolean isBufferTooLarge(ByteBuffer buf) { + return isBufferTooLarge(buf.capacity()); + } + /** * A simple cache of direct buffers. */ @@ -83,6 +132,9 @@ public class Util { * size (or null if no suitable buffer is found). */ ByteBuffer get(int size) { + // Don't call this if the buffer would be too large. + assert !isBufferTooLarge(size); + if (count == 0) return null; // cache is empty @@ -120,6 +172,9 @@ public class Util { } boolean offerFirst(ByteBuffer buf) { + // Don't call this if the buffer is too large. + assert !isBufferTooLarge(buf); + if (count >= TEMP_BUF_POOL_SIZE) { return false; } else { @@ -131,6 +186,9 @@ public class Util { } boolean offerLast(ByteBuffer buf) { + // Don't call this if the buffer is too large. + assert !isBufferTooLarge(buf); + if (count >= TEMP_BUF_POOL_SIZE) { return false; } else { @@ -159,6 +217,15 @@ public class Util { * Returns a temporary buffer of at least the given size */ public static ByteBuffer getTemporaryDirectBuffer(int size) { + // If a buffer of this size is too large for the cache, there + // should not be a buffer in the cache that is at least as + // large. So we'll just create a new one. Also, we don't have + // to remove the buffer from the cache (as this method does + // below) given that we won't put the new buffer in the cache. + if (isBufferTooLarge(size)) { + return ByteBuffer.allocateDirect(size); + } + BufferCache cache = bufferCache.get(); ByteBuffer buf = cache.get(size); if (buf != null) { @@ -188,6 +255,13 @@ public class Util { * likely to be returned by a subsequent call to getTemporaryDirectBuffer. */ static void offerFirstTemporaryDirectBuffer(ByteBuffer buf) { + // If the buffer is too large for the cache we don't have to + // check the cache. We'll just free it. + if (isBufferTooLarge(buf)) { + free(buf); + return; + } + assert buf != null; BufferCache cache = bufferCache.get(); if (!cache.offerFirst(buf)) { @@ -203,6 +277,13 @@ public class Util { * cache in same order that they were obtained. */ static void offerLastTemporaryDirectBuffer(ByteBuffer buf) { + // If the buffer is too large for the cache we don't have to + // check the cache. We'll just free it. + if (isBufferTooLarge(buf)) { + free(buf); + return; + } + assert buf != null; BufferCache cache = bufferCache.get(); if (!cache.offerLast(buf)) { diff --git a/src/share/classes/sun/rmi/server/resources/rmid_zh_TW.properties b/src/share/classes/sun/rmi/server/resources/rmid_zh_TW.properties index 2905dc495a98ccb17d8a4edee003dedad8887a5f..1a32abcb44871e3240eef8731d0e527df27b63ef 100644 --- a/src/share/classes/sun/rmi/server/resources/rmid_zh_TW.properties +++ b/src/share/classes/sun/rmi/server/resources/rmid_zh_TW.properties @@ -1,6 +1,6 @@ # # -# Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1998, 2016, 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 @@ -71,7 +71,7 @@ rmid.group.inactive=rmid: \u555F\u52D5\u7FA4\u7D44\u672A\u5728\u4F7F\u7528\u4E2D # "Activation.main", "sun.rmi.activation.execPolicy", "ExecPermission" and # "ExecOptionPermission" should not be translated, since they refer to # class/permission names. -rmid.exec.perms.inadequate=Activation.main: \u8B66\u544A: sun.rmi.activation.execPolicy \u7CFB\u7D71\n\u5C6C\u6027\u672A\u6307\u5B9A\uFF0C\u4E26\u4E14\u672A\u6388\u4E88 ExecPermissions/ExecOptionPermissions; \n\u5F8C\u7E8C\u7684\u555F\u52D5\u5617\u8A66\u53EF\u80FD\u6703\u56E0\u70BA\u672A\u6210\u529F\u7684\nExecPermission/ExecOptionPermission \u6B0A\u9650\u6AA2\u67E5\u800C\u5931\u6557\u3002\u5982\u9700\n\u95DC\u65BC\u5982\u4F55\u914D\u7F6E rmid \u5B89\u5168\u7684\u8AAA\u660E\u6587\u4EF6\uFF0C\u8ACB\u53C3\u8003:\n\nhttp://java.sun.com/j2se/1.4/docs/tooldocs/solaris/rmid.html\nhttp://java.sun.com/j2se/1.4/docs/tooldocs/win32/rmid.html\n +rmid.exec.perms.inadequate=Activation.main: \u8B66\u544A: sun.rmi.activation.execPolicy \u7CFB\u7D71\n\u5C6C\u6027\u672A\u6307\u5B9A\uFF0C\u4E26\u4E14\u672A\u6388\u4E88 ExecPermissions/ExecOptionPermissions; \n\u5F8C\u7E8C\u7684\u555F\u52D5\u5617\u8A66\u53EF\u80FD\u6703\u56E0\u70BA\u672A\u6210\u529F\u7684\nExecPermission/ExecOptionPermission \u6B0A\u9650\u6AA2\u67E5\u800C\u5931\u6557\u3002\u5982\u9700\n\u95DC\u65BC\u5982\u4F55\u8A2D\u5B9A rmid \u5B89\u5168\u7684\u8AAA\u660E\u6587\u4EF6\uFF0C\u8ACB\u53C3\u8003:\n\nhttp://java.sun.com/j2se/1.4/docs/tooldocs/solaris/rmid.html\nhttp://java.sun.com/j2se/1.4/docs/tooldocs/win32/rmid.html\n # "rmid", "-port", "-log", "-stop", "-C" and "-J" should not be translated, # because they are syntax diff --git a/src/share/classes/sun/rmi/transport/DGCAckHandler.java b/src/share/classes/sun/rmi/transport/DGCAckHandler.java index 7f704400e443f01c70edafc90d93cce70704de53..18e9ec01aa46cc561c195ef02a9db2af0ac5cf12 100644 --- a/src/share/classes/sun/rmi/transport/DGCAckHandler.java +++ b/src/share/classes/sun/rmi/transport/DGCAckHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -118,6 +118,9 @@ public class DGCAckHandler { if (objList != null && task == null) { task = scheduler.schedule(new Runnable() { public void run() { + if (id != null) { + idTable.remove(id); + } release(); } }, dgcAckTimeout, TimeUnit.MILLISECONDS); diff --git a/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java b/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java index ca4d2d3499b236d4801ae8bc5cf44c5ff069e1bf..25fc78c24922d65a14db1b771208125eb3eef4fb 100644 --- a/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java +++ b/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2016, 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 @@ -383,19 +383,19 @@ public final class PKCS12KeyStore extends KeyStoreSpi { // decode secret key } else { - SecretKeyFactory sKeyFactory = - SecretKeyFactory.getInstance(keyAlgo); byte[] keyBytes = in.getOctetString(); SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, keyAlgo); // Special handling required for PBE: needs a PBEKeySpec if (keyAlgo.startsWith("PBE")) { + SecretKeyFactory sKeyFactory = + SecretKeyFactory.getInstance(keyAlgo); KeySpec pbeKeySpec = sKeyFactory.getKeySpec(secretKeySpec, PBEKeySpec.class); key = sKeyFactory.generateSecret(pbeKeySpec); } else { - key = sKeyFactory.generateSecret(secretKeySpec); + key = secretKeySpec; } if (debug != null) { diff --git a/src/share/classes/sun/security/provider/certpath/AdaptableX509CertSelector.java b/src/share/classes/sun/security/provider/certpath/AdaptableX509CertSelector.java index db36c0e4a44334ac02b40ecf7185c7fa24766d96..0ad5387b3248977c23e79f565d96f3b9bdc185ce 100644 --- a/src/share/classes/sun/security/provider/certpath/AdaptableX509CertSelector.java +++ b/src/share/classes/sun/security/provider/certpath/AdaptableX509CertSelector.java @@ -36,9 +36,7 @@ import java.util.Date; import sun.security.util.Debug; import sun.security.util.DerInputStream; -import sun.security.util.DerOutputStream; import sun.security.x509.SerialNumber; -import sun.security.x509.KeyIdentifier; import sun.security.x509.AuthorityKeyIdentifierExtension; /** @@ -131,13 +129,7 @@ class AdaptableX509CertSelector extends X509CertSelector { serial = null; if (ext != null) { - KeyIdentifier akid = (KeyIdentifier)ext.get( - AuthorityKeyIdentifierExtension.KEY_ID); - if (akid != null) { - DerOutputStream derout = new DerOutputStream(); - derout.putOctetString(akid.getIdentifier()); - ski = derout.toByteArray(); - } + ski = ext.getEncodedKeyIdentifier(); SerialNumber asn = (SerialNumber)ext.get( AuthorityKeyIdentifierExtension.SERIAL_NUMBER); if (asn != null) { diff --git a/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java b/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java index 7b1076ef34cfbd642db563a808d3051adfde5afd..086e73f64c938fa1b404c699bd2aa5fa11bc23ba 100644 --- a/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java +++ b/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java @@ -33,7 +33,6 @@ import javax.security.auth.x500.X500Principal; import java.util.*; import sun.security.util.Debug; -import sun.security.util.DerOutputStream; import static sun.security.x509.PKIXExtensions.*; import sun.security.x509.*; @@ -608,12 +607,9 @@ public class DistributionPointFetcher { AuthorityKeyIdentifierExtension akidext = crlImpl.getAuthKeyIdExtension(); if (akidext != null) { - KeyIdentifier akid = (KeyIdentifier)akidext.get( - AuthorityKeyIdentifierExtension.KEY_ID); - if (akid != null) { - DerOutputStream derout = new DerOutputStream(); - derout.putOctetString(akid.getIdentifier()); - certSel.setSubjectKeyIdentifier(derout.toByteArray()); + byte[] kid = akidext.getEncodedKeyIdentifier(); + if (kid != null) { + certSel.setSubjectKeyIdentifier(kid); } SerialNumber asn = (SerialNumber)akidext.get( diff --git a/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java b/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java index 7f30d3b0ceb7f732e8142485d5e592637b044832..3c86d6206ffbfcff0e5816ecf1259f990a4c580c 100644 --- a/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java +++ b/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java @@ -46,9 +46,10 @@ import sun.security.provider.certpath.PKIX.BuilderParams; import sun.security.util.Debug; import sun.security.x509.AccessDescription; import sun.security.x509.AuthorityInfoAccessExtension; +import sun.security.x509.AuthorityKeyIdentifierExtension; import static sun.security.x509.PKIXExtensions.*; import sun.security.x509.X500Name; -import sun.security.x509.AuthorityKeyIdentifierExtension; +import sun.security.x509.X509CertImpl; /** * This class represents a forward builder, which is able to retrieve @@ -69,7 +70,6 @@ class ForwardBuilder extends Builder { private AdaptableX509CertSelector caSelector; private X509CertSelector caTargetSelector; TrustAnchor trustAnchor; - private Comparator comparator; private boolean searchAllCertStores = true; /** @@ -93,7 +93,6 @@ class ForwardBuilder extends Builder { trustedSubjectDNs.add(anchor.getCA()); } } - comparator = new PKIXCertComparator(trustedSubjectDNs); this.searchAllCertStores = searchAllCertStores; } @@ -122,6 +121,8 @@ class ForwardBuilder extends Builder { * As each cert is added, it is sorted based on the PKIXCertComparator * algorithm. */ + Comparator comparator = + new PKIXCertComparator(trustedSubjectDNs, currState.cert); Set certs = new TreeSet<>(comparator); /* @@ -264,14 +265,6 @@ class ForwardBuilder extends Builder { CertPathHelper.setPathToNames (caSelector, currentState.subjectNamesTraversed); - /* - * Facilitate certification path construction with authority - * key identifier and subject key identifier. - */ - AuthorityKeyIdentifierExtension akidext = - currentState.cert.getAuthorityKeyIdentifierExtension(); - caSelector.setSkiAndSerialNumber(akidext); - /* * check the validity period */ @@ -404,41 +397,68 @@ class ForwardBuilder extends Builder { * * Preference order for current cert: * - * 1) Issuer matches a trusted subject + * 1) The key identifier of an AKID extension (if present) in the + * previous certificate matches the key identifier in the SKID extension + * + * 2) Issuer matches a trusted subject * Issuer: ou=D,ou=C,o=B,c=A * - * 2) Issuer is a descendant of a trusted subject (in order of + * 3) Issuer is a descendant of a trusted subject (in order of * number of links to the trusted subject) * a) Issuer: ou=E,ou=D,ou=C,o=B,c=A [links=1] * b) Issuer: ou=F,ou=E,ou=D,ou=C,ou=B,c=A [links=2] * - * 3) Issuer is an ancestor of a trusted subject (in order of number of + * 4) Issuer is an ancestor of a trusted subject (in order of number of * links to the trusted subject) * a) Issuer: ou=C,o=B,c=A [links=1] * b) Issuer: o=B,c=A [links=2] * - * 4) Issuer is in the same namespace as a trusted subject (in order of + * 5) Issuer is in the same namespace as a trusted subject (in order of * number of links to the trusted subject) * a) Issuer: ou=G,ou=C,o=B,c=A [links=2] * b) Issuer: ou=H,o=B,c=A [links=3] * - * 5) Issuer is an ancestor of certificate subject (in order of number + * 6) Issuer is an ancestor of certificate subject (in order of number * of links to the certificate subject) * a) Issuer: ou=K,o=J,c=A * Subject: ou=L,ou=K,o=J,c=A * b) Issuer: o=J,c=A * Subject: ou=L,ou=K,0=J,c=A * - * 6) Any other certificates + * 7) Any other certificates */ static class PKIXCertComparator implements Comparator { - final static String METHOD_NME = "PKIXCertComparator.compare()"; + static final String METHOD_NME = "PKIXCertComparator.compare()"; private final Set trustedSubjectDNs; + private final X509CertSelector certSkidSelector; - PKIXCertComparator(Set trustedSubjectDNs) { + PKIXCertComparator(Set trustedSubjectDNs, + X509CertImpl previousCert) throws IOException { this.trustedSubjectDNs = trustedSubjectDNs; + this.certSkidSelector = getSelector(previousCert); + } + + /** + * Returns an X509CertSelector for matching on the authority key + * identifier, or null if not applicable. + */ + private X509CertSelector getSelector(X509CertImpl previousCert) + throws IOException { + if (previousCert != null) { + AuthorityKeyIdentifierExtension akidExt = + previousCert.getAuthorityKeyIdentifierExtension(); + if (akidExt != null) { + byte[] skid = akidExt.getEncodedKeyIdentifier(); + if (skid != null) { + X509CertSelector selector = new X509CertSelector(); + selector.setSubjectKeyIdentifier(skid); + return selector; + } + } + } + return null; } /** @@ -462,6 +482,16 @@ class ForwardBuilder extends Builder { // if certs are the same, return 0 if (oCert1.equals(oCert2)) return 0; + // If akid/skid match then it is preferable + if (certSkidSelector != null) { + if (certSkidSelector.match(oCert1)) { + return -1; + } + if (certSkidSelector.match(oCert2)) { + return 1; + } + } + X500Principal cIssuer1 = oCert1.getIssuerX500Principal(); X500Principal cIssuer2 = oCert2.getIssuerX500Principal(); X500Name cIssuer1Name = X500Name.asX500Name(cIssuer1); diff --git a/src/share/classes/sun/security/ssl/HandshakeMessage.java b/src/share/classes/sun/security/ssl/HandshakeMessage.java index e921ea061a4aaf26a0652a5ba4156bbfe4713411..8ecaf786898465ae971a3cd24d565b0bb0ee351a 100644 --- a/src/share/classes/sun/security/ssl/HandshakeMessage.java +++ b/src/share/classes/sun/security/ssl/HandshakeMessage.java @@ -812,8 +812,9 @@ class DH_ServerKeyExchange extends ServerKeyExchange if (!localSupportedSignAlgs.contains( preferableSignatureAlgorithm)) { throw new SSLHandshakeException( - "Unsupported SignatureAndHashAlgorithm in " + - "ServerKeyExchange message"); + "Unsupported SignatureAndHashAlgorithm in " + + "ServerKeyExchange message: " + + preferableSignatureAlgorithm); } } else { this.preferableSignatureAlgorithm = null; @@ -846,7 +847,8 @@ class DH_ServerKeyExchange extends ServerKeyExchange sig = RSASignature.getInstance(); break; default: - throw new SSLKeyException("neither an RSA or a DSA key"); + throw new SSLKeyException( + "neither an RSA or a DSA key: " + algorithm); } } @@ -1096,7 +1098,8 @@ class ECDH_ServerKeyExchange extends ServerKeyExchange { preferableSignatureAlgorithm)) { throw new SSLHandshakeException( "Unsupported SignatureAndHashAlgorithm in " + - "ServerKeyExchange message"); + "ServerKeyExchange message: " + + preferableSignatureAlgorithm); } } @@ -1136,7 +1139,8 @@ class ECDH_ServerKeyExchange extends ServerKeyExchange { case "RSA": return RSASignature.getInstance(); default: - throw new NoSuchAlgorithmException("neither an RSA or a EC key"); + throw new NoSuchAlgorithmException( + "neither an RSA or a EC key : " + keyAlgorithm); } } @@ -1343,7 +1347,8 @@ class CertificateRequest extends HandshakeMessage algorithmsLen = input.getInt16(); if (algorithmsLen < 2) { throw new SSLProtocolException( - "Invalid supported_signature_algorithms field"); + "Invalid supported_signature_algorithms field: " + + algorithmsLen); } algorithms = new ArrayList(); @@ -1362,7 +1367,8 @@ class CertificateRequest extends HandshakeMessage if (remains != 0) { throw new SSLProtocolException( - "Invalid supported_signature_algorithms field"); + "Invalid supported_signature_algorithms field. remains: " + + remains); } } else { algorithms = new ArrayList(); @@ -1379,7 +1385,8 @@ class CertificateRequest extends HandshakeMessage } if (len != 0) { - throw new SSLProtocolException("Bad CertificateRequest DN length"); + throw new SSLProtocolException( + "Bad CertificateRequest DN length: " + len); } authorities = v.toArray(new DistinguishedName[v.size()]); @@ -1609,8 +1616,8 @@ static final class CertificateVerify extends HandshakeMessage { if (!localSupportedSignAlgs.contains( preferableSignatureAlgorithm)) { throw new SSLHandshakeException( - "Unsupported SignatureAndHashAlgorithm in " + - "CertificateVerify message"); + "Unsupported SignatureAndHashAlgorithm in " + + "CertificateVerify message: " + preferableSignatureAlgorithm); } } @@ -1977,7 +1984,8 @@ static final class Finished extends HandshakeMessage { SecretKey prfKey = kg.generateKey(); if ("RAW".equals(prfKey.getFormat()) == false) { throw new ProviderException( - "Invalid PRF output, format must be RAW"); + "Invalid PRF output, format must be RAW. " + + "Format received: " + prfKey.getFormat()); } byte[] finished = prfKey.getEncoded(); return finished; diff --git a/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java b/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java index 038cf2a46765a5be12ac3aec5b41a188458522b7..783146cf467eba7e7adcc1691d27b68c3ce5e111 100644 --- a/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java +++ b/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2016, 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 @@ -67,7 +67,8 @@ final class RSAClientKeyExchange extends HandshakeMessage { ProtocolVersion maxVersion, SecureRandom generator, PublicKey publicKey) throws IOException { if (publicKey.getAlgorithm().equals("RSA") == false) { - throw new SSLKeyException("Public key not of type RSA"); + throw new SSLKeyException("Public key not of type RSA: " + + publicKey.getAlgorithm()); } this.protocolVersion = protocolVersion; @@ -98,7 +99,8 @@ final class RSAClientKeyExchange extends HandshakeMessage { int messageSize, PrivateKey privateKey) throws IOException { if (privateKey.getAlgorithm().equals("RSA") == false) { - throw new SSLKeyException("Private key not of type RSA"); + throw new SSLKeyException("Private key not of type RSA: " + + privateKey.getAlgorithm()); } if (currentVersion.v >= ProtocolVersion.TLS10.v) { @@ -113,10 +115,31 @@ final class RSAClientKeyExchange extends HandshakeMessage { byte[] encoded = null; try { + boolean needFailover = false; Cipher cipher = JsseJce.getCipher(JsseJce.CIPHER_RSA_PKCS1); - boolean needFailover = !KeyUtil.isOracleJCEProvider( - cipher.getProvider().getName()); + try { + // Try UNWRAP_MODE mode firstly. + cipher.init(Cipher.UNWRAP_MODE, privateKey, + new TlsRsaPremasterSecretParameterSpec( + maxVersion.v, currentVersion.v), + generator); + + // The provider selection can be delayed, please don't call + // any Cipher method before the call to Cipher.init(). + needFailover = !KeyUtil.isOracleJCEProvider( + cipher.getProvider().getName()); + } catch (InvalidKeyException | UnsupportedOperationException iue) { + if (debug != null && Debug.isOn("handshake")) { + System.out.println("The Cipher provider " + + cipher.getProvider().getName() + + " caused exception: " + iue.getMessage()); + } + + needFailover = true; + } + if (needFailover) { + // Use DECRYPT_MODE and dispose the previous initialization. cipher.init(Cipher.DECRYPT_MODE, privateKey); boolean failed = false; try { @@ -132,17 +155,14 @@ final class RSAClientKeyExchange extends HandshakeMessage { maxVersion.v, currentVersion.v, encoded, generator); } else { - cipher.init(Cipher.UNWRAP_MODE, privateKey, - new TlsRsaPremasterSecretParameterSpec( - maxVersion.v, currentVersion.v), - generator); + // the cipher should have been initialized preMaster = (SecretKey)cipher.unwrap(encrypted, "TlsRsaPremasterSecret", Cipher.SECRET_KEY); } } catch (InvalidKeyException ibk) { // the message is too big to process with RSA - throw new SSLProtocolException( - "Unable to process PreMasterSecret, may be too big"); + throw new SSLException( + "Unable to process PreMasterSecret", ibk); } catch (Exception e) { // unlikely to happen, otherwise, must be a provider exception if (debug != null && Debug.isOn("handshake")) { diff --git a/src/share/classes/sun/security/ssl/SignatureAndHashAlgorithm.java b/src/share/classes/sun/security/ssl/SignatureAndHashAlgorithm.java index c9b31cdc93a9f8473f42a614c21b006c5bf71ea1..256bdf263e5c1a67bd99da02d634ef02ab348802 100644 --- a/src/share/classes/sun/security/ssl/SignatureAndHashAlgorithm.java +++ b/src/share/classes/sun/security/ssl/SignatureAndHashAlgorithm.java @@ -413,12 +413,16 @@ final class SignatureAndHashAlgorithm { "SHA1withECDSA", --p); if (Security.getProvider("SunMSCAPI") == null) { + supports(HashAlgorithm.SHA224, SignatureAlgorithm.DSA, + "SHA224withDSA", --p); supports(HashAlgorithm.SHA224, SignatureAlgorithm.RSA, "SHA224withRSA", --p); supports(HashAlgorithm.SHA224, SignatureAlgorithm.ECDSA, "SHA224withECDSA", --p); } + supports(HashAlgorithm.SHA256, SignatureAlgorithm.DSA, + "SHA256withDSA", --p); supports(HashAlgorithm.SHA256, SignatureAlgorithm.RSA, "SHA256withRSA", --p); supports(HashAlgorithm.SHA256, SignatureAlgorithm.ECDSA, diff --git a/src/share/classes/sun/security/tools/jarsigner/Resources_ja.java b/src/share/classes/sun/security/tools/jarsigner/Resources_ja.java index 7588a641e27ca9ec9dad4e8e12591b35244f5492..b471210bf8eaa625cae7f7bb1baec4ad95552499 100644 --- a/src/share/classes/sun/security/tools/jarsigner/Resources_ja.java +++ b/src/share/classes/sun/security/tools/jarsigner/Resources_ja.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2016, 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 @@ -88,6 +88,8 @@ public class Resources_ja extends java.util.ListResourceBundle { "[-tsacert ] \u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u5C40\u306E\u516C\u958B\u9375\u8A3C\u660E\u66F8"}, {".tsapolicyid.tsapolicyid.for.Timestamping.Authority", "[-tsapolicyid ] \u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u5C40\u306ETSAPolicyID"}, + {".tsadigestalg.algorithm.of.digest.data.in.timestamping.request", + "[-tsadigestalg ] \u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u30FB\u30EA\u30AF\u30A8\u30B9\u30C8\u306E\u30C0\u30A4\u30B8\u30A7\u30B9\u30C8\u30FB\u30C7\u30FC\u30BF\u306E\u30A2\u30EB\u30B4\u30EA\u30BA\u30E0"}, {".altsigner.class.class.name.of.an.alternative.signing.mechanism", "[-altsigner ] \u4EE3\u66FF\u7F72\u540D\u30E1\u30AB\u30CB\u30BA\u30E0\u306E\u30AF\u30E9\u30B9\u540D"}, {".altsignerpath.pathlist.location.of.an.alternative.signing.mechanism", diff --git a/src/share/classes/sun/security/tools/jarsigner/Resources_zh_CN.java b/src/share/classes/sun/security/tools/jarsigner/Resources_zh_CN.java index bdec2e20c63d63b6c2f6da824f06a10ccbfc07a8..76f88c14babc97e8d3fdc1afbf4829ad58390650 100644 --- a/src/share/classes/sun/security/tools/jarsigner/Resources_zh_CN.java +++ b/src/share/classes/sun/security/tools/jarsigner/Resources_zh_CN.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2016, 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 @@ -88,6 +88,8 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { "[-tsacert <\u522B\u540D>] \u65F6\u95F4\u6233\u9881\u53D1\u673A\u6784\u7684\u516C\u5171\u5BC6\u94A5\u8BC1\u4E66"}, {".tsapolicyid.tsapolicyid.for.Timestamping.Authority", "[-tsapolicyid ] \u65F6\u95F4\u6233\u9881\u53D1\u673A\u6784\u7684 TSAPolicyID"}, + {".tsadigestalg.algorithm.of.digest.data.in.timestamping.request", + "[-tsadigestalg <\u7B97\u6CD5>] \u65F6\u95F4\u6233\u8BF7\u6C42\u4E2D\u7684\u6458\u8981\u6570\u636E\u7684\u7B97\u6CD5"}, {".altsigner.class.class.name.of.an.alternative.signing.mechanism", "[-altsigner <\u7C7B>] \u66FF\u4EE3\u7684\u7B7E\u540D\u673A\u5236\u7684\u7C7B\u540D"}, {".altsignerpath.pathlist.location.of.an.alternative.signing.mechanism", diff --git a/src/share/classes/sun/security/tools/keytool/Resources_zh_TW.java b/src/share/classes/sun/security/tools/keytool/Resources_zh_TW.java index 1f0bb68b63e85e539d99544b8c040fc666ed0a58..2e3710146380205d170b904c1ee03d67dfb2c452 100644 --- a/src/share/classes/sun/security/tools/keytool/Resources_zh_TW.java +++ b/src/share/classes/sun/security/tools/keytool/Resources_zh_TW.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2016, 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 @@ -381,9 +381,9 @@ public class Resources_zh_TW extends java.util.ListResourceBundle { "\u6C92\u6709\u4F86\u81EA SSL \u4F3A\u670D\u5668\u7684\u6191\u8B49"}, {".The.integrity.of.the.information.stored.in.your.keystore.", - "* \u5C1A\u672A\u9A57\u8B49\u5132\u5B58\u65BC\u91D1\u9470\u5132\u5B58\u5EAB\u4E2D\u8CC7\u8A0A *\n* \u7684\u5B8C\u6574\u6027\uFF01\u82E5\u8981\u9A57\u8B49\u5176\u5B8C\u6574\u6027\uFF0C*\n* \u60A8\u5FC5\u9808\u63D0\u4F9B\u60A8\u7684\u91D1\u9470\u5132\u5B58\u5EAB\u5BC6\u78BC\u3002 *"}, + "* \u5C1A\u672A\u9A57\u8B49\u5132\u5B58\u65BC\u91D1\u9470\u5132\u5B58\u5EAB\u4E2D\u8CC7\u8A0A *\n* \u7684\u5B8C\u6574\u6027\uFF01\u82E5\u8981\u9A57\u8B49\u5176\u5B8C\u6574\u6027\uFF0C *\n* \u60A8\u5FC5\u9808\u63D0\u4F9B\u60A8\u7684\u91D1\u9470\u5132\u5B58\u5EAB\u5BC6\u78BC\u3002 *"}, {".The.integrity.of.the.information.stored.in.the.srckeystore.", - "* \u5C1A\u672A\u9A57\u8B49\u5132\u5B58\u65BC srckeystore \u4E2D\u8CC7\u8A0A*\n* \u7684\u5B8C\u6574\u6027\uFF01\u82E5\u8981\u9A57\u8B49\u5176\u5B8C\u6574\u6027\uFF0C\u60A8\u5FC5\u9808 *\n* \u63D0\u4F9B srckeystore \u5BC6\u78BC\u3002 *"}, + "* \u5C1A\u672A\u9A57\u8B49\u5132\u5B58\u65BC srckeystore \u4E2D\u8CC7\u8A0A *\n* \u7684\u5B8C\u6574\u6027\uFF01\u82E5\u8981\u9A57\u8B49\u5176\u5B8C\u6574\u6027\uFF0C\u60A8\u5FC5\u9808 *\n* \u63D0\u4F9B srckeystore \u5BC6\u78BC\u3002 *"}, {"Certificate.reply.does.not.contain.public.key.for.alias.", "\u6191\u8B49\u56DE\u8986\u4E26\u672A\u5305\u542B <{0}> \u7684\u516C\u958B\u91D1\u9470"}, diff --git a/src/share/classes/sun/security/tools/policytool/Resources_zh_TW.java b/src/share/classes/sun/security/tools/policytool/Resources_zh_TW.java index a0c60ca8f91edc159ba238fcf73cd66e5b0d6b44..e96ad873299b7d8c1c76faf1b69f5feab9e4c6d2 100644 --- a/src/share/classes/sun/security/tools/policytool/Resources_zh_TW.java +++ b/src/share/classes/sun/security/tools/policytool/Resources_zh_TW.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2016, 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 @@ -35,7 +35,7 @@ public class Resources_zh_TW extends java.util.ListResourceBundle { private static final Object[][] contents = { {"NEWLINE", "\n"}, {"Warning.A.public.key.for.alias.signers.i.does.not.exist.Make.sure.a.KeyStore.is.properly.configured.", - "\u8B66\u544A: \u5225\u540D {0} \u7684\u516C\u958B\u91D1\u9470\u4E0D\u5B58\u5728\u3002\u8ACB\u78BA\u5B9A\u91D1\u9470\u5132\u5B58\u5EAB\u914D\u7F6E\u6B63\u78BA\u3002"}, + "\u8B66\u544A: \u5225\u540D {0} \u7684\u516C\u958B\u91D1\u9470\u4E0D\u5B58\u5728\u3002\u8ACB\u78BA\u5B9A\u91D1\u9470\u5132\u5B58\u5EAB\u8A2D\u5B9A\u6B63\u78BA\u3002"}, {"Warning.Class.not.found.class", "\u8B66\u544A: \u627E\u4E0D\u5230\u985E\u5225 {0}"}, {"Warning.Invalid.argument.s.for.constructor.arg", "\u8B66\u544A: \u7121\u6548\u7684\u5EFA\u69CB\u5B50\u5F15\u6578: {0}"}, diff --git a/src/share/classes/sun/security/util/Resources_zh_TW.java b/src/share/classes/sun/security/util/Resources_zh_TW.java index a1de71838fd140da8b974c0ba87262d8afe07a1c..d83082a950060d2ca0482fbab0093f91aea683ae 100644 --- a/src/share/classes/sun/security/util/Resources_zh_TW.java +++ b/src/share/classes/sun/security/util/Resources_zh_TW.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2016, 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 @@ -83,7 +83,7 @@ public class Resources_zh_TW extends java.util.ListResourceBundle { // javax.security.auth.login.LoginContext {"Invalid.null.input.name", "\u7121\u6548\u7A7A\u503C\u8F38\u5165: \u540D\u7A31"}, {"No.LoginModules.configured.for.name", - "\u7121\u91DD\u5C0D {0} \u914D\u7F6E\u7684 LoginModules"}, + "\u7121\u91DD\u5C0D {0} \u8A2D\u5B9A\u7684 LoginModules"}, {"invalid.null.Subject.provided", "\u63D0\u4F9B\u7121\u6548\u7A7A\u503C\u4E3B\u984C"}, {"invalid.null.CallbackHandler.provided", "\u63D0\u4F9B\u7121\u6548\u7A7A\u503C CallbackHandler"}, diff --git a/src/share/classes/sun/security/x509/AuthorityKeyIdentifierExtension.java b/src/share/classes/sun/security/x509/AuthorityKeyIdentifierExtension.java index afd7c99683da8b792ec98e23893617eefe9b309b..9e76a3a75afe5062194e2a8eb2fa556d34338787 100644 --- a/src/share/classes/sun/security/x509/AuthorityKeyIdentifierExtension.java +++ b/src/share/classes/sun/security/x509/AuthorityKeyIdentifierExtension.java @@ -307,4 +307,16 @@ implements CertAttrSet { public String getName() { return (NAME); } + + /** + * Return the encoded key identifier, or null if not specified. + */ + public byte[] getEncodedKeyIdentifier() throws IOException { + if (id != null) { + DerOutputStream derOut = new DerOutputStream(); + id.encode(derOut); + return derOut.toByteArray(); + } + return null; + } } diff --git a/src/share/classes/sun/util/resources/TimeZoneNames.java b/src/share/classes/sun/util/resources/TimeZoneNames.java index 9befaec83426316459d1dcccac58c5a1bc3cdc20..5722da9d9ed25538f9015a22c9a5fecf81fe1378 100644 --- a/src/share/classes/sun/util/resources/TimeZoneNames.java +++ b/src/share/classes/sun/util/resources/TimeZoneNames.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2016, 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 @@ -310,6 +310,7 @@ public final class TimeZoneNames extends TimeZoneNamesBundle { {"Europe/Bucharest", EET}, {"Asia/Shanghai", CTT}, {"CTT", CTT}, + {"UTC", UTC}, /* Don't change the order of the above zones * to keep compatibility with the previous version. */ @@ -1032,7 +1033,6 @@ public final class TimeZoneNames extends TimeZoneNamesBundle { {"US/Pacific", PST}, {"US/Pacific-New", PST}, {"US/Samoa", SAMOA}, - {"UTC", UTC}, {"VST", ICT}, {"W-SU", MSK}, {"WET", WET}, diff --git a/src/share/classes/sun/util/resources/de/TimeZoneNames_de.java b/src/share/classes/sun/util/resources/de/TimeZoneNames_de.java index d32357c2eac726cdf3a9dbc92fade1dbb65e20c9..8fa22f926f585c9510622c7cdfa461ff597d7c8b 100644 --- a/src/share/classes/sun/util/resources/de/TimeZoneNames_de.java +++ b/src/share/classes/sun/util/resources/de/TimeZoneNames_de.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, 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 @@ -311,6 +311,7 @@ public final class TimeZoneNames_de extends TimeZoneNamesBundle { {"Europe/Bucharest", EET}, {"Asia/Shanghai", CTT}, {"CTT", CTT}, + {"UTC", UTC}, /* Don't change the order of the above zones * to keep compatibility with the previous version. */ @@ -1033,7 +1034,6 @@ public final class TimeZoneNames_de extends TimeZoneNamesBundle { {"US/Pacific", PST}, {"US/Pacific-New", PST}, {"US/Samoa", SAMOA}, - {"UTC", UTC}, {"VST", ICT}, {"W-SU", MSK}, {"WET", WET}, diff --git a/src/share/classes/sun/util/resources/es/TimeZoneNames_es.java b/src/share/classes/sun/util/resources/es/TimeZoneNames_es.java index 40ad3fae752acad52ca067f7130374186ef88192..c20c02e055afb4619e4872c13b0900e03d0f17bf 100644 --- a/src/share/classes/sun/util/resources/es/TimeZoneNames_es.java +++ b/src/share/classes/sun/util/resources/es/TimeZoneNames_es.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, 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 @@ -311,6 +311,7 @@ public final class TimeZoneNames_es extends TimeZoneNamesBundle { {"Europe/Bucharest", EET}, {"Asia/Shanghai", CTT}, {"CTT", CTT}, + {"UTC", UTC}, /* Don't change the order of the above zones * to keep compatibility with the previous version. */ @@ -1033,7 +1034,6 @@ public final class TimeZoneNames_es extends TimeZoneNamesBundle { {"US/Pacific", PST}, {"US/Pacific-New", PST}, {"US/Samoa", SAMOA}, - {"UTC", UTC}, {"VST", ICT}, {"W-SU", MSK}, {"WET", WET}, diff --git a/src/share/classes/sun/util/resources/fr/TimeZoneNames_fr.java b/src/share/classes/sun/util/resources/fr/TimeZoneNames_fr.java index 010d56bb17e3f9a9d1ef912cb15584b7215ca2f8..3d812007a7583c57160620ebbac461f1965fa012 100644 --- a/src/share/classes/sun/util/resources/fr/TimeZoneNames_fr.java +++ b/src/share/classes/sun/util/resources/fr/TimeZoneNames_fr.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, 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 @@ -311,6 +311,7 @@ public final class TimeZoneNames_fr extends TimeZoneNamesBundle { {"Europe/Bucharest", EET}, {"Asia/Shanghai", CTT}, {"CTT", CTT}, + {"UTC", UTC}, /* Don't change the order of the above zones * to keep compatibility with the previous version. */ @@ -1033,7 +1034,6 @@ public final class TimeZoneNames_fr extends TimeZoneNamesBundle { {"US/Pacific", PST}, {"US/Pacific-New", PST}, {"US/Samoa", SAMOA}, - {"UTC", UTC}, {"VST", ICT}, {"W-SU", MSK}, {"WET", WET}, diff --git a/src/share/classes/sun/util/resources/it/TimeZoneNames_it.java b/src/share/classes/sun/util/resources/it/TimeZoneNames_it.java index e2e2e7bfb65afe9c6c19de036c961949a4f233c6..33350c43bfaef28336e7a03c68fabba4e230719b 100644 --- a/src/share/classes/sun/util/resources/it/TimeZoneNames_it.java +++ b/src/share/classes/sun/util/resources/it/TimeZoneNames_it.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, 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 @@ -311,6 +311,7 @@ public final class TimeZoneNames_it extends TimeZoneNamesBundle { {"Europe/Bucharest", EET}, {"Asia/Shanghai", CTT}, {"CTT", CTT}, + {"UTC", UTC}, /* Don't change the order of the above zones * to keep compatibility with the previous version. */ @@ -1033,7 +1034,6 @@ public final class TimeZoneNames_it extends TimeZoneNamesBundle { {"US/Pacific", PST}, {"US/Pacific-New", PST}, {"US/Samoa", SAMOA}, - {"UTC", UTC}, {"VST", ICT}, {"W-SU", MSK}, {"WET", WET}, diff --git a/src/share/classes/sun/util/resources/ja/TimeZoneNames_ja.java b/src/share/classes/sun/util/resources/ja/TimeZoneNames_ja.java index d7a33f2f3aa0a0e69e6980b41f0aa8219f99dd15..57a3fb7bddfa868b64cb312e9ca7c6a78e6a1abe 100644 --- a/src/share/classes/sun/util/resources/ja/TimeZoneNames_ja.java +++ b/src/share/classes/sun/util/resources/ja/TimeZoneNames_ja.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, 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 @@ -311,6 +311,7 @@ public final class TimeZoneNames_ja extends TimeZoneNamesBundle { {"Europe/Bucharest", EET}, {"Asia/Shanghai", CTT}, {"CTT", CTT}, + {"UTC", UTC}, /* Don't change the order of the above zones * to keep compatibility with the previous version. */ @@ -1033,7 +1034,6 @@ public final class TimeZoneNames_ja extends TimeZoneNamesBundle { {"US/Pacific", PST}, {"US/Pacific-New", PST}, {"US/Samoa", SAMOA}, - {"UTC", UTC}, {"VST", ICT}, {"W-SU", MSK}, {"WET", WET}, diff --git a/src/share/classes/sun/util/resources/ko/TimeZoneNames_ko.java b/src/share/classes/sun/util/resources/ko/TimeZoneNames_ko.java index b84d4dfd83762946a0a0eb6e3394fe3226b9b0fe..d17154b3498b398ac2f0c1645198fb24c8cb6a85 100644 --- a/src/share/classes/sun/util/resources/ko/TimeZoneNames_ko.java +++ b/src/share/classes/sun/util/resources/ko/TimeZoneNames_ko.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, 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 @@ -311,6 +311,7 @@ public final class TimeZoneNames_ko extends TimeZoneNamesBundle { {"Europe/Bucharest", EET}, {"Asia/Shanghai", CTT}, {"CTT", CTT}, + {"UTC", UTC}, /* Don't change the order of the above zones * to keep compatibility with the previous version. */ @@ -1033,7 +1034,6 @@ public final class TimeZoneNames_ko extends TimeZoneNamesBundle { {"US/Pacific", PST}, {"US/Pacific-New", PST}, {"US/Samoa", SAMOA}, - {"UTC", UTC}, {"VST", ICT}, {"W-SU", MSK}, {"WET", WET}, diff --git a/src/share/classes/sun/util/resources/pt/TimeZoneNames_pt_BR.java b/src/share/classes/sun/util/resources/pt/TimeZoneNames_pt_BR.java index 5601d959f8358b5309e087650ca07fe920f59a38..32747feeb70300a2e78adb60f56d0b8c2c485a91 100644 --- a/src/share/classes/sun/util/resources/pt/TimeZoneNames_pt_BR.java +++ b/src/share/classes/sun/util/resources/pt/TimeZoneNames_pt_BR.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, 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 @@ -311,6 +311,7 @@ public final class TimeZoneNames_pt_BR extends TimeZoneNamesBundle { {"Europe/Bucharest", EET}, {"Asia/Shanghai", CTT}, {"CTT", CTT}, + {"UTC", UTC}, /* Don't change the order of the above zones * to keep compatibility with the previous version. */ @@ -1033,7 +1034,6 @@ public final class TimeZoneNames_pt_BR extends TimeZoneNamesBundle { {"US/Pacific", PST}, {"US/Pacific-New", PST}, {"US/Samoa", SAMOA}, - {"UTC", UTC}, {"VST", ICT}, {"W-SU", MSK}, {"WET", WET}, diff --git a/src/share/classes/sun/util/resources/sv/TimeZoneNames_sv.java b/src/share/classes/sun/util/resources/sv/TimeZoneNames_sv.java index bdae9066eb2f8840e516046daec82351989941ad..8705bfe881b106651d87418e2f420532644da3f2 100644 --- a/src/share/classes/sun/util/resources/sv/TimeZoneNames_sv.java +++ b/src/share/classes/sun/util/resources/sv/TimeZoneNames_sv.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, 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 @@ -311,6 +311,7 @@ public final class TimeZoneNames_sv extends TimeZoneNamesBundle { {"Europe/Bucharest", EET}, {"Asia/Shanghai", CTT}, {"CTT", CTT}, + {"UTC", UTC}, /* Don't change the order of the above zones * to keep compatibility with the previous version. */ @@ -1033,7 +1034,6 @@ public final class TimeZoneNames_sv extends TimeZoneNamesBundle { {"US/Pacific", PST}, {"US/Pacific-New", PST}, {"US/Samoa", SAMOA}, - {"UTC", UTC}, {"VST", ICT}, {"W-SU", MSK}, {"WET", WET}, diff --git a/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_CN.java b/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_CN.java index 534261fbf07c01ce104e73d1aaf904420e259be8..d5e5215f8049719a7b14d0d9b04559b103528bf4 100644 --- a/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_CN.java +++ b/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_CN.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, 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 @@ -311,6 +311,7 @@ public final class TimeZoneNames_zh_CN extends TimeZoneNamesBundle { {"Europe/Bucharest", EET}, {"Asia/Shanghai", CTT}, {"CTT", CTT}, + {"UTC", UTC}, /* Don't change the order of the above zones * to keep compatibility with the previous version. */ @@ -1033,7 +1034,6 @@ public final class TimeZoneNames_zh_CN extends TimeZoneNamesBundle { {"US/Pacific", PST}, {"US/Pacific-New", PST}, {"US/Samoa", SAMOA}, - {"UTC", UTC}, {"VST", ICT}, {"W-SU", MSK}, {"WET", WET}, diff --git a/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_TW.java b/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_TW.java index ca5558bbadf27e6fc028a56db19e65692b28946c..4dc212bb08fd263f8f077036a31081e31078ec9c 100644 --- a/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_TW.java +++ b/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_TW.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, 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 @@ -311,6 +311,7 @@ public final class TimeZoneNames_zh_TW extends TimeZoneNamesBundle { {"Europe/Bucharest", EET}, {"Asia/Shanghai", CTT}, {"CTT", CTT}, + {"UTC", UTC}, /* Don't change the order of the above zones * to keep compatibility with the previous version. */ @@ -1035,7 +1036,6 @@ public final class TimeZoneNames_zh_TW extends TimeZoneNamesBundle { {"US/Pacific", PST}, {"US/Pacific-New", PST}, {"US/Samoa", SAMOA}, - {"UTC", UTC}, {"VST", ICT}, {"W-SU", MSK}, {"WET", WET}, diff --git a/src/share/lib/management/management.properties b/src/share/lib/management/management.properties index db08b780ebd4498aef6329f4bf785dab85af8fad..70efa2eefbdcd407d02b5502b29e375890bf79d1 100644 --- a/src/share/lib/management/management.properties +++ b/src/share/lib/management/management.properties @@ -316,3 +316,16 @@ # For a non-default password file location use the following line # com.sun.management.jmxremote.access.file=filepath +# + +# ################ Management agent listen interface ######################### +# +# com.sun.management.jmxremote.host= +# Specifies the local interface on which the JMX RMI agent will bind. +# This is useful when running on machines which have several +# interfaces defined. It makes it possible to listen to a specific +# subnet accessible through that interface. +# +# The format of the value for that property is any string accepted +# by java.net.InetAddress.getByName(String). +# diff --git a/src/solaris/classes/java/lang/UNIXProcess.java b/src/solaris/classes/java/lang/UNIXProcess.java index cc3b596172ade9f7b5cd4917def618ef8b13cc59..1793a8f35c40499c1609e135f119a46163a12156 100644 --- a/src/solaris/classes/java/lang/UNIXProcess.java +++ b/src/solaris/classes/java/lang/UNIXProcess.java @@ -225,9 +225,8 @@ final class UNIXProcess extends Process { ThreadGroup systemThreadGroup = tg; ThreadFactory threadFactory = grimReaper -> { - // Our thread stack requirement is quite modest. - Thread t = new Thread(systemThreadGroup, grimReaper, - "process reaper", 32768); + long stackSize = Boolean.getBoolean("jdk.lang.processReaperUseDefaultStackSize") ? 0 : 32768; + Thread t = new Thread(systemThreadGroup, grimReaper,"process reaper", stackSize); t.setDaemon(true); // A small attempt (probably futile) to avoid priority inversion t.setPriority(Thread.MAX_PRIORITY); diff --git a/src/solaris/classes/sun/awt/X11/XBaseWindow.java b/src/solaris/classes/sun/awt/X11/XBaseWindow.java index 25e88528f4af7e630e84f30b93aa7d0d69323ed9..297e2dd40218bcdd452dfd0f69e817a17a59d245 100644 --- a/src/solaris/classes/sun/awt/X11/XBaseWindow.java +++ b/src/solaris/classes/sun/awt/X11/XBaseWindow.java @@ -79,7 +79,6 @@ public class XBaseWindow { static enum InitialiseState { INITIALISING, - NOT_INITIALISED, INITIALISED, FAILED_INITIALISATION }; @@ -122,7 +121,6 @@ public class XBaseWindow { */ void instantPreInit(XCreateWindowParams params) { state_lock = new StateLock(); - initialising = InitialiseState.NOT_INITIALISED; } /** @@ -131,7 +129,6 @@ public class XBaseWindow { */ void preInit(XCreateWindowParams params) { state_lock = new StateLock(); - initialising = InitialiseState.NOT_INITIALISED; embedded = Boolean.TRUE.equals(params.get(EMBEDDED)); visible = Boolean.TRUE.equals(params.get(VISIBLE)); @@ -223,7 +220,6 @@ public class XBaseWindow { return false; } return true; - case NOT_INITIALISED: case FAILED_INITIALISATION: return false; default: @@ -673,7 +669,7 @@ public class XBaseWindow { XToolkit.awtLock(); try { XAtom xa = XAtom.get(XAtom.XA_WM_CLASS); - xa.setProperty8(getWindow(), cl[0] + '\0' + cl[1]); + xa.setProperty8(getWindow(), cl[0] + '\0' + cl[1] + '\0'); } finally { XToolkit.awtUnlock(); } diff --git a/src/solaris/native/java/net/net_util_md.c b/src/solaris/native/java/net/net_util_md.c index 693b4b0ef9742465c07dbd81a43e8fb6ae6bb314..c31d294432c949b1b176a84fdecd04948b2d3fae 100644 --- a/src/solaris/native/java/net/net_util_md.c +++ b/src/solaris/native/java/net/net_util_md.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, 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 @@ -68,13 +68,6 @@ #include "java_net_SocketOptions.h" -/* needed from libsocket on Solaris 8 */ - -getaddrinfo_f getaddrinfo_ptr = NULL; -freeaddrinfo_f freeaddrinfo_ptr = NULL; -gai_strerror_f gai_strerror_ptr = NULL; -getnameinfo_f getnameinfo_ptr = NULL; - /* * EXCLBIND socket options only on Solaris */ @@ -434,8 +427,7 @@ void ThrowUnknownHostExceptionWithGaiError(JNIEnv *env, int size; char *buf; const char *format = "%s: %s"; - const char *error_string = - (gai_strerror_ptr == NULL) ? NULL : (*gai_strerror_ptr)(gai_error); + const char *error_string = gai_strerror(gai_error); if (error_string == NULL) error_string = "unknown error"; diff --git a/src/solaris/native/java/net/net_util_md.h b/src/solaris/native/java/net/net_util_md.h index 68c10d6adcee8a66c9cf7bae47ee1aa10f8acb74..58be69078896c1fe2bfd9afb52fada8b031aa4bc 100644 --- a/src/solaris/native/java/net/net_util_md.h +++ b/src/solaris/native/java/net/net_util_md.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, 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 @@ -134,22 +134,6 @@ typedef struct sock_flow_props_s { #endif /* SO_FLOW_SLA */ #endif /* __solaris__ */ -/* needed from libsocket on Solaris 8 */ - -typedef int (*getaddrinfo_f)(const char *nodename, const char *servname, - const struct addrinfo *hints, struct addrinfo **res); - -typedef void (*freeaddrinfo_f)(struct addrinfo *); - -typedef const char * (*gai_strerror_f)(int ecode); - -typedef int (*getnameinfo_f)(const struct sockaddr *, size_t, - char *, size_t, char *, size_t, int); - -extern getaddrinfo_f getaddrinfo_ptr; -extern freeaddrinfo_f freeaddrinfo_ptr; -extern getnameinfo_f getnameinfo_ptr; - void ThrowUnknownHostExceptionWithGaiError(JNIEnv *env, const char* hostname, int gai_error); diff --git a/src/windows/classes/com/sun/java/accessibility/AccessBridge.java b/src/windows/classes/com/sun/java/accessibility/AccessBridge.java index e21429e16d31306b7d434fa3ea9cd06ce92747ee..3b176da33340ae342f22962f813687ee56b61673 100644 --- a/src/windows/classes/com/sun/java/accessibility/AccessBridge.java +++ b/src/windows/classes/com/sun/java/accessibility/AccessBridge.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, 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 @@ -1501,7 +1501,9 @@ final public class AccessBridge extends AccessBridgeLoader { s.indexOf(AccessibleState.MANAGES_DESCENDANTS.toDisplayString(Locale.US)) == -1) { // Indicate whether this component manages its own // children - AccessibleRole role = ac.getAccessibleRole(); + AccessibleRole role = InvocationUtils.invokeAndWait(() -> { + return ac.getAccessibleRole(); + }, ac); if (role == AccessibleRole.LIST || role == AccessibleRole.TABLE || role == AccessibleRole.TREE) { @@ -1759,7 +1761,9 @@ final public class AccessBridge extends AccessBridgeLoader { */ private AccessibleComponent getAccessibleComponentFromContext(AccessibleContext ac) { if (ac != null) { - AccessibleComponent acmp = ac.getAccessibleComponent(); + AccessibleComponent acmp = InvocationUtils.invokeAndWait(() -> { + return ac.getAccessibleComponent(); + }, ac); if (acmp != null) { debugString("Returning AccessibleComponent Context"); return acmp; diff --git a/src/windows/classes/sun/awt/windows/fontconfig.properties b/src/windows/classes/sun/awt/windows/fontconfig.properties index 65a239a44e43d5aedafb06ca1528781cc036b5f7..6e488eef6aed91baeb7a3ca89b40e5e9c5c18d6e 100644 --- a/src/windows/classes/sun/awt/windows/fontconfig.properties +++ b/src/windows/classes/sun/awt/windows/fontconfig.properties @@ -242,7 +242,7 @@ sequence.fallback=lucida,\ # Exclusion Ranges -exclusion.alphabetic=0700-1e9f,1f00-20ab,20ad-f8ff +exclusion.alphabetic=0700-1e9f,1f00-2017,2020-20ab,20ad-f8ff exclusion.chinese-gb18030=0390-03d6,2200-22ef,2701-27be exclusion.hebrew=0041-005a,0060-007a,007f-00ff,20ac-20ac diff --git a/src/windows/native/java/net/NetworkInterface_winXP.c b/src/windows/native/java/net/NetworkInterface_winXP.c index 7e3e79d1f4927bdc06b037a9c06cd1c0886afdec..4042d16d4eff741b3d5976ffad6a672fa1964fbe 100644 --- a/src/windows/native/java/net/NetworkInterface_winXP.c +++ b/src/windows/native/java/net/NetworkInterface_winXP.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, 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 @@ -28,6 +28,7 @@ #include /* needed for htonl */ #include #include +#include #include "java_net_NetworkInterface.h" #include "jni_util.h" @@ -70,7 +71,7 @@ void printnifs (netif *netifPP, char *str) { #endif -static int bufsize = 1024; +static int bufsize = 4096; /* * return an array of IP_ADAPTER_ADDRESSES containing one element @@ -94,7 +95,12 @@ static int getAdapters (JNIEnv *env, IP_ADAPTER_ADDRESSES **adapters) { ret = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapterInfo, &len); if (ret == ERROR_BUFFER_OVERFLOW) { - IP_ADAPTER_ADDRESSES * newAdapterInfo = (IP_ADAPTER_ADDRESSES *) realloc (adapterInfo, len); + IP_ADAPTER_ADDRESSES * newAdapterInfo = NULL; + if (len < (ULONG_MAX - bufsize)) { + len = len + bufsize; + } + newAdapterInfo = + (IP_ADAPTER_ADDRESSES *) realloc (adapterInfo, len); if (newAdapterInfo == NULL) { free(adapterInfo); JNU_ThrowByName(env, "java/lang/OutOfMemoryError", "Native heap allocation failure"); @@ -103,7 +109,6 @@ static int getAdapters (JNIEnv *env, IP_ADAPTER_ADDRESSES **adapters) { adapterInfo = newAdapterInfo; - bufsize = len; ret = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapterInfo, &len); } @@ -137,7 +142,12 @@ IP_ADAPTER_ADDRESSES *getAdapter (JNIEnv *env, jint index) { flags |= GAA_FLAG_INCLUDE_PREFIX; val = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapterInfo, &len); if (val == ERROR_BUFFER_OVERFLOW) { - IP_ADAPTER_ADDRESSES * newAdapterInfo = (IP_ADAPTER_ADDRESSES *) realloc (adapterInfo, len); + IP_ADAPTER_ADDRESSES * newAdapterInfo = NULL; + if (len < (ULONG_MAX - bufsize)) { + len = len + bufsize; + } + newAdapterInfo = + (IP_ADAPTER_ADDRESSES *) realloc (adapterInfo, len); if (newAdapterInfo == NULL) { free(adapterInfo); JNU_ThrowByName(env, "java/lang/OutOfMemoryError", "Native heap allocation failure"); @@ -146,7 +156,6 @@ IP_ADAPTER_ADDRESSES *getAdapter (JNIEnv *env, jint index) { adapterInfo = newAdapterInfo; - bufsize = len; val = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapterInfo, &len); } diff --git a/src/windows/native/sun/font/lcdglyph.c b/src/windows/native/sun/font/lcdglyph.c index 05f4aae9d82446ab9d64e11496c05d0ce68a6b35..d940e8cb468ff52174d975a19f92eb6839bd7e9c 100644 --- a/src/windows/native/sun/font/lcdglyph.c +++ b/src/windows/native/sun/font/lcdglyph.c @@ -157,6 +157,9 @@ JNIEXPORT jboolean JNICALL if (hBitmap != 0) { \ DeleteObject(hBitmap); \ } \ + if (tmpBitmap != 0) { \ + DeleteObject(tmpBitmap); \ + } \ if (dibImage != NULL) { \ free(dibImage); \ } \ @@ -196,6 +199,7 @@ Java_sun_font_FileFontStrike__1getGlyphImageFromWindows int bmWidth, bmHeight; int x, y; HBITMAP hBitmap = NULL, hOrigBM; + HBITMAP tmpBitmap = NULL; int gamma, orient; HWND hWnd = NULL; @@ -250,6 +254,12 @@ Java_sun_font_FileFontStrike__1getGlyphImageFromWindows } oldFont = SelectObject(hMemoryDC, hFont); + tmpBitmap = CreateCompatibleBitmap(hDesktopDC, 1, 1); + if (tmpBitmap == NULL) { + FREE_AND_RETURN; + } + hOrigBM = (HBITMAP)SelectObject(hMemoryDC, tmpBitmap); + memset(&textMetric, 0, sizeof(TEXTMETRIC)); err = GetTextMetrics(hMemoryDC, &textMetric); if (err == 0) { @@ -334,7 +344,7 @@ Java_sun_font_FileFontStrike__1getGlyphImageFromWindows if (hBitmap == NULL) { FREE_AND_RETURN; } - hOrigBM = (HBITMAP)SelectObject(hMemoryDC, hBitmap); + SelectObject(hMemoryDC, hBitmap); /* Fill in black */ rect.left = 0; @@ -478,6 +488,7 @@ Java_sun_font_FileFontStrike__1getGlyphImageFromWindows ReleaseDC(hWnd, hDesktopDC); DeleteObject(hMemoryDC); DeleteObject(hBitmap); + DeleteObject(tmpBitmap); return ptr_to_jlong(glyphInfo); } diff --git a/test/ProblemList.txt b/test/ProblemList.txt index 25ada7c21ca6d8f5cdc3f6cdee4f42a57e7ae181..c726b04a2f0c6918f9be7058942561d1842a5c77 100644 --- a/test/ProblemList.txt +++ b/test/ProblemList.txt @@ -273,3 +273,13 @@ tools/launcher/FXLauncherTest.java linux-all java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java generic-all ############################################################################ + +# svc_tools + +# 8031482 +sun/tools/jcmd/TestJcmdSanity.java windows-all + +# 6456333 +sun/tools/jps/TestJpsJarRelative.java generic-all + +############################################################################ diff --git a/test/TEST.ROOT b/test/TEST.ROOT index 26377b77a04402d7521b250625fca46948422fe1..7a285b03a3cd413a7b3f1b3a29a90a74982d2c98 100644 --- a/test/TEST.ROOT +++ b/test/TEST.ROOT @@ -1,8 +1,15 @@ # This file identifies the root of the test-suite hierarchy. # It also contains test-suite configuration information. -# The list of keywords supported in the entire test suite -keys=2d dnd i18n +# The list of keywords supported in the entire test suite. The +# "intermittent" keyword marks tests known to fail intermittently. +# The "randomness" keyword marks tests using randomness with test +# cases differing from run to run. (A test using a fixed random seed +# would not count as "randomness" by this definition.) Extra care +# should be taken to handle test failures of intermittent or +# randomness tests. + +keys=2d dnd i18n intermittent randomness # Tests that must run in othervm mode othervm.dirs=java/awt java/beans java/rmi javax/accessibility javax/imageio javax/sound javax/print javax/management com/sun/awt sun/awt sun/java2d sun/pisces sun/rmi @@ -10,5 +17,8 @@ othervm.dirs=java/awt java/beans java/rmi javax/accessibility javax/imageio java # Tests that cannot run concurrently exclusiveAccess.dirs=java/rmi/Naming java/util/Currency java/util/prefs sun/management/jmxremote sun/tools/jstatd sun/security/mscapi javax/rmi +# Allow querying of sun.arch.data.model in @requires clauses +requires.properties=sun.arch.data.model + # Group definitions groups=TEST.groups [closed/TEST.groups] diff --git a/test/TEST.groups b/test/TEST.groups index a17b16ae78c590c8426c7b3e54f526e276e81dd9..886566f995921e074abc283da973a70587bc09a7 100644 --- a/test/TEST.groups +++ b/test/TEST.groups @@ -352,7 +352,8 @@ needs_jdk = \ javax/xml/bind/jxc \ javax/xml/ws/8033113 \ javax/xml/ws/clientjar/TestWsImport.java \ - javax/xml/ws/ebcdic + javax/xml/ws/ebcdic \ + javax/xml/bind/xjc/8145039/JaxbMarshallTest.java # JRE adds further tests to compact3 # diff --git a/test/com/sun/crypto/provider/CICO/CICOChainingTest.java b/test/com/sun/crypto/provider/CICO/CICOChainingTest.java new file mode 100644 index 0000000000000000000000000000000000000000..5e0d3c5a0556bdfe3c01dec46409e190f0cbbbb0 --- /dev/null +++ b/test/com/sun/crypto/provider/CICO/CICOChainingTest.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2007, 2015, 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. + * + * 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. + */ + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.util.Arrays; +import javax.crypto.CipherInputStream; +import javax.crypto.CipherOutputStream; + +/* + * @test + * @bug 8048604 + * @summary This test verifies the assertion "The chaining feature of + * Filter streams should be supported." for feature "CipherInputStream & + * CipherOutputStream" + * @run main CICOChainingTest + */ +public class CICOChainingTest { + /** + * Plain text length. + */ + private static final int PLAIN_TEXT_LENGTH = 200; + + public static void main(String argv[]) throws Exception { + CICOChainingTest test = new CICOChainingTest(); + test.chainTest(true); + test.chainTest(false); + } + + /** + * Chain CipherInputStream/CipherOutputStream with other stream, encrypt + * the text and decrypt it, recovered text is supposed to be same as + * original text. + * @param useInt true if read byte by byte false if read with buffer. + * @throws IOException any I/O operation failed. + */ + public void chainTest(boolean useInt) throws IOException { + byte[] plainText = TestUtilities.generateBytes(PLAIN_TEXT_LENGTH); + byte[] recoveredText = new byte[plainText.length]; + // Do initialization + try (MyNullCipherInputStream ciInput1 = new MyNullCipherInputStream( + new ByteArrayInputStream(plainText)); + PipedOutputStream piOut = new PipedOutputStream(); + MyNullCipherInputStream ciInput2 = new MyNullCipherInputStream( + new PipedInputStream(piOut)); + MyNullCipherOutputStream ciOut = new MyNullCipherOutputStream( + piOut);) { + if (useInt) { + int buffer = ciInput1.read(); + while (buffer != -1) { + piOut.write(buffer); + buffer = ciInput1.read(); + } + } else { + byte[] buffer = new byte[20]; + int len = ciInput1.read(buffer); + while (len != -1) { + ciOut.write(buffer, 0, len); + len = ciInput1.read(buffer); + } + } + ciOut.flush(); + piOut.flush(); + // Get the output + ciInput2.read(recoveredText); + if (ciInput2.available() > 0) { + throw new RuntimeException("Expected no data from ciInput2, but" + + " ciInput2.available() = " + ciInput2.available()); + } + } + // Verify output is same to input. + if (!Arrays.equals(plainText, recoveredText)) { + throw new RuntimeException("plainText:" + new String(plainText) + + " recoveredText:" + new String(recoveredText) + + " Test failed due to result compare fail"); + } + } +} + +class MyNullCipherInputStream extends CipherInputStream { + + public MyNullCipherInputStream(InputStream is) { + super(is); + } +} + +class MyNullCipherOutputStream extends CipherOutputStream { + + public MyNullCipherOutputStream(OutputStream os) { + super(os); + } +} diff --git a/test/com/sun/crypto/provider/CICO/CICODESFuncTest.java b/test/com/sun/crypto/provider/CICO/CICODESFuncTest.java new file mode 100644 index 0000000000000000000000000000000000000000..3164294ecca57aa1362020aa07bd865ef4d61086 --- /dev/null +++ b/test/com/sun/crypto/provider/CICO/CICODESFuncTest.java @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2007, 2015, 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. + * + * 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. + */ +import static java.lang.System.out; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.security.NoSuchAlgorithmException; +import java.security.Provider; +import java.security.Security; +import java.security.spec.AlgorithmParameterSpec; +import java.util.Arrays; +import javax.crypto.CipherInputStream; +import javax.crypto.CipherOutputStream; +import javax.crypto.SecretKey; +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import javax.crypto.spec.IvParameterSpec; + +/* + * @test + * @bug 8048604 + * @summary to verify cipherInputStream and cipherInputStream cipher function + * @run main CICODESFuncTest + */ +public class CICODESFuncTest { + /** + * Algorithms name. + */ + private static final String[] ALGORITHMS = { "DES", "DESede", "Blowfish" }; + private static final String[] MODES = { "ECB", "CBC", "CFB", "CFB24", + "CFB32", "CFB40", "CFB72", "OFB", "OFB20", "OFB48", "OFB56", + "OFB64", "PCBC" }; + /** + * Padding mode. + */ + private static final String[] PADDINGS = { "noPadding", "pkcs5padding" }; + /** + * Plain text length. + */ + private static final int TEXT_LENGTH = 80; + /** + * Initialization vector length. + */ + private static final int IV_LENGTH = 8; + + public static void main(String[] args) throws Exception { + Provider provider = Security.getProvider("SunJCE"); + if (provider == null) { + throw new RuntimeException("SunJCE provider does not exist."); + } + for (String algorithm : ALGORITHMS) { + for (String mode : MODES) { + // We only test noPadding and pkcs5padding for CFB72, OFB20, ECB + // PCBC and CBC. Otherwise test noPadding only. + int padKinds = 1; + if (mode.equalsIgnoreCase("CFB72") + || mode.equalsIgnoreCase("OFB20") + || mode.equalsIgnoreCase("ECB") + || mode.equalsIgnoreCase("PCBC") + || mode.equalsIgnoreCase("CBC")) { + padKinds = PADDINGS.length; + } + // PKCS5padding is meaningful only for ECB, CBC, PCBC + for (int k = 0; k < padKinds; k++) { + for (ReadModel readMode : ReadModel.values()) { + runTest(provider, algorithm, mode, PADDINGS[k], readMode); + } + } + } + } + } + + private static void runTest(Provider p, String algo, String mo, String pad, + ReadModel whichRead) throws GeneralSecurityException, IOException { + // Do initialization + byte[] plainText = TestUtilities.generateBytes(TEXT_LENGTH); + byte[] iv = TestUtilities.generateBytes(IV_LENGTH); + AlgorithmParameterSpec aps = new IvParameterSpec(iv); + try { + KeyGenerator kg = KeyGenerator.getInstance(algo, p); + out.println(algo + "/" + mo + "/" + pad + "/" + whichRead); + SecretKey key = kg.generateKey(); + Cipher ci1 = Cipher.getInstance(algo + "/" + mo + "/" + pad, p); + if ("CFB72".equalsIgnoreCase(mo) || "OFB20".equalsIgnoreCase(mo)) { + throw new RuntimeException( + "NoSuchAlgorithmException not throw when mode" + + " is CFB72 or OFB20"); + } + Cipher ci2 = Cipher.getInstance(algo + "/" + mo + "/" + pad, p); + if ("ECB".equalsIgnoreCase(mo)) { + ci1.init(Cipher.ENCRYPT_MODE, key); + ci2.init(Cipher.DECRYPT_MODE, key); + } else { + ci1.init(Cipher.ENCRYPT_MODE, key, aps); + ci2.init(Cipher.DECRYPT_MODE, key, aps); + } + ByteArrayOutputStream baOutput = new ByteArrayOutputStream(); + try (CipherInputStream cInput + = new CipherInputStream( + new ByteArrayInputStream(plainText), ci1); + CipherOutputStream ciOutput + = new CipherOutputStream(baOutput, ci2);) { + // Read from the input and write to the output using 2 types + // of buffering : byte[] and int + whichRead.read(cInput, ciOutput, ci1, plainText.length); + } + // Verify input and output are same. + if (!Arrays.equals(plainText, baOutput.toByteArray())) { + throw new RuntimeException("Test failed due to compare fail "); + } + } catch (NoSuchAlgorithmException nsaEx) { + if ("CFB72".equalsIgnoreCase(mo) || "OFB20".equalsIgnoreCase(mo)) { + out.println("NoSuchAlgorithmException is expected for CFB72 and OFB20"); + } else { + throw new RuntimeException("Unexpected exception testing: " + + algo + "/" + mo + "/" + pad + "/" + whichRead, nsaEx); + } + } + } +} diff --git a/test/com/sun/crypto/provider/CICO/CICOSkipTest.java b/test/com/sun/crypto/provider/CICO/CICOSkipTest.java new file mode 100644 index 0000000000000000000000000000000000000000..0641845d7f9e4da77e03368afaf39f02ff96e38e --- /dev/null +++ b/test/com/sun/crypto/provider/CICO/CICOSkipTest.java @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2007, 2015, 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. + * + * 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. + */ + +import static java.lang.System.out; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.Provider; +import java.security.Security; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.InvalidKeySpecException; +import javax.crypto.Cipher; +import javax.crypto.CipherInputStream; +import javax.crypto.KeyGenerator; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.PBEKeySpec; +import javax.crypto.spec.PBEParameterSpec; + +/* + * @test + * @bug 8048604 + * @summary This test verifies the assertion "The skip feature of Filter + * streams should be supported." for feature + * CipherInputStream and CipherOutputStream + */ +public class CICOSkipTest { + /** + * Block length. + */ + private static final int BLOCK = 50; + + /** + * Saving bytes length. + */ + private static final int SAVE = 45; + + /** + * Plain text length. + */ + private static final int PLAIN_TEXT_LENGTH = 800; + + /** + * Skip reading byte size. This should be same to BLOCK - SAVE + */ + private static final int DISCARD = BLOCK - SAVE; + + private static final String[] ALGOS = {"DES", "DESede", "Blowfish"}; + private static final String[] MODES = {"ECB", "CBC", "CFB", "CFB32", + "OFB", "OFB64", "PCBC"}; + private static final String[] PADDINGS = {"NoPadding", "Pkcs5Padding"}; + private static final String[] PBE_ALGOS = {"PBEWithMD5AndDES", + "PBEWithMD5AndDES/CBC/PKCS5Padding"}; + + public static void main(String[] args) throws Exception { + // how many kinds of padding mode such as PKCS5padding and NoPadding + for (String algo : ALGOS) { + for (String mode : MODES) { + int padKinds = 1; + if (mode.equalsIgnoreCase("ECB") + || mode.equalsIgnoreCase("PCBC") + || mode.equalsIgnoreCase("CBC")) { + padKinds = PADDINGS.length; + } + // PKCS5padding is meaningful only for ECB, CBC, PCBC + for (int k = 0; k < padKinds; k++) { + String info = algo + "/" + mode + "/" + PADDINGS[k]; + try { + CipherGenerator cg = new CipherGenerator(algo, mode, + PADDINGS[k]); + for (ReadMethod model : ReadMethod.values()) { + runTest(cg.getPair(), info, model); + } + } catch (LengthLimitException exp) { + // skip this if this key length is larger than what's + // configured in the jce jurisdiction policy files + out.println(exp.getMessage() + " is expected."); + } + } + } + } + for (String pbeAlgo : PBE_ALGOS) { + for (ReadMethod model : ReadMethod.values()) { + System.out.println("Testing Algorithm : " + pbeAlgo + + " ReadMethod : " + model); + runTest(new CipherGenerator(pbeAlgo).getPair(), pbeAlgo, model); + } + } + } + + private static void runTest(Cipher[] pair, String info, ReadMethod whichRead) + throws IOException { + byte[] plainText = TestUtilities.generateBytes(PLAIN_TEXT_LENGTH); + out.println("Testing: " + info + "/" + whichRead); + try (ByteArrayInputStream baInput = new ByteArrayInputStream(plainText); + CipherInputStream ciInput1 = new CipherInputStream(baInput, + pair[0]); + CipherInputStream ciInput2 = new CipherInputStream(ciInput1, + pair[1]);) { + // Skip 5 bytes after read 45 bytes and repeat until finish + // (Read from the input and write to the output using 2 types + // of buffering : byte[] and int) + // So output has size: + // (OVERALL/BLOCK)* SAVE = (800 / 50) * 45 = 720 bytes + int numOfBlocks = plainText.length / BLOCK; + + // Output buffer. + byte[] outputText = new byte[numOfBlocks * SAVE]; + int index = 0; + for (int i = 0; i < numOfBlocks; i++) { + index = whichRead.readByte(ciInput2, outputText, SAVE, index); + // If available is more than expected discard byte size. Skip + // discard bytes, otherwise try to read discard bytes by read. + if (ciInput2.available() >= DISCARD) { + ciInput2.skip(DISCARD); + } else { + for (int k = 0; k < DISCARD; k++) { + ciInput2.read(); + } + } + } + // Verify output is same as input + if (!TestUtilities + .equalsBlockPartial(plainText, outputText, BLOCK, SAVE)) { + throw new RuntimeException("Test failed with compare fail"); + } + } + } +} + +class CipherGenerator { + /** + * Initialization vector length. + */ + private static final int IV_LENGTH = 8; + + private static final String PASSWD = "Sesame!(@#$%^&*)"; + + private final Cipher[] pair = new Cipher[2]; + + // For DES/DESede ciphers + CipherGenerator(String algo, String mo, String pad) + throws NoSuchAlgorithmException, + InvalidAlgorithmParameterException, InvalidKeyException, + NoSuchPaddingException, SecurityException, LengthLimitException { + // Do initialization + KeyGenerator kg = KeyGenerator.getInstance(algo); + SecretKey key = kg.generateKey(); + if (key.getEncoded().length * 8 > Cipher.getMaxAllowedKeyLength(algo)) { + // skip this if this key length is larger than what's + // configured in the jce jurisdiction policy files + throw new LengthLimitException( + "Skip this test if key length is larger than what's" + + "configured in the jce jurisdiction policy files"); + } + AlgorithmParameterSpec aps = null; + if (!mo.equalsIgnoreCase("ECB")) { + byte[] iv = TestUtilities.generateBytes(IV_LENGTH); + aps = new IvParameterSpec(iv); + } + initCiphers(algo + "/" + mo + "/" + pad, key, aps); + } + + // For PBE ciphers + CipherGenerator(String algo) throws NoSuchAlgorithmException, + InvalidAlgorithmParameterException, InvalidKeyException, + NoSuchPaddingException, InvalidKeySpecException { + // Do initialization + byte[] salt = TestUtilities.generateBytes(IV_LENGTH); + int iterCnt = 6; + SecretKeyFactory skf = SecretKeyFactory.getInstance(algo.split("/")[0]); + SecretKey key = skf + .generateSecret(new PBEKeySpec(PASSWD.toCharArray())); + AlgorithmParameterSpec aps = new PBEParameterSpec(salt, iterCnt); + initCiphers(algo, key, aps); + } + + private void initCiphers(String algo, SecretKey key, + AlgorithmParameterSpec aps) throws NoSuchAlgorithmException, + NoSuchPaddingException, InvalidKeyException, + InvalidAlgorithmParameterException { + Provider provider = Security.getProvider("SunJCE"); + if (provider == null) { + throw new RuntimeException("SunJCE provider does not exist."); + } + Cipher ci1 = Cipher.getInstance(algo, provider); + ci1.init(Cipher.ENCRYPT_MODE, key, aps); + pair[0] = ci1; + Cipher ci2 = Cipher.getInstance(algo, provider); + ci2.init(Cipher.DECRYPT_MODE, key, aps); + pair[1] = ci2; + } + + Cipher[] getPair() { + return pair; + } +} + +enum ReadMethod { + // read one byte at a time for save times + READ_ONE_BYTE { + @Override + int readByte(CipherInputStream ciIn2, byte[] outputText, int save, + int index) throws IOException { + for (int j = 0; j < save; j++, index++) { + int buffer0 = ciIn2.read(); + if (buffer0 != -1) { + outputText[index] = (byte) buffer0; + } else { + break; + } + } + return index; + } + }, + // read a chunk of save bytes if possible + READ_BLOCK { + @Override + int readByte(CipherInputStream ciIn2, byte[] outputText, int save, + int index) throws IOException { + int len1 = ciIn2.read(outputText, index, save); + out.println("Init: index=" + index + ",len=" + len1); + // read more until save bytes + index += len1; + int len2 = 0; + while (len1 != save && len2 != -1) { + len2 = ciIn2.read(outputText, index, save - len1); + out.println("Cont: index=" + index + ",len=" + len2); + len1 += len2; + index += len2; + } + return index; + } + }; + + abstract int readByte(CipherInputStream ciIn2, byte[] outputText, int save, + int index) throws IOException; +}; + +class LengthLimitException extends Exception { + + public LengthLimitException(String string) { + super(string); + } +} diff --git a/test/com/sun/crypto/provider/CICO/PBEFunc/AESPBEWrapper.java b/test/com/sun/crypto/provider/CICO/PBEFunc/AESPBEWrapper.java new file mode 100644 index 0000000000000000000000000000000000000000..e6e5c2faa01c6df47420ab7a7df500d3d7230be0 --- /dev/null +++ b/test/com/sun/crypto/provider/CICO/PBEFunc/AESPBEWrapper.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2007, 2015, 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. + * + * 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. + */ + +import java.security.AlgorithmParameters; +import java.security.GeneralSecurityException; +import java.security.Provider; +import java.security.Security; +import javax.crypto.SecretKey; +import javax.crypto.Cipher; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; + +/** + * Wrapper class to test a given AES-based PBE algorithm. + */ +public class AESPBEWrapper extends AbstractPBEWrapper { + /** + * the algorithm parameters. + */ + private AlgorithmParameters pbeParams; + + /** + * the encryption key. + */ + private final SecretKey key; + + /** + * The Wrapper constructor. Instantiate Cipher using the given AES-based PBE + * algorithm. + * + * @param algo AES-based PBE algorithm. + * @param passwd password phrase. + * @throws GeneralSecurityException all security exceptions are thrown. + */ + public AESPBEWrapper(PBEAlgorithm algo, String passwd) + throws GeneralSecurityException { + // salt and iteration count will be generated during encryption + super(algo, passwd, 0); + + // Generate secret key. We expect no mode and padding specified. + SecretKeyFactory skf = SecretKeyFactory.getInstance(algo.baseAlgo); + key = skf.generateSecret(new PBEKeySpec(passwd.toCharArray())); + } + + /** + * Initiate the Cipher object using given "mode". + * @return a cipher object. + * @throws GeneralSecurityException all security exceptions are thrown. + */ + @Override + protected Cipher initCipher(int mode) throws GeneralSecurityException { + Provider provider = Security.getProvider("SunJCE"); + if (provider == null) { + throw new RuntimeException("SunJCE provider does not exist."); + } + // get Cipher instance + Cipher ci = Cipher.getInstance(transformation, provider); + if (Cipher.ENCRYPT_MODE == mode) { + ci.init(Cipher.ENCRYPT_MODE, key); + pbeParams = ci.getParameters(); + } else { + ci.init(Cipher.DECRYPT_MODE, key, pbeParams); + } + return ci; + } +} diff --git a/test/com/sun/crypto/provider/CICO/PBEFunc/AbstractPBEWrapper.java b/test/com/sun/crypto/provider/CICO/PBEFunc/AbstractPBEWrapper.java new file mode 100644 index 0000000000000000000000000000000000000000..d155a140a7a4b8ebdece699f6099b18006ca7d4a --- /dev/null +++ b/test/com/sun/crypto/provider/CICO/PBEFunc/AbstractPBEWrapper.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2007, 2015, 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. + * + * 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. + */ +import java.security.GeneralSecurityException; +import javax.crypto.Cipher; + +/** + * PBEWrapper is an abstract class for all concrete PBE Cipher wrappers. + */ +public abstract class AbstractPBEWrapper { + /** + * Iteration count. + */ + public static final int DEFAULT_ITERATION = 1000; + + public static final String PBKDF2 = "PBKDF2"; + public static final String AES = "AES"; + public static final String DEFAULT = "default"; + + /** + * transformation the name of the transformation, e.g., + * DES/CBC/PKCS5Padding + */ + protected final String transformation; + + /** + * the standard name of the requested secret-key algorithm. + */ + protected final String baseAlgo; + + /** + * The contents of salt are copied to protect against subsequent + * modification. + */ + protected final byte[] salt; + + /** + * Password. + */ + protected final String password; + + /** + * PBEWrapper creator. + * + * @param algo PBE algorithm to test + * @param passwd a password phrase + * @return PBEWrapper in accordance to requested algo. + * @throws GeneralSecurityException all exceptions are thrown. + */ + public static AbstractPBEWrapper createWrapper(PBEAlgorithm algo, String passwd) + throws GeneralSecurityException { + switch (algo.type) { + case PBKDF2: + return new PBKDF2Wrapper(algo, passwd); + case AES: + return new AESPBEWrapper(algo, passwd); + default: + return new DefaultPBEWrapper(algo, passwd); + } + } + + /** + * PBEWrapper constructor. + * + * @param algo algorithm to wrap + * @param password password phrase + * @param saltSize salt size (defined in subclasses) + */ + protected AbstractPBEWrapper(PBEAlgorithm algo, String password, int saltSize) { + this.transformation = algo.getTransformation(); + this.baseAlgo = algo.baseAlgo; + this.salt = TestUtilities.generateBytes(saltSize); + this.password = password; + } + + /** + * Initialize Cipher object for the operation requested in the mode parameter. + * + * @param mode encryption or decryption + * @return a cipher initialize by mode. + * @throws GeneralSecurityException all security exceptions are thrown. + */ + protected abstract Cipher initCipher(int mode) throws GeneralSecurityException; +} diff --git a/test/com/sun/crypto/provider/CICO/PBEFunc/CICOPBEFuncTest.java b/test/com/sun/crypto/provider/CICO/PBEFunc/CICOPBEFuncTest.java new file mode 100644 index 0000000000000000000000000000000000000000..0e4b376e01ea3b7d7a64803147e00eeafe0f9c92 --- /dev/null +++ b/test/com/sun/crypto/provider/CICO/PBEFunc/CICOPBEFuncTest.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2007, 2015, 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. + * + * 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. + */ + +/* + * @test + * @bug 8048604 + * @summary This test verifies the assertion "The encrypt/decrypt + * mechanism of cipher should perform correctly." for feature + * "CipherInputStream & CipherOutputStream". + * @library ../ + * @run main CICOPBEFuncTest + */ + +import java.util.Arrays; +import javax.crypto.Cipher; + +public class CICOPBEFuncTest { + + public static void main(String[] args) throws Exception { + for (PBEAlgorithm algorithm : PBEAlgorithm.values()) { + // int buffertin test + String algo = algorithm.baseAlgo.toUpperCase(); + if (!algo.contains("TRIPLEDES") && !algo.contains("AES_256") + || Cipher.getMaxAllowedKeyLength(algo) > 128) { + // skip this if this key length is larger than what's + // configured in the jce jurisdiction policy files + System.out.println("Testing " + algorithm.getTransformation()); + for (String type : Arrays.asList(CICO_PBE_Test.INT_BYTE_BUFFER, + CICO_PBE_Test.BYTE_ARR_BUFFER)) { + new CICO_PBE_RW_Test(algorithm) + .proceedTest(type); + new CICO_PBE_SKIP_Test(algorithm) + .proceedTest(type); + } + } + } + } +} diff --git a/test/com/sun/crypto/provider/CICO/PBEFunc/CICO_PBE_RW_Test.java b/test/com/sun/crypto/provider/CICO/PBEFunc/CICO_PBE_RW_Test.java new file mode 100644 index 0000000000000000000000000000000000000000..da149f04f631bfb55b95db47168d661a954dbefb --- /dev/null +++ b/test/com/sun/crypto/provider/CICO/PBEFunc/CICO_PBE_RW_Test.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2007, 2015, 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. + * + * 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. + */ + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.security.GeneralSecurityException; + +import javax.crypto.CipherOutputStream; + +/** + * CICO PBE Read/Write functional test. + * + * Verifies for the given PBE algorithm if the encrypt/decrypt mechanism is + * performed correctly for CipherInputStream and CipherOutputStream. + * + * Test scenario: + * 1. initializes plain text with random generated data. + * 2. for the given PBE algorithm instantiates encrypt and decrypt Ciphers. + * 3. instantiates CipherInputStream with the encrypt Cipher. + * 4. instantiates CipherOutputStream with the decrypt Cipher. + * 5. performs reading from the CipherInputStream (encryption data) and writing + * to the CipherOutputStream (decryption). As a result the output of the + * CipherOutputStream should be the same as an original plain text. + * 6. compares if the original plain text is the same as the output of the + * CipherOutputStream. + * + * The test implements 2 test cases in accordance with buffering type: + * 1. byte array buffering + * 2. int buffering + */ +public class CICO_PBE_RW_Test extends CICO_PBE_Test { + + public CICO_PBE_RW_Test(PBEAlgorithm pbeAlgo) + throws GeneralSecurityException { + super(pbeAlgo); + } + + /** + * The CICO PBE RW test specific part of the super.doTest(). Implements the + * scenario in accordance to the class description. + * @param type byteArrayBuffering or intByteBuffering + * @throws IOException any I/O operation failed. + * @throws GeneralSecurityException any security error. + */ + @Override + public void proceedTest(String type) throws IOException, + GeneralSecurityException { + ByteArrayOutputStream baOutput = new ByteArrayOutputStream(); + try (CipherOutputStream ciOutput = new CipherOutputStream(baOutput, + getDecryptCipher())) { + if (type.equals(CICO_PBE_Test.BYTE_ARR_BUFFER)) { + proceedTestUsingByteArrayBuffer(ciOutput); + } else { + proceedTestUsingIntBuffer(ciOutput); + } + ciOutput.flush(); + } + // Compare input and output + if (!TestUtilities.equalsBlock(plainText, baOutput.toByteArray(), TEXT_SIZE)) { + throw new RuntimeException("outputText not same with expectedText" + + " when test " + type); + } + } + + /** + * Implements byte array buffering type test case of the CICO PBE RW test. + * @param ciOutput output stream for data written. + * @throws java.io.IOException any I/O operation failed. + */ + public void proceedTestUsingByteArrayBuffer( + CipherOutputStream ciOutput) throws IOException { + byte[] buffer = new byte[TEXT_SIZE]; + int len = getCiInput().read(buffer); + while (len != -1) { + ciOutput.write(buffer, 0, len); + len = getCiInput().read(buffer); + } + } + + /** + * Implements int buffering type test case. + * @param ciOutput output stream for data written. + * @throws java.io.IOException any I/O operation failed. + */ + public void proceedTestUsingIntBuffer(CipherOutputStream ciOutput) + throws IOException { + int buffer = getCiInput().read(); + while (buffer != -1) { + ciOutput.write(buffer); + buffer = getCiInput().read(); + } + } +} diff --git a/test/com/sun/crypto/provider/CICO/PBEFunc/CICO_PBE_SKIP_Test.java b/test/com/sun/crypto/provider/CICO/PBEFunc/CICO_PBE_SKIP_Test.java new file mode 100644 index 0000000000000000000000000000000000000000..62ebd8327f8d59beb66d2518ecfc3c2c10405e6e --- /dev/null +++ b/test/com/sun/crypto/provider/CICO/PBEFunc/CICO_PBE_SKIP_Test.java @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2007, 2015, 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. + * + * 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. + */ +import java.io.IOException; +import java.security.GeneralSecurityException; +import javax.crypto.CipherInputStream; + +/** + * CICO PBE SKIP functional test. + * + * Verifies for the given PBE algorithm if the encrypt/decrypt mechanism is + * performed correctly for CipherInputStream when skip() method is used. + * + * Test scenario: + * 1. initializes plain text with random generated data with length TEXT_SIZE. + * 2. for the given PBE algorithm instantiates encrypt and decrypt Ciphers. + * 3. instantiates CipherInputStream 1 with the encrypt Cipher. + * 4. instantiates CipherInputStream 2 with the CipherInputStream 1 and decrypt + * Cipher. + * 5. the plain text is divided on TEXT_SIZE/BLOCK blocks. Reading from + * CipherInputStream 2 one block at time. The last BLOCK - SAVE bytes are + * skipping for each block. Therefor the plain text data go through + * CipherInputStream 1 (encrypting) and CipherInputStream 2 (decrypting). + * As a result the output should equal to the original text except DISCARD + * byte for each block are skipped. + * 6. get the standard output. + * 7. compares the expected standard output with the output of the + * CipherInputStream 2. If it is the same the test passed. Otherwise it + * failed. Any uncaught exceptions should be considered as an error. + * The test implements 2 test cases in accordance with a buffering type: + * 1. byte array buffering + * 2. int buffering + */ +public class CICO_PBE_SKIP_Test extends CICO_PBE_Test { + /** + * Block size. + */ + private static final int BLOCK = 50; + + /** + * Valid reading byte size. + */ + private static final int SAVE = 45; + + /** + * Skip reading byte size. This should be same to BLOCK - SAVE + */ + private static final int DISCARD = BLOCK - SAVE; + + /** + * Number of blocks. + */ + private static final int NUMBER_OF_BLOCKS = TEXT_SIZE / BLOCK; + + private final byte[] outputText; + /** + * CICO PBE Skip test constructor + * + * @param pbeAlgo the PBE algorithm to test. + * @throws java.security.GeneralSecurityException + */ + public CICO_PBE_SKIP_Test(PBEAlgorithm pbeAlgo) + throws GeneralSecurityException { + super(pbeAlgo); + outputText = new byte[NUMBER_OF_BLOCKS * SAVE]; + } + + /** + * Implements byte array buffering type test case of the CICO SKIP test. + * + * @param blockNum block number to read. + */ + private void proceedSkipTestUsingByteArrayBufferingType( + CipherInputStream ciIn2, int blockNum) throws IOException { + int index = blockNum * SAVE; + int len1 = ciIn2.read(outputText, index, SAVE); + // read more until SAVE bytes + index += len1; + int len2 = 0; + int totalRead = len1; + while (len1 != SAVE && len2 != -1) { + len2 = ciIn2.read(outputText, index, SAVE - len1); + len1 += len2; + index += len2; + totalRead += len2; + } + if (totalRead != SAVE) { + throw new RuntimeException("Read bytes number " + totalRead + + " does not equal to given number " + SAVE); + } + } + + /** + * Implements int buffering type test case of the CICO SKIP test. + * + * @param blockNum block number to read. + */ + private void proceedSkipTestUsingIntBufferingType(CipherInputStream ciIn2, + int blockNum) throws IOException { + int index = blockNum * SAVE; + int totalRead = 0; + for (int j = 0; j < SAVE; j++, index++) { + int buffer0 = ciIn2.read(); + if (buffer0 != -1) { + outputText[index] = (byte) buffer0; + totalRead++; + } else { + break; + } + } + if (totalRead != SAVE) { + throw new RuntimeException("Read bytes number " + totalRead + + " does not equal to given number " + SAVE); + } + } + + /** + * The CICO PBE SKIP test specific part of the super.doTest(). Implements + * the scenario in accordance to the class description. + * @throws java.io.IOException any I/O failed. + */ + @Override + public void proceedTest(String type) throws IOException { + System.out.println("Test type: " + type); + // init second input stream with decrypt Cipher + try (CipherInputStream ciIn2 = new CipherInputStream(getCiInput(), + getDecryptCipher())) { + for (int i = 0; i < NUMBER_OF_BLOCKS; i++) { + if (type.equals(CICO_PBE_Test.BYTE_ARR_BUFFER)) { + proceedSkipTestUsingByteArrayBufferingType(ciIn2, i); + } else { + proceedSkipTestUsingIntBufferingType(ciIn2, i); + } + if (ciIn2.available() >= DISCARD) { + ciIn2.skip(DISCARD); + } else { + for (int k = 0; k < DISCARD; k++) { + ciIn2.read(); + } + } + } + } + if (!TestUtilities.equalsBlockPartial(plainText, outputText, BLOCK, SAVE)) { + throw new RuntimeException("outputText not same with expectedText" + + " when test " + type); + } + } + +} diff --git a/test/com/sun/crypto/provider/CICO/PBEFunc/CICO_PBE_Test.java b/test/com/sun/crypto/provider/CICO/PBEFunc/CICO_PBE_Test.java new file mode 100644 index 0000000000000000000000000000000000000000..9879bf4d1fb0c3618d1c2cf145cf5dd294347e28 --- /dev/null +++ b/test/com/sun/crypto/provider/CICO/PBEFunc/CICO_PBE_Test.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2007, 2015, 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. + * + * 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. + */ +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.security.GeneralSecurityException; +import javax.crypto.Cipher; +import javax.crypto.CipherInputStream; + +/** + * This is an abstract class for CipherInputStream/CipherOutputStream PBE + * functional tests. + */ +public abstract class CICO_PBE_Test { + /** + * Sample string for byte buffer. + */ + public static final String BYTE_ARR_BUFFER = "byteArrayBuffering"; + + /** + * Sample string for int buffer. + */ + public static final String INT_BYTE_BUFFER = "intByteBuffering"; + public static final String PASS_PHRASE = "Some password phrase!"; + + /** + * Text string size. + */ + public static final int TEXT_SIZE = 800; + + protected final byte[] plainText; + private final Cipher encryptCipher, decryptCipher; + + /** + * An CipherInputStream for reading cipher and plain text. + */ + private final CipherInputStream ciInput; + + /** + * Constructor by algorithm. + * @param pbeAlgo PBE algorithm to test. + * @throws GeneralSecurityException if any security error. + */ + public CICO_PBE_Test(PBEAlgorithm pbeAlgo) throws GeneralSecurityException { + // Do initialization of the plainText + plainText = TestUtilities.generateBytes(TEXT_SIZE); + // Do initialization of the ciphers + AbstractPBEWrapper pbeWrap = AbstractPBEWrapper.createWrapper(pbeAlgo, PASS_PHRASE); + encryptCipher = pbeWrap.initCipher(Cipher.ENCRYPT_MODE); + decryptCipher = pbeWrap.initCipher(Cipher.DECRYPT_MODE); + // init cipher input stream + ciInput = new CipherInputStream(new ByteArrayInputStream(plainText), + encryptCipher); + } + + protected byte[] getPlainText() { + return plainText; + } + + /** + * The body of the test. Should be defined in subclasses. + * @param type byteArrayBuffering or intByteBuffering + * @throws IOException I/O operation failed. + * @throws GeneralSecurityException all exceptions thrown. + */ + protected abstract void proceedTest(String type) + throws IOException, GeneralSecurityException; + + protected Cipher getEncryptCipher() { + return encryptCipher; + } + + public CipherInputStream getCiInput() { + return ciInput; + } + + public Cipher getDecryptCipher() { + return decryptCipher; + } +} diff --git a/test/com/sun/crypto/provider/CICO/PBEFunc/CipherNCFuncTest.java b/test/com/sun/crypto/provider/CICO/PBEFunc/CipherNCFuncTest.java new file mode 100644 index 0000000000000000000000000000000000000000..73952ebb7c36ed97f46441c497acf7c3cd9b93b6 --- /dev/null +++ b/test/com/sun/crypto/provider/CICO/PBEFunc/CipherNCFuncTest.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2001, 2015, 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. + * + * 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. + */ +/* + * @test + * @bug 8048604 + * @library ../ /lib/testlibrary + * @summary This test verifies the assertion "There should be no transformation + * on the plaintext/ciphertext in encryption/decryption mechanism" for + * feature "NullCipher". + */ +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NullCipher; +import javax.crypto.ShortBufferException; +import jdk.testlibrary.RandomFactory; + +public class CipherNCFuncTest { + public static void main(String[] args) throws ShortBufferException, + IllegalBlockSizeException, BadPaddingException { + byte[] plainText = new byte[801]; + // Initialization + RandomFactory.getRandom().nextBytes(plainText); + Cipher ci = new NullCipher(); + // Encryption + byte[] cipherText = new byte[ci.getOutputSize(plainText.length)]; + int offset = ci.update(plainText, 0, plainText.length, cipherText, 0); + ci.doFinal(cipherText, offset); + // Decryption + byte[] recoveredText = new byte[ci.getOutputSize(cipherText.length)]; + int len = ci.doFinal(cipherText, 0, cipherText.length, recoveredText); + // Comparison + if (len != plainText.length || + !TestUtilities.equalsBlock(plainText, cipherText, len) || + !TestUtilities.equalsBlock(plainText, recoveredText, len)) { + throw new RuntimeException( + "Test failed because plainText not equal to cipherText and revoveredText"); + } + } +} diff --git a/test/com/sun/crypto/provider/CICO/PBEFunc/DefaultPBEWrapper.java b/test/com/sun/crypto/provider/CICO/PBEFunc/DefaultPBEWrapper.java new file mode 100644 index 0000000000000000000000000000000000000000..f68fd85146bf701fbb05e7bbc17ff492b381208d --- /dev/null +++ b/test/com/sun/crypto/provider/CICO/PBEFunc/DefaultPBEWrapper.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2007, 2015, 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. + * + * 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. + */ +import java.security.GeneralSecurityException; +import java.security.Provider; +import java.security.Security; +import javax.crypto.SecretKey; +import javax.crypto.Cipher; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; +import javax.crypto.spec.PBEParameterSpec; + +/** + * Default wrapper for a password based encryption Cipher. + */ + +public class DefaultPBEWrapper extends AbstractPBEWrapper { + /** + * Define default SALT size as 8. + */ + private static final int PBE_SALT_SIZE = 8; + + /** + * Default PBE wrapper constructor. + * + * @param algo PGE algorithm to wrap. + * @param passwd password phrase + */ + public DefaultPBEWrapper(PBEAlgorithm algo, String passwd) { + super(algo, passwd, PBE_SALT_SIZE); + } + + /** + * Instantiate Cipher for the PBE algorithm. + * + * @param mode Cipher mode: encrypt or decrypt. + * @return Cipher in accordance to the PBE algorithm + * @throws java.security.GeneralSecurityException + */ + @Override + protected Cipher initCipher(int mode) throws GeneralSecurityException { + Provider provider = Security.getProvider("SunJCE"); + if (provider == null) { + throw new RuntimeException("SunJCE provider does not exist."); + } + SecretKey key = SecretKeyFactory.getInstance(baseAlgo) + .generateSecret(new PBEKeySpec(password.toCharArray())); + Cipher ci = Cipher.getInstance(transformation, provider); + ci.init(mode, key, new PBEParameterSpec(salt, DEFAULT_ITERATION)); + return ci; + } +} diff --git a/test/com/sun/crypto/provider/CICO/PBEFunc/PBEAlgorithm.java b/test/com/sun/crypto/provider/CICO/PBEFunc/PBEAlgorithm.java new file mode 100644 index 0000000000000000000000000000000000000000..98ef4f2d926556b92f4b944c1856f65c027aab81 --- /dev/null +++ b/test/com/sun/crypto/provider/CICO/PBEFunc/PBEAlgorithm.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2007, 2015, 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. + * + * 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. + */ + +import java.util.StringJoiner; + +public enum PBEAlgorithm { + MD5_DES("PBEWithMD5ANDdes", "", "", AbstractPBEWrapper.DEFAULT), + MD5_DES_CBC_PKCS5("PBEWithMD5AndDES", "CBC", "PKCS5Padding", + AbstractPBEWrapper.DEFAULT), + MD5_TRIPLEDES("PBEWithMD5ANDtripledes", "", "", AbstractPBEWrapper.DEFAULT), + MD5_TRIPLEDES_CBC_PKCS5("PBEWithMD5AndTRIPLEDES", "CBC", "PKCS5Padding", + AbstractPBEWrapper.DEFAULT), + SHA1_DESEDE("PBEwithSHA1AndDESede", "", "", AbstractPBEWrapper.DEFAULT), + SHA1_DESEDE_CBC_PKCS5("PBEwithSHA1AndDESede", "CBC", "PKCS5Padding", + AbstractPBEWrapper.DEFAULT), + SHA1_RC2_40("PBEwithSHA1AndRC2_40", "", "", AbstractPBEWrapper.DEFAULT), + SHA1_RC2_40_PKCS5("PBEwithSHA1Andrc2_40", "CBC", "PKCS5Padding", + AbstractPBEWrapper.DEFAULT), + SHA1_RC2_128("PBEWithSHA1AndRC2_128", "", "", AbstractPBEWrapper.DEFAULT), + SHA1_RC2_128_PKCS5("PBEWithSHA1andRC2_128", "CBC", "PKCS5Padding", + AbstractPBEWrapper.DEFAULT), + SHA1_RC4_40("PBEWithSHA1AndRC4_40", "", "", AbstractPBEWrapper.DEFAULT), + SHA1_RC4_40_ECB_NOPADDING("PBEWithsha1AndRC4_40", "ECB", "NoPadding", + AbstractPBEWrapper.DEFAULT), + SHA1_RC4_128("PBEWithSHA1AndRC4_128", "", "", AbstractPBEWrapper.DEFAULT), + SHA1_RC4_128_ECB_NOPADDING("pbeWithSHA1AndRC4_128", "ECB", "NoPadding", + AbstractPBEWrapper.DEFAULT), + HMAC_SHA1_AES_128("PBEWithHmacSHA1AndAES_128", "", "", AbstractPBEWrapper.AES), + HMAC_SHA224_AES_128("PBEWithHmacSHA224AndAES_128", "", "", AbstractPBEWrapper.AES), + HMAC_SHA256_AES_128("PBEWithHmacSHA256AndAES_128", "", "", AbstractPBEWrapper.AES), + HMAC_SHA384_AES_128("PBEWithHmacSHA384AndAES_128", "", "", AbstractPBEWrapper.AES), + HMAC_SHA512_AES_128("PBEWithHmacSHA512AndAES_128", "", "", AbstractPBEWrapper.AES), + HMAC_SHA1_AES_256("PBEWithHmacSHA1AndAES_256", "", "", AbstractPBEWrapper.AES), + HMAC_SHA224_AES_256("PBEWithHmacSHA224AndAES_256", "", "", AbstractPBEWrapper.AES), + HMAC_SHA256_AES_256("PBEWithHmacSHA256AndAES_256", "", "", AbstractPBEWrapper.AES), + HMAC_SHA384_AES_256("PBEWithHmacSHA384AndAES_256", "", "", AbstractPBEWrapper.AES), + HMAC_SHA512_AES_256("PBEWithHmacSHA512AndAES_256", "", "", AbstractPBEWrapper.AES), + PBKDF_HMAC_SHA1("PBKDF2WithHmacSHA1", "", "", AbstractPBEWrapper.PBKDF2), + PBKDF_HMAC_SHA224("PBKDF2WithHmacSHA224", "", "", AbstractPBEWrapper.PBKDF2), + PBKDF_HMAC_SHA256("PBKDF2WithHmacSHA256", "", "", AbstractPBEWrapper.PBKDF2), + PBKDF_HMAC_SHA384("PBKDF2WithHmacSHA384", "", "", AbstractPBEWrapper.PBKDF2), + PBKDF_HMAC_SHA512("PBKDF2WithHmacSHA512", "", "", AbstractPBEWrapper.PBKDF2); + final String baseAlgo; + final String mode; + final String padding; + final String type; + + PBEAlgorithm(String alg, String mode, String padding, String type) { + this.baseAlgo = alg; + this.mode = mode; + this.padding = padding; + this.type = type; + } + + public String getTransformation() { + StringJoiner sj = new StringJoiner("/"); + sj.add(baseAlgo); + if (!mode.equals("")) { + sj.add(this.mode); + } + if (!padding.equals("")) { + sj.add(this.padding); + } + return sj.toString(); + } +} diff --git a/test/com/sun/crypto/provider/CICO/PBEFunc/PBKDF2Wrapper.java b/test/com/sun/crypto/provider/CICO/PBEFunc/PBKDF2Wrapper.java new file mode 100644 index 0000000000000000000000000000000000000000..fb2d0ac901f892cd7b767ebab5f1b6eb82898227 --- /dev/null +++ b/test/com/sun/crypto/provider/CICO/PBEFunc/PBKDF2Wrapper.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2007, 2015, 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. + * + * 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. + */ + +import java.security.GeneralSecurityException; +import java.security.Provider; +import java.security.Security; +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.PBEKeySpec; +import javax.crypto.spec.SecretKeySpec; + +/** + * Wrapper class to test a given SecretKeyFactory.PBKDF2 algorithm. + */ +public class PBKDF2Wrapper extends AbstractPBEWrapper { + /** + * Default salt size. + */ + public static final int PBKDF2_SALT_SIZE = 64; + + /** + * Default key length. + */ + public static final int PKDF2_DEFAULT_KEY_LEN = 128; + + /** + * Default transformation. + */ + public static final String CIPHER_TRANSFORMATION = "AES/CBC/PKCS5Padding"; + + /** + * Algorithm name. + */ + public static final String KEY_ALGORITHM = "AES"; + + /** + * Initialization vector length. + */ + private static final int IV_LENGTH = 16; + + /** + * The buffer with the IV. + */ + private final byte[] iv; + + /** + * PBKDF2Wrapper constructor. Instantiate Cipher using + * "AES/CBC/PKCS5Padding" transformation. Generate a secret key using PKDF2 + * algorithms given in the "algo" parameter. + * + * @param algo AES-based PBE algorithm. + * @param passwd password phrase. + * @throws GeneralSecurityException all security exceptions are thrown. + */ + public PBKDF2Wrapper(PBEAlgorithm algo, String passwd) + throws GeneralSecurityException { + super(algo, passwd, PBKDF2_SALT_SIZE); + iv = TestUtilities.generateBytes(IV_LENGTH); + } + + /** + * Initiate the Cipher object for PBKDF2 algorithm using given "mode". + * + * @param mode Cipher mode: encrypt or decrypt + * @return Cipher object for PBKDF2 algorithm + * @throws GeneralSecurityException all security exceptions are thrown. + */ + @Override + protected Cipher initCipher(int mode) throws GeneralSecurityException { + Provider provider = Security.getProvider("SunJCE"); + if (provider == null) { + throw new RuntimeException("SunJCE provider does not exist."); + } + // Generate secret key + PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray(), + salt, DEFAULT_ITERATION, PKDF2_DEFAULT_KEY_LEN); + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(baseAlgo); + SecretKey key = keyFactory.generateSecret(pbeKeySpec); + + // get Cipher instance + Cipher cipher = Cipher.getInstance(CIPHER_TRANSFORMATION, provider); + cipher.init(mode, + new SecretKeySpec(key.getEncoded(),KEY_ALGORITHM), + new IvParameterSpec(iv)); + return cipher; + } +} diff --git a/test/com/sun/crypto/provider/CICO/ReadModel.java b/test/com/sun/crypto/provider/CICO/ReadModel.java new file mode 100644 index 0000000000000000000000000000000000000000..d1cfb7153b6ca07cbd98cbd1c0c137e11e2c62f3 --- /dev/null +++ b/test/com/sun/crypto/provider/CICO/ReadModel.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2007, 2015, 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. + * + * 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. + */ +import java.io.IOException; + +import javax.crypto.Cipher; +import javax.crypto.CipherInputStream; +import javax.crypto.CipherOutputStream; + +/** + * ReadModel provides different way to test + * CipherInputStream.read()/read(byte[])/read(byte[], int, int) and + * CipherOutputStream.write(int)/write(byte[], int, int)/read(byte[]) API + */ +enum ReadModel { + READ_BYTE { + @Override + public void read(CipherInputStream cInput, CipherOutputStream ciOutput, + Cipher ciIn, int inputLen) throws IOException { + int buffer0 = cInput.read(); + while (buffer0 != -1) { + ciOutput.write(buffer0); + buffer0 = cInput.read(); + } + } + }, + READ_BUFFER { + @Override + public void read(CipherInputStream cInput, CipherOutputStream ciOutput, + Cipher ciIn, int inputLen) throws IOException { + byte[] buffer1 = new byte[20]; + int len1; + while ((len1 = cInput.read(buffer1)) != -1) { + ciOutput.write(buffer1, 0, len1); + } + + } + }, + READ_BUFFER_OFFSET { + @Override + public void read(CipherInputStream cInput, CipherOutputStream ciOutput, + Cipher ciIn, int inputLen) throws IOException { + byte[] buffer2 = new byte[ciIn.getOutputSize(inputLen)]; + int offset2 = 0; + int len2 = 0; + while (len2 != -1) { + len2 = cInput.read(buffer2, offset2, buffer2.length - offset2); + offset2 += len2; + } + ciOutput.write(buffer2); + + } + }; + + abstract public void read(CipherInputStream cInput, + CipherOutputStream ciOutput, Cipher ciIn, int inputLen) + throws IOException; +} diff --git a/test/com/sun/crypto/provider/CICO/TestUtilities.java b/test/com/sun/crypto/provider/CICO/TestUtilities.java new file mode 100644 index 0000000000000000000000000000000000000000..a1160f7395d2a688e128a34aed8f6205acb6f65e --- /dev/null +++ b/test/com/sun/crypto/provider/CICO/TestUtilities.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2007, 2015, 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. + * + * 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. + */ + +/* + * utility class + */ + +public class TestUtilities { + public static boolean equalsBlock(byte[] b1, byte[] b2, int len) { + for (int i = 0; i < len; i++) { + if (b1[i] != b2[i]) { + System.err.println("b1[" + i + "] : " + b1[i] + + " b2[" + i + "] : " + b2[i]); + return false; + } + } + return true; + } + + public static boolean equals(byte[] b1, byte[] b2) { + if (b2.length != b1.length) { + System.err.println("b1.length = " + b1.length + + " b2.length = " + b2.length ); + return false; + } + return equalsBlock(b1, b2, b1.length); + } + + /** + * Verify b1's partial part is same as b2. compares b1 and b2 by chopping up + * b1 into blocks of b1BKSize and b2 into blocks of b2BKSize, and then + * compare the first b2BKSize bytes of each block, return true if they equal + * , otherwise return false. + * @param b1 byte array to be compared. + * @param b2 saved byte array. + * @param b1BKSize b1's block size. + * @param b2BKSize b2's block size. + * @return true is same. false otherwise. + */ + public static boolean equalsBlockPartial(byte[] b1, byte[] b2, int b1BKSize, + int b2BKSize) { + int numOfBlock = b1.length / b1BKSize; + for (int b = 0; b < numOfBlock; b++) { + for (int i = 0; i < b2BKSize; i++) { + int j1 = b * b1BKSize + i; + int j2 = b * b2BKSize + i; + if (b1[j1] != b2[j2]) { + System.err.println("Compare failed at b1[" + j1 + "]:" + + b1[j1] + " b2[" + j2 + "]:" + b2[j2]); + return false; + } + } + } + return true; + } + + /** + * Generate a byte block by given length. The content of byte block + * is determined by the index. + * @param length length of byte array + * @return a byte array + */ + public static byte[] generateBytes(int length) { + byte[] bytes = new byte[length]; + for (int i = 0; i < length; i++) { + bytes[i] = (byte) (i & 0xff); + } + return bytes; + } +} diff --git a/test/com/sun/crypto/provider/Cipher/AEAD/Encrypt.java b/test/com/sun/crypto/provider/Cipher/AEAD/Encrypt.java new file mode 100644 index 0000000000000000000000000000000000000000..d96cb00a6f4dc3936e144de7ba07b99c31c061f6 --- /dev/null +++ b/test/com/sun/crypto/provider/Cipher/AEAD/Encrypt.java @@ -0,0 +1,753 @@ +/* + * Copyright (c) 2007, 2015, 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. + * + * 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. + */ + +import java.nio.ByteBuffer; +import java.security.AlgorithmParameters; +import java.security.Provider; +import java.security.Security; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import javax.crypto.SecretKey; +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; + +/* + * @test + * @bug 8048596 + * @summary AEAD encryption/decryption test + */ + +/* + * The test does the following: + * - create an input text and additional data + * - generate a secret key + * - instantiate a cipher according to the GCM transformation + * - generate an outputText using a single-part encryption/decryption + * in AEAD mode + * - perform 16 different combinations of multiple-part encryption/decryption + * operation in AEAD mode (in encryption mode new Cipher object is created + * and initialized with the same secret key and parameters) + * - check that all 17 results are equal + * + * Combinations: + * + * combination #1 + * updateAAD(byte[] src) + * update(byte[], int, int) + * doFinal(byte[], int, int) + * + * combination #2 + * updateAAD(byte[] src) + * update(byte[], int, int) + * doFinal(byte[], int, int, byte[], int) + * + * combination #3 + * updateAAD(byte[] src) + * update(byte[], int, int, byte[], int) + * doFinal(byte[], int, int) + * + * combination #4 + * updateAAD(byte[] src) + * update(byte[], int, int, byte[], int) + * doFinal(byte[], int, int, byte[], int) + * + * combination #5 - #8 are similar to #1 -#4, + * but with updateAAD(byte[] src, int offset, int len) + * + * combination #9 - #12 are similar to #1 - #4, + * but with updateAAD(ByteBuffer src) + * + * combination #13 - #16 are similar to #9 - #12 but with directly allocated + * ByteBuffer and update(ByteBuffer input, ByteBuffer output) + * + */ +public class Encrypt { + + private static final String ALGORITHMS[] = { "AES", "Rijndael" }; + private static final int KEY_STRENGTHS[] = { 128, 192, 256 }; + private static final int TEXT_LENGTHS[] = { 0, 256, 1024 }; + private static final int AAD_LENGTHS[] = { 0, 8, 128, 256, 1024 }; + private static final int ARRAY_OFFSET = 8; + + private final String transformation; + private final Provider provider; + private final SecretKey key; + private final int textLength; + private final int AADLength; + + /** + * @param provider Security provider + * @param algorithm Security algorithm to test + * @param mode The mode (GCM is only expected) + * @param padding Algorithm padding + * @param keyStrength key length + * @param textLength Plain text length + * @param AADLength Additional data length + */ + public Encrypt(Provider provider, String algorithm, String mode, + String padding, int keyStrength, int textLength, int AADLength) + throws Exception { + + // init a secret Key + KeyGenerator kg = KeyGenerator.getInstance(algorithm, provider); + kg.init(keyStrength); + key = kg.generateKey(); + + this.provider = provider; + this.transformation = algorithm + "/" + mode + "/" + padding; + this.textLength = textLength; + this.AADLength = AADLength; + } + + public static void main(String[] args) throws Exception { + Provider p = Security.getProvider("SunJCE"); + for (String alg : ALGORITHMS) { + for (int keyStrength : KEY_STRENGTHS) { + if (keyStrength > Cipher.getMaxAllowedKeyLength(alg)) { + // skip this if this key length is larger than what's + // configured in the JCE jurisdiction policy files + continue; + } + for (int textLength : TEXT_LENGTHS) { + for (int AADLength : AAD_LENGTHS) { + Encrypt test = new Encrypt(p, alg, + "GCM", "NoPadding", keyStrength, textLength, + AADLength); + Cipher cipher = test.createCipher(Cipher.ENCRYPT_MODE, + null); + AlgorithmParameters params = cipher.getParameters(); + test.doTest(params); + System.out.println("Test " + alg + ":" + + keyStrength + ":" + textLength + ":" + + AADLength + " passed"); + } + } + } + } + } + + public void doTest(AlgorithmParameters params) throws Exception { + System.out.println("Test transformation = " + transformation + + ", textLength = " + textLength + + ", AADLength = " + AADLength); + byte[] input = Helper.generateBytes(textLength); + byte[] AAD = Helper.generateBytes(AADLength); + byte[] result = execute(Cipher.ENCRYPT_MODE, AAD, input, params); + result = execute(Cipher.DECRYPT_MODE, AAD, result, params); + if (!Arrays.equals(input, result)) { + throw new RuntimeException("Test failed"); + } + System.out.println("Test passed"); + } + + /** + * Create a Cipher object for the requested encryption/decryption mode. + * + * @param mode encryption or decryption mode + * @return Cipher object initiated to perform requested mode operation + */ + private Cipher createCipher(int mode, AlgorithmParameters params) + throws Exception { + Cipher ci; + if (Cipher.ENCRYPT_MODE == mode) { + // create a new Cipher object for encryption + ci = Cipher.getInstance(transformation, provider); + + // initiate it with the saved parameters + if (params != null) { + ci.init(Cipher.ENCRYPT_MODE, key, params); + } else { + // initiate the cipher without parameters + ci.init(Cipher.ENCRYPT_MODE, key); + } + } else { + // it is expected that parameters already generated + // before decryption + ci = Cipher.getInstance(transformation, provider); + ci.init(Cipher.DECRYPT_MODE, key, params); + } + + return ci; + } + + /** + * Test AEAD combinations + * + * @param mode decryption or encryption + * @param AAD additional data for AEAD operations + * @param inputText plain text to decrypt/encrypt + * @return output text after encrypt/decrypt + */ + public byte[] execute(int mode, byte[] AAD, byte[] inputText, + AlgorithmParameters params) throws Exception { + + Cipher cipher = createCipher(mode, params); + + // results of each combination will be saved in the outputTexts + List outputTexts = new ArrayList<>(); + + // generate a standard outputText using a single-part en/de-cryption + cipher.updateAAD(AAD); + byte[] output = cipher.doFinal(inputText); + + // execute multiple-part encryption/decryption combinations + combination_1(outputTexts, mode, AAD, inputText, params); + combination_2(outputTexts, mode, AAD, inputText, params); + combination_3(outputTexts, mode, AAD, inputText, params); + combination_4(outputTexts, mode, AAD, inputText, params); + combination_5(outputTexts, mode, AAD, inputText, params); + combination_6(outputTexts, mode, AAD, inputText, params); + combination_7(outputTexts, mode, AAD, inputText, params); + combination_8(outputTexts, mode, AAD, inputText, params); + combination_9(outputTexts, mode, AAD, inputText, params); + combination_10(outputTexts, mode, AAD, inputText, params); + combination_11(outputTexts, mode, AAD, inputText, params); + combination_12(outputTexts, mode, AAD, inputText, params); + combination_13(outputTexts, mode, AAD, inputText, params); + combination_14(outputTexts, mode, AAD, inputText, params); + combination_15(outputTexts, mode, AAD, inputText, params); + combination_16(outputTexts, mode, AAD, inputText, params); + + for (int k = 0; k < outputTexts.size(); k++) { + if (!Arrays.equals(output, outputTexts.get(k))) { + throw new RuntimeException("Combination #" + k + " failed"); + } + } + return output; + } + + /* + * Execute multiple-part encryption/decryption combination #1: + * updateAAD(byte[] src) + * update(byte[], int, int) + * doFinal(byte[], int, int) + */ + private void combination_1(List results, int mode, byte[] AAD, + byte[] plainText, AlgorithmParameters params) throws Exception { + Cipher c = createCipher(mode, params); + c.updateAAD(AAD); + byte[] part11 = c.update(plainText, 0, plainText.length); + int part11_length = part11 == null ? 0 : part11.length; + byte[] part12 = c.doFinal(); + byte[] outputText1 = new byte[part11_length + part12.length]; + if (part11 != null) { + System.arraycopy(part11, 0, outputText1, 0, part11_length); + } + System.arraycopy(part12, 0, outputText1, part11_length, part12.length); + results.add(outputText1); + } + + /* + * Execute multiple-part encryption/decryption combination #2: + * updateAAD(byte[] src) + * update(byte[], int, int) + * doFinal(byte[], int, int, byte[], int) + */ + private void combination_2(List results, int mode, byte[] AAD, + byte[] plainText, AlgorithmParameters params) throws Exception { + Cipher c = createCipher(mode, params); + c.updateAAD(AAD); + int t = 0; + int offset = 0; + if (plainText.length > ARRAY_OFFSET) { + t = plainText.length - ARRAY_OFFSET; + offset = ARRAY_OFFSET; + } + byte[] part21 = c.update(plainText, 0, t); + byte[] part22 = new byte[c.getOutputSize(plainText.length)]; + int len2 = c.doFinal(plainText, t, offset, part22, 0); + int part21Length = part21 != null ? part21.length : 0; + byte[] outputText2 = new byte[part21Length + len2]; + if (part21 != null) { + System.arraycopy(part21, 0, outputText2, 0, part21Length); + } + System.arraycopy(part22, 0, outputText2, part21Length, len2); + results.add(outputText2); + } + + /* + * Execute multiple-part encryption/decryption combination #3 + * updateAAD(byte[] src) + * update(byte[], int, int, byte[], int) + * doFinal(byte[], int, int) + */ + private void combination_3(List results, int mode, byte[] AAD, + byte[] plainText, AlgorithmParameters params) throws Exception { + Cipher ci = createCipher(mode, params); + ci.updateAAD(AAD); + byte[] part31 = new byte[ci.getOutputSize(plainText.length)]; + int offset = plainText.length > ARRAY_OFFSET ? ARRAY_OFFSET : 0; + int len = ci.update(plainText, 0, plainText.length - offset, part31, 0); + byte[] part32 = ci.doFinal(plainText, plainText.length - offset, + offset); + byte[] outputText3 = new byte[len + part32.length]; + System.arraycopy(part31, 0, outputText3, 0, len); + System.arraycopy(part32, 0, outputText3, len, part32.length); + results.add(outputText3); + } + + /* + * Execute multiple-part encryption/decryption combination #4: + * updateAAD(byte[] src) + * update(byte[], int, int, byte[], int) + * doFinal(byte[], int, int, byte[], int) + */ + private void combination_4(List results, int mode, byte[] AAD, + byte[] plainText, AlgorithmParameters params) throws Exception { + Cipher ci = createCipher(mode, params); + ci.updateAAD(AAD); + byte[] part41 = new byte[ci.getOutputSize(plainText.length)]; + int offset = plainText.length > ARRAY_OFFSET ? ARRAY_OFFSET : 0; + int len = ci.update(plainText, 0, plainText.length - offset, part41, 0); + int rest4 = ci.doFinal(plainText, plainText.length - offset, offset, + part41, len); + byte[] outputText4 = new byte[len + rest4]; + System.arraycopy(part41, 0, outputText4, 0, outputText4.length); + results.add(outputText4); + } + + /* + * Execute multiple-part encryption/decryption combination #5: + * updateAAD(byte[] src, int offset, int len) + * update(byte[], int, int) + * doFinal(byte[], int, int) + */ + private void combination_5(List results, int mode, byte[] AAD, + byte[] plainText, AlgorithmParameters params) throws Exception { + Cipher c = createCipher(mode, params); + c.updateAAD(AAD, 0, AAD.length); + byte[] part51 = c.update(plainText, 0, plainText.length); + byte[] part52 = c.doFinal(); + int part51Length = part51 != null ? part51.length : 0; + byte[] outputText5 = new byte[part51Length + part52.length]; + if (part51 != null) { + System.arraycopy(part51, 0, outputText5, 0, part51Length); + } + System.arraycopy(part52, 0, outputText5, part51Length, part52.length); + results.add(outputText5); + } + + /* + * Execute multiple-part encryption/decryption combination #6: + * updateAAD(byte[] src, int offset, int len) + * updateAAD(byte[] src, int offset, int len) + * update(byte[], int, int) doFinal(byte[], int, int, byte[], int) + */ + private void combination_6(List results, int mode, byte[] AAD, + byte[] plainText, AlgorithmParameters params) throws Exception { + Cipher c = createCipher(mode, params); + c.updateAAD(AAD, 0, AAD.length / 2); + c.updateAAD(AAD, AAD.length / 2, AAD.length - AAD.length / 2); + int t = 0; + int offset = 0; + if (plainText.length > ARRAY_OFFSET) { + t = plainText.length - ARRAY_OFFSET; + offset = ARRAY_OFFSET; + } + byte[] part61 = c.update(plainText, 0, t); + byte[] part62 = new byte[c.getOutputSize(plainText.length)]; + int len = c.doFinal(plainText, t, offset, part62, 0); + int part61Length = part61 != null ? part61.length : 0; + byte[] outputText6 = new byte[part61Length + len]; + if (part61 != null) { + System.arraycopy(part61, 0, outputText6, 0, part61Length); + } + System.arraycopy(part62, 0, outputText6, part61Length, len); + results.add(outputText6); + } + + /* + * Execute multiple-part encryption/decryption combination #7 + * updateAAD(byte[] src, int offset, int len) + * updateAAD(byte[] src, src.length, 0) + * update(byte[], int, int, byte[], int) doFinal(byte[],int, int) + */ + private void combination_7(List results, int mode, byte[] AAD, + byte[] plainText, AlgorithmParameters params) throws Exception { + Cipher ci = createCipher(mode, params); + ci.updateAAD(AAD, 0, AAD.length); + ci.updateAAD(AAD, AAD.length, 0); + byte[] part71 = new byte[ci.getOutputSize(plainText.length)]; + int offset = plainText.length > ARRAY_OFFSET ? ARRAY_OFFSET : 0; + int len = ci.update(plainText, 0, plainText.length - offset, part71, 0); + byte[] part72 = ci.doFinal(plainText, plainText.length - offset, offset); + byte[] outputText7 = new byte[len + part72.length]; + System.arraycopy(part71, 0, outputText7, 0, len); + System.arraycopy(part72, 0, outputText7, len, part72.length); + results.add(outputText7); + } + + /* + * Execute multiple-part encryption/decryption combination #8: + * updateAAD(byte[] src, 0, 0) + * updateAAD(byte[] src, 0, src.length) + * update(byte[], int, int, byte[], int) + * doFinal(byte[], int, int, byte[], int) + */ + private void combination_8(List results, int mode, byte[] AAD, + byte[] plainText, AlgorithmParameters params) throws Exception { + Cipher ci = createCipher(mode, params); + ci.updateAAD(AAD, 0, 0); + ci.updateAAD(AAD, 0, AAD.length); + byte[] part81 = new byte[ci.getOutputSize(plainText.length)]; + int offset = plainText.length > ARRAY_OFFSET ? ARRAY_OFFSET : 0; + int len = ci.update(plainText, 0, plainText.length - offset, part81, 0); + int rest = ci.doFinal(plainText, plainText.length - offset, offset, + part81, len); + byte[] outputText8 = new byte[len + rest]; + System.arraycopy(part81, 0, outputText8, 0, outputText8.length); + results.add(outputText8); + } + + /* + * Execute multiple-part encryption/decryption combination #9: + * updateAAD(ByteBuffer src) + * update(byte[], int, int) doFinal(byte[], int, int) + */ + private void combination_9(List results, int mode, byte[] AAD, + byte[] plainText, AlgorithmParameters params) throws Exception { + + // prepare ByteBuffer to test + ByteBuffer buf = ByteBuffer.allocate(AAD.length); + buf.put(AAD); + buf.position(0); + buf.limit(AAD.length); + + // Get Cipher object and do the combination + Cipher c = createCipher(mode, params); + c.updateAAD(buf); + byte[] part91 = c.update(plainText, 0, plainText.length); + int part91_length = part91 == null ? 0 : part91.length; + byte[] part92 = c.doFinal(); + byte[] outputText9 = new byte[part91_length + part92.length]; + + // form result of the combination + if (part91 != null) { + System.arraycopy(part91, 0, outputText9, 0, part91_length); + } + System.arraycopy(part92, 0, outputText9, part91_length, part92.length); + results.add(outputText9); + } + + /* + * Execute multiple-part encryption/decryption combination #10: + * updateAAD(ByteBuffer src) + * updateAAD(ByteBuffer src) update(byte[], int, int) + * doFinal(byte[], int, int, byte[], int) + */ + private void combination_10(List results, int mode, byte[] AAD, + byte[] plainText, AlgorithmParameters params) throws Exception { + + // prepare ByteBuffer to test + ByteBuffer buf = ByteBuffer.allocate(AAD.length); + buf.put(AAD); + buf.position(0); + buf.limit(AAD.length / 2); + + // get a Cipher object and do the combination + Cipher c = createCipher(mode, params); + + // process the first half of AAD data + c.updateAAD(buf); + + // process the rest of AAD data + buf.limit(AAD.length); + c.updateAAD(buf); + + // prapare variables for the combination + int t = 0; + int offset = 0; + if (plainText.length > ARRAY_OFFSET) { + t = plainText.length - ARRAY_OFFSET; + offset = ARRAY_OFFSET; + } + + // encrypt the text + byte[] part10_1 = c.update(plainText, 0, t); + int part10_1_Length = part10_1 != null ? part10_1.length : 0; + byte[] part10_2 = new byte[c.getOutputSize(plainText.length)]; + int len2 = c.doFinal(plainText, t, offset, part10_2, 0); + + // form the combination's result + byte[] outputText10 = new byte[part10_1_Length + len2]; + if (part10_1 != null) { + System.arraycopy(part10_1, 0, outputText10, 0, part10_1_Length); + } + System.arraycopy(part10_2, 0, outputText10, part10_1_Length, len2); + results.add(outputText10); + } + + /* + * Execute multiple-part encryption/decryption combination #11 + * updateAAD(ByteBuffer src1) + * updateAAD(ByteBuffer src2) + * update(byte[],int, int, byte[], int) + * doFinal(byte[], int, int) + */ + private void combination_11(List results, int mode, byte[] AAD, + byte[] plainText, AlgorithmParameters params) throws Exception { + + // prepare ByteBuffer1 to test + ByteBuffer buf1 = ByteBuffer.allocate(AAD.length / 2); + buf1.put(AAD, 0, AAD.length / 2); + buf1.position(0); + buf1.limit(AAD.length / 2); + + // get a Cipher object and do combination + Cipher ci = createCipher(mode, params); + + // process the first half of AAD data + ci.updateAAD(buf1); + + // prepare ByteBuffer2 to test + ByteBuffer buf2 = ByteBuffer.allocate(AAD.length - AAD.length / 2); + buf2.put(AAD, AAD.length / 2, AAD.length - AAD.length / 2); + buf2.position(0); + buf2.limit(AAD.length - AAD.length / 2); + + // process the rest of AAD data + ci.updateAAD(buf2); + + // encrypt plain text + byte[] part11_1 = new byte[ci.getOutputSize(plainText.length)]; + int offset = plainText.length > ARRAY_OFFSET ? ARRAY_OFFSET : 0; + int len_11 = ci.update(plainText, 0, plainText.length - offset, + part11_1, 0); + byte[] part11_2 = ci.doFinal(plainText, plainText.length - offset, + offset); + byte[] outputText11 = new byte[len_11 + part11_2.length]; + System.arraycopy(part11_1, 0, outputText11, 0, len_11); + System.arraycopy(part11_2, 0, outputText11, len_11, part11_2.length); + results.add(outputText11); + } + + /* + * Execute multiple-part encryption/decryption combination #12: + * updateAAD(ByteBuffer src) + * updateAAD(ByteBuffer emptyByteBuffer) + * update(byte[], int, int, byte[], int) + * doFinal(byte[], int, int, byte[], int) + */ + private void combination_12(List results, int mode, byte[] AAD, + byte[] plainText, AlgorithmParameters params) throws Exception { + + // prepare ByteBuffer to test + ByteBuffer buf = ByteBuffer.allocate(AAD.length); + buf.put(AAD); + buf.position(0); + buf.limit(AAD.length); + Cipher ci = createCipher(mode, params); + ci.updateAAD(buf); + + // prepare an empty ByteBuffer + ByteBuffer emptyBuf = ByteBuffer.allocate(0); + emptyBuf.put(new byte[0]); + ci.updateAAD(emptyBuf); + byte[] part12_1 = new byte[ci.getOutputSize(plainText.length)]; + int offset = plainText.length > ARRAY_OFFSET ? ARRAY_OFFSET : 0; + int len12 = ci.update(plainText, 0, plainText.length - offset, + part12_1, 0); + int rest12 = ci.doFinal(plainText, plainText.length - offset, offset, + part12_1, len12); + byte[] outputText12 = new byte[len12 + rest12]; + System.arraycopy(part12_1, 0, outputText12, 0, outputText12.length); + results.add(outputText12); + } + + /* + * Execute multiple-part encryption/decryption combination #13: + * updateAAD(ByteBuffer src), where src is directly allocated + * update(ByteBuffer input, ByteBuffer out) + * doFinal(ByteBuffer input, ByteBuffer out) + */ + private void combination_13(List results, int mode, byte[] AAD, + byte[] plainText, AlgorithmParameters params) throws Exception { + Cipher c = createCipher(mode, params); + + // prepare ByteBuffer to test + ByteBuffer buf = ByteBuffer.allocateDirect(AAD.length); + buf.put(AAD); + buf.position(0); + buf.limit(AAD.length); + c.updateAAD(buf); + + // prepare buffers to encrypt/decrypt + ByteBuffer in = ByteBuffer.allocateDirect(plainText.length); + in.put(plainText); + in.position(0); + in.limit(plainText.length); + ByteBuffer output = ByteBuffer.allocateDirect( + c.getOutputSize(in.limit())); + output.position(0); + output.limit(c.getOutputSize(in.limit())); + + // process input text + c.update(in, output); + c.doFinal(in, output); + int resultSize = output.position(); + byte[] result13 = new byte[resultSize]; + output.position(0); + output.limit(resultSize); + output.get(result13, 0, resultSize); + results.add(result13); + } + + /* + * Execute multiple-part encryption/decryption combination #14: + * updateAAD(ByteBuffer src) updateAAD(ByteBuffer src), + * where src is directly allocated + * update(ByteBuffer input, ByteBuffer out) + * doFinal(ByteBuffer input, ByteBuffer out) + */ + private void combination_14(List results, int mode, byte[] AAD, + byte[] plainText, AlgorithmParameters params) throws Exception { + Cipher c = createCipher(mode, params); + // prepare ByteBuffer to test + ByteBuffer buf = ByteBuffer.allocateDirect(AAD.length); + buf.put(AAD); + + // process the first half of AAD data + buf.position(0); + buf.limit(AAD.length / 2); + c.updateAAD(buf); + + // process the rest of AAD data + buf.limit(AAD.length); + c.updateAAD(buf); + + // prepare buffers to encrypt/decrypt + ByteBuffer in = ByteBuffer.allocate(plainText.length); + in.put(plainText); + in.position(0); + in.limit(plainText.length); + ByteBuffer out = ByteBuffer.allocate(c.getOutputSize(in.limit())); + out.position(0); + out.limit(c.getOutputSize(in.limit())); + + // process input text + c.update(in, out); + c.doFinal(in, out); + int resultSize = out.position(); + byte[] result14 = new byte[resultSize]; + out.position(0); + out.limit(resultSize); + out.get(result14, 0, resultSize); + results.add(result14); + } + + /* + * Execute multiple-part encryption/decryption combination #15 + * updateAAD(ByteBuffer src1), where src1 is directly allocated + * updateAAD(ByteBuffer src2), where src2 is directly allocated + * doFinal(ByteBuffer input, ByteBuffer out) + */ + private void combination_15(List results, int mode, byte[] AAD, + byte[] plainText, AlgorithmParameters params) throws Exception { + Cipher c = createCipher(mode, params); + + // prepare ByteBuffer1 to test + ByteBuffer buf1 = ByteBuffer.allocateDirect(AAD.length / 2); + buf1.put(AAD, 0, AAD.length / 2); + buf1.position(0); + buf1.limit(AAD.length / 2); + + // process the first half of AAD data + c.updateAAD(buf1); + + // prepare ByteBuffer2 to test + ByteBuffer buf2 = ByteBuffer.allocateDirect( + AAD.length - AAD.length / 2); + buf2.put(AAD, AAD.length / 2, AAD.length - AAD.length / 2); + buf2.position(0); + buf2.limit(AAD.length - AAD.length / 2); + + // process the rest of AAD data + c.updateAAD(buf2); + + // prepare buffers to encrypt/decrypt + ByteBuffer in = ByteBuffer.allocateDirect(plainText.length); + in.put(plainText); + in.position(0); + in.limit(plainText.length); + ByteBuffer output = ByteBuffer.allocateDirect( + c.getOutputSize(in.limit())); + output.position(0); + output.limit(c.getOutputSize(in.limit())); + + // process input text + c.doFinal(in, output); + int resultSize = output.position(); + byte[] result15 = new byte[resultSize]; + output.position(0); + output.limit(resultSize); + output.get(result15, 0, resultSize); + results.add(result15); + } + + /* + * Execute multiple-part encryption/decryption combination #16: + * updateAAD(ByteBuffer src) + * updateAAD(ByteBuffer emptyByteBuffer) + * update(ByteBuffer input, ByteBuffer out) + * doFinal(EmptyByteBuffer, ByteBuffer out) + */ + private void combination_16(List results, int mode, byte[] AAD, + byte[] plainText, AlgorithmParameters params) throws Exception { + Cipher c = createCipher(mode, params); + + // prepare ByteBuffer to test + ByteBuffer buf = ByteBuffer.allocateDirect(AAD.length); + buf.put(AAD); + buf.position(0); + buf.limit(AAD.length); + c.updateAAD(buf); + + // prepare empty ByteBuffer + ByteBuffer emptyBuf = ByteBuffer.allocateDirect(0); + emptyBuf.put(new byte[0]); + c.updateAAD(emptyBuf); + + // prepare buffers to encrypt/decrypt + ByteBuffer in = ByteBuffer.allocateDirect(plainText.length); + in.put(plainText); + in.position(0); + in.limit(plainText.length); + ByteBuffer output = ByteBuffer.allocateDirect( + c.getOutputSize(in.limit())); + output.position(0); + output.limit(c.getOutputSize(in.limit())); + + // process input text with an empty buffer + c.update(in, output); + ByteBuffer emptyBuf2 = ByteBuffer.allocate(0); + emptyBuf2.put(new byte[0]); + c.doFinal(emptyBuf2, output); + int resultSize = output.position(); + byte[] result16 = new byte[resultSize]; + output.position(0); + output.limit(resultSize); + output.get(result16, 0, resultSize); + results.add(result16); + } +} diff --git a/test/com/sun/crypto/provider/Cipher/AEAD/GCMParameterSpecTest.java b/test/com/sun/crypto/provider/Cipher/AEAD/GCMParameterSpecTest.java new file mode 100644 index 0000000000000000000000000000000000000000..7250c4d7f0f36a341c5c206df7dea833debcf636 --- /dev/null +++ b/test/com/sun/crypto/provider/Cipher/AEAD/GCMParameterSpecTest.java @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2007, 2015, 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. + * + * 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. + */ + +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.util.Arrays; +import javax.crypto.SecretKey; +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import javax.crypto.spec.GCMParameterSpec; + +/* + * @test + * @bug 8048596 + * @summary Check if GCMParameterSpec works as expected + */ +public class GCMParameterSpecTest { + + private static final int[] IV_LENGTHS = { 96, 8, 1024 }; + private static final int[] KEY_LENGTHS = { 128, 192, 256 }; + private static final int[] DATA_LENGTHS = { 0, 128, 1024 }; + private static final int[] AAD_LENGTHS = { 0, 128, 1024 }; + private static final int[] TAG_LENGTHS = { 128, 120, 112, 104, 96 }; + private static final int[] OFFSETS = { 0, 2, 5, 99 }; + private static final String TRANSFORMATION = "AES/GCM/NoPadding"; + private static final String TEMPLATE = "Test:\n tag = %d\n" + + " IV length = %d\n data length = %d\n" + + " AAD length = %d\n offset = %d\n keylength = %d\n"; + + private final byte[] IV; + private final byte[] IVO; + private final byte[] data; + private final byte[] AAD; + private final SecretKey key; + private final int tagLength; + private final int IVlength; + private final int offset; + + /** + * Initialize IV, IV with offset, plain text, AAD and SecretKey + * + * @param keyLength length of a secret key + * @param tagLength tag length + * @param IVlength IV length + * @param offset offset in a buffer for IV + * @param textLength plain text length + * @param AADLength AAD length + */ + public GCMParameterSpecTest(int keyLength, int tagLength, int IVlength, + int offset, int textLength, int AADLength) + throws NoSuchAlgorithmException, NoSuchProviderException { + this.tagLength = tagLength; // save tag length + this.IVlength = IVlength; // save IV length + this.offset = offset; // save IV offset + + // prepare IV + IV = Helper.generateBytes(IVlength); + + // prepare IV with offset + IVO = new byte[this.IVlength + this.offset]; + System.arraycopy(IV, 0, IVO, offset, this.IVlength); + + // prepare data + data = Helper.generateBytes(textLength); + + // prepare AAD + AAD = Helper.generateBytes(AADLength); + + // init a secret key + KeyGenerator kg = KeyGenerator.getInstance("AES", "SunJCE"); + kg.init(keyLength); + key = kg.generateKey(); + } + + /* + * Run the test for each key length, tag length, IV length, plain text + * length, AAD length and offset. + */ + public static void main(String[] args) throws Exception { + boolean success = true; + for (int k : KEY_LENGTHS) { + if (k > Cipher.getMaxAllowedKeyLength(TRANSFORMATION)) { + // skip this if this key length is larger than what's + // allowed in the jce jurisdiction policy files + continue; + } + for (int t : TAG_LENGTHS) { + for (int n : IV_LENGTHS) { + for (int p : DATA_LENGTHS) { + for (int a : AAD_LENGTHS) { + for (int o : OFFSETS) { + System.out.printf(TEMPLATE, t, n, p, a, o, k); + success &= new GCMParameterSpecTest( + k, t, n, o, p, a).doTest(); + } + } + } + } + } + } + + if (!success) { + throw new RuntimeException("At least one test case failed"); + } + } + + /* + * Run the test: + * - check if result of encryption of plain text is the same + * when parameters constructed with different GCMParameterSpec + * constructors are used + * - check if GCMParameterSpec.getTLen() is equal to actual tag length + * - check if ciphertext has the same length as plaintext + */ + private boolean doTest() throws Exception { + GCMParameterSpec spec1 = new GCMParameterSpec(tagLength, IV); + GCMParameterSpec spec2 = new GCMParameterSpec(tagLength, IVO, offset, + IVlength); + byte[] cipherText1 = getCipherTextBySpec(spec1); + if (cipherText1 == null) { + return false; + } + byte[] cipherText2 = getCipherTextBySpec(spec2); + if (cipherText2 == null) { + return false; + } + if (!Arrays.equals(cipherText1, cipherText2)) { + System.out.println("Cipher texts are different"); + return false; + } + if (spec1.getTLen() != spec2.getTLen()) { + System.out.println("Tag lengths are not equal"); + return false; + } + byte[] recoveredText1 = recoverCipherText(cipherText1, spec2); + if (recoveredText1 == null) { + return false; + } + byte[] recoveredText2 = recoverCipherText(cipherText2, spec1); + if (recoveredText2 == null) { + return false; + } + if (!Arrays.equals(recoveredText1, recoveredText2)) { + System.out.println("Recovered texts are different"); + return false; + } + if (!Arrays.equals(recoveredText1, data)) { + System.out.println("Recovered and original texts are not equal"); + return false; + } + + return true; + } + + /* + * Encrypt a plain text, and check if GCMParameterSpec.getIV() + * is equal to Cipher.getIV() + */ + private byte[] getCipherTextBySpec(GCMParameterSpec spec) throws Exception { + // init a cipher + Cipher cipher = createCipher(Cipher.ENCRYPT_MODE, spec); + cipher.updateAAD(AAD); + byte[] cipherText = cipher.doFinal(data); + + // check IVs + if (!Arrays.equals(cipher.getIV(), spec.getIV())) { + System.out.println("IV in parameters is incorrect"); + return null; + } + if (spec.getTLen() != (cipherText.length - data.length) * 8) { + System.out.println("Tag length is incorrect"); + return null; + } + return cipherText; + } + + private byte[] recoverCipherText(byte[] cipherText, GCMParameterSpec spec) + throws Exception { + // init a cipher + Cipher cipher = createCipher(Cipher.DECRYPT_MODE, spec); + + // check IVs + if (!Arrays.equals(cipher.getIV(), spec.getIV())) { + System.out.println("IV in parameters is incorrect"); + return null; + } + + cipher.updateAAD(AAD); + return cipher.doFinal(cipherText); + } + + private Cipher createCipher(int mode, GCMParameterSpec spec) + throws Exception { + Cipher cipher = Cipher.getInstance(TRANSFORMATION, "SunJCE"); + cipher.init(mode, key, spec); + return cipher; + } +} diff --git a/test/com/sun/crypto/provider/Cipher/AEAD/Helper.java b/test/com/sun/crypto/provider/Cipher/AEAD/Helper.java new file mode 100644 index 0000000000000000000000000000000000000000..dad216b9f7cf1490b3497698029638725b540b37 --- /dev/null +++ b/test/com/sun/crypto/provider/Cipher/AEAD/Helper.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +public class Helper { + + public static byte[] generateBytes(int length) { + byte[] bytes = new byte[length]; + for (int i = 0; i < length; i++) { + bytes[i] = (byte) (i % 256); + } + return bytes; + } +} diff --git a/test/com/sun/crypto/provider/Cipher/AEAD/KeyWrapper.java b/test/com/sun/crypto/provider/Cipher/AEAD/KeyWrapper.java new file mode 100644 index 0000000000000000000000000000000000000000..21f1deec45b65ea5a3ed16d3440c8aed1b84f1ed --- /dev/null +++ b/test/com/sun/crypto/provider/Cipher/AEAD/KeyWrapper.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2007, 2015, 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. + * + * 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. + */ + +import java.security.AlgorithmParameters; +import java.security.Key; +import java.util.Arrays; +import javax.crypto.SecretKey; +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; + +/* + * @test + * @bug 8048596 + * @summary Check if a key wrapper works properly with GCM mode + */ +public class KeyWrapper { + + static final String AES = "AES"; + static final String TRANSFORMATION = "AES/GCM/NoPadding"; + static final String PROVIDER = "SunJCE"; + static final int KEY_LENGTH = 128; + + public static void main(String argv[]) throws Exception { + doTest(PROVIDER, TRANSFORMATION); + } + + private static void doTest(String provider, String algo) throws Exception { + SecretKey key; + SecretKey keyToWrap; + + // init a secret Key + KeyGenerator kg = KeyGenerator.getInstance(AES, PROVIDER); + kg.init(KEY_LENGTH); + key = kg.generateKey(); + keyToWrap = kg.generateKey(); + + // initialization + Cipher cipher = Cipher.getInstance(algo, provider); + cipher.init(Cipher.WRAP_MODE, key); + AlgorithmParameters params = cipher.getParameters(); + + // wrap the key + byte[] keyWrapper = cipher.wrap(keyToWrap); + try { + // check if we can't wrap it again with the same key/IV + keyWrapper = cipher.wrap(keyToWrap); + throw new RuntimeException( + "FAILED: expected IllegalStateException hasn't " + + "been thrown "); + } catch (IllegalStateException ise) { + System.out.println(ise.getMessage()); + System.out.println("Expected exception"); + } + + // unwrap the key + cipher.init(Cipher.UNWRAP_MODE, key, params); + cipher.unwrap(keyWrapper, algo, Cipher.SECRET_KEY); + + // check if we can unwrap second time + Key unwrapKey = cipher.unwrap(keyWrapper, algo, Cipher.SECRET_KEY); + + if (!Arrays.equals(keyToWrap.getEncoded(), unwrapKey.getEncoded())) { + throw new RuntimeException( + "FAILED: original and unwrapped keys are not equal"); + } + } +} diff --git a/test/com/sun/crypto/provider/Cipher/AEAD/ReadWriteSkip.java b/test/com/sun/crypto/provider/Cipher/AEAD/ReadWriteSkip.java new file mode 100644 index 0000000000000000000000000000000000000000..f6bd3805ae4c6564b38ca5b5e851d68be0007315 --- /dev/null +++ b/test/com/sun/crypto/provider/Cipher/AEAD/ReadWriteSkip.java @@ -0,0 +1,317 @@ +/* + * Copyright (c) 2007, 2015, 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. + * + * 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. + */ + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; +import javax.crypto.Cipher; +import javax.crypto.CipherInputStream; +import javax.crypto.CipherOutputStream; +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; + +/* + * @test + * @bug 8048596 + * @summary Test CICO AEAD read/write/skip operations + */ +public class ReadWriteSkip { + + static enum BufferType { + BYTE_ARRAY_BUFFERING, INT_BYTE_BUFFERING + } + + static final int KEY_LENGTHS[] = {128, 192, 256}; + static final int TXT_LENGTHS[] = {800, 0}; + static final int AAD_LENGTHS[] = {0, 100}; + static final int BLOCK = 50; + static final int SAVE = 45; + static final int DISCARD = BLOCK - SAVE; + static final String PROVIDER = "SunJCE"; + static final String AES = "AES"; + static final String GCM = "GCM"; + static final String PADDING = "NoPadding"; + static final String TRANSFORM = AES + "/" + GCM + "/" + PADDING; + + final SecretKey key; + final byte[] plaintext; + final byte[] AAD; + final int textLength;; + final int keyLength; + Cipher encryptCipher; + Cipher decryptCipher; + CipherInputStream ciInput; + + public static void main(String[] args) throws Exception { + boolean success = true; + for (int keyLength : KEY_LENGTHS) { + if (keyLength > Cipher.getMaxAllowedKeyLength(TRANSFORM)) { + // skip this if this key length is larger than what's + // configured in the jce jurisdiction policy files + continue; + } + for (int textLength : TXT_LENGTHS) { + for (int AADLength : AAD_LENGTHS) { + System.out.println("Key length = " + keyLength + + ", text length = " + textLength + + ", AAD length = " + AADLength); + try { + run(keyLength, textLength, AADLength); + System.out.println("Test case passed"); + } catch (Exception e) { + System.out.println("Test case failed: " + e); + success = false; + } + } + } + } + + if (!success) { + throw new RuntimeException("At least one test case failed"); + } + + System.out.println("Test passed"); + } + + ReadWriteSkip(int keyLength, int textLength, int AADLength) + throws Exception { + this.keyLength = keyLength; + this.textLength = textLength; + + // init AAD + this.AAD = Helper.generateBytes(AADLength); + + // init a secret Key + KeyGenerator kg = KeyGenerator.getInstance(AES, PROVIDER); + kg.init(this.keyLength); + this.key = kg.generateKey(); + + this.plaintext = Helper.generateBytes(textLength); + } + + final void doTest(BufferType type) throws Exception { + // init ciphers + encryptCipher = createCipher(Cipher.ENCRYPT_MODE); + decryptCipher = createCipher(Cipher.DECRYPT_MODE); + + // init cipher input stream + ciInput = new CipherInputStream(new ByteArrayInputStream(plaintext), + encryptCipher); + + runTest(type); + } + + void runTest(BufferType type) throws Exception {} + + private Cipher createCipher(int mode) throws GeneralSecurityException { + Cipher cipher = Cipher.getInstance(TRANSFORM, PROVIDER); + if (mode == Cipher.ENCRYPT_MODE) { + cipher.init(Cipher.ENCRYPT_MODE, key); + } else { + if (encryptCipher != null) { + cipher.init(Cipher.DECRYPT_MODE, key, + encryptCipher.getParameters()); + } else { + throw new RuntimeException("Can't create a cipher"); + } + } + cipher.updateAAD(AAD); + return cipher; + } + + /* + * Run test cases + */ + static void run(int keyLength, int textLength, int AADLength) + throws Exception { + new ReadWriteTest(keyLength, textLength, AADLength) + .doTest(BufferType.BYTE_ARRAY_BUFFERING); + new ReadWriteTest(keyLength, textLength, AADLength) + .doTest(BufferType.INT_BYTE_BUFFERING); + new SkipTest(keyLength, textLength, AADLength) + .doTest(BufferType.BYTE_ARRAY_BUFFERING); + new SkipTest(keyLength, textLength, AADLength) + .doTest(BufferType.INT_BYTE_BUFFERING); + } + + static void check(byte[] first, byte[] second) { + if (!Arrays.equals(first, second)) { + throw new RuntimeException("Arrays are not equal"); + } + } + + /* + * CICO AEAD read/write functional test. + * + * Check if encrypt/decrypt operations work correctly. + * + * Test scenario: + * - initializes plain text + * - for given AEAD algorithm instantiates encrypt and decrypt Ciphers + * - instantiates CipherInputStream with the encrypt Cipher + * - instantiates CipherOutputStream with the decrypt Cipher + * - performs reading from the CipherInputStream (encryption data) + * and writing to the CipherOutputStream (decryption). As a result, + * output of the CipherOutputStream should be equal + * with original plain text + * - check if the original plain text is equal to output + * of the CipherOutputStream + * - if it is equal the test passes, otherwise it fails + */ + static class ReadWriteTest extends ReadWriteSkip { + + public ReadWriteTest(int keyLength, int textLength, int AADLength) + throws Exception { + super(keyLength, textLength, AADLength); + } + + @Override + public void runTest(BufferType bufType) throws IOException, + GeneralSecurityException { + + ByteArrayOutputStream baOutput = new ByteArrayOutputStream(); + try (CipherOutputStream ciOutput = new CipherOutputStream(baOutput, + decryptCipher)) { + if (bufType == BufferType.BYTE_ARRAY_BUFFERING) { + doByteTest(ciOutput); + } else { + doIntTest(ciOutput); + } + } + + check(plaintext, baOutput.toByteArray()); + } + + /* + * Implements byte array buffering type test case + */ + public void doByteTest(CipherOutputStream out) throws IOException { + byte[] buffer = Helper.generateBytes(textLength + 1); + int len = ciInput.read(buffer); + while (len != -1) { + out.write(buffer, 0, len); + len = ciInput.read(buffer); + } + } + + /* + * Implements integer buffering type test case + */ + public void doIntTest(CipherOutputStream out) throws IOException { + int buffer = ciInput.read(); + while (buffer != -1) { + out.write(buffer); + buffer = ciInput.read(); + } + } + } + + /* + * CICO AEAD SKIP functional test. + * + * Checks if the encrypt/decrypt operations work correctly + * when skip() method is used. + * + * Test scenario: + * - initializes a plain text + * - initializes ciphers + * - initializes cipher streams + * - split plain text to TEXT_SIZE/BLOCK blocks + * - read from CipherInputStream2 one block at time + * - the last DISCARD = BLOCK - SAVE bytes are skipping for each block + * - therefore, plain text data go through CipherInputStream1 (encrypting) + * and CipherInputStream2 (decrypting) + * - as a result, output should equal to the original text + * except DISCART byte for each block + * - check result buffers + */ + static class SkipTest extends ReadWriteSkip { + + private final int numberOfBlocks; + private final byte[] outputText; + + public SkipTest(int keyLength, int textLength, int AADLength) + throws Exception { + super(keyLength, textLength, AADLength); + numberOfBlocks = this.textLength / BLOCK; + outputText = new byte[numberOfBlocks * SAVE]; + } + + private void doByteTest(int blockNum, CipherInputStream cis) + throws IOException { + int index = blockNum * SAVE; + int len = cis.read(outputText, index, SAVE); + index += len; + int read = 0; + while (len != SAVE && read != -1) { + read = cis.read(outputText, index, SAVE - len); + len += read; + index += read; + } + } + + private void doIntTest(int blockNum, CipherInputStream cis) + throws IOException { + int i = blockNum * SAVE; + for (int j = 0; j < SAVE && i < outputText.length; j++, i++) { + int b = cis.read(); + if (b != -1) { + outputText[i] = (byte) b; + } + } + } + + @Override + public void runTest(BufferType type) throws IOException, + NoSuchAlgorithmException { + try (CipherInputStream cis = new CipherInputStream(ciInput, + decryptCipher)) { + for (int i = 0; i < numberOfBlocks; i++) { + if (type == BufferType.BYTE_ARRAY_BUFFERING) { + doByteTest(i, cis); + } else { + doIntTest(i, cis); + } + if (cis.available() >= DISCARD) { + cis.skip(DISCARD); + } else { + for (int k = 0; k < DISCARD; k++) { + cis.read(); + } + } + } + } + + byte[] expectedText = new byte[numberOfBlocks * SAVE]; + for (int m = 0; m < numberOfBlocks; m++) { + for (int n = 0; n < SAVE; n++) { + expectedText[m * SAVE + n] = plaintext[m * BLOCK + n]; + } + } + check(expectedText, outputText); + } + } +} diff --git a/test/com/sun/crypto/provider/Cipher/AEAD/SameBuffer.java b/test/com/sun/crypto/provider/Cipher/AEAD/SameBuffer.java new file mode 100644 index 0000000000000000000000000000000000000000..30afb8ee8ea677fa4d7d984bb6631956d25ebd46 --- /dev/null +++ b/test/com/sun/crypto/provider/Cipher/AEAD/SameBuffer.java @@ -0,0 +1,423 @@ +/* + * Copyright (c) 2007, 2015, 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. + * + * 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. + */ + +import java.nio.ByteBuffer; +import java.security.AlgorithmParameters; +import java.security.Provider; +import java.security.Security; +import javax.crypto.SecretKey; +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import javax.crypto.spec.GCMParameterSpec; + +/* + * @test + * @bug 8048596 + * @summary Check if AEAD operations work correctly when buffers used + * for storing plain text and cipher text are overlapped or the same + */ +public class SameBuffer { + + private static final String PROVIDER = "SunJCE"; + private static final String AES = "AES"; + private static final String GCM = "GCM"; + private static final String PADDING = "NoPadding"; + private static final int OFFSET = 2; + private static final int OFFSETS = 4; + private static final int KEY_LENGTHS[] = { 128, 192, 256 }; + private static final int TEXT_LENGTHS[] = { 0, 1024 }; + private static final int AAD_LENGTHS[] = { 0, 1024 }; + + private final Provider provider; + private final SecretKey key; + private final String transformation; + private final int textLength; + private final int AADLength; + + /** + * Constructor of the test + * + * @param provider security provider + * @param keyStrength key length + * @param textLength length of data + * @param AADLength AAD length + */ + public SameBuffer(Provider provider, String algorithm, String mode, + String padding, int keyStrength, int textLength, int AADLength) + throws Exception { + + // init a secret key + KeyGenerator kg = KeyGenerator.getInstance(algorithm, provider); + kg.init(keyStrength); + key = kg.generateKey(); + + this.transformation = algorithm + "/" + mode + "/" + padding; + this.provider = provider; + this.textLength = textLength; + this.AADLength = AADLength; + } + + public static void main(String[] args) throws Exception { + Provider p = Security.getProvider(PROVIDER); + for (int keyLength : KEY_LENGTHS) { + for (int textLength : TEXT_LENGTHS) { + for (int AADLength : AAD_LENGTHS) { + for (int i = 0; i < OFFSETS; i++) { + // try different offsets + int offset = i * OFFSET; + runTest(p, AES, GCM, PADDING, keyLength, textLength, + AADLength, offset); + } + } + } + } + } + + /* + * Run single test case with given parameters + */ + static void runTest(Provider p, String algo, String mode, + String padding, int keyLength, int textLength, int AADLength, + int offset) throws Exception { + System.out.println("Testing " + keyLength + " key length; " + + textLength + " text lenght; " + AADLength + " AAD length; " + + offset + " offset"); + if (keyLength > Cipher.getMaxAllowedKeyLength(algo)) { + // skip this if this key length is larger than what's + // configured in the jce jurisdiction policy files + return; + } + SameBuffer test = new SameBuffer(p, algo, mode, + padding, keyLength, textLength, AADLength); + + /* + * There are four test cases: + * 1. AAD and text are placed in separated byte arrays + * 2. AAD and text are placed in the same byte array + * 3. AAD and text are placed in separated byte buffers + * 4. AAD and text are placed in the same byte buffer + */ + Cipher ci = test.createCipher(Cipher.ENCRYPT_MODE, null); + AlgorithmParameters params = ci.getParameters(); + test.doTestWithSeparateArrays(offset, params); + test.doTestWithSameArrays(offset, params); + test.doTestWithSeparatedBuffer(offset, params); + test.doTestWithSameBuffer(offset, params); + } + + /* + * Run the test in case when AAD and text are placed in separated byte + * arrays. + */ + private void doTestWithSeparateArrays(int offset, + AlgorithmParameters params) throws Exception { + // prepare buffers to test + Cipher c = createCipher(Cipher.ENCRYPT_MODE, params); + int outputLength = c.getOutputSize(textLength); + int outputBufSize = outputLength + offset * 2; + + byte[] inputText = Helper.generateBytes(outputBufSize); + byte[] AAD = Helper.generateBytes(AADLength); + + // do the test + runGCMWithSeparateArray(Cipher.ENCRYPT_MODE, AAD, inputText, offset * 2, + textLength, offset, params); + int tagLength = c.getParameters() + .getParameterSpec(GCMParameterSpec.class).getTLen() / 8; + runGCMWithSeparateArray(Cipher.DECRYPT_MODE, AAD, inputText, offset, + textLength + tagLength, offset, params); + } + + /** + * Run the test in case when AAD and text are placed in the same byte + * array. + */ + private void doTestWithSameArrays(int offset, AlgorithmParameters params) + throws Exception { + // prepare buffers to test + Cipher c = createCipher(Cipher.ENCRYPT_MODE, params); + int outputLength = c.getOutputSize(textLength); + int outputBufSize = AADLength + outputLength + offset * 2; + + byte[] AAD_and_text = Helper.generateBytes(outputBufSize); + + // do the test + runGCMWithSameArray(Cipher.ENCRYPT_MODE, AAD_and_text, AADLength + offset, + textLength, params); + int tagLength = c.getParameters() + .getParameterSpec(GCMParameterSpec.class).getTLen() / 8; + runGCMWithSameArray(Cipher.DECRYPT_MODE, AAD_and_text, AADLength + offset, + textLength + tagLength, params); + } + + /* + * Run the test in case when AAD and text are placed in separated ByteBuffer + */ + private void doTestWithSeparatedBuffer(int offset, + AlgorithmParameters params) throws Exception { + // prepare AAD byte buffers to test + byte[] AAD = Helper.generateBytes(AADLength); + ByteBuffer AAD_Buf = ByteBuffer.allocate(AADLength); + AAD_Buf.put(AAD, 0, AAD.length); + AAD_Buf.flip(); + + // prepare text byte buffer to encrypt/decrypt + Cipher c = createCipher(Cipher.ENCRYPT_MODE, params); + int outputLength = c.getOutputSize(textLength); + int outputBufSize = outputLength + offset; + byte[] inputText = Helper.generateBytes(outputBufSize); + ByteBuffer plainTextBB = ByteBuffer.allocateDirect(inputText.length); + plainTextBB.put(inputText); + plainTextBB.position(offset); + plainTextBB.limit(offset + textLength); + + // do test + runGCMWithSeparateBuffers(Cipher.ENCRYPT_MODE, AAD_Buf, plainTextBB, offset, + textLength, params); + int tagLength = c.getParameters() + .getParameterSpec(GCMParameterSpec.class).getTLen() / 8; + plainTextBB.position(offset); + plainTextBB.limit(offset + textLength + tagLength); + runGCMWithSeparateBuffers(Cipher.DECRYPT_MODE, AAD_Buf, plainTextBB, offset, + textLength + tagLength, params); + } + + /* + * Run the test in case when AAD and text are placed in the same ByteBuffer + */ + private void doTestWithSameBuffer(int offset, AlgorithmParameters params) + throws Exception { + // calculate output length + Cipher c = createCipher(Cipher.ENCRYPT_MODE, params); + int outputLength = c.getOutputSize(textLength); + + // prepare byte buffer contained AAD and plain text + int bufSize = AADLength + offset + outputLength; + byte[] AAD_and_Text = Helper.generateBytes(bufSize); + ByteBuffer AAD_and_Text_Buf = ByteBuffer.allocate(bufSize); + AAD_and_Text_Buf.put(AAD_and_Text, 0, AAD_and_Text.length); + + // do test + runGCMWithSameBuffer(Cipher.ENCRYPT_MODE, AAD_and_Text_Buf, offset, + textLength, params); + int tagLength = c.getParameters() + .getParameterSpec(GCMParameterSpec.class).getTLen() / 8; + AAD_and_Text_Buf.limit(AADLength + offset + textLength + tagLength); + runGCMWithSameBuffer(Cipher.DECRYPT_MODE, AAD_and_Text_Buf, offset, + textLength + tagLength, params); + + } + + /* + * Execute GCM encryption/decryption of a text placed in a byte array. + * AAD is placed in the separated byte array. + * Data are processed twice: + * - in a separately allocated buffer + * - in the text buffer + * Check if two results are equal + */ + private void runGCMWithSeparateArray(int mode, byte[] AAD, byte[] text, + int txtOffset, int lenght, int offset, AlgorithmParameters params) + throws Exception { + // first, generate the cipher text at an allocated buffer + Cipher cipher = createCipher(mode, params); + cipher.updateAAD(AAD); + byte[] outputText = cipher.doFinal(text, txtOffset, lenght); + + // new cipher for encrypt operation + Cipher anotherCipher = createCipher(mode, params); + anotherCipher.updateAAD(AAD); + + // next, generate cipher text again at the same buffer of plain text + int myoff = offset; + int off = anotherCipher.update(text, txtOffset, lenght, text, myoff); + anotherCipher.doFinal(text, myoff + off); + + // check if two resutls are equal + if (!isEqual(text, myoff, outputText, 0, outputText.length)) { + throw new RuntimeException("Two results not equal, mode:" + mode); + } + } + + /* + * Execute GCM encrption/decryption of a text. The AAD and text to process + * are placed in the same byte array. Data are processed twice: + * - in a separetly allocated buffer + * - in a buffer that shares content of the AAD_and_Text_BA + * Check if two results are equal + */ + private void runGCMWithSameArray(int mode, byte[] array, int txtOffset, + int length, AlgorithmParameters params) throws Exception { + // first, generate cipher text at an allocated buffer + Cipher cipher = createCipher(mode, params); + cipher.updateAAD(array, 0, AADLength); + byte[] outputText = cipher.doFinal(array, txtOffset, length); + + // new cipher for encrypt operation + Cipher anotherCipher = createCipher(mode, params); + anotherCipher.updateAAD(array, 0, AADLength); + + // next, generate cipher text again at the same buffer of plain text + int off = anotherCipher.update(array, txtOffset, length, + array, txtOffset); + anotherCipher.doFinal(array, txtOffset + off); + + // check if two results are equal or not + if (!isEqual(array, txtOffset, outputText, 0, + outputText.length)) { + throw new RuntimeException( + "Two results are not equal, mode:" + mode); + } + } + + /* + * Execute GCM encryption/decryption of textBB. AAD and text to process are + * placed in different byte buffers. Data are processed twice: + * - in a separately allocated buffer + * - in a buffer that shares content of the textBB + * Check if results are equal + */ + private void runGCMWithSeparateBuffers(int mode, ByteBuffer buffer, + ByteBuffer textBB, int txtOffset, int dataLength, + AlgorithmParameters params) throws Exception { + // take offset into account + textBB.position(txtOffset); + textBB.mark(); + + // first, generate the cipher text at an allocated buffer + Cipher cipher = createCipher(mode, params); + cipher.updateAAD(buffer); + buffer.flip(); + ByteBuffer outBB = ByteBuffer.allocateDirect( + cipher.getOutputSize(dataLength)); + + cipher.doFinal(textBB, outBB);// get cipher text in outBB + outBB.flip(); + + // restore positions + textBB.reset(); + + // next, generate cipher text again in a buffer that shares content + Cipher anotherCipher = createCipher(mode, params); + anotherCipher.updateAAD(buffer); + buffer.flip(); + ByteBuffer buf2 = textBB.duplicate(); // buf2 shares textBuf context + buf2.limit(txtOffset + anotherCipher.getOutputSize(dataLength)); + int dataProcessed2 = anotherCipher.doFinal(textBB, buf2); + buf2.position(txtOffset); + buf2.limit(txtOffset + dataProcessed2); + + if (!buf2.equals(outBB)) { + throw new RuntimeException( + "Two results are not equal, mode:" + mode); + } + } + + /* + * Execute GCM encryption/decryption of text. AAD and a text to process are + * placed in the same buffer. Data is processed twice: + * - in a separately allocated buffer + * - in a buffer that shares content of the AAD_and_Text_BB + */ + private void runGCMWithSameBuffer(int mode, ByteBuffer buffer, + int txtOffset, int length, AlgorithmParameters params) + throws Exception { + + // allocate a separate buffer + Cipher cipher = createCipher(mode, params); + ByteBuffer outBB = ByteBuffer.allocateDirect( + cipher.getOutputSize(length)); + + // first, generate the cipher text at an allocated buffer + buffer.flip(); + buffer.limit(AADLength); + cipher.updateAAD(buffer); + buffer.limit(AADLength + txtOffset + length); + buffer.position(AADLength + txtOffset); + cipher.doFinal(buffer, outBB); + outBB.flip(); // cipher text in outBB + + // next, generate cipherText again in the same buffer + Cipher anotherCipher = createCipher(mode, params); + buffer.flip(); + buffer.limit(AADLength); + anotherCipher.updateAAD(buffer); + buffer.limit(AADLength + txtOffset + length); + buffer.position(AADLength + txtOffset); + + // share textBuf context + ByteBuffer buf2 = buffer.duplicate(); + buf2.limit(AADLength + txtOffset + anotherCipher.getOutputSize(length)); + int dataProcessed2 = anotherCipher.doFinal(buffer, buf2); + buf2.position(AADLength + txtOffset); + buf2.limit(AADLength + txtOffset + dataProcessed2); + + if (!buf2.equals(outBB)) { + throw new RuntimeException( + "Two results are not equal, mode:" + mode); + } + } + + private boolean isEqual(byte[] A, int offsetA, byte[] B, int offsetB, + int bytesToCompare) { + System.out.println("offsetA: " + offsetA + " offsetB: " + offsetA + + " bytesToCompare: " + bytesToCompare); + for (int i = 0; i < bytesToCompare; i++) { + int setA = i + offsetA; + int setB = i + offsetB; + if (setA > A.length - 1 || setB > B.length - 1 + || A[setA] != B[setB]) { + return false; + } + } + + return true; + } + + /* + * Creates a Cipher object for testing: for encryption it creates new Cipher + * based on previously saved parameters (it is prohibited to use the same + * Cipher twice for encription during GCM mode), or returns initiated + * existing Cipher. + */ + private Cipher createCipher(int mode, AlgorithmParameters params) + throws Exception { + Cipher cipher = Cipher.getInstance(transformation, provider); + if (Cipher.ENCRYPT_MODE == mode) { + // initiate it with the saved parameters + if (params != null) { + cipher.init(Cipher.ENCRYPT_MODE, key, params); + } else { + // intiate the cipher and save parameters + cipher.init(Cipher.ENCRYPT_MODE, key); + } + } else if (cipher != null) { + cipher.init(Cipher.DECRYPT_MODE, key, params); + } else { + throw new RuntimeException("Can't create cipher"); + } + + return cipher; + } + +} diff --git a/test/com/sun/crypto/provider/Cipher/AEAD/SealedObjectTest.java b/test/com/sun/crypto/provider/Cipher/AEAD/SealedObjectTest.java new file mode 100644 index 0000000000000000000000000000000000000000..6f5e8200e104d7ab55e67f5aee93ba365ba1743f --- /dev/null +++ b/test/com/sun/crypto/provider/Cipher/AEAD/SealedObjectTest.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2007, 2015, 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. + * + * 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. + */ + +import java.security.AlgorithmParameters; +import java.util.Arrays; +import javax.crypto.SecretKey; +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import javax.crypto.SealedObject; + +/* + * @test + * @bug 8048596 + * @summary Check if the seal/unseal feature works properly in AEAD/GCM mode. + */ +public class SealedObjectTest { + + private static final String AES = "AES"; + private static final String TRANSFORMATION = "AES/GCM/NoPadding"; + private static final String PROVIDER = "SunJCE"; + private static final int KEY_LENGTH = 128; + + public static void main(String[] args) throws Exception { + doTest(); + } + + /* + * Run the test: + * - init a cipher with AES/GCM/NoPadding transformation + * - seal an object + * - check if we can't seal it again with the same key/IV + * - unseal the object using different methods of SealedObject class + * - check if the original and sealed objects are equal + */ + static void doTest() throws Exception { + // init a secret Key + KeyGenerator kg = KeyGenerator.getInstance(AES, PROVIDER); + kg.init(KEY_LENGTH); + SecretKey key = kg.generateKey(); + + // initialization + Cipher cipher = Cipher.getInstance(TRANSFORMATION, PROVIDER); + cipher.init(Cipher.ENCRYPT_MODE, key); + AlgorithmParameters params = cipher.getParameters(); + + // seal an object + SealedObject so = new SealedObject(key, cipher); + try { + // check if we can't seal it again with the same key/IV + so = new SealedObject(key, cipher); + throw new RuntimeException( + "FAILED: expected IllegalStateException hasn't " + + "been thrown"); + } catch (IllegalStateException ise) { + System.out.println("Expected exception when seal it again with" + + " the same key/IV: " + ise); + } + + // unseal the object using getObject(Cipher) and compare + cipher.init(Cipher.DECRYPT_MODE, key, params); + SecretKey unsealedKey = (SecretKey) so.getObject(cipher); + assertKeysSame(unsealedKey, key, "SealedObject.getObject(Cipher)"); + + // unseal the object using getObject(Key) and compare + unsealedKey = (SecretKey) so.getObject(key); + assertKeysSame(unsealedKey, key, "SealedObject.getObject(Key)"); + + // unseal the object using getObject(Key, String) and compare + unsealedKey = (SecretKey) so.getObject(key, PROVIDER); + + assertKeysSame(unsealedKey, key, + "SealedObject.getObject(Key, String)"); + } + + /** + * Compare two SecretKey objects. + * + * @param key1 first key + * @param key2 second key + * @param meth method that was used for unsealing the SecretKey object + * @return true if key1 and key2 are the same, false otherwise. + */ + static void assertKeysSame(SecretKey key1, SecretKey key2, String meth) { + if (!Arrays.equals(key1.getEncoded(), key2.getEncoded())) { + throw new RuntimeException( + "FAILED: original and unsealed objects aren't the same for " + + meth); + } + } +} diff --git a/test/com/sun/crypto/provider/Cipher/AEAD/WrongAAD.java b/test/com/sun/crypto/provider/Cipher/AEAD/WrongAAD.java new file mode 100644 index 0000000000000000000000000000000000000000..157a8bb329dea237a1d7201a08c94c1cc6855671 --- /dev/null +++ b/test/com/sun/crypto/provider/Cipher/AEAD/WrongAAD.java @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2007, 2015, 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. + * + * 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. + */ + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.security.AlgorithmParameters; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.util.Arrays; +import javax.crypto.CipherInputStream; +import javax.crypto.CipherOutputStream; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; + +/* + * @test + * @bug 8048596 + * @summary Check if wrong or empty AAD is rejected + */ +public class WrongAAD { + + private static final String PROVIDER = "SunJCE"; + private static final String TRANSFORMATION = "AES/GCM/NoPadding"; + private static final int TEXT_SIZE = 800; + private static final int KEY_SIZE = 128; + private static final int AAD_SIZE = 128; + + private final SecretKey key; + private final byte[] plainText; + private final Cipher encryptCipher; + + public WrongAAD() throws Exception { + // init a secret key + KeyGenerator kg = KeyGenerator.getInstance("AES", PROVIDER); + kg.init(KEY_SIZE); + key = kg.generateKey(); + + // generate a plain text + plainText = Helper.generateBytes(TEXT_SIZE); + + // init AADs + byte[] AAD = Helper.generateBytes(AAD_SIZE); + + // init a cipher + encryptCipher = createCipher(Cipher.ENCRYPT_MODE, null); + encryptCipher.updateAAD(AAD); + } + + public static void main(String[] args) throws Exception { + WrongAAD test = new WrongAAD(); + test.decryptWithEmptyAAD(); + test.decryptWithWrongAAD(); + } + + /* + * Attempt to decrypt a cipher text using Cipher object + * initialized without AAD used for encryption. + */ + private void decryptWithEmptyAAD() throws Exception { + System.out.println("decryptWithEmptyAAD() started"); + // initialize it with empty AAD to get exception during decryption + Cipher decryptCipher = createCipher(Cipher.DECRYPT_MODE, + encryptCipher.getParameters()); + try (ByteArrayOutputStream baOutput = new ByteArrayOutputStream(); + CipherOutputStream ciOutput = new CipherOutputStream(baOutput, + decryptCipher)) { + if (decrypt(ciOutput, baOutput)) { + throw new RuntimeException( + "Decryption has been perfomed successfully in" + + " spite of the decrypt Cipher has NOT been" + + " initialized with AAD"); + } + } + System.out.println("decryptWithEmptyAAD() passed"); + } + + /* + * Attempt to decrypt the cipher text using Cipher object + * initialized with some fake AAD. + */ + private void decryptWithWrongAAD() throws Exception { + System.out.println("decrypt with wrong AAD"); + + // initialize it with wrong AAD to get an exception during decryption + Cipher decryptCipher = createCipher(Cipher.DECRYPT_MODE, + encryptCipher.getParameters()); + byte[] someAAD = Helper.generateBytes(AAD_SIZE + 1); + decryptCipher.updateAAD(someAAD); + + // init output stream + try (ByteArrayOutputStream baOutput = new ByteArrayOutputStream(); + CipherOutputStream ciOutput = new CipherOutputStream(baOutput, + decryptCipher);) { + if (decrypt(ciOutput, baOutput)) { + throw new RuntimeException( + "A decryption has been perfomed successfully in" + + " spite of the decrypt Cipher has been" + + " initialized with fake AAD"); + } + } + + System.out.println("Passed"); + } + + private boolean decrypt(CipherOutputStream ciOutput, + ByteArrayOutputStream baOutput) throws IOException { + try (ByteArrayInputStream baInput = new ByteArrayInputStream(plainText); + CipherInputStream ciInput = new CipherInputStream(baInput, + encryptCipher)) { + byte[] buffer = new byte[TEXT_SIZE]; + int len = ciInput.read(buffer); + + while (len != -1) { + ciOutput.write(buffer, 0, len); + len = ciInput.read(buffer); + } + ciOutput.flush(); + byte[] recoveredText = baOutput.toByteArray(); + System.out.println("recoveredText: " + new String(recoveredText)); + + /* + * See bug 8012900, AEADBadTagException is swalloed by CI/CO streams + * If recovered text is empty, than decryption failed + */ + if (recoveredText.length == 0) { + return false; + } + return Arrays.equals(plainText, recoveredText); + } catch (IllegalStateException e) { + System.out.println("Expected IllegalStateException: " + + e.getMessage()); + e.printStackTrace(System.out); + return false; + } + } + + private Cipher createCipher(int mode, AlgorithmParameters params) + throws NoSuchAlgorithmException, NoSuchProviderException, + NoSuchPaddingException, InvalidKeyException, + InvalidAlgorithmParameterException { + Cipher cipher = Cipher.getInstance(TRANSFORMATION, PROVIDER); + if (params != null) { + cipher.init(mode, key, params); + } else { + cipher.init(mode, key); + } + return cipher; + } +} diff --git a/test/com/sun/crypto/provider/Cipher/AES/CICO.java b/test/com/sun/crypto/provider/Cipher/AES/CICO.java new file mode 100644 index 0000000000000000000000000000000000000000..811724be8ce1483888173fb2b924d53eedc3f245 --- /dev/null +++ b/test/com/sun/crypto/provider/Cipher/AES/CICO.java @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2014, 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. + * + * 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. + */ + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.spec.AlgorithmParameterSpec; +import java.util.Random; +import javax.crypto.Cipher; +import javax.crypto.CipherInputStream; +import javax.crypto.CipherOutputStream; +import javax.crypto.KeyGenerator; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.spec.IvParameterSpec; + +/** + * @test + * @bug 8043836 + * @summary Test AES ciphers with different modes and padding schemes (ECB mode + * doesn't use IV). The test tries 3 different read methods of + * CipherInputStream. + */ +public class CICO { + private static final String ALGORITHM = "aEs"; + private static final String[] MODES = { "PCBC", "ECb", "cbC", "cFB", + "cFB24", "cFB32", "Cfb40", "CFB72", "OfB", "OfB20", "OfB48", + "OfB56", "OFB64", "OFB112", "CFB112", "pCbC" }; + private static final String[] PADDING = { "noPadding", "pkcs5padding" }; + private static final String PROVIDER = "SunJCE"; + private static final int NREADS = 3; + private static final int KEY_LENGTH = 128; + + private final byte[] plainText = new byte[1600000]; + + + public static void main(String argv[]) throws Exception { + CICO test = new CICO(); + for (String mode : MODES) { + for (String pad : PADDING) { + for (int m = 0; m < NREADS; m++) { + test.runTest(ALGORITHM, mode, pad, m); + } + } + } + } + + public void runTest(String algo, String mo, String pad, int whichRead) throws Exception { + Cipher ci1 = null; + Cipher ci2 = null; + byte[] iv = null; + AlgorithmParameterSpec aps = null; + SecretKey key = null; + + try { + // Do initialization + Random rdm = new Random(); + rdm.nextBytes(plainText); + KeyGenerator kg = KeyGenerator.getInstance(algo, PROVIDER); + if (!kg.getAlgorithm().equals(algo)) { + throw new RuntimeException("Unexpected algorithm <" + + kg.getAlgorithm() + ">, expected value is <" + algo + + ">"); + } + + kg.init(KEY_LENGTH); + key = kg.generateKey(); + + ci1 = Cipher.getInstance(algo + "/" + mo + "/" + pad, PROVIDER); + + if (mo.equalsIgnoreCase("ECB")) { + ci1.init(Cipher.ENCRYPT_MODE, key); + } else { + ci1.init(Cipher.ENCRYPT_MODE, key, aps); + } + + if (!mo.equalsIgnoreCase("ECB")) { + iv = ci1.getIV(); + aps = new IvParameterSpec(iv); + } else { + aps = null; + } + + ci2 = Cipher.getInstance(algo + "/" + mo + "/" + pad, PROVIDER); + if (mo.equalsIgnoreCase("ECB")) { + ci2.init(Cipher.DECRYPT_MODE, key); + } else { + ci2.init(Cipher.DECRYPT_MODE, key, aps); + } + + ByteArrayInputStream baInput = new ByteArrayInputStream(plainText); + ByteArrayOutputStream baOutput = new ByteArrayOutputStream(); + try (CipherInputStream ciInput = new CipherInputStream(baInput, ci1); + CipherOutputStream ciOutput = new CipherOutputStream( + baOutput, ci2)) { + // According to specification, CipherInputStream does not support the + // mark and reset methods + if (ciInput.markSupported()) { + throw new RuntimeException( + "CipherInputStream unexpectedly supports the mark and reset methods"); + } + + // Read from the input and write to the output using 2 types + // of buffering : byte[] and int + switch (whichRead) { + case 0: + int buffer0 = ciInput.read(); + while (buffer0 != -1) { + ciOutput.write(buffer0); + buffer0 = ciInput.read(); + } + break; + case 1: + byte[] buffer1 = new byte[20]; + int len1 = ciInput.read(buffer1); + while (len1 != -1) { + ciOutput.write(buffer1, 0, len1); + len1 = ciInput.read(buffer1); + } + break; + case NREADS - 1: + byte[] buffer2 = new byte[ci1 + .getOutputSize(plainText.length)]; + int offset2 = 0; + int len2 = 0; + while (len2 != -1) { + len2 = ciInput.read(buffer2, offset2, buffer2.length + - offset2); + offset2 += len2; + } + ciOutput.write(buffer2, 0, buffer2.length); + break; + } + } + + // Get the output + byte[] recoveredText = new byte[baOutput.size()]; + recoveredText = baOutput.toByteArray(); + if (!java.util.Arrays.equals(plainText, recoveredText)) { + throw new RuntimeException( + "Original text is not equal with recovered text, with " + + algo + "/" + mo + "/" + pad + "/" + whichRead); + } + + // Compare input and output + + } catch (NoSuchAlgorithmException e) { + //OFB20 is for negative testing + if (!mo.equalsIgnoreCase("OFB20")) { + System.out.println("Unexpected NoSuchAlgorithmException with " + + algo + "/" + mo + "/" + pad + "/" + whichRead); + throw new RuntimeException("Test failed!"); + } + } catch (IOException | NoSuchProviderException | NoSuchPaddingException + | InvalidKeyException | InvalidAlgorithmParameterException e) { + System.out.println("Unexpected Exception with " + + algo + "/" + mo + "/" + pad + "/" + whichRead); + System.out.println("Test failed!"); + throw e; + } + } +} diff --git a/test/com/sun/crypto/provider/Cipher/AES/CTR.java b/test/com/sun/crypto/provider/Cipher/AES/CTR.java new file mode 100644 index 0000000000000000000000000000000000000000..808f3e2691620c81563d538970b2bf29f936f1c4 --- /dev/null +++ b/test/com/sun/crypto/provider/Cipher/AES/CTR.java @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2014, 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. + * + * 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. + */ + +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.spec.AlgorithmParameterSpec; +import java.util.Arrays; +import java.util.Random; +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.KeyGenerator; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.ShortBufferException; +import javax.crypto.spec.IvParameterSpec; + + +/** + * @test + * @bug 8043836 + * @summary Test AES ciphers with 4 different modes with NoPadding. Check if + * data before encryption and after decryption is the same. + */ + +public class CTR { + + private static final String ALGORITHM = "AES"; + + private static final String PROVIDER = "SunJCE"; + + private static final String[] MODES = {"CTR","CFB24","OFB32","GCM"}; + + private static final String PADDING = "NoPadding"; + + + private static final int KEY_LENGTH = 128; + + public static void main(String argv[]) throws Exception { + CTR test = new CTR(); + for (String mode : MODES) { + test.runTest(ALGORITHM, mode, PADDING); + } + } + + + public void runTest(String algo, String mo, String pad) throws Exception { + Cipher ci = null; + byte[] iv = null; + AlgorithmParameterSpec aps = null; + SecretKey key = null; + + try { + Random rdm = new Random(); + byte[] plainText; + + ci = Cipher.getInstance(algo + "/" + mo + "/" + pad, PROVIDER); + KeyGenerator kg = KeyGenerator.getInstance(algo, PROVIDER); + kg.init(KEY_LENGTH); + key = kg.generateKey(); + + for (int i = 0; i < 15; i++) { + plainText = new byte[1600 + i + 1]; + rdm.nextBytes(plainText); + + if (!mo.equalsIgnoreCase("GCM")) { + ci.init(Cipher.ENCRYPT_MODE, key, aps); + } else { + ci.init(Cipher.ENCRYPT_MODE, key); + } + + byte[] cipherText = new byte[ci.getOutputSize(plainText.length)]; + int offset = ci.update(plainText, 0, plainText.length, + cipherText, 0); + + ci.doFinal(cipherText, offset); + + if (!mo.equalsIgnoreCase("ECB")) { + iv = ci.getIV(); + aps = new IvParameterSpec(iv); + } else { + aps = null; + } + + if (!mo.equalsIgnoreCase("GCM")) { + ci.init(Cipher.DECRYPT_MODE, key, aps); + } else { + ci.init(Cipher.DECRYPT_MODE, key, ci.getParameters()); + } + + byte[] recoveredText = new byte[ci.getOutputSize(cipherText.length)]; + int len = ci.doFinal(cipherText, 0, cipherText.length, + recoveredText); + byte[] tmp = new byte[len]; + + for (int j = 0; j < len; j++) { + tmp[j] = recoveredText[j]; + } + Arrays.toString(plainText); + if (!java.util.Arrays.equals(plainText, tmp)) { + System.out.println("Original: "); + dumpBytes(plainText); + System.out.println("Recovered: "); + dumpBytes(tmp); + throw new RuntimeException("Original text is not equal with recovered text, with mode:" + mo); + } + } + } catch (NoSuchAlgorithmException | NoSuchProviderException | NoSuchPaddingException + | InvalidKeyException | InvalidAlgorithmParameterException + | ShortBufferException | IllegalBlockSizeException + | BadPaddingException e) { + System.out.println("Test failed!"); + throw e; + } + } + + private void dumpBytes(byte[] bytes){ + for (byte b : bytes){ + System.out.print(Integer.toHexString(b)); + } + System.out.println(); + } +} diff --git a/test/com/sun/crypto/provider/Cipher/AES/Padding.java b/test/com/sun/crypto/provider/Cipher/AES/Padding.java new file mode 100644 index 0000000000000000000000000000000000000000..6023ec7cc67dbca6665ed97dd132f677b352ad09 --- /dev/null +++ b/test/com/sun/crypto/provider/Cipher/AES/Padding.java @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2014, 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. + * + * 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. + */ + +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.spec.AlgorithmParameterSpec; +import java.util.Random; +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.KeyGenerator; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.ShortBufferException; +import javax.crypto.spec.IvParameterSpec; + +/** + * @test + * @bug 8043836 + * @summary Test AES ciphers with different modes and padding schemes (ECB mode + * doesn't use IV). The test tries 3 different read methods of + * CipherInputStream. + */ +public class Padding { + + private static final String ALGORITHM = "AES"; + private static final String PROVIDER = "SunJCE"; + private static final String[] MODES = { "ECb", "CbC", "PCBC", "OFB", + "OFB150", "cFB", "CFB7", "cFB8", "cFB16", "cFB24", "cFB32", + "Cfb40", "cfB48", "cfB56", "cfB64", "cfB72", "cfB80", "cfB88", + "cfB96", "cfb104", "cfB112", "cfB120", "OFB8", "OFB16", "OFB24", + "OFB32", "OFB40", "OFB48", "OFB56", "OFB64", "OFB72", "OFB80", + "OFB88", "OFB96", "OFB104", "OFB112", "OFB120", "GCM" }; + private static final String PADDING = "PKCS5Padding"; + private static final int KEY_LENGTH = 128; + + public static void main(String argv[]) throws Exception { + Padding test = new Padding(); + for (String mode : MODES) { + test.runTest(ALGORITHM, mode, PADDING); + } + } + + public void runTest(String algo, String mo, String pad) throws Exception { + Cipher ci = null; + byte[] iv = null; + AlgorithmParameterSpec aps = null; + SecretKey key = null; + try { + Random rdm = new Random(); + byte[] plainText; + + ci = Cipher.getInstance(algo + "/" + mo + "/" + pad, PROVIDER); + KeyGenerator kg = KeyGenerator.getInstance(algo, PROVIDER); + kg.init(KEY_LENGTH); + key = kg.generateKey(); + + for (int i = 0; i < 15; i++) { + plainText = new byte[1600 + i + 1]; + rdm.nextBytes(plainText); + + if (!mo.equalsIgnoreCase("GCM")) { + ci.init(Cipher.ENCRYPT_MODE, key, aps); + } else { + ci.init(Cipher.ENCRYPT_MODE, key); + } + + byte[] cipherText = new byte[ci.getOutputSize(plainText.length)]; + int offset = ci.update(plainText, 0, plainText.length, + cipherText, 0); + ci.doFinal(cipherText, offset); + + if (!mo.equalsIgnoreCase("ECB")) { + iv = ci.getIV(); + aps = new IvParameterSpec(iv); + } else { + aps = null; + } + + if (!mo.equalsIgnoreCase("GCM")) { + ci.init(Cipher.DECRYPT_MODE, key, aps); + } else { + ci.init(Cipher.DECRYPT_MODE, key, ci.getParameters()); + } + + byte[] recoveredText = new byte[ci.getOutputSize(cipherText.length)]; + int len = ci.doFinal(cipherText, 0, cipherText.length, + recoveredText); + byte[] tmp = new byte[len]; + + for (int j = 0; j < len; j++) { + tmp[j] = recoveredText[j]; + } + + if (!java.util.Arrays.equals(plainText, tmp)) { + System.out.println("Original: "); + dumpBytes(plainText); + System.out.println("Recovered: "); + dumpBytes(tmp); + throw new RuntimeException( + "Original text is not equal with recovered text, with mode:" + + mo); + } + } + } catch (NoSuchAlgorithmException e) { + //CFB7 and OFB150 are for negative testing + if (!mo.equalsIgnoreCase("CFB7") && !mo.equalsIgnoreCase("OFB150")) { + System.out + .println("Unexpected NoSuchAlgorithmException with mode: " + + mo); + throw new RuntimeException("Test failed!"); + } + } catch ( NoSuchProviderException | NoSuchPaddingException + | InvalidKeyException | InvalidAlgorithmParameterException + | ShortBufferException | IllegalBlockSizeException + | BadPaddingException e) { + System.out.println("Test failed!"); + throw e; + } + } + + private void dumpBytes(byte[] bytes) { + for (byte b : bytes) { + System.out.print(Integer.toHexString(b)); + } + + System.out.println(); + } +} diff --git a/test/com/sun/crypto/provider/Cipher/AES/TestAESCipher.java b/test/com/sun/crypto/provider/Cipher/AES/TestAESCipher.java new file mode 100644 index 0000000000000000000000000000000000000000..190b58630cc658b10db7d5709a96ce80d5800837 --- /dev/null +++ b/test/com/sun/crypto/provider/Cipher/AES/TestAESCipher.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2014, 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. + * + * 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. + */ + +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.spec.AlgorithmParameterSpec; +import java.util.Random; +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.KeyGenerator; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.ShortBufferException; +import javax.crypto.spec.IvParameterSpec; + +/** + * @test + * @bug 8043836 + * @summary Test AES ciphers with different modes and padding schemes (ECB mode + * doesn't use IV). + * @author Liwen Wang + * @author Parag Salvi + */ +public class TestAESCipher { + + private static final String ALGORITHM = "AES"; + private static final String PROVIDER = "SunJCE"; + private static final String[] MODES = { "ECb", "CbC", "CTR", "PCBC", "OFB", + "OFB150", "cFB", "CFB7", "cFB8", "cFB16", "cFB24", "cFB32", + "Cfb40", "cfB48", "cfB56", "cfB64", "cfB72", "cfB80", "cfB88", + "cfB96", "cfb104", "cfB112", "cfB120", "OFB8", "OFB16", "OFB24", + "OFB32", "OFB40", "OFB48", "OFB56", "OFB64", "OFB72", "OFB80", + "OFB88", "OFB96", "OFB104", "OFB112", "OFB120", "GCM" }; + private static final String[] PADDING = { "NoPadding", "PKCS5Padding" }; + private static final int KEY_LENGTH = 128; + + public static void main(String argv[]) throws Exception { + TestAESCipher test = new TestAESCipher(); + for (String mode : MODES) { + int padKinds = 1; + if (mode.equalsIgnoreCase("ECB") || mode.equalsIgnoreCase("PCBC") + || mode.equalsIgnoreCase("CBC")) { + padKinds = PADDING.length; + } + + for (int k = 0; k < padKinds; k++) { + test.runTest(ALGORITHM, mode, PADDING[k]); + } + } + } + + public void runTest(String algo, String mo, String pad) throws Exception { + Cipher ci = null; + byte[] iv = null; + AlgorithmParameterSpec aps = null; + SecretKey key = null; + try { + // Initialization + Random rdm = new Random(); + byte[] plainText = new byte[128]; + rdm.nextBytes(plainText); + + ci = Cipher.getInstance(algo + "/" + mo + "/" + pad, PROVIDER); + KeyGenerator kg = KeyGenerator.getInstance(algo, PROVIDER); + kg.init(KEY_LENGTH); + key = kg.generateKey(); + + // encrypt + if (!mo.equalsIgnoreCase("GCM")) { + ci.init(Cipher.ENCRYPT_MODE, key, aps); + } else { + ci.init(Cipher.ENCRYPT_MODE, key); + } + + byte[] cipherText = new byte[ci.getOutputSize(plainText.length)]; + int offset = ci.update(plainText, 0, plainText.length, cipherText, + 0); + ci.doFinal(cipherText, offset); + + if (!mo.equalsIgnoreCase("ECB")) { + iv = ci.getIV(); + aps = new IvParameterSpec(iv); + } else { + aps = null; + } + + if (!mo.equalsIgnoreCase("GCM")) { + ci.init(Cipher.DECRYPT_MODE, key, aps); + } else { + ci.init(Cipher.DECRYPT_MODE, key, ci.getParameters()); + } + + byte[] recoveredText = new byte[ci.getOutputSize(cipherText.length)]; + int len = ci.doFinal(cipherText, 0, cipherText.length, + recoveredText); + byte[] tmp = new byte[len]; + System.arraycopy(recoveredText, 0, tmp, 0, len); + + // Comparison + if (!java.util.Arrays.equals(plainText, tmp)) { + System.out.println("Original: "); + dumpBytes(plainText); + System.out.println("Recovered: "); + dumpBytes(tmp); + throw new RuntimeException( + "Original text is not equal with recovered text, with mode:" + + mo); + } + + } catch (NoSuchAlgorithmException e) { + //CFB7 and OFB150 are for negative testing + if (!mo.equalsIgnoreCase("CFB7") && !mo.equalsIgnoreCase("OFB150")) { + System.out.println("Unexpected NoSuchAlgorithmException with mode: " + + mo); + throw new RuntimeException("Test failed!"); + } + } catch ( NoSuchProviderException | NoSuchPaddingException + | InvalidKeyException | InvalidAlgorithmParameterException + | ShortBufferException | IllegalBlockSizeException + | BadPaddingException e) { + System.out.println("Test failed!"); + throw e; + } + } + + private void dumpBytes(byte[] bytes) { + for (byte b : bytes) { + System.out.print(Integer.toHexString(b)); + } + + System.out.println(); + } +} diff --git a/test/com/sun/crypto/provider/Cipher/AES/TestNonexpanding.java b/test/com/sun/crypto/provider/Cipher/AES/TestNonexpanding.java new file mode 100644 index 0000000000000000000000000000000000000000..200d38b547bc23626abdfbf1134565bc683b2f73 --- /dev/null +++ b/test/com/sun/crypto/provider/Cipher/AES/TestNonexpanding.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2014, 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. + * + * 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. + */ + +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.spec.InvalidParameterSpecException; +import java.util.Random; +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.KeyGenerator; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.ShortBufferException; +import javax.crypto.spec.GCMParameterSpec; + +/** + * @test + * @bug 8043836 + * @summary Test AES encryption with no padding. Expect the original data length + * is the same as the encrypted data. + */ +public class TestNonexpanding { + + private static final String ALGORITHM = "AES"; + private static final String PROVIDER = "SunJCE"; + private static final String[] MODES = { "ECb", "CbC", "OFB", "OFB150", + "cFB", "CFB7", "cFB8", "cFB16", "cFB24", "cFB32", "Cfb40", "cfB48", + "cfB56", "cfB64", "cfB72", "cfB80", "cfB88", "cfB96", "cfb104", + "cfB112", "cfB120", "GCM" }; + private static final String PADDING = "NoPadding"; + private static final int KEY_LENGTH = 128; + + public static void main(String argv[]) throws Exception { + TestNonexpanding test = new TestNonexpanding(); + for (String mode : MODES) { + test.runTest(ALGORITHM, mode, PADDING); + } + } + + public void runTest(String algo, String mo, String pad) throws Exception { + Cipher ci = null; + SecretKey key = null; + try { + // Initialization + Random rdm = new Random(); + byte[] plainText = new byte[128]; + rdm.nextBytes(plainText); + + ci = Cipher.getInstance(algo + "/" + mo + "/" + pad, PROVIDER); + + KeyGenerator kg = KeyGenerator.getInstance(algo, PROVIDER); + kg.init(KEY_LENGTH); + key = kg.generateKey(); + + // encrypt + ci.init(Cipher.ENCRYPT_MODE, key); + byte[] cipherText = new byte[ci.getOutputSize(plainText.length)]; + int offset = ci.update(plainText, 0, plainText.length, cipherText, + 0); + ci.doFinal(cipherText, offset); + + // Comparison + if (!(plainText.length == cipherText.length)) { + // The result of encryption in GCM is a combination of an + // authentication tag and cipher text. + if (mo.equalsIgnoreCase("GCM")) { + GCMParameterSpec spec = ci.getParameters().getParameterSpec(GCMParameterSpec.class); + int cipherTextLength = cipherText.length - spec.getTLen() + / 8; + if (plainText.length == cipherTextLength) { + return; + } + } + System.out.println("Original length: " + plainText.length); + System.out.println("Cipher text length: " + cipherText.length); + throw new RuntimeException("Test failed!"); + } + } catch (NoSuchAlgorithmException e) { + //CFB7 and OFB150 are for negative testing + if (!mo.equalsIgnoreCase("CFB7") && !mo.equalsIgnoreCase("OFB150")) { + System.out.println("Unexpected NoSuchAlgorithmException with mode: " + + mo); + throw new RuntimeException("Test failed!"); + } + } catch ( NoSuchProviderException | NoSuchPaddingException + | InvalidKeyException | InvalidParameterSpecException + | ShortBufferException | IllegalBlockSizeException + | BadPaddingException e) { + System.out.println("Test failed!"); + throw e; + } + } +} diff --git a/test/com/sun/crypto/provider/Cipher/AES/TestSameBuffer.java b/test/com/sun/crypto/provider/Cipher/AES/TestSameBuffer.java new file mode 100644 index 0000000000000000000000000000000000000000..bbba223a7c47f3f0be5f6156871d0cc3c7ef7363 --- /dev/null +++ b/test/com/sun/crypto/provider/Cipher/AES/TestSameBuffer.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2014, 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. + * + * 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. + */ + +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.spec.AlgorithmParameterSpec; +import java.util.Random; +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.KeyGenerator; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.ShortBufferException; +import javax.crypto.spec.IvParameterSpec; + +/** + * @test + * @bug 8043836 + * @summary Test AES ciphers with different modes and padding schemes (ECB mode + * doesn't use IV). The test tries 3 different read methods of + * CipherInputStream. + */ +public class TestSameBuffer { + + private static final String ALGORITHM = "Rijndael"; + private static final String PROVIDER = "SunJCE"; + private static final String[] MODES = { "ECb", "CbC", "OFB", "CFB150", + "cFB", "CFB7", " cFB8", "cFB16", "cFB24", "cFB32", "Cfb40", + "cfB48", " cfB56", "cfB64", "cfB72", "cfB80", "cfB88", "cfB96", + "cfb104", "cfB112", "cfB120" }; + private static final String PADDING = "NoPadding"; + private static final int KEY_LENGTH = 128; + + public static void main(String argv[]) throws Exception { + TestSameBuffer test = new TestSameBuffer(); + for (String mode : MODES) { + test.runTest(ALGORITHM, mode, PADDING); + } + } + + public void runTest(String algo, String mo, String pad) throws Exception { + Cipher ci = null; + byte[] iv = null; + AlgorithmParameterSpec aps = null; + SecretKey key = null; + try { + // Initialization + Random rdm = new Random(); + byte[] plainText = new byte[128]; + rdm.nextBytes(plainText); + + // keep the plain text + byte[] tmpText = new byte[plainText.length]; + for (int i = 0; i < plainText.length; i++) { + tmpText[i] = plainText[i]; + } + + ci = Cipher.getInstance(algo + "/" + mo + "/" + pad, PROVIDER); + + KeyGenerator kg = KeyGenerator.getInstance(algo, PROVIDER); + kg.init(KEY_LENGTH); + key = kg.generateKey(); + + // encrypt + ci.init(Cipher.ENCRYPT_MODE, key); + int offset = ci + .update(plainText, 0, plainText.length, plainText, 0); + ci.doFinal(plainText, offset); + + if (!mo.equalsIgnoreCase("ECB")) { + iv = ci.getIV(); + aps = new IvParameterSpec(iv); + } else { + aps = null; + } + + ci.init(Cipher.DECRYPT_MODE, key, aps); + byte[] recoveredText = new byte[ci.getOutputSize(plainText.length)]; + ci.doFinal(plainText, 0, plainText.length, recoveredText); + + // Comparison + if (!java.util.Arrays.equals(tmpText, recoveredText)) { + System.out.println("Original: "); + dumpBytes(plainText); + System.out.println("Recovered: "); + dumpBytes(recoveredText); + throw new RuntimeException( + "Original text is not equal with recovered text, with mode:" + + mo); + } + + } catch (NoSuchAlgorithmException e) { + //CFB7 and CFB150 are for negative testing + if (!mo.equalsIgnoreCase("CFB7") && !mo.equalsIgnoreCase("CFB150")) { + System.out.println("Unexpected NoSuchAlgorithmException with mode: " + + mo); + throw new RuntimeException("Test failed!"); + } + } catch (NoSuchProviderException | NoSuchPaddingException + | InvalidKeyException | InvalidAlgorithmParameterException + | ShortBufferException | IllegalBlockSizeException + | BadPaddingException e) { + System.out.println("Test failed!"); + throw e; + } + } + + private void dumpBytes(byte[] bytes) { + for (byte b : bytes) { + System.out.print(Integer.toHexString(b)); + } + + System.out.println(); + } +} diff --git a/test/com/sun/crypto/provider/Cipher/DES/TestUtility.java b/test/com/sun/crypto/provider/Cipher/DES/TestUtility.java index 61efd621bdb87ffb082ff85b576e49636e318c5e..ffa0a5bfcb3dfbe279df6e29ba98465c7876ec8b 100644 --- a/test/com/sun/crypto/provider/Cipher/DES/TestUtility.java +++ b/test/com/sun/crypto/provider/Cipher/DES/TestUtility.java @@ -27,39 +27,52 @@ public class TestUtility { - private static final String digits = "0123456789abcdef"; + private static final String DIGITS = "0123456789abcdef"; - public TestUtility() { + private TestUtility() { } public static String hexDump(byte[] bytes) { - StringBuffer buf = new StringBuffer (bytes.length * 2); - int i; + StringBuilder buf = new StringBuilder(bytes.length * 2); + int i; - buf.append (" "); // four spaces + buf.append(" "); // four spaces for (i = 0; i < bytes.length; i++) { - buf.append (digits.charAt ((bytes[i] >> 4) & 0x0f)); - buf.append (digits.charAt (bytes[i] & 0x0f)); - if (((i + 1) % 32) == 0) { - if ((i + 1) != bytes.length) - buf.append ("\n "); // line after four words - } else if (((i + 1) % 4) == 0) - buf.append (' '); // space between words + buf.append(DIGITS.charAt(bytes[i] >> 4 & 0x0f)); + buf.append(DIGITS.charAt(bytes[i] & 0x0f)); + if ((i + 1) % 32 == 0) { + if (i + 1 != bytes.length) { + buf.append("\n "); // line after four words + } + } else if ((i + 1) % 4 == 0) { + buf.append(' '); // space between words + } } - return buf.toString (); + return buf.toString(); } + public static String hexDump(byte[] bytes, int index) { + StringBuilder buf = new StringBuilder(bytes.length * 2); + int i; + + buf.append(" "); // four spaces + buf.append(DIGITS.charAt(bytes[index] >> 4 & 0x0f)); + buf.append(DIGITS.charAt(bytes[index] & 0x0f)); + return buf.toString(); + } public static boolean equalsBlock(byte[] b1, byte[] b2) { - if (b1.length != b2.length) + if (b1.length != b2.length) { return false; + } - for (int i=0; i LINIMITED_KEYSIZE) { + out.println(algo + " will not run if unlimited version of" + + " JCE jurisdiction policy files are installed"); + continue; + } + test.wrapperAesDESedeKeyTest(algo, wrapper, keySize); + if (algoWrapper == AlgorithmWrapper.NegtiveWrap) { + throw new RuntimeException("Expected not throw when algo" + + " and wrapAlgo are not match:" + algo); + } + } catch (InvalidKeyException e) { + if (algoWrapper == AlgorithmWrapper.NegtiveWrap) { + out.println("Expepted exception when algo" + + " and wrapAlgo are not match:" + algo); + } else { + throw e; + } + } + } + test.wrapperBlowfishKeyTest(); + // PBE and public wrapper test. + String[] publicPrivateAlgos = new String[] { "DiffieHellman", "DSA", + "RSA" }; + Provider provider = Security.getProvider(SUN_JCE); + if (provider == null) { + throw new RuntimeException("SUN_JCE provider not exist"); + } + + test.wrapperPBEKeyTest(provider); + // Public and private key wrap test + test.wrapperPublicPriviteKeyTest(provider, publicPrivateAlgos); + } + + private void wrapperAesDESedeKeyTest(String algo, String wrapAlgo, + int keySize) throws InvalidKeyException, NoSuchAlgorithmException, + NoSuchPaddingException, IllegalBlockSizeException, + InvalidAlgorithmParameterException { + // Initialization + KeyGenerator kg = KeyGenerator.getInstance(algo); + if (keySize != -1) { + kg.init(keySize); + } + SecretKey key = kg.generateKey(); + wrapTest(algo, wrapAlgo, key, key, Cipher.SECRET_KEY, false); + } + + private void wrapperBlowfishKeyTest() throws InvalidKeyException, + NoSuchAlgorithmException, NoSuchPaddingException, + IllegalBlockSizeException, InvalidAlgorithmParameterException { + // how many kinds of padding mode + int padKinds; + // Keysize should be multiple of 8 bytes. + int KeyCutter = 8; + int kSize = BLOWFISH_MIN_KEYSIZE; + String algorithm = "Blowfish"; + int maxAllowKeyLength = Cipher.getMaxAllowedKeyLength(algorithm); + boolean unLimitPolicy = maxAllowKeyLength == Integer.MAX_VALUE; + SecretKey key = null; + while (kSize <= BLOWFISH_MAX_KEYSIZE) { + for (String mode : MODEL_AR) { + // PKCS5padding is meaningful only for ECB, CBC, PCBC + if (mode.equalsIgnoreCase(MODEL_AR[0]) + || mode.equalsIgnoreCase(MODEL_AR[1]) + || mode.equalsIgnoreCase(MODEL_AR[2])) { + padKinds = PADDING_AR.length; + } else { + padKinds = 1; + } + // Initialization + KeyGenerator kg = KeyGenerator.getInstance(algorithm); + for (int k = 0; k < padKinds; k++) { + String transformation = algorithm + "/" + mode + "/" + + PADDING_AR[k]; + if (NOPADDING.equals(PADDING_AR[k]) && kSize % 64 != 0) { + out.println(transformation + + " will not run if input length not multiple" + + " of 8 bytes when padding is " + NOPADDING); + continue; + } + kg.init(kSize); + key = kg.generateKey(); + // only run the tests on longer key lengths if unlimited + // version of JCE jurisdiction policy files are installed + if (!unLimitPolicy && kSize > LINIMITED_KEYSIZE) { + out.println("keyStrength > 128 within " + algorithm + + " will not run under global policy"); + } else { + wrapTest(transformation, transformation, key, key, + Cipher.SECRET_KEY, false); + } + } + } + if (kSize <= LINIMITED_KEYSIZE) { + KeyCutter = 8; + } else { + KeyCutter = 48; + } + kSize += KeyCutter; + } + } + + private void wrapperPBEKeyTest(Provider p) throws InvalidKeySpecException, + InvalidKeyException, NoSuchPaddingException, + IllegalBlockSizeException, InvalidAlgorithmParameterException, + NoSuchAlgorithmException { + for (String alg : PBE_ALGORITHM_AR) { + String baseAlgo = alg.split("/")[0].toUpperCase(); + // only run the tests on longer key lengths if unlimited version + // of JCE jurisdiction policy files are installed + + if (Cipher.getMaxAllowedKeyLength(alg) < Integer.MAX_VALUE + && (baseAlgo.endsWith("TRIPLEDES") || alg + .endsWith("AES_256"))) { + out.println("keyStrength > 128 within " + alg + + " will not run under global policy"); + continue; + } + SecretKeyFactory skf = SecretKeyFactory.getInstance(baseAlgo, p); + SecretKey key = skf.generateSecret(new PBEKeySpec("Secret Lover" + .toCharArray())); + wrapTest(alg, alg, key, key, Cipher.SECRET_KEY, true); + } + } + + private void wrapperPublicPriviteKeyTest(Provider p, String[] algorithms) + throws NoSuchAlgorithmException, InvalidKeyException, + NoSuchPaddingException, IllegalBlockSizeException, + InvalidAlgorithmParameterException { + for (String algo : algorithms) { + // Key pair generated + System.out.println("Generate key pair (algorithm: " + algo + + ", provider: " + p.getName() + ")"); + KeyPairGenerator kpg = KeyPairGenerator.getInstance(algo); + kpg.initialize(512); + KeyPair kp = kpg.genKeyPair(); + // key generated + String algoWrap = "DES"; + KeyGenerator kg = KeyGenerator.getInstance(algoWrap, p); + Key key = kg.generateKey(); + wrapTest(algo, algoWrap, key, kp.getPrivate(), Cipher.PRIVATE_KEY, + false); + wrapTest(algo, algoWrap, key, kp.getPublic(), Cipher.PUBLIC_KEY, + false); + } + } + + private void wrapTest(String transformation, String wrapAlgo, Key initKey, + Key wrapKey, int keyType, boolean isPBE) + throws NoSuchAlgorithmException, NoSuchPaddingException, + InvalidKeyException, IllegalBlockSizeException, + InvalidAlgorithmParameterException { + String algo = transformation.split("/")[0]; + boolean isAESBlowfish = algo.indexOf("AES") != -1 + || algo.indexOf("Blowfish") != -1; + AlgorithmParameters aps = null; + AlgorithmParameterSpec pbeParams = null; + if (isPBE) { + byte[] salt = new byte[8]; + int iterCnt = 1000; + new Random().nextBytes(salt); + pbeParams = new PBEParameterSpec(salt, iterCnt); + } + // Wrap & UnWrap operation + Cipher wrapCI = Cipher.getInstance(wrapAlgo); + if (isPBE && !isAESBlowfish) { + wrapCI.init(Cipher.WRAP_MODE, initKey, pbeParams); + } else if (isAESBlowfish) { + wrapCI.init(Cipher.WRAP_MODE, initKey); + aps = wrapCI.getParameters(); + } else { + wrapCI.init(Cipher.WRAP_MODE, initKey); + } + out.println("keysize : " + wrapKey.getEncoded().length); + byte[] keyWrapper = wrapCI.wrap(wrapKey); + if (isPBE && !isAESBlowfish) { + wrapCI.init(Cipher.UNWRAP_MODE, initKey, pbeParams); + } else if (isAESBlowfish) { + wrapCI.init(Cipher.UNWRAP_MODE, initKey, aps); + } else { + wrapCI.init(Cipher.UNWRAP_MODE, initKey); + } + Key unwrappedKey = wrapCI.unwrap(keyWrapper, algo, keyType); + // Comparison + if (!Arrays.equals(wrapKey.getEncoded(), unwrappedKey.getEncoded())) { + throw new RuntimeException("Comparation failed testing " + + transformation + ":" + wrapAlgo + ":" + keyType); + } + } +} diff --git a/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/AESPBEWrapper.java b/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/AESPBEWrapper.java new file mode 100644 index 0000000000000000000000000000000000000000..16dd69ad32ffd397477c206f3dc5c2af7bc8b4f1 --- /dev/null +++ b/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/AESPBEWrapper.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2012, 2014, 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. + * + * 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. + */ + +import java.io.PrintStream; +import java.security.AlgorithmParameters; +import java.security.InvalidKeyException; +import java.security.Provider; +import javax.crypto.Cipher; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; + +/** + * Wrapper class to test a given AES-based PBE algorithm. + * + * @author Alexander Fomin + */ +public class AESPBEWrapper extends PBEWrapper { + + private AlgorithmParameters pbeParams; + + /** + * Constructor. Instantiate Cipher using the given AES-based PBE algorithms. + * + * @param p security Provider + * @param algo PKDF2 algorithm + * @param passwd password phrase + * @param out print stream + * @throws Exception all exceptions are thrown + */ + public AESPBEWrapper(Provider p, String algo, String passwd, + PrintStream out) throws Exception { + super(algo, + SecretKeyFactory.getInstance(algo, p).generateSecret( + new PBEKeySpec(passwd.toCharArray())), + Cipher.getInstance(algo, p), out); + } + + /** + * Perform encryption/decryption operation (depending on the specified + * edMode) on the same byte buffer. Compare result with the result at an + * allocated buffer. If both results are equal - return true, otherwise + * return false. + * + * @param edMode specified mode + * @param inputText text to decrypt + * @param offset offset in the text + * @param len input length + * @return ture - test passed; false - test failed + */ + @Override + public boolean execute(int edMode, byte[] inputText, int offset, int len) { + try { + // init Cipher + if (Cipher.ENCRYPT_MODE == edMode) { + ci.init(Cipher.ENCRYPT_MODE, this.key); + pbeParams = ci.getParameters(); + } else { + ci.init(Cipher.DECRYPT_MODE, this.key, pbeParams); + } + + // First, generate the cipherText at an allocated buffer + byte[] outputText = ci.doFinal(inputText, offset, len); + + // Second, generate cipherText again at the same buffer of plainText + int myoff = offset / 2; + int off = ci.update(inputText, offset, len, inputText, myoff); + ci.doFinal(inputText, myoff + off); + + if (this.algo.endsWith("AES_256")) { + out.print("Expected exception uncaught, " + + "keyStrength > 128 within " + this.algo); + + return false; + } + + // Compare to see whether the two results are the same or not + return equalsBlock(inputText, myoff, outputText, 0, + outputText.length); + } catch (Exception ex) { + if ((ex instanceof InvalidKeyException) + && this.algo.endsWith("AES_256")) { + out.println("Expected InvalidKeyException exception: " + + ex.getMessage()); + + return true; + } + + out.println("Catch unexpected exception within " + algo); + ex.printStackTrace(out); + + return false; + } + } +} diff --git a/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/PBECipherWrapper.java b/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/PBECipherWrapper.java new file mode 100644 index 0000000000000000000000000000000000000000..e4a8509ca34f60c5aa4cfd67b16f72d069fb0de3 --- /dev/null +++ b/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/PBECipherWrapper.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2012, 2014, 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. + * + * 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. + */ + +/* + * @author Valerie PENG + * @author Yun Ke + * @author Alexander Fomin + * @author rhalade + */ +import java.security.spec.AlgorithmParameterSpec; + +import java.util.StringTokenizer; + +import java.security.InvalidKeyException; +import java.security.Provider; + +import java.io.PrintStream; + +import javax.crypto.Cipher; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; +import javax.crypto.spec.PBEParameterSpec; + +public class PBECipherWrapper extends PBEWrapper { + + private final AlgorithmParameterSpec aps; + + public PBECipherWrapper( + Provider p, String algo, String passwd, PrintStream out) + throws Exception { + super(algo, + SecretKeyFactory.getInstance( + new StringTokenizer(algo, "/").nextToken(), p).generateSecret( + new PBEKeySpec(passwd.toCharArray())), + Cipher.getInstance(algo, p), out); + + int SALT_SIZE = 8; + aps = new PBEParameterSpec(generateSalt(SALT_SIZE), ITERATION_COUNT); + } + + @Override + public boolean execute(int edMode, byte[] inputText, int offset, + int len) { + StringTokenizer st = new StringTokenizer(algo, "/"); + String baseAlgo = st.nextToken().toUpperCase(); + + // Perform encryption or decryption depends on the specified edMode + try { + ci.init(edMode, key, aps); + + // First, generate the cipherText at an allocated buffer + byte[] outputText = ci.doFinal(inputText, offset, len); + + // Second, generate cipherText again at the same buffer of + // plainText + int myoff = offset / 2; + int off = ci.update(inputText, offset, len, inputText, myoff); + + ci.doFinal(inputText, myoff + off); + + if (baseAlgo.endsWith("TRIPLEDES") + || baseAlgo.endsWith("AES_256")) { + out.print("Expected exception uncaught," + + "keyStrength > 128 within " + this.algo); + + return false; + } + + // Compare to see whether the two results are the same or not + boolean result = equalsBlock(inputText, myoff, outputText, 0, + outputText.length); + + return result; + } catch (Exception ex) { + if ((ex instanceof InvalidKeyException) + && (baseAlgo.endsWith("TRIPLEDES") + || baseAlgo.endsWith("AES_256"))) { + out.println("Expected InvalidKeyException exception: " + + ex.getMessage()); + + return true; + } + + out.println("Catch unexpected exception within " + algo); + ex.printStackTrace(out); + + return false; + } + } +} diff --git a/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/PBESameBuffer.java b/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/PBESameBuffer.java new file mode 100644 index 0000000000000000000000000000000000000000..4fe20f8cbacd1326c985805a47b97324d9b970a3 --- /dev/null +++ b/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/PBESameBuffer.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2012, 2014, 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. + * + * 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. + */ + +/** + * @test + * @bug 8041787 + * @library . + * @build PBEWrapper PBEWrapperCreator PBKDF2Wrapper AESPBEWrapper PBECipherWrapper + * @summary Verify that same encrypt/decrypt buffer can be used for PBE ciphers + * @author Alexander Fomin + * @author rhalade + * @run main PBESameBuffer + */ +import java.io.PrintStream; +import java.security.*; +import java.util.Random; +import javax.crypto.Cipher; + +public class PBESameBuffer { + + private static final String[] pbeAlgorithms = { + "pbeWithMD5ANDdes", "PBEWithMD5AndDES/CBC/PKCS5Padding", + "pbeWithMD5ANDtripledes", "PBEWithMD5AndTRIPLEDES/CBC/PKCS5Padding", + "PBEwithSHA1AndDESede", "PBEwithSHA1AndDESede/CBC/PKCS5Padding", + "PBEwithSHA1AndRC2_40", "PBEwithSHA1AndRC2_40/CBC/PKCS5Padding", + "PBEWithSHA1AndRC2_128", "PBEWithSHA1AndRC2_128/CBC/PKCS5Padding", + "PBEWithSHA1AndRC4_40", "PBEWithSHA1AndRC4_40/ECB/NoPadding", + "PBEWithSHA1AndRC4_128", "PBEWithSHA1AndRC4_128/ECB/NoPadding", + "PBEWithHmacSHA1AndAES_128", + "PBEWithHmacSHA224AndAES_128", + "PBEWithHmacSHA256AndAES_128", + "PBEWithHmacSHA384AndAES_128", + "PBEWithHmacSHA512AndAES_128", + "PBEWithHmacSHA1AndAES_256", + "PBEWithHmacSHA224AndAES_256", + "PBEWithHmacSHA256AndAES_256", + "PBEWithHmacSHA384AndAES_256", + "PBEWithHmacSHA512AndAES_256", + "PBKDF2WithHmacSHA1", + "PBKDF2WithHmacSHA224", + "PBKDF2WithHmacSHA256", + "PBKDF2WithHmacSHA384", + "PBKDF2WithHmacSHA512" + }; + + private static final String PBEPASS = "Hush, it's supposed to be a secret!"; + + private static final int INPUT_LENGTH = 800; + private static final int[] OFFSETS = {0, 1, 2, 3}; + private static final int NUM_PAD_BYTES = 8; + private static final int PBKDF2_ADD_PAD_BYTES = 8; + + private static int OUTPUT_OFFSET; + + public static void main(String[] args) { + if (!(new PBESameBuffer().test(args, System.out))) { + throw new RuntimeException("Some PBE algorithm tests failed"); + } + } + + public boolean test(String[] args, PrintStream out) { + boolean result = true; + + Provider p = Security.getProvider("SunJCE"); + + for (int loop : OFFSETS) { + OUTPUT_OFFSET = loop; + + // generate input data + byte[] inputText = new byte[INPUT_LENGTH + NUM_PAD_BYTES + + OUTPUT_OFFSET * 2 + PBKDF2_ADD_PAD_BYTES]; + new Random().nextBytes(inputText); + + for (String algorithm : pbeAlgorithms) { + out.println("=> Testing algorithm " + algorithm + " and offset " + + OUTPUT_OFFSET + ":"); + + try { + // Initialize Cipher and key for this algorithm + PBEWrapper pbeCi = PBEWrapperCreator.createWrapper(p, + algorithm, + PBEPASS, + out); + + // Encrypt + if ((pbeCi != null) && (!pbeCi.execute(Cipher.ENCRYPT_MODE, + inputText, + OUTPUT_OFFSET * 2, + INPUT_LENGTH))) { + result = false; + } + + // PBKDF2 required 16 byte padding + int padLength = getPadLength(algorithm); + + // Decrypt + // Note: inputText is implicitly padded by the above encrypt + // operation so decrypt operation can safely proceed + if ((pbeCi != null) && (!pbeCi.execute(Cipher.DECRYPT_MODE, + inputText, + OUTPUT_OFFSET, + INPUT_LENGTH + padLength))) { + result = false; + } + } catch (Exception ex) { + ex.printStackTrace(out); + result = false; + } + } + } + + return result; + } + + /** + * Get the padding length for the given algorithm + * + * @param theAlgName algorithm name + * @return padding length for the given algorithm + */ + private int getPadLength(String theAlgName) { + if (theAlgName.toUpperCase().contains("PBKDF2")) { + return NUM_PAD_BYTES + PBKDF2_ADD_PAD_BYTES; + } + + if (theAlgName.toUpperCase().contains("AES")) { + return NUM_PAD_BYTES + PBKDF2_ADD_PAD_BYTES; + } + + return NUM_PAD_BYTES; + } +} diff --git a/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/PBEWrapper.java b/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/PBEWrapper.java new file mode 100644 index 0000000000000000000000000000000000000000..9e76584d6c92cd24369e77c62ed44220a3f2a820 --- /dev/null +++ b/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/PBEWrapper.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2012, 2014, 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. + * + * 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. + */ + +import java.io.PrintStream; +import java.util.Random; +import javax.crypto.Cipher; +import javax.crypto.SecretKey; + +/** + * PBEWrapper is the abstract class for all concrete PBE Cipher wrappers. A + * PBEWrapper object encapsulates the information and behavior needed to test if + * the multiple-part encryption/decryption is performing by expected way on the + * same byte buffer. + * + * @author Alexandr Fomin + * @author rhalade + */ +public abstract class PBEWrapper { + + protected final static int ITERATION_COUNT = 1000; + + protected final SecretKey key; + protected final Cipher ci; + protected final String algo; + protected final PrintStream out; + + public PBEWrapper(String pAlgo, SecretKey pKey, Cipher pCi, + PrintStream pOut ){ + this.algo = pAlgo; + this.key = pKey; + this.ci = pCi; + this.out = pOut; + } + + /** + * Abstract method need to be implemented in the subclasses. + * + * @param edMode Cipher mode - encrypt/decrypt + * @param inputText byte buffer to process + * @param offset offset in byte the inputText + * @param len length of byte to process in inputText + * @return true if cipher operation is successful, false otherwise + */ + public abstract boolean execute(int edMode, byte[] inputText, int offset, + int len); + + /** + * An utility method to prepare "salt" for following Secret Key generation. + * + * @param numberOfBytes number of bytes in salt + * @return randomly generated byte array + */ + protected static byte[] generateSalt(int numberOfBytes) { + byte[] salt = new byte[numberOfBytes]; + new Random().nextBytes(salt); + return salt; + } + + /** + * An utility method to check if two byte arrays are equal + * + * @param b1 first byte array + * @param off1 offset to compare from in b1 + * @param b2 second byte array + * @param off2 offset to compare from in b2 + * @param len length to compare + * @return true of arrays are equal, false otherwise + */ + protected boolean equalsBlock(byte[] b1, int off1, + byte[] b2, int off2, int len) { + for (int i = off1, j = off2, k = 0; k < len; i++, j++, k++) { + if (b1[i] != b2[j]) { + return false; + } + } + return true; + } +} diff --git a/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/PBEWrapperCreator.java b/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/PBEWrapperCreator.java new file mode 100644 index 0000000000000000000000000000000000000000..85a19c9d90f01a5e21c73969aede3d7d37eaec66 --- /dev/null +++ b/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/PBEWrapperCreator.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2012, 2014, 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. + * + * 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. + */ + +import java.security.Provider; +import java.io.PrintStream; + +/** + * An utility class to create PBEWrapper object for the TestCipherSameBuffer + * test. + * + * @author Alexander Fomin + */ +public class PBEWrapperCreator { + + private static final String PBKDF2 = "PBKDF2"; + private static final String AES = "AES"; + + /** + * Create PBEWrapper for the TestCipherSameBuffer test using given + * parameters. + * + * @param p security provider + * @param algo algorithms to test + * @param passwd a password phrase + * @param out print stream object + * @return PBEWrapper in accordance to requested algorithm + * @throws Exception all exception are thrown. + */ + public static PBEWrapper createWrapper(Provider p, String algo, + String passwd, PrintStream out) throws Exception { + if (algo.toUpperCase().contains(PBKDF2)) { + return new PBKDF2Wrapper(p, algo, passwd, out); + } else if (algo.toUpperCase().contains(AES)) { + return new AESPBEWrapper(p, algo, passwd, out); + } else { + return new PBECipherWrapper(p, algo, passwd, out); + } + } +} diff --git a/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/PBKDF2Wrapper.java b/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/PBKDF2Wrapper.java new file mode 100644 index 0000000000000000000000000000000000000000..6a2110d784148c3d26ee8464003ed21cf562a7c2 --- /dev/null +++ b/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/PBKDF2Wrapper.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2012, 2014, 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. + * + * 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. + */ + +import java.io.PrintStream; +import java.security.Provider; +import javax.crypto.Cipher; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.PBEKeySpec; +import javax.crypto.spec.SecretKeySpec; + +/** + * Wrapper class to test a given SecretKeyFactory.PBKDF2 algorithm. + * + * @author Alexander Fomin + */ +public class PBKDF2Wrapper extends PBEWrapper { + private static final String CIPHER_TANSFORMATION = "AES/CBC/PKCS5Padding"; + private static final int SALT_SIZE = 64; + private static final int PKDF2_DEFAULT_KEY_LEN = 128; + + private static volatile byte[] iv; + + /** + * PBKDF2Wrapper constructor. Instantiate Cipher using + * "AES/CBC/PKCS5Padding" transformation. Generate a secret key using given + * PKDF2 algorithms. + * + * @param p security Provider + * @param algo PKDF2 algorithm + * @param passwd password phrase + * @param out print stream + * @throws Exception all exceptions are thrown + */ + public PBKDF2Wrapper(Provider p, String algo, String passwd, + PrintStream out) throws Exception { + super(algo, + SecretKeyFactory.getInstance(algo, p).generateSecret( + new PBEKeySpec(passwd.toCharArray(), + generateSalt(SALT_SIZE), ITERATION_COUNT, PKDF2_DEFAULT_KEY_LEN)), + Cipher.getInstance(CIPHER_TANSFORMATION, p), out); + } + + /** + * Perform encryption/decryption operation (depending on the specified + * edMode) on the same byte buffer. Compare result with the result at an + * allocated buffer. If both results are equal - return true, otherwise + * return false. + * + * @param edMode specified mode + * @param inputText text to decrypt + * @param offset offset in the text + * @param len input length + * @return ture - test passed; false - test failed + */ + @Override + public boolean execute(int edMode, byte[] inputText, int offset, int len) { + int needBytesForResult = -1; + String KEY_ALGORITHM = "AES"; + + try { + // init Cipher + if (Cipher.ENCRYPT_MODE == edMode) { + ci.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getEncoded(), + KEY_ALGORITHM)); + iv = ci.getParameters().getParameterSpec(IvParameterSpec.class). + getIV(); + } else { + ci.init(Cipher.DECRYPT_MODE, + new SecretKeySpec(key.getEncoded(), KEY_ALGORITHM), + new IvParameterSpec(iv)); + } + + // First, generate the cipherText at an allocated buffer + byte[] outputText = ci.doFinal(inputText, offset, len); + + // Second, generate cipherText again at the same buffer of plainText + int myoff = offset / 2; + int off = ci.update(inputText, offset, len, inputText, myoff); + ci.doFinal(inputText, myoff + off); + + // Compare to see whether the two results are the same or not + return equalsBlock(inputText, myoff, outputText, 0, + outputText.length); + } catch (Exception ex) { + out.println("Catch unexpected exception within " + algo + + " " + edMode + ": " + ex.getMessage() + + ". getOutputSize()" + "returned " + needBytesForResult); + ex.printStackTrace(out); + + return false; + } + } +} diff --git a/test/com/sun/crypto/provider/Cipher/PBE/PBESealedObject.java b/test/com/sun/crypto/provider/Cipher/PBE/PBESealedObject.java new file mode 100644 index 0000000000000000000000000000000000000000..2420b9bc4a3ad6ca53cdef8d859503187ece220b --- /dev/null +++ b/test/com/sun/crypto/provider/Cipher/PBE/PBESealedObject.java @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2012, 2014, 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. + * + * 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. + */ + +import java.io.PrintStream; +import java.security.AlgorithmParameters; +import java.security.InvalidKeyException; +import java.security.Provider; +import java.security.Security; +import java.security.spec.AlgorithmParameterSpec; +import java.util.Arrays; +import java.util.Random; +import java.util.StringTokenizer; +import javax.crypto.Cipher; +import javax.crypto.SealedObject; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; +import javax.crypto.spec.PBEParameterSpec; + +/** + * @test + * @bug 8041781 + * @summary test if seal/unseal works correctly with PBE algorithms + * @author Yun Ke + * @author Bill Situ + * @author Alexander Fomin + * @run main PBESealedObject + */ +public class PBESealedObject { + + private static final String[] PBEAlgorithms = { + "pbeWithMD5ANDdes", + "PBEWithMD5AndDES/CBC/PKCS5Padding", + "PBEWithMD5AndTripleDES", + "PBEWithMD5AndTripleDES/CBC/PKCS5Padding", + "PBEwithSHA1AndDESede", + "PBEwithSHA1AndDESede/CBC/PKCS5Padding", + "PBEwithSHA1AndRC2_40", + "PBEwithSHA1Andrc2_40/CBC/PKCS5Padding", + "PBEWithSHA1AndRC2_128", + "PBEWithSHA1andRC2_128/CBC/PKCS5Padding", + "PBEWithSHA1AndRC4_40", + "PBEWithsha1AndRC4_40/ECB/NoPadding", + "PBEWithSHA1AndRC4_128", + "pbeWithSHA1AndRC4_128/ECB/NoPadding", + "PBEWithHmacSHA1AndAES_128", + "PBEWithHmacSHA224AndAES_128", + "PBEWithHmacSHA256AndAES_128", + "PBEWithHmacSHA384AndAES_128", + "PBEWithHmacSHA512AndAES_128", + "PBEWithHmacSHA1AndAES_256", + "PBEWithHmacSHA224AndAES_256", + "PBEWithHmacSHA256AndAES_256", + "PBEWithHmacSHA384AndAES_256", + "PBEWithHmacSHA512AndAES_256" + }; + + public static void main(String[] args) { + PBESealedObject test = new PBESealedObject(); + Provider sunjce = Security.getProvider("SunJCE"); + + if (!test.runAll(sunjce, System.out)) { + throw new RuntimeException("One or more tests have failed...."); + } + } + + public boolean runAll(Provider p, PrintStream out) { + boolean finalResult = true; + + for (String algorithm : PBEAlgorithms) { + out.println("Running test with " + algorithm + ":"); + try { + if (!runTest(p, algorithm, out)) { + finalResult = false; + out.println("STATUS: Failed"); + } else { + out.println("STATUS: Passed"); + } + } catch (Exception ex) { + finalResult = false; + ex.printStackTrace(out); + out.println("STATUS:Failed"); + } + } + + return finalResult; + } + + // Have a generic throws Exception as it can throw many different exceptions + public boolean runTest(Provider p, String algo, PrintStream out) + throws Exception { + + byte[] salt = new byte[8]; + int ITERATION_COUNT = 1000; + AlgorithmParameters pbeParams = null; + + String baseAlgo + = new StringTokenizer(algo, "/").nextToken().toUpperCase(); + boolean isAES = baseAlgo.contains("AES"); + + try { + // Initialization + Cipher ci = Cipher.getInstance(algo, p); + new Random().nextBytes(salt); + AlgorithmParameterSpec aps = new PBEParameterSpec(salt, + ITERATION_COUNT); + SecretKeyFactory skf = SecretKeyFactory.getInstance(baseAlgo, p); + SecretKey key = skf.generateSecret( + new PBEKeySpec("Secret Lover".toCharArray())); + + // Seal + if (isAES) { + ci.init(Cipher.ENCRYPT_MODE, key); + pbeParams = ci.getParameters(); + } else { + ci.init(Cipher.ENCRYPT_MODE, key, aps); + } + + SealedObject so = new SealedObject(key, ci); + + // Unseal and compare + if (isAES) { + ci.init(Cipher.DECRYPT_MODE, key, pbeParams); + } else { + ci.init(Cipher.DECRYPT_MODE, key, aps); + } + + SecretKey unsealedKey; + + unsealedKey = (SecretKey) so.getObject(ci); + if (!Arrays.equals(unsealedKey.getEncoded(), key.getEncoded())) { + return false; + } + + unsealedKey = (SecretKey) so.getObject(key); + if (!Arrays.equals(unsealedKey.getEncoded(), key.getEncoded())) { + return false; + } + + unsealedKey = (SecretKey) so.getObject(key, "SunJCE"); + return Arrays.equals(unsealedKey.getEncoded(), key.getEncoded()); + } catch (InvalidKeyException ex) { + if (baseAlgo.endsWith("TRIPLEDES") || baseAlgo.endsWith("AES_256")) { + out.println( + "Expected exception , keyStrength > 128 within" + algo); + return true; + } + + throw ex; + } + } + +} diff --git a/test/com/sun/crypto/provider/Cipher/PBE/PBKDF2Translate.java b/test/com/sun/crypto/provider/Cipher/PBE/PBKDF2Translate.java new file mode 100644 index 0000000000000000000000000000000000000000..36681591e46e06435b5677d7a21935719b701b4e --- /dev/null +++ b/test/com/sun/crypto/provider/Cipher/PBE/PBKDF2Translate.java @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2012, 2014, 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. + * + * 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. + */ + +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.spec.InvalidKeySpecException; +import java.util.Arrays; +import java.util.Random; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.interfaces.PBEKey; +import javax.crypto.spec.PBEKeySpec; + +/** + * @test + * @bug 8041781 + * @summary Verify if the SecretKeyFactory.translateKey() method works + * @author Alexander Fomin + * @run main PBKDF2Translate + */ +public class PBKDF2Translate { + + private static final String[] ALGO_TO_TEST = { + "PBKDF2WithHmacSHA1", + "PBKDF2WithHmacSHA224", + "PBKDF2WithHmacSHA256", + "PBKDF2WithHmacSHA384", + "PBKDF2WithHmacSHA512" + }; + + private static final String PASS_PHRASE = "some hidden string"; + private static final int ITERATION_COUNT = 1000; + private static final int KEY_SIZE = 128; + + private final String algoToTest; + private final byte[] salt = new byte[8]; + + public static void main(String[] args) throws Exception { + + boolean failed = false; + + for (String algo : ALGO_TO_TEST) { + + System.out.println("Testing " + algo + ":"); + PBKDF2Translate theTest = new PBKDF2Translate(algo); + + try { + if (!theTest.testMyOwnSecretKey() + || !theTest.generateAndTranslateKey() + || !theTest.translateSpoiledKey()) { + // we don't want to set failed to false + failed = true; + } + } catch (InvalidKeyException | NoSuchAlgorithmException | + InvalidKeySpecException e) { + e.printStackTrace(System.err); + failed = true; + } + } + + if (failed) { + throw new RuntimeException("One or more tests failed...."); + } + } + + public PBKDF2Translate(String algoToTest) { + this.algoToTest = algoToTest; + new Random().nextBytes(this.salt); + } + + /** + * The test case scenario implemented in the method: - derive PBKDF2 key + * using the given algorithm; - translate the key - check if the translated + * and original keys have the same key value. + * + * @return true if the test case passed; false - otherwise. + * @throws NoSuchAlgorithmException + * @throws InvalidKeySpecException + * @throws InvalidKeyException + */ + public boolean generateAndTranslateKey() throws NoSuchAlgorithmException, + InvalidKeySpecException, InvalidKeyException { + // derive PBKDF2 key + SecretKey key1 = getSecretKeyForPBKDF2(algoToTest); + + // translate key + SecretKeyFactory skf = SecretKeyFactory.getInstance(algoToTest); + SecretKey key2 = skf.translateKey(key1); + + // check if it still the same after translation + if (!Arrays.equals(key1.getEncoded(), key2.getEncoded())) { + System.err.println("generateAndTranslateKey test case failed: the " + + "key1 and key2 values in its primary encoding format are " + + "not the same for " + algoToTest + "algorithm."); + return false; + } + + return true; + } + + /** + * The test case scenario implemented in the method: - derive Key1 for the + * given PBKDF2 algorithm - create my own secret Key2 as an instance of a + * class implements PBEKey - translate Key2 - check if the key value of the + * translated key and Key1 are the same. + * + * @return true if the test case passed; false - otherwise. + * @throws NoSuchAlgorithmException + * @throws InvalidKeySpecException + * @throws InvalidKeyException + */ + public boolean testMyOwnSecretKey() + throws NoSuchAlgorithmException, InvalidKeySpecException, + InvalidKeyException { + SecretKey key1 = getSecretKeyForPBKDF2(algoToTest); + SecretKey key2 = getMyOwnSecretKey(); + + // Is it actually the same? + if (!Arrays.equals(key1.getEncoded(), key2.getEncoded())) { + System.err.println("We shouldn't be here. The key1 and key2 values " + + "in its primary encoding format have to be the same!"); + return false; + } + + // Translate key + SecretKeyFactory skf = SecretKeyFactory.getInstance(algoToTest); + SecretKey key3 = skf.translateKey(key2); + + // Check if it still the same after translation + if (!Arrays.equals(key1.getEncoded(), key3.getEncoded())) { + System.err.println("testMyOwnSecretKey test case failed: the key1 " + + "and key3 values in its primary encoding format are not " + + "the same for " + algoToTest + "algorithm."); + return false; + } + + return true; + } + + /** + * The test case scenario implemented in the method: - create my own secret + * Key2 as an instance of a class implements PBEKey - spoil the key (set + * iteration count to 0, for example) - try to translate key - + * InvalidKeyException is expected. + * + * @return true if InvalidKeyException occurred; false - otherwise. + * @throws NoSuchAlgorithmException + * @throws InvalidKeySpecException + */ + public boolean translateSpoiledKey() throws NoSuchAlgorithmException, + InvalidKeySpecException { + // derive the key + SecretKey key1 = getMyOwnSecretKey(); + + // spoil the key + ((MyPBKDF2SecretKey) key1).spoil(); + + // translate key + SecretKeyFactory skf = SecretKeyFactory.getInstance(algoToTest); + try { + SecretKey key2 = skf.translateKey(key1); + } catch (InvalidKeyException ike) { + // this is expected + return true; + } + + return false; + } + + /** + * Generate a PBKDF2 secret key using given algorithm. + * + * @param algoToDeriveKey PBKDF2 algorithm + * @return PBKDF2 secret key + * @throws NoSuchAlgorithmException + * @throws InvalidKeySpecException + */ + private SecretKey getSecretKeyForPBKDF2(String algoToDeriveKey) + throws NoSuchAlgorithmException, InvalidKeySpecException { + SecretKeyFactory skf = SecretKeyFactory.getInstance(algoToDeriveKey); + + PBEKeySpec spec = new PBEKeySpec(PASS_PHRASE.toCharArray(), + this.salt, ITERATION_COUNT, KEY_SIZE); + + return skf.generateSecret(spec); + } + + /** + * Generate a secrete key as an instance of a class implements PBEKey. + * + * @return secrete key + * @throws InvalidKeySpecException + * @throws NoSuchAlgorithmException + */ + private SecretKey getMyOwnSecretKey() throws InvalidKeySpecException, + NoSuchAlgorithmException { + return new MyPBKDF2SecretKey(PASS_PHRASE, this.algoToTest, this.salt, + ITERATION_COUNT, KEY_SIZE); + } +} + +/** + * An utility class to check the SecretKeyFactory.translateKey() method. + */ +class MyPBKDF2SecretKey implements PBEKey { + + private final byte[] key; + private final byte[] salt; + private final String algorithm; + private final int keySize, keyLength; + private int itereationCount; + private final String pass; + + @Override + public String getAlgorithm() { + return algorithm; + } + + @Override + public String getFormat() { + return "RAW"; + } + + @Override + public byte[] getEncoded() { + byte[] copy = new byte[keyLength]; + System.arraycopy(this.key, 0, copy, 0, keyLength); + return copy; + } + + /** + * The key is generating by SecretKeyFactory and its value just copying in + * the key field of MySecretKey class. So, this is real key derived using + * the given algorithm. + * + * @param passPhrase some string intended to be a password + * @param algo PBKDF2 algorithm + * @param salt slat for PBKDF2 + * @param iterationCount iteration count + * @param keySize key size in bits + * @throws InvalidKeySpecException + * @throws NoSuchAlgorithmException + */ + public MyPBKDF2SecretKey(String passPhrase, String algo, byte[] salt, + int iterationCount, int keySize) + throws InvalidKeySpecException, NoSuchAlgorithmException { + this.algorithm = algo; + this.salt = salt; + this.itereationCount = iterationCount; + this.keySize = keySize; + this.pass = passPhrase; + + PBEKeySpec spec = new PBEKeySpec(passPhrase.toCharArray(), + this.salt, iterationCount, this.keySize); + + SecretKeyFactory keyFactory + = SecretKeyFactory.getInstance(algo); + + SecretKey realKey = keyFactory.generateSecret(spec); + + this.keyLength = realKey.getEncoded().length; + + this.key = new byte[this.keyLength]; + System.arraycopy(realKey.getEncoded(), 0, this.key, 0, + this.keyLength); + } + + @Override + public int getIterationCount() { + return itereationCount; + } + + @Override + public byte[] getSalt() { + return salt; + } + + @Override + public char[] getPassword() { + return this.pass.toCharArray(); + } + + /** + * Spoil the generated key (before translation) to cause an + * InvalidKeyException + */ + public void spoil() { + this.itereationCount = -1; + } + +} diff --git a/test/com/sun/crypto/provider/Cipher/PBE/PBMacBuffer.java b/test/com/sun/crypto/provider/Cipher/PBE/PBMacBuffer.java new file mode 100644 index 0000000000000000000000000000000000000000..fc0256e5de9a2aba41c7d92e9d2a345319c67251 --- /dev/null +++ b/test/com/sun/crypto/provider/Cipher/PBE/PBMacBuffer.java @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2012, 2014, 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. + * + * 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. + */ + +import java.nio.ByteBuffer; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.spec.InvalidKeySpecException; +import java.util.Random; +import javax.crypto.Mac; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; + +/** + * @test + * @bug 8041787 + * @summary verify that Mac.update works with different size ByteBuffer + * @author Alexander Fomin + * @run main PBMacBuffer + */ +public class PBMacBuffer { + + private final int LARGE_SIZE = 500000; + + public static void main(String[] args) { + String[] PBMAC1Algorithms = { + "HmacPBESHA1", + "PBEWithHmacSHA1", + "PBEWithHmacSHA224", + "PBEWithHmacSHA256", + "PBEWithHmacSHA384", + "PBEWithHmacSHA512" + }; + + String[] PBKDF2Algorithms = { + "PBKDF2WithHmacSHA1", + "PBKDF2WithHmacSHA224", + "PBKDF2WithHmacSHA256", + "PBKDF2WithHmacSHA384", + "PBKDF2WithHmacSHA512" + }; + + PBMacBuffer testRunner = new PBMacBuffer(); + boolean failed = false; + + for (String thePBMacAlgo : PBMAC1Algorithms) { + + for (String thePBKDF2Algo : PBKDF2Algorithms) { + + System.out.println("Running test with " + thePBMacAlgo + + " and " + thePBKDF2Algo + ":"); + try { + if (!testRunner.doTest(thePBMacAlgo, thePBKDF2Algo)) { + failed = true; + } + } catch (NoSuchAlgorithmException | InvalidKeyException | + InvalidKeySpecException e) { + failed = true; + e.printStackTrace(System.out); + System.out.println("Test FAILED."); + } + } + } + + if (failed) { + throw new RuntimeException("One or more tests failed...."); + } + } + + /** + * Tests Mac.update(ByteBuffer input) method. Three test cases are + * performed: - large ByteBuffer test case to test if the update() method + * process a large ByteBuffer correctly; - empty ByteBuffer test case to + * test if the update() method process an empty ByteBuffer correctly; - NULL + * ByteBuffer test case to test if the update() method throws expected + * IllegalArgumentException exception. + * + * @param theMacAlgo PBMAC algorithm to test + * @param thePBKDF2Algo PBKDF2 algorithm to test + * @return true - test passed; false - otherwise. + * @throws NoSuchAlgorithmException + * @throws InvalidKeyException + * @throws InvalidKeySpecException + * @see javax.crypto.Mac + */ + protected boolean doTest(String theMacAlgo, String thePBKDF2Algo) + throws NoSuchAlgorithmException, InvalidKeyException, + InvalidKeySpecException { + // obtain a SecretKey using PBKDF2 + SecretKey key = getSecretKey(thePBKDF2Algo); + + // Instantiate Mac object and init it with a SecretKey + Mac theMac = Mac.getInstance(theMacAlgo); + theMac.init(key); + + // Do large ByteBuffer test case + if (!largeByteBufferTest(theMac)) { + System.out.println("Large ByteBuffer test case failed."); + return false; + } + + // Do empty ByteBuffer test case + if (!emptyByteBufferTest(theMac)) { + System.out.println("Empty ByteBuffer test case failed."); + return false; + } + + // Do null ByteBuffer test case + if (!nullByteBufferTest(theMac)) { + System.out.println("NULL ByteBuffer test case failed."); + return false; + } + + return true; + } + + /** + * Large ByteBuffer test case. Generate random ByteBuffer of LARGE_SIZE + * size. Performs MAC operation with the given Mac object (theMac + * parameter).Verifies the assertion "Upon return, the buffer's position + * will be equal to its limit; its limit will not have changed". + * + * @param theMac MAC object to test. + * @return true - test case passed; false - otherwise; + */ + protected boolean largeByteBufferTest(Mac theMac) { + ByteBuffer buf = generateRandomByteBuffer(LARGE_SIZE); + int limitBefore = buf.limit(); + + theMac.update(buf); + theMac.doFinal(); + + int limitAfter = buf.limit(); + int positonAfter = buf.position(); + + if (limitAfter != limitBefore) { + System.out.println("FAIL: Buffer's limit has been chenged."); + return false; + } + + if (positonAfter != limitAfter) { + System.out.println("FAIL: " + + "Buffer's position isn't equal to its limit"); + return false; + } + + return true; + } + + /** + * Empty ByteBuffer test case. Generates an empty ByteBuffer. Perform MAC + * operation. No exceptions are expected. + * + * @param theMac + * @return true - test case pass; exception otherwise + */ + protected boolean emptyByteBufferTest(Mac theMac) { + ByteBuffer buf = generateRandomByteBuffer(0); + theMac.update(buf); + theMac.doFinal(); + return true; + } + + /** + * NULL ByteBuffer test case. Pass NULL ByteBuffer to Mac.update(ByteBuffer + * buffer) method. An IllegalArgumentException expected. + * + * @param theMac Mac object to test. + * @return true - test case pass; false - otherwise. + */ + protected boolean nullByteBufferTest(Mac theMac) { + try { + ByteBuffer buf = null; + theMac.update(buf); + theMac.doFinal(); + } catch (IllegalArgumentException e) { + // expected exception has been thrown + return true; + } + + System.out.println("FAIL: " + + "IllegalArgumentException hasn't been thrown as expected"); + + return false; + } + + /** + * Get SecretKey for the given PBKDF2 algorithm. + * + * @param thePBKDF2Algorithm - PBKDF2 algorithm + * @return SecretKey according to thePBKDF2Algorithm + * @throws NoSuchAlgorithmException + * @throws InvalidKeySpecException + */ + protected SecretKey getSecretKey(String thePBKDF2Algorithm) + throws NoSuchAlgorithmException, InvalidKeySpecException { + // Prepare salt + byte[] salt = new byte[64]; // PKCS #5 v2.1 recommendation + new SecureRandom().nextBytes(salt); + + // Generate secret key + PBEKeySpec pbeKeySpec = new PBEKeySpec( + "A #pwd# implied to be hidden!".toCharArray(), + salt, 1000, 128); + SecretKeyFactory keyFactory + = SecretKeyFactory.getInstance(thePBKDF2Algorithm); + return keyFactory.generateSecret(pbeKeySpec); + } + + /** + * An utility method to generate a random ByteBuffer of the requested size. + * + * @param size size of the ByteBuffer. + * @return ByteBuffer populated random data; + */ + private ByteBuffer generateRandomByteBuffer(int size) { + // generate randome byte array + byte[] data = new byte[size]; + new Random().nextBytes(data); + + // create ByteBuffer + ByteBuffer bb = ByteBuffer.wrap(data); + + return bb; + } + +} diff --git a/test/com/sun/crypto/provider/Cipher/PBE/PBMacDoFinalVsUpdate.java b/test/com/sun/crypto/provider/Cipher/PBE/PBMacDoFinalVsUpdate.java new file mode 100644 index 0000000000000000000000000000000000000000..1f67f16376161d6536e8c5fe166046ce41f3205d --- /dev/null +++ b/test/com/sun/crypto/provider/Cipher/PBE/PBMacDoFinalVsUpdate.java @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2012, 2014, 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. + * + * 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. + */ + +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.spec.InvalidKeySpecException; +import javax.crypto.Mac; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; + +/** + * @test + * @bug 8041787 + * @summary Check if doFinal and update operation result in same PBMac + * @author Alexander Fomin + * @run main PBMacDoFinalVsUpdate + */ +public class PBMacDoFinalVsUpdate { + + public static void main(String[] args) { + String[] PBMAC1Algorithms = { + "HmacPBESHA1", + "PBEWithHmacSHA1", + "PBEWithHmacSHA224", + "PBEWithHmacSHA256", + "PBEWithHmacSHA384", + "PBEWithHmacSHA512" + }; + + String[] PBKDF2Algorithms = { + "PBKDF2WithHmacSHA1", + "PBKDF2WithHmacSHA224", + "PBKDF2WithHmacSHA256", + "PBKDF2WithHmacSHA384", + "PBKDF2WithHmacSHA512" + }; + + PBMacDoFinalVsUpdate testRunner = new PBMacDoFinalVsUpdate(); + boolean failed = false; + + for (String thePBMacAlgo : PBMAC1Algorithms) { + + for (String thePBKDF2Algo : PBKDF2Algorithms) { + + System.out.println("Running test with " + thePBMacAlgo + + " and " + thePBKDF2Algo + ":"); + try { + if (!testRunner.doTest(thePBMacAlgo, thePBKDF2Algo)) { + failed = true; + } + } catch (NoSuchAlgorithmException | InvalidKeyException | + InvalidKeySpecException e) { + failed = true; + e.printStackTrace(System.out); + System.out.println("Test FAILED."); + } + } + } + + if (failed) { + throw new RuntimeException("One or more tests failed...."); + } + } + + /** + * Uses a random generator to initialize a message, instantiate a Mac object + * according to the given PBMAC1 algorithm, initialize the object with a + * SecretKey derived using PBKDF2 algorithm (see PKCS #5 v21, chapter 7.1), + * feed the message into the Mac object all at once and get the output MAC + * as result1. Reset the Mac object, chop the message into three pieces, + * feed into the Mac object sequentially, and get the output MAC as result2. + * Finally, compare result1 and result2 and see if they are the same. + * + * @param theMacAlgo PBMAC algorithm to test + * @param thePBKDF2Algo PBKDF2 algorithm to test + * @return true - the test is passed; false - otherwise. + * @throws NoSuchAlgorithmException + * @throws InvalidKeyException + * @throws InvalidKeySpecException + */ + protected boolean doTest(String theMacAlgo, String thePBKDF2Algo) + throws NoSuchAlgorithmException, InvalidKeyException, + InvalidKeySpecException { + int OFFSET = 5; + + // Some message for which a MAC result will be calculated + byte[] plain = new byte[25]; + new SecureRandom().nextBytes(plain); + + // Form tail - is one of the three pieces + byte[] tail = new byte[plain.length - OFFSET]; + System.arraycopy(plain, OFFSET, tail, 0, tail.length); + + // Obtain a SecretKey using PBKDF2 + SecretKey key = getSecretKey(thePBKDF2Algo); + + // Instantiate Mac object and init it with a SecretKey and calc result1 + Mac theMac = Mac.getInstance(theMacAlgo); + theMac.init(key); + byte[] result1 = theMac.doFinal(plain); + + if (!isMacLengthExpected(theMacAlgo, result1.length)) { + return false; + } + + // Reset Mac and calculate result2 + theMac.reset(); + theMac.update(plain[0]); + theMac.update(plain, 1, OFFSET - 1); + byte[] result2 = theMac.doFinal(tail); + + // Return result + if (!java.util.Arrays.equals(result1, result2)) { + System.out.println("result1 and result2 are not the same:"); + System.out.println("result1: " + dumpByteArray(result1)); + System.out.println("result2: " + dumpByteArray(result2)); + return false; + } else { + System.out.println("Resulted MAC with update and doFinal is same"); + } + + return true; + } + + /** + * Get SecretKey for the given PBKDF2 algorithm. + * + * @param thePBKDF2Algorithm - PBKDF2 algorithm + * @return SecretKey according to thePBKDF2Algorithm + * @throws NoSuchAlgorithmException + * @throws InvalidKeySpecException + */ + protected SecretKey getSecretKey(String thePBKDF2Algorithm) + throws NoSuchAlgorithmException, InvalidKeySpecException { + // Prepare salt + byte[] salt = new byte[64]; // PKCS #5 v2.1 recommendation + new SecureRandom().nextBytes(salt); + + // Generate secret key + PBEKeySpec pbeKeySpec = new PBEKeySpec( + "A #pwd# implied to be hidden!".toCharArray(), + salt, 1000, 128); + SecretKeyFactory keyFactory + = SecretKeyFactory.getInstance(thePBKDF2Algorithm); + return keyFactory.generateSecret(pbeKeySpec); + } + + /** + * Check if the lengthToCheck is expected length for the given MACAlgo. + * + * @param MACAlgo PBMAC algorithm + * @param lengthToCheck the length of MAC need to check + * @return true - lengthToCheck is expected length for the MACAlgo; false - + * otherwise. + */ + protected boolean isMacLengthExpected(String MACAlgo, int lengthToCheck) { + java.util.regex.Pattern p = java.util.regex.Pattern.compile("(\\d+)", + java.util.regex.Pattern.CASE_INSENSITIVE); + java.util.regex.Matcher m = p.matcher(MACAlgo); + int val = 0; + + if (m.find()) { + val = Integer.parseInt(m.group(1)); + } + + // HmacPBESHA1 should return MAC 20 byte length + if ((val == 1) && (lengthToCheck == 20)) { + return true; + } + + return (val / 8) == lengthToCheck; + } + + /** + * An utility method to dump a byte array for debug output. + * + * @param theByteArray the byte array to dump + * @return string representation of the theByteArray in Hex. + */ + protected String dumpByteArray(byte[] theByteArray) { + StringBuilder buf = new StringBuilder(); + + for (byte b : theByteArray) { + buf.append(Integer.toHexString(b)); + } + + return buf.toString(); + } + +} diff --git a/test/com/sun/crypto/provider/Cipher/PBE/TestCipherKeyWrapperPBEKey.java b/test/com/sun/crypto/provider/Cipher/PBE/TestCipherKeyWrapperPBEKey.java new file mode 100644 index 0000000000000000000000000000000000000000..cc237d0549da316c5761b435bd1518080eff3d7e --- /dev/null +++ b/test/com/sun/crypto/provider/Cipher/PBE/TestCipherKeyWrapperPBEKey.java @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2012, 2014, 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. + * + * 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. + */ + +import java.io.PrintStream; +import java.security.AlgorithmParameters; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.Provider; +import java.security.Security; +import java.security.spec.AlgorithmParameterSpec; +import java.util.Arrays; +import java.util.Random; +import java.util.StringTokenizer; +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; +import javax.crypto.spec.PBEParameterSpec; + +/** + * @test + * @bug 8041781 + * @summary Test to see if key wrapper works correctly with PBEKey + * @author Yu-Ching (Valerie) PENG + * @author Bill Situ + * @author Yun Ke + * @run main TestCipherKeyWrapperPBEKey + */ +public class TestCipherKeyWrapperPBEKey { + + private static final String[] PBEAlgorithms = { + "pbeWithMD5ANDdes", + "PBEWithMD5AndDES/CBC/PKCS5Padding", + "PBEWithMD5AndTripleDES", + "PBEWithMD5AndTripleDES/CBC/PKCS5Padding", + "PBEwithSHA1AndDESede", + "PBEwithSHA1AndDESede/CBC/PKCS5Padding", + "PBEwithSHA1AndRC2_40", + "PBEwithSHA1Andrc2_40/CBC/PKCS5Padding", + "PBEWithSHA1AndRC2_128", + "PBEWithSHA1andRC2_128/CBC/PKCS5Padding", + "PBEWithSHA1AndRC4_40", + "PBEWithsha1AndRC4_40/ECB/NoPadding", + "PBEWithSHA1AndRC4_128", + "pbeWithSHA1AndRC4_128/ECB/NoPadding", + "PBEWithHmacSHA1AndAES_128", + "PBEWithHmacSHA224AndAES_128", + "PBEWithHmacSHA256AndAES_128", + "PBEWithHmacSHA384AndAES_128", + "PBEWithHmacSHA512AndAES_128", + "PBEWithHmacSHA1AndAES_256", + "PBEWithHmacSHA224AndAES_256", + "PBEWithHmacSHA256AndAES_256", + "PBEWithHmacSHA384AndAES_256", + "PBEWithHmacSHA512AndAES_256" + }; + + public static void main(String[] args) { + + TestCipherKeyWrapperPBEKey test = new TestCipherKeyWrapperPBEKey(); + Provider sunjce = Security.getProvider("SunJCE"); + + if (!test.runAll(sunjce, System.out)) { + throw new RuntimeException("One or more tests have failed...."); + } + } + + public boolean runAll(Provider p, PrintStream out) { + boolean finalResult = true; + + for (String algorithm : PBEAlgorithms) { + out.println("Running test with " + algorithm + ":"); + try { + if (!runTest(p, algorithm, out)) { + finalResult = false; + out.println("STATUS: Failed"); + } else { + out.println("STATUS: Passed"); + } + } catch (Exception ex) { + finalResult = false; + ex.printStackTrace(out); + out.println("STATUS:Failed"); + } + } + + return finalResult; + } + + // Have a generic throws Exception as it can throw many different exceptions + public boolean runTest(Provider p, String algo, PrintStream out) + throws Exception { + + byte[] salt = new byte[8]; + int ITERATION_COUNT = 1000; + AlgorithmParameters pbeParams = null; + + String baseAlgo + = new StringTokenizer(algo, "/").nextToken().toUpperCase(); + boolean isAES = baseAlgo.contains("AES"); + + try { + // Initialization + new Random().nextBytes(salt); + AlgorithmParameterSpec aps = new PBEParameterSpec(salt, + ITERATION_COUNT); + SecretKeyFactory skf = SecretKeyFactory.getInstance(baseAlgo, p); + SecretKey key = skf.generateSecret(new PBEKeySpec( + "Secret Key".toCharArray())); + Cipher ci = Cipher.getInstance(algo); + + if (isAES) { + ci.init(Cipher.WRAP_MODE, key); + pbeParams = ci.getParameters(); + } else { + ci.init(Cipher.WRAP_MODE, key, aps); + } + + byte[] keyWrapper = ci.wrap(key); + if (isAES) { + ci.init(Cipher.UNWRAP_MODE, key, pbeParams); + } else { + ci.init(Cipher.UNWRAP_MODE, key, aps); + } + + Key unwrappedKey = ci.unwrap(keyWrapper, algo, Cipher.SECRET_KEY); + + if (baseAlgo.endsWith("TRIPLEDES") + || baseAlgo.endsWith("AES_256")) { + out.print( + "InvalidKeyException not thrown when keyStrength > 128"); + return false; + } + + return (Arrays.equals(key.getEncoded(), unwrappedKey.getEncoded())); + + } catch (InvalidKeyException ex) { + + if ((baseAlgo.endsWith("TRIPLEDES") + || baseAlgo.endsWith("AES_256"))) { + out.println("Expected InvalidKeyException, keyStrength > 128"); + return true; + } else { + throw ex; + } + } + } +} diff --git a/test/com/sun/crypto/provider/Cipher/PBE/TestCipherPBECons.java b/test/com/sun/crypto/provider/Cipher/PBE/TestCipherPBECons.java new file mode 100644 index 0000000000000000000000000000000000000000..c42952342e042abeb90b4b69c7e07c94991c88e3 --- /dev/null +++ b/test/com/sun/crypto/provider/Cipher/PBE/TestCipherPBECons.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2012, 2014, 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. + * + * 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. + */ + +import java.io.PrintStream; +import java.security.NoSuchAlgorithmException; +import java.security.Provider; +import java.security.Security; +import javax.crypto.Cipher; +import javax.crypto.NoSuchPaddingException; + +/** + * @test + * @bug 8041787 + * @summary Verify that for PBEWithMD5AndDES cipher, only CBC mode and + * PKCS#5Padding is allowed + * @author Yun Ke + * @author Bill Situ + * @author Yu-Ching (Valerie) PENG + * @run main TestCipherKeyWrapperPBEKey + */ +public class TestCipherPBECons { + + private static final String[] PBEAlgorithms = {"pbeWithMD5ANDdes", + "PBEWithMD5AndTripleDES"}; + private static final String[] cipherModes = {"ECb", "cbC", "cFB", "Cfb32", + "OfB", "oFb64", "pCbC"}; + private static final String[] cipherPaddings = {"Pkcs5Padding", "NoPaDDing"}; + + public static void main(String[] args) { + TestCipherPBECons test = new TestCipherPBECons(); + Provider sunjce = Security.getProvider("SunJCE"); + + if (!test.runAll(sunjce, System.out)) { + throw new RuntimeException("One or more tests have failed...."); + } + } + + public boolean runAll(Provider p, PrintStream out) { + boolean finalResult = true; + + for (String algorithm : PBEAlgorithms) { + for (String mode : cipherModes) { + for (String padding : cipherPaddings) { + out.println("Running test with " + algorithm + + "/" + mode + "/" + padding); + try { + if (!runTest(p, algorithm, mode, padding, out)) { + finalResult = false; + out.println("STATUS: Failed"); + } else { + out.println("STATUS: Passed"); + } + } catch (Exception ex) { + finalResult = false; + ex.printStackTrace(out); + out.println("STATUS:Failed"); + } + } + } + } + + return finalResult; + } + + public boolean runTest(Provider p, String algo, String mo, String pad, + PrintStream out) throws Exception { + try { + // Initialization + Cipher ci = Cipher.getInstance(algo + "/" + mo + "/" + pad, p); + + // No exception thrown, must be of the right mode and right + // padding scheme + return (mo.equalsIgnoreCase("CBC")) + && (pad.equalsIgnoreCase("PKCS5Padding")); + } catch (NoSuchAlgorithmException ex) { + if (p.getName().compareTo("SunJCE") == 0) { + if (!(mo.equalsIgnoreCase("CBC") + && pad.equalsIgnoreCase("PKCS5Padding"))) { + out.println("NoSuchAlgorithmException is as expected"); + return true; + } + } + + out.println("Caught exception: " + ex.getMessage()); + throw ex; + } catch (NoSuchPaddingException ex) { + if (mo.equalsIgnoreCase("CBC") + && pad.equalsIgnoreCase("NoPadding")) { + out.println("NoSuchPaddingException is as expected"); + return true; + } else { + out.println("Caught unexpected exception: " + ex.getMessage()); + return false; + } + } + } +} diff --git a/test/com/sun/crypto/provider/KeyAgreement/SameDHKeyStressTest.java b/test/com/sun/crypto/provider/KeyAgreement/SameDHKeyStressTest.java new file mode 100644 index 0000000000000000000000000000000000000000..f0067da5439b38efbc92f910656242eecd6ab181 --- /dev/null +++ b/test/com/sun/crypto/provider/KeyAgreement/SameDHKeyStressTest.java @@ -0,0 +1,169 @@ +/* + * Copyright (c) 1999, 2014, 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. + * + * 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. + */ + +/* + * @test + * @bug 8048819 + * @summary This test stressful verifies the assertion of "The secret keys generated + * by all involved parties should be the same." for javax.crypto.KeyAgreement + * @run main SameDHKeyStressTest + */ +import java.security.AlgorithmParameterGenerator; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.spec.AlgorithmParameterSpec; +import java.util.Arrays; +import javax.crypto.KeyAgreement; +import javax.crypto.SecretKey; +import javax.crypto.spec.DHGenParameterSpec; +import javax.crypto.spec.DHParameterSpec; + +public class SameDHKeyStressTest { + + static final String[] ALGORITHMS = {"DH", "DiffieHellman", "dh", "diffieHELLMAN"}; + static final String[] SECRET_ALOGRITHMS = {"DES", "DESede", "blowfish"}; + static final int[] NUMBER_OF_PARTIES = {2, 3, 4}; + static final String[] PA_NAMES = {"Alice", "Bob", "Carol", "David"}; + + public static void main(String args[]) { + int failedCnt = 0; + StringBuilder failedList = new StringBuilder("Failed List:"); + + for (String algorithm : ALGORITHMS) { + for (int numOfParties : NUMBER_OF_PARTIES) { + for (String secretAlgorithm : SECRET_ALOGRITHMS) { + if (!runTest(algorithm, numOfParties, secretAlgorithm)) { + failedCnt++; + failedList.append("\n Altorightm = ").append(algorithm). + append(" Number of Parties = ").append(numOfParties). + append(" Secret Algorithm = ").append(secretAlgorithm); + } + } + } + } //end of for loop + + if (failedCnt > 0) { + System.out.println(failedList); + throw new RuntimeException("SameDHKeyStressTest Failed"); + } + } + + public static boolean runTest(String algo, int numParties, String secretAlgo) { + KAParticipant[] parties = new KAParticipant[numParties]; + Key[] keyArchives = new Key[numParties]; + try { + // generate AlogirhtmParameterSpec + AlgorithmParameterGenerator apg = AlgorithmParameterGenerator.getInstance("DH","SunJCE"); + AlgorithmParameterSpec aps = new DHGenParameterSpec(512, 64); + apg.init(aps); + DHParameterSpec spec = apg.generateParameters(). + getParameterSpec(DHParameterSpec.class); + + //initilize all KeyAgreement participants + for (int i = 0; i < numParties; i++) { + parties[i] = new KAParticipant(PA_NAMES[i], algo); + parties[i].initialize(spec); + keyArchives[i] = parties[i].getPublicKey(); + } + + // Do all phases in the KeyAgreement for all participants + Key[] keyBuffer = new Key[numParties]; + boolean lastPhase = false; + for (int j = 0; j < numParties - 1; j++) { + if (j == numParties - 2) { + lastPhase = true; + } + for (int k = 0; k < numParties; k++) { + if (k == numParties - 1) { + keyBuffer[k] = parties[k].doPhase(keyArchives[0], lastPhase); + } else { + keyBuffer[k] = parties[k].doPhase(keyArchives[k + 1], lastPhase); + } + } + System.arraycopy(keyBuffer, 0, keyArchives, 0, numParties); + } + + //Comparison: The secret keys generated by all involved parties should be the same + SecretKey[] sKeys = new SecretKey[numParties]; + for (int n = 0; n < numParties; n++) { + sKeys[n] = parties[n].generateSecret(secretAlgo); + } + for (int q = 0; q < numParties - 1; q++) { + if (!Arrays.equals(sKeys[q].getEncoded(), sKeys[q + 1].getEncoded())) { + return false; + } + } + return true; + } catch (Exception ex) { + ex.printStackTrace(); + return false; + } + + } + +} + +class KAParticipant { + + private String name = null; + private String algorithm = null; + private KeyPairGenerator keyGen = null; + private KeyPair keys = null; + private KeyAgreement ka = null; + + public KAParticipant(String pName, String algo) throws NoSuchAlgorithmException, NoSuchProviderException { + name = pName; + algorithm = algo; + keyGen = KeyPairGenerator.getInstance(algo,"SunJCE"); + ka = KeyAgreement.getInstance(algo,"SunJCE"); + } + + public void initialize(AlgorithmParameterSpec spec) throws InvalidAlgorithmParameterException, InvalidKeyException { + keyGen.initialize(spec); + keys = keyGen.generateKeyPair(); + ka.init(keys.getPrivate()); + } + + public Key doPhase(Key key, boolean lastPhase) throws InvalidKeyException { + return ka.doPhase(key, lastPhase); + } + + public Key getPublicKey() { + return keys.getPublic(); + } + + public byte[] generateSecret() { + return ka.generateSecret(); + } + + public SecretKey generateSecret(String algo) throws java.lang.IllegalStateException, + java.security.NoSuchAlgorithmException, + java.security.InvalidKeyException { + return ka.generateSecret(algo); + } +} diff --git a/test/com/sun/crypto/provider/Mac/EmptyByteBufferTest.java b/test/com/sun/crypto/provider/Mac/EmptyByteBufferTest.java new file mode 100644 index 0000000000000000000000000000000000000000..9b1dd1cb3736d871deefc32d8bfc272e263a6c79 --- /dev/null +++ b/test/com/sun/crypto/provider/Mac/EmptyByteBufferTest.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 1998, 2014, 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. + * + * 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. + */ + +import java.nio.ByteBuffer; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import javax.crypto.Mac; +import javax.crypto.SecretKey; + +/** + * @test + * @bug 8048603 + * @summary Checks if MAC algorithms work fine with empty buffer + * @author Alexander Fomin + * @build Utils + * @run main EmptyByteBufferTest + */ +public class EmptyByteBufferTest implements MacTest { + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + Utils.runTests(new EmptyByteBufferTest()); + } + + @Override + public void doTest(String alg) throws NoSuchAlgorithmException, + InvalidKeyException, NoSuchProviderException { + SecretKey key = Utils.getSecretKeySpec(); + + // instantiate Mac object and init it with a SecretKey + Mac mac = Mac.getInstance(alg, "SunJCE"); + mac.init(key); + + // prepare buffer + byte[] data = new byte[0]; + ByteBuffer buf = ByteBuffer.wrap(data); + + mac.update(buf); + mac.doFinal(); + } + +} diff --git a/test/com/sun/crypto/provider/Mac/LargeByteBufferTest.java b/test/com/sun/crypto/provider/Mac/LargeByteBufferTest.java new file mode 100644 index 0000000000000000000000000000000000000000..f294b67743b9a4f8133fb54aa64adca05e98ba49 --- /dev/null +++ b/test/com/sun/crypto/provider/Mac/LargeByteBufferTest.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 1998, 2014, 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. + * + * 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. + */ + +import java.nio.ByteBuffer; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import javax.crypto.Mac; +import javax.crypto.SecretKey; + +/** + * @test + * @bug 8048603 + * @summary Checks if PBE algorithms work fine with large buffer + * @author Alexander Fomin + * @build Utils + * @run main LargeByteBufferTest + */ +public class LargeByteBufferTest implements MacTest { + + private static final int BUFFER_SIZE = 65535; + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + Utils.runTests(new LargeByteBufferTest()); + } + + @Override + public void doTest(String alg) throws NoSuchAlgorithmException, + InvalidKeyException, NoSuchProviderException { + SecretKey key = Utils.getSecretKeySpec(); + + // instantiate Mac object and init it with a SecretKey + Mac mac = Mac.getInstance(alg, "SunJCE"); + mac.init(key); + + // prepare buffer + byte[] data = new byte[BUFFER_SIZE]; + for (int i = 0; i < BUFFER_SIZE; i++) { + data[i] = (byte) (i % 256); + } + + ByteBuffer buf = ByteBuffer.wrap(data); + int limitBefore = buf.limit(); + + mac.update(buf); + mac.doFinal(); + + int limitAfter = buf.limit(); + int positonAfter = buf.position(); + + if (limitAfter != limitBefore) { + System.out.println("limit after = " + limitAfter); + System.out.println("limit before = " + limitBefore); + throw new RuntimeException("Test failed: " + + "limit of buffer has been chenged."); + } + + if (positonAfter != limitAfter) { + System.out.println("position after = " + positonAfter); + System.out.println("limit after = " + limitAfter); + throw new RuntimeException("Test failed: " + + "position of buffer isn't equal to its limit"); + } + } + +} diff --git a/test/com/sun/crypto/provider/Mac/MacSameTest.java b/test/com/sun/crypto/provider/Mac/MacSameTest.java new file mode 100644 index 0000000000000000000000000000000000000000..8d97f1a6a88fac919fe870e591f81811f814856d --- /dev/null +++ b/test/com/sun/crypto/provider/Mac/MacSameTest.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 1998, 2014, 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. + * + * 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. + */ + +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SecureRandom; +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; + +/** + * @test + * @bug 8048603 + * @summary Check if doFinal and update operation result in same Mac + * @author Yu-Ching Valerie Peng, Bill Situ, Alexander Fomin + * @build Utils + * @run main MacSameTest + */ +public class MacSameTest implements MacTest { + + private static final int MESSAGE_SIZE = 25; + private static final int OFFSET = 5; + private static final int KEY_SIZE = 70; + + /** + * Initialize a message, instantiate a Mac object, + * initialize the object with a SecretKey, + * feed the message into the Mac object + * all at once and get the output MAC as result1. + * Reset the Mac object, chop the message into three pieces, + * feed into the Mac object sequentially, and get the output MAC as result2. + * Finally, compare result1 and result2 and see if they are the same. + * + * @param args the command line arguments + */ + public static void main(String[] args) { + Utils.runTests(new MacSameTest()); + } + + @Override + public void doTest(String algo) throws NoSuchAlgorithmException, + NoSuchProviderException, InvalidKeyException { + Mac mac; + try { + mac = Mac.getInstance(algo, "SunJCE"); + } catch (NoSuchAlgorithmException nsae) { + // depending on Solaris configuration, + // it can support HMAC or not with Mac + System.out.println("Expected NoSuchAlgorithmException thrown: " + + nsae); + return; + } + + byte[] plain = new byte[MESSAGE_SIZE]; + for (int i = 0; i < MESSAGE_SIZE; i++) { + plain[i] = (byte) (i % 256); + } + + byte[] tail = new byte[plain.length - OFFSET]; + System.arraycopy(plain, OFFSET, tail, 0, tail.length); + + SecureRandom srdm = new SecureRandom(); + byte[] keyVal = new byte[KEY_SIZE]; + srdm.nextBytes(keyVal); + SecretKeySpec keySpec = new SecretKeySpec(keyVal, "HMAC"); + + mac.init(keySpec); + byte[] result1 = mac.doFinal(plain); + + mac.reset(); + mac.update(plain[0]); + mac.update(plain, 1, OFFSET - 1); + byte[] result2 = mac.doFinal(tail); + + if (!java.util.Arrays.equals(result1, result2)) { + throw new RuntimeException("result1 and result2 are not the same"); + } + } + +} diff --git a/test/com/sun/crypto/provider/Mac/NullByteBufferTest.java b/test/com/sun/crypto/provider/Mac/NullByteBufferTest.java new file mode 100644 index 0000000000000000000000000000000000000000..d71d4f96317667ed62fb2a76509420985fcec594 --- /dev/null +++ b/test/com/sun/crypto/provider/Mac/NullByteBufferTest.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 1998, 2014, 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. + * + * 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. + */ + +import java.nio.ByteBuffer; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import javax.crypto.Mac; +import javax.crypto.SecretKey; + +/** + * @test + * @bug 8048603 + * @summary Checks if PBE algorithms work fine with null buffer + * @author Alexander Fomin + * @build Utils + * @run main NullByteBufferTest + */ +public class NullByteBufferTest implements MacTest { + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + Utils.runTests(new NullByteBufferTest()); + } + + @Override + public void doTest(String alg) throws NoSuchAlgorithmException, + InvalidKeyException, NoSuchProviderException { + SecretKey key = Utils.getSecretKeySpec(); + + // instantiate Mac object and init it with a SecretKey + Mac mac = Mac.getInstance(alg, "SunJCE"); + mac.init(key); + + try { + ByteBuffer buf = null; + mac.update(buf); + mac.doFinal(); + throw new RuntimeException( + "Expected IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + System.out.println("Expected IllegalArgumentException thrown: " + + e); + } + } + +} diff --git a/test/com/sun/crypto/provider/Mac/Utils.java b/test/com/sun/crypto/provider/Mac/Utils.java new file mode 100644 index 0000000000000000000000000000000000000000..389d40b0d14e4665a9212c3cdfedc2c272595320 --- /dev/null +++ b/test/com/sun/crypto/provider/Mac/Utils.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 1998, 2014, 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. + * + * 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. + */ + +import java.security.SecureRandom; +import javax.crypto.spec.SecretKeySpec; + +/** + * Helper class. + */ +class Utils { + + static final int KEY_SIZE = 70; + + static final String[] MAC_ALGOS = {"HmacMD5", "HmacSHA1", "HmacSHA224", + "HmacSHA256", "HmacSHA384", "HmacSHA512"}; + + /** + * Get SecretKeySpec. + */ + static SecretKeySpec getSecretKeySpec() { + SecureRandom srdm = new SecureRandom(); + byte[] keyVal = new byte[KEY_SIZE]; + srdm.nextBytes(keyVal); + return new SecretKeySpec(keyVal, "HMAC"); + } + + static void runTests(MacTest... tests) { + boolean success = true; + for (MacTest test : tests) { + success &= runTest(test); + } + + if (success) { + System.out.println("Test passed"); + } else { + throw new RuntimeException("Test failed"); + } + } + + private static boolean runTest(MacTest test) { + boolean success = true; + for (String alg : MAC_ALGOS) { + try { + System.out.println("Test " + alg); + test.doTest(alg); + } catch (Exception e) { + System.out.println("Unexpected exception:"); + e.printStackTrace(); + success = false; + } + } + + return success; + } +} + +interface MacTest { + void doTest(String alg) throws Exception; +} \ No newline at end of file diff --git a/test/com/sun/crypto/provider/NSASuiteB/TestAESOids.java b/test/com/sun/crypto/provider/NSASuiteB/TestAESOids.java new file mode 100644 index 0000000000000000000000000000000000000000..062c34ceda351d57986e0b2d746c9874ce46063b --- /dev/null +++ b/test/com/sun/crypto/provider/NSASuiteB/TestAESOids.java @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +import static javax.crypto.Cipher.ENCRYPT_MODE; +import static javax.crypto.Cipher.getMaxAllowedKeyLength; + +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.spec.AlgorithmParameterSpec; +import java.util.Arrays; +import java.util.List; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.KeyGenerator; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.ShortBufferException; +import javax.crypto.spec.IvParameterSpec; + +/* + * @test + * @bug 8075286 + * @summary Test the AES algorithm OIDs in JDK. + * OID and Algorithm transformation string should match. + * Both could be able to be used to generate the algorithm instance. + * @run main TestAESOids + */ +public class TestAESOids { + + private static final String PROVIDER_NAME = "SunJCE"; + private static final byte[] INPUT = "1234567890123456".getBytes(); + + private static final List DATA = Arrays.asList( + new DataTuple("2.16.840.1.101.3.4.1.1", "AES_128/ECB/NoPadding", + 128, "ECB"), + new DataTuple("2.16.840.1.101.3.4.1.2", "AES_128/CBC/NoPadding", + 128, "CBC"), + new DataTuple("2.16.840.1.101.3.4.1.3", "AES_128/OFB/NoPadding", + 128, "OFB"), + new DataTuple("2.16.840.1.101.3.4.1.4", "AES_128/CFB/NoPadding", + 128, "CFB"), + new DataTuple("2.16.840.1.101.3.4.1.21", "AES_192/ECB/NoPadding", + 192, "ECB"), + new DataTuple("2.16.840.1.101.3.4.1.22", "AES_192/CBC/NoPadding", + 192, "CBC"), + new DataTuple("2.16.840.1.101.3.4.1.23", "AES_192/OFB/NoPadding", + 192, "OFB"), + new DataTuple("2.16.840.1.101.3.4.1.24", "AES_192/CFB/NoPadding", + 192, "CFB"), + new DataTuple("2.16.840.1.101.3.4.1.41", "AES_256/ECB/NoPadding", + 256, "ECB"), + new DataTuple("2.16.840.1.101.3.4.1.42", "AES_256/CBC/NoPadding", + 256, "CBC"), + new DataTuple("2.16.840.1.101.3.4.1.43", "AES_256/OFB/NoPadding", + 256, "OFB"), + new DataTuple("2.16.840.1.101.3.4.1.44", "AES_256/CFB/NoPadding", + 256, "CFB")); + + public static void main(String[] args) throws Exception { + for (DataTuple dataTuple : DATA) { + int maxAllowedKeyLength = + getMaxAllowedKeyLength(dataTuple.algorithm); + boolean supportedKeyLength = + maxAllowedKeyLength >= dataTuple.keyLength; + + try { + runTest(dataTuple, supportedKeyLength); + System.out.println("passed"); + } catch (InvalidKeyException ike) { + if (supportedKeyLength) { + throw new RuntimeException(String.format( + "The key length %d is supported, but test failed.", + dataTuple.keyLength), ike); + } else { + System.out.printf( + "Catch expected InvalidKeyException due " + + "to the key length %d is greater than " + + "max supported key length %d%n", + dataTuple.keyLength, maxAllowedKeyLength); + } + } + } + } + + private static void runTest(DataTuple dataTuple, + boolean supportedKeyLength) throws NoSuchAlgorithmException, + NoSuchProviderException, NoSuchPaddingException, + InvalidKeyException, ShortBufferException, + IllegalBlockSizeException, BadPaddingException, + InvalidAlgorithmParameterException { + Cipher algorithmCipher = Cipher.getInstance(dataTuple.algorithm, + PROVIDER_NAME); + Cipher oidCipher = Cipher.getInstance(dataTuple.oid, PROVIDER_NAME); + + if (algorithmCipher == null) { + throw new RuntimeException( + String.format("Test failed: algorithm string %s getInstance" + + " failed.%n", dataTuple.algorithm)); + } + + if (oidCipher == null) { + throw new RuntimeException( + String.format("Test failed: OID %s getInstance failed.%n", + dataTuple.oid)); + } + + if (!algorithmCipher.getAlgorithm().equals(dataTuple.algorithm)) { + throw new RuntimeException(String.format( + "Test failed: algorithm string %s getInstance " + + "doesn't generate expected algorithm.%n", + dataTuple.algorithm)); + } + + KeyGenerator kg = KeyGenerator.getInstance("AES"); + kg.init(dataTuple.keyLength); + SecretKey key = kg.generateKey(); + + // encrypt + algorithmCipher.init(ENCRYPT_MODE, key); + if (!supportedKeyLength) { + throw new RuntimeException(String.format( + "The key length %d is not supported, so the initialization " + + "of algorithmCipher should fail.%n", + dataTuple.keyLength)); + } + + byte[] cipherText = new byte[algorithmCipher.getOutputSize(INPUT.length)]; + int offset = algorithmCipher.update(INPUT, 0, INPUT.length, + cipherText, 0); + algorithmCipher.doFinal(cipherText, offset); + + AlgorithmParameterSpec aps = null; + if (!dataTuple.mode.equalsIgnoreCase("ECB")) { + aps = new IvParameterSpec(algorithmCipher.getIV()); + } + + oidCipher.init(Cipher.DECRYPT_MODE, key, aps); + if (!supportedKeyLength) { + throw new RuntimeException(String.format( + "The key length %d is not supported, so the " + + "initialization of oidCipher should fail.%n", + dataTuple.keyLength)); + } + + byte[] recoveredText = new byte[oidCipher.getOutputSize(cipherText.length)]; + oidCipher.doFinal(cipherText, 0, cipherText.length, recoveredText); + + // Comparison + if (!Arrays.equals(INPUT, recoveredText)) { + throw new RuntimeException( + "Decrypted data is not the same as the original text"); + } + } + + private static class DataTuple { + + private final String oid; + private final String algorithm; + private final int keyLength; + private final String mode; + + private DataTuple(String oid, String algorithm, int keyLength, + String mode) { + this.oid = oid; + this.algorithm = algorithm; + this.keyLength = keyLength; + this.mode = mode; + } + } +} diff --git a/test/com/sun/crypto/provider/NSASuiteB/TestAESWrapOids.java b/test/com/sun/crypto/provider/NSASuiteB/TestAESWrapOids.java new file mode 100644 index 0000000000000000000000000000000000000000..2db96a52b3f83481226ac23aa786ab3c48ac586f --- /dev/null +++ b/test/com/sun/crypto/provider/NSASuiteB/TestAESWrapOids.java @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +import static javax.crypto.Cipher.getMaxAllowedKeyLength; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.util.Arrays; +import java.util.List; + +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.KeyGenerator; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; + +/* + * @test + * @bug 8075286 + * @summary Test the AESWrap algorithm OIDs in JDK. + * OID and Algorithm transformation string should match. + * Both could be able to be used to generate the algorithm instance. + * @run main TestAESWrapOids + */ +public class TestAESWrapOids { + + private static final String PROVIDER_NAME = "SunJCE"; + + private static final List DATA = Arrays.asList( + new DataTuple("2.16.840.1.101.3.4.1.5", "AESWrap_128", 128), + new DataTuple("2.16.840.1.101.3.4.1.25", "AESWrap_192", 192), + new DataTuple("2.16.840.1.101.3.4.1.45", "AESWrap_256", 256)); + + public static void main(String[] args) throws Exception { + for (DataTuple dataTuple : DATA) { + int maxAllowedKeyLength = getMaxAllowedKeyLength( + dataTuple.algorithm); + boolean supportedKeyLength = + maxAllowedKeyLength >= dataTuple.keyLength; + + try { + runTest(dataTuple, supportedKeyLength); + System.out.println("passed"); + } catch (InvalidKeyException ike) { + if (supportedKeyLength) { + throw new RuntimeException(String.format( + "The key length %d is supported, but test failed.", + dataTuple.keyLength), ike); + } else { + System.out.printf( + "Catch expected InvalidKeyException " + + "due to the key length %d is greater " + + "than max supported key length %d%n", + dataTuple.keyLength, maxAllowedKeyLength); + } + } + } + } + + private static void runTest(DataTuple dataTuple, boolean supportedKeyLength) + throws NoSuchAlgorithmException, NoSuchProviderException, + NoSuchPaddingException, InvalidKeyException, + IllegalBlockSizeException { + Cipher algorithmCipher = Cipher.getInstance( + dataTuple.algorithm, PROVIDER_NAME); + Cipher oidCipher = Cipher.getInstance(dataTuple.oid, PROVIDER_NAME); + + if (algorithmCipher == null) { + throw new RuntimeException(String.format( + "Test failed: algorithm string %s getInstance failed.%n", + dataTuple.algorithm)); + } + + if (oidCipher == null) { + throw new RuntimeException( + String.format("Test failed: OID %s getInstance failed.%n", + dataTuple.oid)); + } + + if (!algorithmCipher.getAlgorithm().equals( + dataTuple.algorithm)) { + throw new RuntimeException(String.format( + "Test failed: algorithm string %s getInstance " + + "doesn't generate expected algorithm.%n", + dataTuple.oid)); + } + + KeyGenerator kg = KeyGenerator.getInstance("AES"); + kg.init(dataTuple.keyLength); + SecretKey key = kg.generateKey(); + + // Wrap the key + algorithmCipher.init(Cipher.WRAP_MODE, key); + if (!supportedKeyLength) { + throw new RuntimeException(String.format( + "The key length %d is not supported, so the initialization" + + " of algorithmCipher should fail.%n", + dataTuple.keyLength)); + } + + // Unwrap the key + oidCipher.init(Cipher.UNWRAP_MODE, key); + if (!supportedKeyLength) { + throw new RuntimeException(String.format( + "The key length %d is not supported, so the initialization" + + " of oidCipher should fail.%n", + dataTuple.keyLength)); + } + + byte[] keyWrapper = algorithmCipher.wrap(key); + Key unwrappedKey = oidCipher.unwrap(keyWrapper, "AES", + Cipher.SECRET_KEY); + + // Comparison + if (!Arrays.equals(key.getEncoded(), unwrappedKey.getEncoded())) { + throw new RuntimeException("Key comparison failed"); + } + } + + private static class DataTuple { + + private final String oid; + private final String algorithm; + private final int keyLength; + + private DataTuple(String oid, String algorithm, int keyLength) { + this.oid = oid; + this.algorithm = algorithm; + this.keyLength = keyLength; + } + } +} diff --git a/test/com/sun/crypto/provider/NSASuiteB/TestHmacSHAOids.java b/test/com/sun/crypto/provider/NSASuiteB/TestHmacSHAOids.java new file mode 100644 index 0000000000000000000000000000000000000000..15110d78d853a29528035241f6cb5cdb51f6680b --- /dev/null +++ b/test/com/sun/crypto/provider/NSASuiteB/TestHmacSHAOids.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.util.Arrays; +import java.util.List; + +import javax.crypto.KeyGenerator; +import javax.crypto.Mac; +import javax.crypto.SecretKey; + +/* + * @test + * @bug 8075286 + * @summary Test the HmacSHA algorithm OIDs in JDK. + * OID and Algorithm transformation string should match. + * Both could be able to be used to generate the algorithm instance. + * @run main TestHmacSHAOids + */ +public class TestHmacSHAOids { + + private static final String PROVIDER_NAME = "SunJCE"; + private static final byte[] INPUT = "1234567890".getBytes(); + + private static final List DATA = Arrays.asList( + new DataTuple("1.2.840.113549.2.7", "HmacSHA1"), + new DataTuple("1.2.840.113549.2.8", "HmacSHA224"), + new DataTuple("1.2.840.113549.2.9", "HmacSHA256"), + new DataTuple("1.2.840.113549.2.10", "HmacSHA384"), + new DataTuple("1.2.840.113549.2.11", "HmacSHA512")); + + public static void main(String[] args) throws Exception { + for (DataTuple dataTuple : DATA) { + runTest(dataTuple); + System.out.println("passed"); + } + System.out.println("All tests passed"); + } + + private static void runTest(DataTuple dataTuple) + throws NoSuchAlgorithmException, NoSuchProviderException, + InvalidKeyException { + Mac mcAlgorithm = Mac.getInstance(dataTuple.algorithm, + PROVIDER_NAME); + Mac mcOid = Mac.getInstance(dataTuple.oid, PROVIDER_NAME); + + if (mcAlgorithm == null) { + throw new RuntimeException(String.format( + "Test failed: Mac using algorithm " + + "string %s getInstance failed.%n", + dataTuple.algorithm)); + } + + if (mcOid == null) { + throw new RuntimeException(String.format( + "Test failed: Mac using OID %s getInstance failed.%n", + dataTuple.oid)); + } + + if (!mcAlgorithm.getAlgorithm().equals(dataTuple.algorithm)) { + throw new RuntimeException(String.format( + "Test failed: Mac using algorithm string %s getInstance " + + "doesn't generate expected algorithm.%n", + dataTuple.algorithm)); + } + + KeyGenerator kg = KeyGenerator.getInstance(dataTuple.algorithm, + PROVIDER_NAME); + SecretKey key = kg.generateKey(); + + mcAlgorithm.init(key); + mcAlgorithm.update(INPUT); + + mcOid.init(key); + mcOid.update(INPUT); + + // Comparison + if (!Arrays.equals(mcAlgorithm.doFinal(), mcOid.doFinal())) { + throw new RuntimeException("Digest comparison failed: " + + "the two MACs are not the same"); + } + } + + private static class DataTuple { + + private final String oid; + private final String algorithm; + + private DataTuple(String oid, String algorithm) { + this.oid = oid; + this.algorithm = algorithm; + } + } +} diff --git a/test/com/sun/jdi/RedefineAddPrivateMethod.sh b/test/com/sun/jdi/RedefineAddPrivateMethod.sh new file mode 100644 index 0000000000000000000000000000000000000000..d91f74ab85c29143b81a613c3b2170c3b99fa4d3 --- /dev/null +++ b/test/com/sun/jdi/RedefineAddPrivateMethod.sh @@ -0,0 +1,79 @@ +#!/bin/sh + +# +# Copyright (c) 2016, 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. +# +# 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. +# + +# @test +# @bug 8149743 +# @summary crash when adding a breakpoint after redefining to add a private static method +# @run shell RedefineAddPrivateMethod.sh + +compileOptions=-g + +createJavaFile() +{ + cat < $1.java.1 +public class $1 { + static public void main(String[] args) { + System.out.println("@1 breakpoint"); + System.out.println("@2 breakpoint"); + } + + // @1 uncomment private static void test() {} +} +EOF +} + +# This is called to feed cmds to jdb. +dojdbCmds() +{ + setBkpts @1 + runToBkpt @1 + redefineClass @1 + setBkpts @2 + runToBkpt @2 + cmd exitJdb +} + + +mysetup() +{ + if [ -z "$TESTSRC" ] ; then + TESTSRC=. + fi + + for ii in . $TESTSRC $TESTSRC/.. ; do + if [ -r "$ii/ShellScaffold.sh" ] ; then + . $ii/ShellScaffold.sh + break + fi + done +} + +# You could replace this next line with the contents +# of ShellScaffold.sh and this script will run just the same. +mysetup + +runit +debuggeeFailIfPresent "Internal exception:" +pass diff --git a/test/com/sun/tools/attach/RunnerUtil.java b/test/com/sun/tools/attach/RunnerUtil.java index 3555a299a3189dd67defc772170a2e0e781c0b9a..0fd278941704238af32540934ab99f861603bdf2 100644 --- a/test/com/sun/tools/attach/RunnerUtil.java +++ b/test/com/sun/tools/attach/RunnerUtil.java @@ -139,12 +139,19 @@ public class RunnerUtil { String content = null; // Read file or wait for it to be created. + long startTime = System.currentTimeMillis(); + long lastWarningTime = 0; while (true) { content = readFile(file); if (content != null && content.indexOf("done") >= 0) { break; } Thread.sleep(100); + long elapsedTime = (System.currentTimeMillis() - startTime) / 1000; + if (elapsedTime > lastWarningTime) { + lastWarningTime = elapsedTime; + System.out.println("Waited " + elapsedTime + " seconds for file."); + } } ProcessInfo info = new ProcessInfo(); diff --git a/test/com/sun/tools/attach/TempDirTest.java b/test/com/sun/tools/attach/TempDirTest.java index e60f9ce46cab6dc6c66ec02af122f12dfce38c5b..520b6b679a44b298c0766126dd658f9e00f3ff4b 100644 --- a/test/com/sun/tools/attach/TempDirTest.java +++ b/test/com/sun/tools/attach/TempDirTest.java @@ -39,13 +39,22 @@ import jdk.testlibrary.ProcessThread; * @summary Test to make sure attach and jvmstat works correctly when java.io.tmpdir is set * @library /lib/testlibrary * @run build Application Shutdown RunnerUtil - * @run main/timeout=10 TempDirTest + * @run main/timeout=200 TempDirTest + */ + +/* + * This test runs with an extra long timeout since it takes a really long time with -Xcomp + * when starting many processes.cd / */ public class TempDirTest { + private static long startTime; + public static void main(String args[]) throws Throwable { + startTime = System.currentTimeMillis(); + Path clientTmpDir = Files.createTempDirectory("TempDirTest-client"); clientTmpDir.toFile().deleteOnExit(); Path targetTmpDir = Files.createTempDirectory("TempDirTest-target"); @@ -76,6 +85,9 @@ public class TempDirTest { System.out.print(" target: " + (targetTmpDir == null ? "no" : "yes")); System.out.println(" ###"); + long elapsedTime = (System.currentTimeMillis() - startTime) / 1000; + System.out.println("Started after " + elapsedTime + "s"); + final String pidFile = "TempDirTest.Application.pid-" + counter++; ProcessThread processThread = null; RunnerUtil.ProcessInfo info = null; @@ -95,6 +107,10 @@ public class TempDirTest { // Make sure the Application process is stopped. RunnerUtil.stopApplication(info.shutdownPort, processThread); } + + elapsedTime = (System.currentTimeMillis() - startTime) / 1000; + System.out.println("Completed after " + elapsedTime + "s"); + } /** diff --git a/test/java/awt/Paint/ComponentIsNotDrawnAfterRemoveAddTest/ComponentIsNotDrawnAfterRemoveAddTest.java b/test/java/awt/Paint/ComponentIsNotDrawnAfterRemoveAddTest/ComponentIsNotDrawnAfterRemoveAddTest.java new file mode 100644 index 0000000000000000000000000000000000000000..186b572df44dacbd00b5360051440fbb04c90d42 --- /dev/null +++ b/test/java/awt/Paint/ComponentIsNotDrawnAfterRemoveAddTest/ComponentIsNotDrawnAfterRemoveAddTest.java @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2016, 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. + * + * 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. + */ + +/* @test + @bug 8139581 + @summary AWT components are not drawn after removal and addition to a container + @author Anton Litvinov + */ + +import java.awt.Button; +import java.awt.Color; +import java.awt.Canvas; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Panel; +import java.util.ArrayList; + +public class ComponentIsNotDrawnAfterRemoveAddTest { + private final Frame frame; + private final Panel panel; + private final ArrayList compList = new ArrayList(); + + public ComponentIsNotDrawnAfterRemoveAddTest() { + frame = new Frame("ComponentIsNotDrawnAfterRemoveAddTest"); + frame.setSize(500, 500); + frame.setLocation(200, 200); + frame.setLayout(null); + frame.setBackground(Color.RED); + + panel = new Panel(); + panel.setLayout(null); + panel.setBounds(25, 100, 455, 295); + panel.setBackground(Color.GREEN); + + for (int i = 0; i < 10; i++) { + TestCanvas canv1 = new TestCanvas(); + canv1.setBounds(i * 45 + 5, 15, 30 + i, 30 + i); + panel.add(canv1); + compList.add(canv1); + + TestButton btn1 = new TestButton(); + btn1.setBounds(i * 45 + 5, 60, 30 + i, 30 + i); + panel.add(btn1); + compList.add(btn1); + + TestCanvas canv2 = new TestCanvas(); + canv2.setBounds(i * 45 + 5, 105, 30 + i, 30 + i); + panel.add(canv2); + compList.add(canv2); + + TestButton btn2 = new TestButton(); + btn2.setBounds(i * 45 + 5, 150, 30 + i, 30 + i); + panel.add(btn2); + compList.add(btn2); + + TestCanvas canv3 = new TestCanvas(); + canv3.setBounds(i * 45 + 5, 195, 30 + i, 30 + i); + panel.add(canv3); + compList.add(canv3); + + TestButton btn3 = new TestButton(); + btn3.setBounds(i * 45 + 5, 240, 30 + i, 30 + i); + panel.add(btn3); + compList.add(btn3); + } + + frame.add(panel); + frame.setVisible(true); + } + + private void runTest() { + try { + doSleep(1500); + checkTestableComponents(); + + for (int i = 0; i < 5; i++) { + System.err.println(String.format("Test iteration #%d:", i)); + + frame.remove(panel); + frame.invalidate(); + frame.validate(); + frame.add(panel); + + doSleep(1500); + checkTestableComponents(); + } + } finally { + frame.dispose(); + } + } + + private void doSleep(long millis) { + try { + Thread.sleep(millis); + } catch (InterruptedException ie) { + ie.printStackTrace(); + } + } + + private void checkTestableComponents() throws RuntimeException { + int notDrawnCompsCount = 0; + for (Testable comp : compList) { + if (!comp.wasPaintCalled()) { + notDrawnCompsCount++; + } else { + comp.resetPaintCalledFlag(); + } + } + if (notDrawnCompsCount > 0) { + throw new RuntimeException(String.format( + "'paint' method of %d components was not called.", notDrawnCompsCount)); + } + } + + private interface Testable { + boolean wasPaintCalled(); + void resetPaintCalledFlag(); + } + + private static class TestCanvas extends Canvas implements Testable { + private volatile boolean paintWasCalled = false; + + @Override + public void paint(Graphics g) { + paintWasCalled = true; + super.paint(g); + g.setColor(Color.BLUE); + g.fillRect(0, 0, getWidth(), getHeight()); + } + + @Override + public boolean wasPaintCalled() { + return paintWasCalled; + } + + @Override + public void resetPaintCalledFlag() { + paintWasCalled = false; + } + } + + private static class TestButton extends Button implements Testable { + private volatile boolean paintWasCalled = false; + + @Override + public void paint(Graphics g) { + paintWasCalled = true; + super.paint(g); + g.setColor(Color.YELLOW); + g.fillRect(0, 0, 15, 15); + } + + @Override + public boolean wasPaintCalled() { + return paintWasCalled; + } + + @Override + public void resetPaintCalledFlag() { + paintWasCalled = false; + } + } + + public static void main(String[] args) { + new ComponentIsNotDrawnAfterRemoveAddTest().runTest(); + } +} diff --git a/test/java/awt/font/MonospacedGlyphWidth/MonospacedGlyphWidthTest.java b/test/java/awt/font/MonospacedGlyphWidth/MonospacedGlyphWidthTest.java new file mode 100644 index 0000000000000000000000000000000000000000..82dd8ab57f19346fe39f4ae927cbb35c85bd8839 --- /dev/null +++ b/test/java/awt/font/MonospacedGlyphWidth/MonospacedGlyphWidthTest.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2016, 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. + * + * 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. + */ + +/* @test + * @bug 8073400 + * @summary Some Monospaced logical fonts have a different width + * @author Dmitry Markov + * @run main MonospacedGlyphWidthTest + */ +import java.awt.*; +import java.awt.font.FontRenderContext; + +public class MonospacedGlyphWidthTest { + private static final int START_INDEX = 0x2018; + private static final int END_INDEX = 0x201F; + + public static void main(String[] args) { + Font font = new Font(Font.MONOSPACED, Font.PLAIN, 12); + double width = getCharWidth(font, 'a'); + + for (int i = START_INDEX; i <= END_INDEX; i++) { + if (width != getCharWidth(font, (char)i)) { + throw new RuntimeException("Test Failed: characters have different width!"); + } + } + System.out.println("Test Passed!"); + } + + private static double getCharWidth(Font font, char c) { + FontRenderContext fontRenderContext = new FontRenderContext(null, false, false); + return font.getStringBounds(new char[] {c}, 0, 1, fontRenderContext).getWidth(); + } +} + diff --git a/test/java/lang/StringBuilder/Capacity.java b/test/java/lang/StringBuilder/Capacity.java new file mode 100644 index 0000000000000000000000000000000000000000..e23e9151b46956cb8348b9c7fc85c4104e1fa2e8 --- /dev/null +++ b/test/java/lang/StringBuilder/Capacity.java @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2016, 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. + * + * 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. + */ + +/* + * @test + * @bug 8149330 + * @summary Basic set of tests of capacity management + * @run testng Capacity + */ + +import java.lang.reflect.Field; +import java.util.AbstractList; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.SplittableRandom; + +import org.testng.annotations.Test; +import org.testng.annotations.DataProvider; +import static org.testng.Assert.*; + +public class Capacity { + static final int DEFAULT_CAPACITY = 16; + + private static int newCapacity(int oldCapacity, + int desiredCapacity) + { + return Math.max(oldCapacity * 2 + 2, desiredCapacity); + } + + private static int nextNewCapacity(int oldCapacity) { + return newCapacity(oldCapacity, oldCapacity + 1); + } + + @Test(dataProvider = "singleChar") + public void defaultCapacity(Character ch) { + StringBuilder sb = new StringBuilder(); + assertEquals(sb.capacity(), DEFAULT_CAPACITY); + for (int i = 0; i < DEFAULT_CAPACITY; i++) { + sb.append(ch); + assertEquals(sb.capacity(), DEFAULT_CAPACITY); + } + sb.append(ch); + assertEquals(sb.capacity(), nextNewCapacity(DEFAULT_CAPACITY)); + } + + @Test(dataProvider = "charCapacity") + public void explicitCapacity(Character ch, int initCapacity) { + StringBuilder sb = new StringBuilder(initCapacity); + assertEquals(sb.capacity(), initCapacity); + for (int i = 0; i < initCapacity; i++) { + sb.append(ch); + assertEquals(sb.capacity(), initCapacity); + } + sb.append(ch); + assertEquals(sb.capacity(), nextNewCapacity(initCapacity)); + } + + @Test(dataProvider = "singleChar") + public void sbFromString(Character ch) { + String s = "string " + ch; + int expectedCapacity = s.length() + DEFAULT_CAPACITY; + StringBuilder sb = new StringBuilder(s); + assertEquals(sb.capacity(), expectedCapacity); + for (int i = 0; i < DEFAULT_CAPACITY; i++) { + sb.append(ch); + assertEquals(sb.capacity(), expectedCapacity); + } + sb.append(ch); + assertEquals(sb.capacity(), nextNewCapacity(expectedCapacity)); + } + + @Test(dataProvider = "singleChar") + public void sbFromCharSeq(Character ch) { + CharSequence cs = new MyCharSeq("char seq " + ch); + int expectedCapacity = cs.length() + DEFAULT_CAPACITY; + StringBuilder sb = new StringBuilder(cs); + assertEquals(sb.capacity(), expectedCapacity); + for (int i = 0; i < DEFAULT_CAPACITY; i++) { + sb.append(ch); + assertEquals(sb.capacity(), expectedCapacity); + } + sb.append(ch); + assertEquals(sb.capacity(), nextNewCapacity(expectedCapacity)); + } + + @Test(dataProvider = "charCapacity") + public void ensureCapacity(Character ch, int cap) { + StringBuilder sb = new StringBuilder(0); + assertEquals(sb.capacity(), 0); + sb.ensureCapacity(cap); // only has effect if cap > 0 + int newCap = (cap == 0) ? 0 : newCapacity(0, cap); + assertEquals(sb.capacity(), newCap); + sb.ensureCapacity(newCap + 1); + assertEquals(sb.capacity(), nextNewCapacity(newCap)); + sb.append(ch); + assertEquals(sb.capacity(), nextNewCapacity(newCap)); + } + + @Test(dataProvider = "negativeCapacity", + expectedExceptions = NegativeArraySizeException.class) + public void negativeInitialCapacity(int negCap) { + StringBuilder sb = new StringBuilder(negCap); + } + + @Test(dataProvider = "negativeCapacity") + public void ensureNegativeCapacity(int negCap) { + StringBuilder sb = new StringBuilder(); + sb.ensureCapacity(negCap); + assertEquals(sb.capacity(), DEFAULT_CAPACITY); + } + + @Test(dataProvider = "charCapacity") + public void trimToSize(Character ch, int cap) { + StringBuilder sb = new StringBuilder(cap); + int halfOfCap = cap / 2; + for (int i = 0; i < halfOfCap; i++) { + sb.append(ch); + } + sb.trimToSize(); + // according to the spec, capacity doesn't have to + // become exactly the size + assertTrue(sb.capacity() >= halfOfCap); + } + + @DataProvider + public Object[][] singleChar() { + return new Object[][] { {'J'}, {'\u042b'} }; + } + + @DataProvider + public Object[][] charCapacity() { + return new Object[][] { + {'J', 0}, + {'J', 1}, + {'J', 15}, + {'J', DEFAULT_CAPACITY}, + {'J', 1024}, + {'\u042b', 0}, + {'\u042b', 1}, + {'\u042b', 15}, + {'\u042b', DEFAULT_CAPACITY}, + {'\u042b', 1024}, + }; + } + + @DataProvider + public Object[][] negativeCapacity() { + return new Object[][] { {-1}, {Integer.MIN_VALUE} }; + } + + private static class MyCharSeq implements CharSequence { + private CharSequence s; + public MyCharSeq(CharSequence s) { this.s = s; } + public char charAt(int i) { return s.charAt(i); } + public int length() { return s.length(); } + public CharSequence subSequence(int st, int e) { + return s.subSequence(st, e); + } + public String toString() { return s.toString(); } + } +} diff --git a/test/java/lang/StringBuilder/HugeCapacity.java b/test/java/lang/StringBuilder/HugeCapacity.java new file mode 100644 index 0000000000000000000000000000000000000000..4140a026949db6f15615d0ca2450b3ade4e6b86c --- /dev/null +++ b/test/java/lang/StringBuilder/HugeCapacity.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2016, 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. + * + * 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. + */ + +/** + * @test + * @bug 8149330 + * @summary Capacity should not get close to Integer.MAX_VALUE unless + * necessary + * @run main/othervm -Xmx10G HugeCapacity + * @ignore This test has huge memory requirements + */ + +public class HugeCapacity { + private static int failures = 0; + + public static void main(String[] args) { + testLatin1(); + testUtf16(); + if (failures > 0) { + throw new RuntimeException(failures + " tests failed"); + } + } + + private static void testLatin1() { + try { + StringBuilder sb = new StringBuilder(); + sb.ensureCapacity(Integer.MAX_VALUE / 2); + sb.ensureCapacity(Integer.MAX_VALUE / 2 + 1); + } catch (OutOfMemoryError oom) { + oom.printStackTrace(); + failures++; + } + } + + private static void testUtf16() { + try { + StringBuilder sb = new StringBuilder(); + sb.append('\u042b'); + sb.ensureCapacity(Integer.MAX_VALUE / 4); + sb.ensureCapacity(Integer.MAX_VALUE / 4 + 1); + } catch (OutOfMemoryError oom) { + oom.printStackTrace(); + failures++; + } + } +} diff --git a/test/java/lang/invoke/AccessControlTest.java b/test/java/lang/invoke/AccessControlTest.java index 891710fd8141e705e564eaff96bacfdf91f322c3..06da8155b3b4b696e93995c65042f3adcfd2fb6a 100644 --- a/test/java/lang/invoke/AccessControlTest.java +++ b/test/java/lang/invoke/AccessControlTest.java @@ -23,9 +23,7 @@ /* @test * @summary test access checking by java.lang.invoke.MethodHandles.Lookup - * @library ../../../.. - * @build test.java.lang.invoke.AccessControlTest - * @build test.java.lang.invoke.AccessControlTest_subpkg.Acquaintance_remote + * @compile AccessControlTest.java AccessControlTest_subpkg/Acquaintance_remote.java * @run testng/othervm test.java.lang.invoke.AccessControlTest */ diff --git a/test/java/lang/management/MemoryMXBean/LowMemoryTest2.sh b/test/java/lang/management/MemoryMXBean/LowMemoryTest2.sh index d05a75958ee8b25c6a47648523ae0d92b7a3fbee..b584c085b46b1d502bcd58c4285090b7c1cdec5f 100644 --- a/test/java/lang/management/MemoryMXBean/LowMemoryTest2.sh +++ b/test/java/lang/management/MemoryMXBean/LowMemoryTest2.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2014, 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 @@ -25,7 +25,7 @@ # @test # @bug 4982128 # @summary Test low memory detection of non-heap memory pool -# +# @requires vm.gc=="null" # @run build LowMemoryTest2 MemoryUtil # @run shell/timeout=600 LowMemoryTest2.sh # diff --git a/test/java/lang/management/MemoryMXBean/MemoryManagementConcMarkSweepGC.sh b/test/java/lang/management/MemoryMXBean/MemoryManagementConcMarkSweepGC.sh index 8db78142ef68c581e2f1b3b23af8e08321284077..a80f2c417f172c4b5463cc381a59afc39c7b472a 100644 --- a/test/java/lang/management/MemoryMXBean/MemoryManagementConcMarkSweepGC.sh +++ b/test/java/lang/management/MemoryMXBean/MemoryManagementConcMarkSweepGC.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 2014, 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 @@ -26,7 +26,7 @@ # @bug 4530538 # @summary Run MemoryManagement test with concurrent mark sweep GC # @author Mandy Chung -# +# @requires vm.gc=="ConcMarkSweep" | vm.gc=="null" # @run build MemoryManagement # @run shell/timeout=600 MemoryManagementConcMarkSweepGC.sh # diff --git a/test/java/lang/management/MemoryMXBean/MemoryManagementParallelGC.sh b/test/java/lang/management/MemoryMXBean/MemoryManagementParallelGC.sh index 0435302e8e9cd7f6610490f1000ded7a73412b8d..f315c96eb310a8e7b133d277bd30f1742f31d5cb 100644 --- a/test/java/lang/management/MemoryMXBean/MemoryManagementParallelGC.sh +++ b/test/java/lang/management/MemoryMXBean/MemoryManagementParallelGC.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 2014, 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 @@ -26,7 +26,7 @@ # @bug 4530538 # @summary Run MemoryManagement test with parallel GC # @author Mandy Chung -# +# @requires vm.gc=="Parallel" | vm.gc=="null" # @run build MemoryManagement # @run shell/timeout=600 MemoryManagementParallelGC.sh # diff --git a/test/java/lang/management/MemoryMXBean/MemoryManagementSerialGC.sh b/test/java/lang/management/MemoryMXBean/MemoryManagementSerialGC.sh index e7ea40a1e8f68d29555551e0daa3591c1b10ec15..043323071d7c20b4540e05992d66d7992076e4a7 100644 --- a/test/java/lang/management/MemoryMXBean/MemoryManagementSerialGC.sh +++ b/test/java/lang/management/MemoryMXBean/MemoryManagementSerialGC.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 2014, 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 @@ -26,7 +26,7 @@ # @bug 4530538 # @summary Run MemoryManagement test with serial GC # @author Mandy Chung -# +# @requires vm.gc=="Serial" | vm.gc=="null" # @run build MemoryManagement # @run shell/timeout=600 MemoryManagementSerialGC.sh # diff --git a/test/java/lang/management/MemoryMXBean/MemoryTestAllGC.sh b/test/java/lang/management/MemoryMXBean/MemoryTestAllGC.sh index be0827ae32a001e40431b98ad5412088dd8c53fa..6dbbc1659d93cd901b791b3b6976b85e77bf33ca 100644 --- a/test/java/lang/management/MemoryMXBean/MemoryTestAllGC.sh +++ b/test/java/lang/management/MemoryMXBean/MemoryTestAllGC.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 2014, 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 @@ -26,7 +26,7 @@ # @bug 4530538 # @summary # @author Mandy Chung -# +# @requires vm.gc=="Parallel" | vm.gc=="null" # @run compile MemoryTest.java # @run shell MemoryTestAllGC.sh # @@ -52,7 +52,5 @@ runOne MemoryTest 2 # Test MemoryTest with parallel scavenger collector runOne -XX:+UseParallelGC MemoryTest 2 -# Test MemoryTest with concurrent collector -#runOne -XX:+UseConcMarkSweepGC MemoryTest 3 exit 0 diff --git a/test/java/lang/management/MemoryMXBean/PendingAllGC.sh b/test/java/lang/management/MemoryMXBean/PendingAllGC.sh index edf18b3ffa03ef35d6264aa15bef365651100090..2a1ccc3be7e1b39c035f9e5416c2c8dc63273544 100644 --- a/test/java/lang/management/MemoryMXBean/PendingAllGC.sh +++ b/test/java/lang/management/MemoryMXBean/PendingAllGC.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 2014, 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 @@ -26,7 +26,7 @@ # @bug 4530538 # @summary # @author Mandy Chung -# +# @requires vm.gc=="null" # @run compile Pending.java # @run shell PendingAllGC.sh # diff --git a/test/java/lang/management/RuntimeMXBean/TestInputArgument.sh b/test/java/lang/management/RuntimeMXBean/TestInputArgument.sh index 5c57e4878e5910f37149780b7527fa3570c1daf4..6c135415875ce3d4c09fd3b519682364e635f575 100644 --- a/test/java/lang/management/RuntimeMXBean/TestInputArgument.sh +++ b/test/java/lang/management/RuntimeMXBean/TestInputArgument.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 2014, 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 @@ -26,7 +26,6 @@ # @bug 4530538 # @summary # @author Mandy Chung -# # @run compile InputArgument.java # @run shell TestInputArgument.sh # @@ -48,8 +47,8 @@ runOne() runOne InputArgument -runOne -XX:+UseParallelGC -XX:+PrintGCDetails InputArgument -XX:+PrintGCDetails -runOne -XX:+UseParallelGC -XX:+PrintGCDetails InputArgument -XX:+UseParallelGC +runOne -XX:+UseFastJNIAccessors -XX:+PrintGCDetails InputArgument -XX:+PrintGCDetails +runOne -XX:+UseFastJNIAccessors -XX:+PrintGCDetails InputArgument -XX:+UseFastJNIAccessors runOne "-Dprops=one two three" InputArgument "-Dprops=one two three" exit 0 diff --git a/test/java/lang/management/ThreadMXBean/Locks.java b/test/java/lang/management/ThreadMXBean/Locks.java index 92233648544cbbadf5f285c96bb9b90a36471c8b..1c8da469289f613ded263a4354a8d8b4b74e8397 100644 --- a/test/java/lang/management/ThreadMXBean/Locks.java +++ b/test/java/lang/management/ThreadMXBean/Locks.java @@ -170,6 +170,9 @@ public class Locks { private static CheckerThread checker; static class WaitingThread extends Thread { private final Phaser p; + + volatile boolean waiting = false; + public WaitingThread(Phaser p) { super("WaitingThread"); this.p = p; @@ -180,7 +183,9 @@ public class Locks { log("WaitingThread about to wait on objC"); try { // Signal checker thread, about to wait on objC. + waiting = false; p.arriveAndAwaitAdvance(); // Phase 1 (waiting) + waiting = true; objC.wait(); } catch (InterruptedException e) { e.printStackTrace(); @@ -199,7 +204,9 @@ public class Locks { synchronized(objC) { try { // signal checker thread, about to wait on objC + waiting = false; p.arriveAndAwaitAdvance(); // Phase 3 (waiting) + waiting = true; objC.wait(); } catch (InterruptedException e) { e.printStackTrace(); @@ -208,25 +215,35 @@ public class Locks { } log("WaitingThread about to exit waiting on objC 2"); } - } - static class CheckerThread extends Thread { - private final Phaser p; - public CheckerThread(Phaser p) { - super("CheckerThread"); - this.p = p; + + public void waitForWaiting() { + p.arriveAndAwaitAdvance(); + while (!waiting) { + goSleep(10); + } + waitForState(State.WAITING); } - private void waitForState(Thread.State state) { + public void waitForBlocked() { p.arriveAndAwaitAdvance(); + waitForState(State.BLOCKED); + } + + private void waitForState(Thread.State state) { while (!waiter.isInterrupted() && waiter.getState() != state) { - goSleep(10); + Thread.yield(); } } + } + static class CheckerThread extends Thread { + public CheckerThread() { + super("CheckerThread"); + } public void run() { synchronized (ready) { // wait until WaitingThread about to wait for objC - waitForState(Thread.State.WAITING); // Phase 1 (waiting) + waiter.waitForWaiting(); // Phase 1 (waiting) checkBlockedObject(waiter, objC, null, Thread.State.WAITING); synchronized (objC) { @@ -235,13 +252,13 @@ public class Locks { // wait for waiter thread to about to enter // synchronized object ready. - waitForState(Thread.State.BLOCKED); // Phase 2 (waiting) + waiter.waitForBlocked(); // Phase 2 (waiting) checkBlockedObject(waiter, ready, this, Thread.State.BLOCKED); } // wait for signal from waiting thread that it is about // wait for objC. - waitForState(Thread.State.WAITING); // Phase 3 (waiting) + waiter.waitForWaiting(); // Phase 3 (waiting) synchronized(objC) { checkBlockedObject(waiter, objC, Thread.currentThread(), Thread.State.WAITING); objC.notify(); @@ -289,7 +306,7 @@ public class Locks { waiter = new WaitingThread(p); waiter.start(); - checker = new CheckerThread(p); + checker = new CheckerThread(); checker.start(); try { diff --git a/test/java/lang/ref/EnqueuePollRace.java b/test/java/lang/ref/EnqueuePollRace.java index c19a366715d00c8cbe1f448b154a61cd5819a2ea..5171e138e5aa9bea718d7830aaa1bf59f1ef534f 100644 --- a/test/java/lang/ref/EnqueuePollRace.java +++ b/test/java/lang/ref/EnqueuePollRace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, 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 @@ -25,7 +25,7 @@ * @bug 8014890 * @summary Verify that a race between ReferenceQueue.enqueue() and poll() does not occur. * @author thomas.schatzl@oracle.com - * @run main/othervm -XX:+UseSerialGC -Xmx10M EnqueuePollRace + * @run main/othervm -Xmx10M EnqueuePollRace */ import java.lang.ref.*; diff --git a/test/java/net/InetAddress/B6246242.java b/test/java/net/InetAddress/B6246242.java index 8ca80176bd3c08ad98f0d9408ded6f511da21a2d..77e96287043d88b69a9ccfb28a6ccc01de7e4aa9 100644 --- a/test/java/net/InetAddress/B6246242.java +++ b/test/java/net/InetAddress/B6246242.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, 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 @@ -23,7 +23,7 @@ /** * @test - * @bug 6246242 + * @bug 6246242 8135259 * @summary UnknownHostException contains wrong error message */ @@ -36,7 +36,7 @@ public class B6246242 { a = InetAddress.getByName("foo.bar"); } catch (UnknownHostException e) { String s = e.getMessage(); - if (s.indexOf("foo.bar: foo.bar") >= 0) + if (s.contains("foo.bar: foo.bar") || s.contains("unknown error")) throw new RuntimeException("UnknownHostException has wrong message: " + s); } } diff --git a/test/java/net/SetFactoryPermission/SetFactoryPermission.java b/test/java/net/SetFactoryPermission/SetFactoryPermission.java new file mode 100644 index 0000000000000000000000000000000000000000..94779628a052ffe56fc25036c08f8df1218a64ae --- /dev/null +++ b/test/java/net/SetFactoryPermission/SetFactoryPermission.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2014, 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. + * + * 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. + */ + + +/* + * @test + * @bug 8048052 + * @summary Test a series of methods which requires "setFactory" runtime permission + * @run main SetFactoryPermission success + * @run main/othervm/policy=policy.fail SetFactoryPermission fail + * @run main/othervm/policy=policy.success SetFactoryPermission success + */ +import java.net.ServerSocket; +import java.net.Socket; +import java.net.URL; +import java.net.URLConnection; +import java.rmi.server.RMISocketFactory; +import java.security.AccessControlException; + +public class SetFactoryPermission { + static boolean success = false; + + interface Runner { + public void run() throws Exception; + } + + public static void main (String[] args) throws Exception { + if (args.length > 0) { + success = System.getSecurityManager() == null || args[0].equals("success"); + } + + doTest(()->{ + System.out.println("Verify URLConnection.setContentHandlerFactor()"); + URLConnection.setContentHandlerFactory(null); + }); + doTest(()->{ + System.out.println("Verify URL.setURLStreamHandlerFactory()"); + URL.setURLStreamHandlerFactory(null); + }); + doTest(()->{ + System.out.println("Verify ServerSocket.setSocketFactory()"); + ServerSocket.setSocketFactory(null); + }); + doTest(()->{ + System.out.println("Verify Socket.setSocketImplFactory()"); + Socket.setSocketImplFactory(null); + }); + doTest(()->{ + System.out.println("Verify RMISocketFactory.setSocketFactory()"); + RMISocketFactory.setSocketFactory(null); + }); + } + + static void doTest(Runner func) throws Exception { + try { + func.run(); + if (!success) { + throw new RuntimeException("AccessControlException is not thrown. Test failed"); + } + } catch (SecurityException e) { + if (success) { + e.printStackTrace(); + throw new RuntimeException("AccessControlException is thrown unexpectedly. Test failed"); + } + } + } +} diff --git a/test/java/net/SetFactoryPermission/policy.fail b/test/java/net/SetFactoryPermission/policy.fail new file mode 100644 index 0000000000000000000000000000000000000000..a4c6d11f44fdabcedb6d5d6bec4e960627f1428f --- /dev/null +++ b/test/java/net/SetFactoryPermission/policy.fail @@ -0,0 +1,3 @@ +grant { + +}; diff --git a/test/java/net/SetFactoryPermission/policy.success b/test/java/net/SetFactoryPermission/policy.success new file mode 100644 index 0000000000000000000000000000000000000000..d382afce449a41c1429c74efebbe10463b93c47d --- /dev/null +++ b/test/java/net/SetFactoryPermission/policy.success @@ -0,0 +1,4 @@ +grant { + permission java.lang.RuntimePermission "setFactory"; +}; + diff --git a/test/java/net/SocketPermission/SocketPermissionTest.java b/test/java/net/SocketPermission/SocketPermissionTest.java new file mode 100644 index 0000000000000000000000000000000000000000..1552acce1dc0f57592fada345bb84fb5e438099b --- /dev/null +++ b/test/java/net/SocketPermission/SocketPermissionTest.java @@ -0,0 +1,339 @@ +/* + * Copyright (c) 2014, 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. + * + * 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. + */ + +/* + * @test + * @bug 8047031 + * @summary SocketPermission tests for legacy socket types + * @run testng/othervm SocketPermissionTest + */ +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.MulticastSocket; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketPermission; +import java.security.AccessControlContext; +import java.security.AccessController; +import java.security.CodeSource; +import java.security.Permission; +import java.security.PermissionCollection; +import java.security.Permissions; +import java.security.Policy; +import java.security.PrivilegedExceptionAction; +import java.security.ProtectionDomain; + +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import static org.testng.Assert.*; + +import static java.nio.charset.StandardCharsets.UTF_8; + +public class SocketPermissionTest { + + @BeforeMethod + public void setupSecurityManager() throws Exception { + // All permissions, a specific ACC will be used to when testing + // with a reduced permission set. + Policy.setPolicy(new Policy() { + final PermissionCollection perms = new Permissions(); + { perms.add(new java.security.AllPermission()); } + public PermissionCollection getPermissions(ProtectionDomain domain) { + return perms; + } + public PermissionCollection getPermissions(CodeSource codesource) { + return perms; + } + public boolean implies(ProtectionDomain domain, Permission perm) { + return perms.implies(perm); + } + } ); + System.setSecurityManager(new SecurityManager()); + } + + static final AccessControlContext RESTRICTED_ACC = getAccessControlContext(); + + @Test + public void connectSocketTest() throws Exception { + try (ServerSocket ss = new ServerSocket(0)) { + int port = ss.getLocalPort(); + + String addr = "localhost:" + port; + AccessControlContext acc = getAccessControlContext( + new SocketPermission(addr, "listen,connect,resolve")); + + // Positive + AccessController.doPrivileged((PrivilegedExceptionAction) () -> { + try (Socket client = new Socket(InetAddress.getLocalHost(), port)) { + } + return null; + }, acc); + + //Negative + try { + AccessController.doPrivileged((PrivilegedExceptionAction) () -> { + Socket client = new Socket(InetAddress.getLocalHost(), port); + fail("Expected SecurityException"); + return null; + }, RESTRICTED_ACC); + } catch (SecurityException expected) { } + } + } + + @Test + public void connectDatagramSocketTest() throws Exception { + byte[] msg = "Hello".getBytes(UTF_8); + InetAddress lh = InetAddress.getLocalHost(); + + try (DatagramSocket ds = new DatagramSocket(0)) { + int port = ds.getLocalPort(); + + String addr = lh.getHostAddress() + ":" + port; + AccessControlContext acc = getAccessControlContext( + new SocketPermission(addr, "connect,resolve")); + + // Positive + AccessController.doPrivileged((PrivilegedExceptionAction) () -> { + DatagramPacket dp = new DatagramPacket(msg, msg.length, lh, port); + ds.send(dp); + return null; + }, acc); + + // Negative + try { + AccessController.doPrivileged((PrivilegedExceptionAction) () -> { + DatagramPacket dp = new DatagramPacket(msg, msg.length, lh, port); + ds.send(dp); + fail("Expected SecurityException"); + return null; + }, RESTRICTED_ACC); + } catch (SecurityException expected) { } + } + } + + @Test + public void acceptServerSocketTest() throws Exception { + try (ServerSocket ss = new ServerSocket(0)) { + int port = ss.getLocalPort(); + + String addr = "localhost:" + port; + AccessControlContext acc = getAccessControlContext( + new SocketPermission(addr, "listen,connect,resolve"), + new SocketPermission("localhost:1024-", "accept")); + + // Positive + AccessController.doPrivileged((PrivilegedExceptionAction) () -> { + InetAddress me = InetAddress.getLocalHost(); + try (Socket client = new Socket(me, port)) { + ss.accept(); + } + return null; + }, acc); + + // Negative + try { + AccessController.doPrivileged((PrivilegedExceptionAction) () -> { + InetAddress me = InetAddress.getLocalHost(); + try (Socket client = new Socket(me, port)) { + ss.accept(); + } + fail("Expected SecurityException"); + return null; + }, RESTRICTED_ACC); + } catch (SecurityException expected) { } + } + } + + @Test + public void sendDatagramPacketTest() throws Exception { + byte[] msg = "Hello".getBytes(UTF_8); + InetAddress group = InetAddress.getByName("229.227.226.221"); + + try (DatagramSocket ds = new DatagramSocket(0)) { + int port = ds.getLocalPort(); + + String addr = "localhost:" + port; + //test for SocketPermission "229.227.226.221", "connect,accept" + AccessControlContext acc = getAccessControlContext( + new SocketPermission(addr, "listen,resolve"), + new SocketPermission("229.227.226.221", "connect,accept")); + + // Positive + AccessController.doPrivileged((PrivilegedExceptionAction) () -> { + DatagramPacket hi = new DatagramPacket(msg, msg.length, group, port); + ds.send(hi); + return null; + }, acc); + + // Negative + try { + AccessController.doPrivileged((PrivilegedExceptionAction) () -> { + DatagramPacket hi = new DatagramPacket(msg, msg.length, group, port); + ds.send(hi); + fail("Expected SecurityException"); + return null; + }, RESTRICTED_ACC); + } catch (SecurityException expected) { } + } + } + + @Test + public void joinGroupMulticastTest() throws Exception { + InetAddress group = InetAddress.getByName("229.227.226.221"); + try (MulticastSocket s = new MulticastSocket(0)) { + int port = s.getLocalPort(); + + String addr = "localhost:" + port; + AccessControlContext acc = getAccessControlContext( + new SocketPermission(addr, "listen,resolve"), + new SocketPermission("229.227.226.221", "connect,accept")); + + // Positive + AccessController.doPrivileged((PrivilegedExceptionAction) () -> { + s.joinGroup(group); + s.leaveGroup(group); + return null; + }, acc); + + // Negative + try { + AccessController.doPrivileged((PrivilegedExceptionAction) () -> { + s.joinGroup(group); + s.leaveGroup(group); + fail("Expected SecurityException"); + return null; + }, RESTRICTED_ACC); + } catch (SecurityException expected) { } + } + + } + + @Test + public void listenDatagramSocketTest() throws Exception { + // the hardcoded port number doesn't really matter since we expect the + // security permission to be checked before the underlying operation. + int port = 8899; + String addr = "localhost:" + port; + AccessControlContext acc = getAccessControlContext( + new SocketPermission(addr, "listen")); + + // Positive + AccessController.doPrivileged((PrivilegedExceptionAction) () -> { + try (DatagramSocket ds = new DatagramSocket(port)) { } + catch (IOException intermittentlyExpected) { /* ignore */ } + return null; + }, acc); + + // Negative + try { + AccessController.doPrivileged((PrivilegedExceptionAction) () -> { + try (DatagramSocket ds = new DatagramSocket(port)) { } + catch (IOException intermittentlyExpected) { /* ignore */ } + fail("Expected SecurityException"); + return null; + }, RESTRICTED_ACC); + } catch (SecurityException expected) { } + } + + @Test + public void listenMulticastSocketTest() throws Exception { + // the hardcoded port number doesn't really matter since we expect the + // security permission to be checked before the underlying operation. + int port = 8899; + String addr = "localhost:" + port; + AccessControlContext acc = getAccessControlContext( + new SocketPermission(addr, "listen")); + + // Positive + AccessController.doPrivileged((PrivilegedExceptionAction) () -> { + try (MulticastSocket ms = new MulticastSocket(port)) { } + catch (IOException intermittentlyExpected) { /* ignore */ } + return null; + }, acc); + + // Negative + try { + AccessController.doPrivileged((PrivilegedExceptionAction) () -> { + try (MulticastSocket ms = new MulticastSocket(port)) { } + catch (IOException intermittentlyExpected) { /* ignore */ } + fail("Expected SecurityException"); + return null; + }, RESTRICTED_ACC); + } catch (SecurityException expected) { } + } + + @Test + public void listenServerSocketTest() throws Exception { + // the hardcoded port number doesn't really matter since we expect the + // security permission to be checked before the underlying operation. + int port = 8899; + String addr = "localhost:" + port; + AccessControlContext acc = getAccessControlContext( + new SocketPermission(addr, "listen")); + + // Positive + AccessController.doPrivileged((PrivilegedExceptionAction) () -> { + try (ServerSocket ss = new ServerSocket(port)) { } + catch (IOException intermittentlyExpected) { /* ignore */ } + return null; + }, acc); + + // Negative + try { + AccessController.doPrivileged((PrivilegedExceptionAction) () -> { + try (ServerSocket ss = new ServerSocket(port)) { } + catch (IOException intermittentlyExpected) { /* ignore */ } + fail("Expected SecurityException"); + return null; + }, RESTRICTED_ACC); + } catch (SecurityException expected) { } + + } + + private static AccessControlContext getAccessControlContext(Permission... ps) { + Permissions perms = new Permissions(); + for (Permission p : ps) { + perms.add(p); + } + /* + *Create an AccessControlContext that consist a single protection domain + * with only the permissions calculated above + */ + ProtectionDomain pd = new ProtectionDomain(null, perms); + return new AccessControlContext(new ProtectionDomain[]{pd}); + } + + // Standalone entry point for running with, possibly older, JDKs. + public static void main(String[] args) throws Throwable { + SocketPermissionTest test = new SocketPermissionTest(); + test.setupSecurityManager(); + for (java.lang.reflect.Method m : SocketPermissionTest.class.getDeclaredMethods()) { + if (m.getAnnotation(Test.class) != null) { + System.out.println("Invoking " + m.getName()); + m.invoke(test); + } + } + } +} diff --git a/test/java/rmi/dgc/dgcAckFailure/DGCAckFailure.java b/test/java/rmi/dgc/dgcAckFailure/DGCAckFailure.java index 82eeab00b163db750011b0150daeeca69fd4b4a1..bc1c2dc50ba20a73e600c8d4323c97a7553fb9f3 100644 --- a/test/java/rmi/dgc/dgcAckFailure/DGCAckFailure.java +++ b/test/java/rmi/dgc/dgcAckFailure/DGCAckFailure.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2016, 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 @@ -22,7 +22,7 @@ */ /* @test - * @bug 4017232 + * @bug 4017232 8046339 * @summary If, after returning a reference to a remote object in the current * VM (which gets implicitly converted to a remote stub), the client fails to * both send a DGC dirty call and to send a "DGC acknowledgment", the RMI @@ -36,10 +36,14 @@ import java.io.*; import java.net.*; +import java.lang.reflect.Field; import java.lang.ref.*; import java.rmi.*; import java.rmi.server.*; +import java.util.Map; + +import sun.rmi.transport.DGCAckHandler; interface ReturnRemote extends Remote { Object returnRemote() throws RemoteException; @@ -48,6 +52,7 @@ interface ReturnRemote extends Remote { public class DGCAckFailure implements ReturnRemote { private static final long TIMEOUT = 20000; + private static final long ACK_TIMEOUT = TIMEOUT / 2; public Object returnRemote() { return new Wrapper(this); @@ -55,7 +60,8 @@ public class DGCAckFailure implements ReturnRemote { public static void main(String[] args) throws Exception { - System.setProperty("sun.rmi.dgc.ackTimeout", "10000"); + System.setProperty("sun.rmi.dgc.ackTimeout", + Long.toString(ACK_TIMEOUT)); /* * Set a socket factory that has a hook for shutting down all client @@ -93,12 +99,31 @@ public class DGCAckFailure implements ReturnRemote { break; } } - if (ref == weakRef) { - System.err.println("TEST PASSED"); - } else { + if (ref != weakRef) { throw new RuntimeException("TEST FAILED: " + "timed out, remote object not garbage collected"); } + + // 8046339 + // All DGCAckHandlers must be properly released after timeout + Thread.sleep(ACK_TIMEOUT + 100); + try { + Field field = + DGCAckHandler.class.getDeclaredField("idTable"); + field.setAccessible(true); + Object obj = field.get(null); + Map idTable = (Map)obj; + + if (!idTable.isEmpty()) { + throw new RuntimeException("TEST FAILED: " + + "DGCAckHandler.idTable isn't empty"); + } + } catch (ReflectiveOperationException roe) { + throw new RuntimeException(roe); + } + + System.err.println("TEST PASSED"); + } finally { try { UnicastRemoteObject.unexportObject((Remote) weakRef.get(), diff --git a/src/share/classes/sun/invoke/anon/InvalidConstantPoolFormatException.java b/test/java/security/AccessController/DoPrivAccomplice.java similarity index 65% rename from src/share/classes/sun/invoke/anon/InvalidConstantPoolFormatException.java rename to test/java/security/AccessController/DoPrivAccomplice.java index d420d34b0d610ee928efb613dae309148d80c5d8..6cc2846deee301275776ebc4c4f993ce72689b57 100644 --- a/src/share/classes/sun/invoke/anon/InvalidConstantPoolFormatException.java +++ b/test/java/security/AccessController/DoPrivAccomplice.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2014, 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 @@ -23,23 +23,12 @@ * questions. */ -package sun.invoke.anon; +public class DoPrivAccomplice { -/** Exception used when there is an error in the constant pool - * format. - */ -public class InvalidConstantPoolFormatException extends Exception { - private static final long serialVersionUID=-6103888330523770949L; - - public InvalidConstantPoolFormatException(String message,Throwable cause) { - super(message,cause); - } - - public InvalidConstantPoolFormatException(String message) { - super(message); - } - - public InvalidConstantPoolFormatException(Throwable cause) { - super(cause); + public String go() { + String name = (String)java.security.AccessController. + doPrivileged((java.security.PrivilegedAction)() -> + System.getProperty("user.name")); + return name; } } diff --git a/test/java/security/AccessController/DoPrivAccompliceTest.java b/test/java/security/AccessController/DoPrivAccompliceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..d18038c9a8792f705168cc933436a4c9afc0468e --- /dev/null +++ b/test/java/security/AccessController/DoPrivAccompliceTest.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2007, 2014, 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. + */ + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.net.URI; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @test + * @bug 8048362 + * @compile ../../../lib/testlibrary/JavaToolUtils.java + * DoPrivAccomplice.java DoPrivTest.java + * @summary Tests the doPrivileged with accomplice Generate two jars + * (DoPrivTest.jar and DoPrivAccomplice.jar) and grant permission to + * DoPrivAccmplice.jar for reading user.home property from a PrivilagedAction. + * Run DoPrivTest.jar and try to access user.home property using + * DoPrivAccmplice.jar. + * @run main/othervm DoPrivAccompliceTest + */ + +public class DoPrivAccompliceTest { + + private static final String PWD = System.getProperty("test.classes", "./"); + private static final String ACTION_SOURCE = "DoPrivAccomplice"; + private static final String TEST_SOURCE = "DoPrivTest"; + + public static void createPolicyFile(URI codebaseURL) throws IOException { + String codebase = codebaseURL.toString(); + String quotes = "\""; + StringBuilder policyFile = new StringBuilder(); + policyFile.append("grant codeBase ").append(quotes). + append(codebase).append(quotes).append("{\n"). + append("permission java.util.PropertyPermission "). + append(quotes).append("user.name").append(quotes). + append(",").append(quotes).append("read").append(quotes). + append(";\n};"); + try (FileWriter writer = new FileWriter(new File(PWD, "java.policy"))) { + writer.write(policyFile.toString()); + writer.close(); + } catch (IOException e) { + System.err.println("Error while creating policy file"); + throw e; + } + } + + public static void main(String[] args) throws Exception { + final File class1 = new File(PWD, ACTION_SOURCE + ".class"); + final File class2 = new File(PWD, TEST_SOURCE + ".class"); + final File jarFile1 = new File(PWD, ACTION_SOURCE + ".jar"); + final File jarFile2 = new File(PWD, TEST_SOURCE + ".jar"); + System.out.println("Compilation successfull"); + JavaToolUtils.createJar(jarFile1, Arrays.asList(new File[]{class1})); + System.out.println("Created jar file " + jarFile1); + JavaToolUtils.createJar(jarFile2, Arrays.asList(new File[]{class2})); + System.out.println("Created jar file " + jarFile2); + createPolicyFile(jarFile1.toURI()); + + List commands = new ArrayList<>(); + final String pathSepartor = System.getProperty("path.separator"); + commands.add("-Djava.security.manager"); + commands.add("-Djava.security.policy=" + PWD + "/java.policy"); + commands.add("-classpath"); + commands.add(PWD + "/" + TEST_SOURCE + ".jar" + pathSepartor + + PWD + "/" + ACTION_SOURCE + ".jar"); + commands.add(TEST_SOURCE); + if (JavaToolUtils.runJava(commands) == 0) { + System.out.println("Test PASSES"); + } + } + +} diff --git a/test/java/security/AccessController/DoPrivTest.java b/test/java/security/AccessController/DoPrivTest.java new file mode 100644 index 0000000000000000000000000000000000000000..9ed0f97d000e288b68093a40a3c5226af5e7b040 --- /dev/null +++ b/test/java/security/AccessController/DoPrivTest.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2007, 2014, 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. + */ + +public class DoPrivTest { + + public static void main(String[] args) { + String name = new DoPrivAccomplice().go(); + System.out.println("Received Name : " + name); + } +} diff --git a/test/java/security/AccessController/LimitedDoPrivilegedWithNullPerms.java b/test/java/security/AccessController/LimitedDoPrivilegedWithNullPerms.java new file mode 100644 index 0000000000000000000000000000000000000000..13b2db47c0f941d54c43df025d88659852437f17 --- /dev/null +++ b/test/java/security/AccessController/LimitedDoPrivilegedWithNullPerms.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2013,2014, 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. + * + * 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. + */ + +/* + * @test + * @bug 8050281 + * @summary Test that NullPointerException is thrown if any element of perms + * parameter is null + * @run testng LimitedDoPrivilegedWithNullPerms + */ +import java.security.AccessControlContext; +import java.security.AccessController; +import java.security.Permission; +import java.security.PrivilegedAction; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.util.PropertyPermission; +import org.testng.annotations.Test; + +public class LimitedDoPrivilegedWithNullPerms { + + AccessControlContext acc = AccessController.getContext(); + Permission p1 = new PropertyPermission("user.name", "read"); + + @Test(expectedExceptions = NullPointerException.class) + public void test1() { + AccessController.doPrivileged( + (PrivilegedAction) () -> null, acc, null); + } + + @Test(expectedExceptions = NullPointerException.class) + public void test2() { + AccessController.doPrivileged( + (PrivilegedAction) () -> null, acc, p1, null); + } + + @Test(expectedExceptions = NullPointerException.class) + public void test3() { + AccessController.doPrivilegedWithCombiner( + (PrivilegedAction) () -> null, acc, null); + } + + @Test(expectedExceptions = NullPointerException.class) + public void test4() { + AccessController.doPrivilegedWithCombiner( + (PrivilegedAction) () -> null, acc, p1, null); + } + + @Test(expectedExceptions = NullPointerException.class) + public void test5() throws PrivilegedActionException { + AccessController.doPrivileged( + (PrivilegedExceptionAction) () -> null, + acc, null); + } + + @Test(expectedExceptions = NullPointerException.class) + public void test6() throws PrivilegedActionException { + AccessController.doPrivileged( + (PrivilegedExceptionAction) () -> null, + acc, p1, null); + } + + @Test(expectedExceptions = NullPointerException.class) + public void test7() throws PrivilegedActionException { + AccessController.doPrivilegedWithCombiner( + (PrivilegedExceptionAction) () -> null, + acc, null); + } + + @Test(expectedExceptions = NullPointerException.class) + public void test8() throws PrivilegedActionException { + AccessController.doPrivilegedWithCombiner( + (PrivilegedExceptionAction) () -> null, + acc, p1, null); + } +} diff --git a/test/java/security/AccessController/LimitedDoPrivilegedWithThread.java b/test/java/security/AccessController/LimitedDoPrivilegedWithThread.java new file mode 100644 index 0000000000000000000000000000000000000000..955f39d86fb8c68b1ea0e7d7a6a2b99412a38048 --- /dev/null +++ b/test/java/security/AccessController/LimitedDoPrivilegedWithThread.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013,2014, 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. + * + * 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. + */ + +/* + * @test + * @bug 8050281 + * @summary Test limited doprivileged action with trhead calls. + * @run main/othervm/policy=policy LimitedDoPrivilegedWithThread + */ +import java.io.FilePermission; +import java.security.AccessControlContext; +import java.security.AccessControlException; +import java.security.AccessController; +import java.security.Permission; +import java.security.PrivilegedAction; +import java.security.ProtectionDomain; +import java.util.PropertyPermission; + +public class LimitedDoPrivilegedWithThread { + + private static final Permission PROPERTYPERM + = new PropertyPermission("user.name", "read"); + private static final Permission FILEPERM + = new FilePermission("*", "read"); + private static final AccessControlContext ACC + = new AccessControlContext( + new ProtectionDomain[]{new ProtectionDomain(null, null)}); + + public static void main(String args[]) { + //parent thread without any permission + AccessController.doPrivileged( + (PrivilegedAction) () -> { + Thread ct = new Thread( + new ChildThread(PROPERTYPERM, FILEPERM)); + ct.start(); + try { + ct.join(); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + ie.printStackTrace(); + throw new RuntimeException("Unexpected InterruptedException"); + } + return null; + }, ACC); + } +} + +class ChildThread implements Runnable { + + private final Permission P1; + private final Permission P2; + private boolean catchACE = false; + + public ChildThread(Permission p1, Permission p2) { + this.P1 = p1; + this.P2 = p2; + } + + @Override + public void run() { + //Verified that child thread has permission p1, + runTest(null, P1, false, 1); + //Verified that child thread inherits parent thread's access control context + AccessControlContext childAcc = AccessController.getContext(); + runTest(childAcc, P1, true, 2); + //Verified that we can give permision p2 to limit the "privilege" of the + //class calling doprivileged action, stack walk will continue + runTest(null, P2, true, 3); + + } + + public void runTest(AccessControlContext acc, Permission perm, + boolean expectACE, int id) { + + AccessController.doPrivileged( + (PrivilegedAction) () -> { + try { + AccessController.getContext().checkPermission(P1); + } catch (AccessControlException ace) { + catchACE = true; + } + if (catchACE ^ expectACE) { + throw new RuntimeException("test" + id + " failed"); + } + return null; + }, acc, perm); + } +} diff --git a/test/java/security/AccessController/policy b/test/java/security/AccessController/policy new file mode 100644 index 0000000000000000000000000000000000000000..83ed146df9e952a6c35d8469ec10f629f55e22b5 --- /dev/null +++ b/test/java/security/AccessController/policy @@ -0,0 +1,4 @@ +grant{ + permission java.util.PropertyPermission "user.name", "read"; + permission java.io.FilePermission "*", "read"; +}; diff --git a/test/java/security/KeyStore/PKCS12/CheckDefaults.java b/test/java/security/KeyStore/PKCS12/CheckDefaults.java new file mode 100644 index 0000000000000000000000000000000000000000..59a7b80ec0a890d94428439a82cfee40fbaffba9 --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/CheckDefaults.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2012, 2016, 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. + */ +import java.security.KeyStore; +import java.security.Security; +import static java.lang.System.out; + +/** + * @test + * @bug 8048830 + * @summary Set up keystore.type secure property and check that + * KeyStore.getDefaultType() value is related to property value. Expect a full + * match the value 'keystore.type' and the value of the + * KeyStore.getDefaultType() + * @run main/othervm CheckDefaults + */ +public class CheckDefaults { + private static final String DEFAULT_KEY_STORE_TYPE = "jks"; + private static final String[] KEY_STORE_TYPES = {"jks", "pkcs12", "jceks", + "Unregistered_type_of_KS"}; + + private void runTest(String[] args) { + if (!KeyStore.getDefaultType(). + equalsIgnoreCase(DEFAULT_KEY_STORE_TYPE)) { + throw new RuntimeException(String.format("Default keystore type " + + "Expected '%s' . Actual: '%s' ", DEFAULT_KEY_STORE_TYPE, + KeyStore.getDefaultType())); + } + for (String ksDefaultType : KEY_STORE_TYPES) { + Security.setProperty("keystore.type", ksDefaultType); + if (!KeyStore.getDefaultType().equals(ksDefaultType)) { + throw new RuntimeException(String.format( + "Keystore default type value: '%s' cannot be set up via" + + " keystore.type " + + "security property, Actual: '%s'", + ksDefaultType, KeyStore.getDefaultType())); + } + } + out.println("Test Passed"); + } + + public static void main(String[] args) { + CheckDefaults checkDefaultsTest = new CheckDefaults(); + checkDefaultsTest.runTest(args); + } +} diff --git a/test/java/security/KeyStore/PKCS12/ConvertP12Test.java b/test/java/security/KeyStore/PKCS12/ConvertP12Test.java new file mode 100644 index 0000000000000000000000000000000000000000..f5334bff7109dca1331a4c1d4adb02875732bbc5 --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/ConvertP12Test.java @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2008, 2014, 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. + * + * 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. + */ + +import static java.lang.System.out; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.Key; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.Certificate; +import java.util.Arrays; +import java.util.Base64; +import java.util.Enumeration; + +/* + * @test + * @bug 8048619 + * @author Bill Situ + * @summary Test converting keystore from jceks to P12 and from P12 to other + * (jceks,jks). including following test cases: + * Read jceks key store and convert to the p12 key store, then compare entries + * in the two key stores. + * Read p12 key store and convert to the jceks key store, then compare entries + * in the two key stores. + * Read p12 key store (contains only private key and a self-signed certificate) + * and convert to the jceks key store, then compare entries of two key stores. + * Read p12 key store (contains 2 entries) and convert to the jceks key store, + * then compare entries in the two key stores. + * Read p12 key store (entry password and key store password are different) and + * convert to the jceks key store, then compare entries in the two key stores. + * Read p12 key store and convert to the jks key store, then compare entries + * in the two key stores. + * Read p12 key store (contains only private key and a self-signed certificate) + * and convert to the jks key store, then compare entries in the two key stores. + * Read p12 key store (contains 2 entries) and convert to the jks key store, + * then compare entries in the two key stores. + * Read p12 key store (entry password and key store password are different) and + * convert to the jks key store, then compare entries in the two key stores. + */ + +public class ConvertP12Test { + + private static final String SUN_JSSE = "SunJSSE"; + private static final String SUN_JCE = "SunJCE"; + private static final String SUN = "SUN"; + private static final String PKCS12 = "pkcs12"; + private static final String JCE_KS = "JceKS"; + private static final String JKS = "JKS"; + + public static void main(String args[]) throws Exception { + + ConvertP12Test jstest = new ConvertP12Test(); + + jstest.driver("JceksToP12", "keystoreCA.jceks.data", JCE_KS, SUN_JCE, + "storepass", "keypass", PKCS12, SUN_JSSE); + + jstest.driver("P12ToJceks_Chain", "ie_jceks_chain.pfx.data", PKCS12, + SUN_JSSE, "pass", "pass", JCE_KS, SUN_JCE); + + jstest.driver("P12ToJceks_SelfSigned", "jdk_jceks_selfsigned.p12.data", + PKCS12, SUN_JSSE, "pass", "pass", JCE_KS, SUN_JCE); + + jstest.driver("P12ToJceks_TwoEntry", "jdk_jceks_twoentry.p12.data", + PKCS12, SUN_JSSE, "pass", "pass", JCE_KS, SUN_JCE); + + jstest.driver("P12ToJceks_TwoPass", "jdk_jceks_twopass.p12.data", + PKCS12, SUN_JSSE, "storepass", "keypass", JCE_KS, SUN_JCE); + + jstest.driver("P12ToJks_Chain", "ie_jks_chain.pfx.data", PKCS12, + SUN_JSSE, "pass", "pass", JKS, SUN); + + jstest.driver("P12ToJks_SelfSigned", "jdk_jks_selfsigned.p12.data", + PKCS12, SUN_JSSE, "pass", "pass", JKS, SUN); + + jstest.driver("P12ToJks_TwoEntry", "jdk_jks_twoentry.p12.data", PKCS12, + SUN_JSSE, "pass", "pass", JKS, SUN); + + jstest.driver("P12ToJks_TwoPass", "jdk_jks_twopass.p12.data", PKCS12, + SUN_JSSE, "storepass", "keypass", JKS, SUN); + + } + + private void driver(String testCase, String inKeyStore, + String inKeyStoreType, String inKeyStoreTypePrv, + String inStorePass, String inKeyPass, String outKeyStoreType, + String outKeyStorePrv) throws Exception { + + String outStorePass = "pass"; + String outKeyPass = "pass"; + KeyStore inputKeyStore, outputKeyStore; + + out.println("Testing " + testCase); + String keystorePath = System.getProperty("test.src", ".") + + File.separator + "certs" + File.separator + "convertP12"; + out.println("Output KeyStore : " + inKeyStore + ".out"); + String outKeyStoreName = inKeyStore + ".out"; + try (FileOutputStream fout = new FileOutputStream(outKeyStoreName);) { + inputKeyStore = KeyStore.getInstance(inKeyStoreType, + inKeyStoreTypePrv); + + // KeyStore have encoded by Base64.getMimeEncoder().encode(),need + // decode first. + byte[] input = Files.readAllBytes(Paths.get(keystorePath, + inKeyStore)); + ByteArrayInputStream arrayIn = new ByteArrayInputStream(Base64 + .getMimeDecoder().decode(input)); + + out.println("Input KeyStore : " + inKeyStore); + + inputKeyStore.load(arrayIn, inStorePass.toCharArray()); + + outputKeyStore = KeyStore.getInstance(outKeyStoreType, + outKeyStorePrv); + outputKeyStore.load(null, null); + + run(inputKeyStore, outputKeyStore, inKeyPass, outKeyPass); + + outputKeyStore.store(fout, outStorePass.toCharArray()); + + // for P12ToJks_TwoEntry test case will test includes each other, + // others just test compareKeystore + if (testCase.contains("TwoEntry")) { + + compareKeyStore(inputKeyStore, outputKeyStore, inKeyPass, + outKeyPass, 2); + compareKeyStore(outputKeyStore, inputKeyStore, outKeyPass, + inKeyPass, 2); + } else { + compareKeyStore(inputKeyStore, outputKeyStore, inKeyPass, + outKeyPass, 1); + } + out.println("Test " + testCase + " STATUS: Pass!!"); + } catch (Exception ex) { + out.println("Test " + testCase + " STATUS: failed with exception: " + + ex.getMessage()); + throw ex; + } + } + + private void run(KeyStore inputKeyStore, KeyStore outputKeyStore, + String inKeyPass, String outKeyPass) throws Exception { + Enumeration e = inputKeyStore.aliases(); + String alias; + while (e.hasMoreElements()) { + alias = e.nextElement(); + Certificate[] certs = inputKeyStore.getCertificateChain(alias); + + boolean isCertEntry = inputKeyStore.isCertificateEntry(alias); + // Test KeyStore only contain key pair entries. + if (isCertEntry == true) { + throw new RuntimeException( + "inputKeystore should not be certEntry because test" + + " keystore only contain key pair entries" + + " for alias:" + alias); + } + + boolean isKeyEntry = inputKeyStore.isKeyEntry(alias); + Key key = null; + if (isKeyEntry) { + key = inputKeyStore.getKey(alias, inKeyPass.toCharArray()); + } else { + throw new RuntimeException("Entry type unknown for alias:" + + alias); + } + outputKeyStore.setKeyEntry(alias, key, outKeyPass.toCharArray(), + certs); + } + } + + private void compareKeyStore(KeyStore a, KeyStore b, String inKeyPass, + String outKeyPass, int keyStoreSize) throws Exception { + if (a.size() != keyStoreSize || b.size() != keyStoreSize) { + throw new RuntimeException("size not match or size not equal to " + + keyStoreSize); + } + + Enumeration eA = a.aliases(); + while (eA.hasMoreElements()) { + String aliasA = eA.nextElement(); + + if (!b.containsAlias(aliasA)) { + throw new RuntimeException("alias not match for alias:" + + aliasA); + } + + compareKeyEntry(a, b, inKeyPass, outKeyPass, aliasA); + } + } + + private void compareKeyEntry(KeyStore a, KeyStore b, String aPass, + String bPass, String alias) throws KeyStoreException, + UnrecoverableKeyException, NoSuchAlgorithmException { + Certificate[] certsA = a.getCertificateChain(alias); + Certificate[] certsB = b.getCertificateChain(alias); + + if (!Arrays.equals(certsA, certsB)) { + throw new RuntimeException("Certs don't match for alias:" + alias); + } + + Key keyA = a.getKey(alias, aPass.toCharArray()); + Key keyB = b.getKey(alias, bPass.toCharArray()); + + if (!keyA.equals(keyB)) { + throw new RuntimeException( + "Key don't match for alias:" + alias); + } + } +} diff --git a/test/java/security/KeyStore/PKCS12/EntryProtectionTest.java b/test/java/security/KeyStore/PKCS12/EntryProtectionTest.java new file mode 100644 index 0000000000000000000000000000000000000000..586eda31912cddd9b868021f0e8d652bf21d726b --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/EntryProtectionTest.java @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2012, 2016, 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. + */ +import java.io.File; +import static java.lang.System.err; +import java.security.*; +import java.security.cert.Certificate; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import javax.crypto.spec.PBEParameterSpec; +import jdk.testlibrary.RandomFactory; +import static java.lang.System.out; +import java.util.Arrays; + +/** + * @test + * @bug 8048830 + * @summary Test for feature 'support stronger entry protection'. An entry is + * stored to keystore with different PasswordProtection objects which are + * specified by different PBE algorithms (use -Dseed=X to set PRNG seed) + * @library /lib/testlibrary ../ + */ +public class EntryProtectionTest { + private static final char[] PASSWORD = "passwd".toCharArray(); + private static final String ALIAS = "testkey"; + private static final byte[] SALT = new byte[8]; + private static final int ITERATION_COUNT = 1024; + private static final List PASSWORD_PROTECTION + = new ArrayList<>(); + private static final String KEYSTORE_PATH = System.getProperty( + "test.classes" + File.separator + "ks.pkcs12", + "." + File.separator + "ks.pkcs12"); + + private void runTest() throws Exception { + KeyStore ksIn = Utils.loadKeyStore(KEYSTORE_PATH, + Utils.KeyStoreType.pkcs12, PASSWORD); + KeyStore ksTest = KeyStore + .getInstance(Utils.KeyStoreType.pkcs12.name()); + ksTest.load(null); + Certificate cert = ksIn.getCertificate(ALIAS); + Key key = ksIn.getKey(ALIAS, PASSWORD); + KeyStore.Entry keyStoreEntry = new KeyStore.PrivateKeyEntry( + (PrivateKey) key, new Certificate[]{cert}); + for (KeyStore.PasswordProtection passwordAlgorithm : + PASSWORD_PROTECTION) { + out.println("Try to use: " + + passwordAlgorithm.getProtectionAlgorithm()); + ksTest.setEntry(ALIAS, keyStoreEntry, passwordAlgorithm); + KeyStore.Entry entryRead = ksTest.getEntry(ALIAS, + new KeyStore.PasswordProtection(PASSWORD)); + if (!isPrivateKeyEntriesEqual((KeyStore.PrivateKeyEntry) + keyStoreEntry, (KeyStore.PrivateKeyEntry)entryRead)) { + err.println("Original entry in KeyStore: " + keyStoreEntry); + err.println("Enc/Dec entry : " + entryRead); + throw new RuntimeException( + String.format( + "Decrypted & original enities do " + + "not match. Algo: %s, Actual: %s, " + + "Expected: %s", + passwordAlgorithm.getProtectionAlgorithm(), + entryRead, keyStoreEntry)); + } + ksTest.deleteEntry(ALIAS); + } + out.println("Test Passed"); + } + + public static void main(String args[]) throws Exception { + EntryProtectionTest entryProtectionTest = new EntryProtectionTest(); + entryProtectionTest.setUp(); + entryProtectionTest.runTest(); + } + + private void setUp() { + out.println("Using KEYSTORE_PATH:"+KEYSTORE_PATH); + Utils.createKeyStore(Utils.KeyStoreType.pkcs12, KEYSTORE_PATH, ALIAS); + Random rand = RandomFactory.getRandom(); + rand.nextBytes(SALT); + out.print("Salt: "); + for (byte b : SALT) { + out.format("%02X ", b); + } + out.println(""); + PASSWORD_PROTECTION + .add(new KeyStore.PasswordProtection(PASSWORD, + "PBEWithMD5AndDES", new PBEParameterSpec(SALT, + ITERATION_COUNT))); + PASSWORD_PROTECTION.add(new KeyStore.PasswordProtection(PASSWORD, + "PBEWithSHA1AndDESede", null)); + PASSWORD_PROTECTION.add(new KeyStore.PasswordProtection(PASSWORD, + "PBEWithSHA1AndRC2_40", null)); + PASSWORD_PROTECTION.add(new KeyStore.PasswordProtection(PASSWORD, + "PBEWithSHA1AndRC2_128", null)); + PASSWORD_PROTECTION.add(new KeyStore.PasswordProtection(PASSWORD, + "PBEWithSHA1AndRC4_40", null)); + PASSWORD_PROTECTION.add(new KeyStore.PasswordProtection(PASSWORD, + "PBEWithSHA1AndRC4_128", null)); + } + + /** + * Checks whether given two KeyStore.PrivateKeyEntry parameters are equal + * The KeyStore.PrivateKeyEntry fields like {privateKey, certificateChain[]} + * are checked for equality and another field Set is not checked + * as default implementation adds few PKCS12 attributes during read + * operation + * @param first + * parameter is of type KeyStore.PrivateKeyEntry + * @param second + * parameter is of type KeyStore.PrivateKeyEntry + * @return boolean + * true when both the KeyStore.PrivateKeyEntry fields are equal + */ + boolean isPrivateKeyEntriesEqual(KeyStore.PrivateKeyEntry first, + KeyStore.PrivateKeyEntry second) { + //compare privateKey + if (!Arrays.equals(first.getPrivateKey().getEncoded(), + second.getPrivateKey().getEncoded())) { + err.println("Mismatch found in privateKey!"); + return false; + } + //compare certificateChain[] + if (!Arrays.equals(first.getCertificateChain(), + second.getCertificateChain())) { + err.println("Mismatch found in certificate chain!"); + return false; + } + return true; + } +} diff --git a/test/java/security/KeyStore/PKCS12/KeytoolReaderP12Test.java b/test/java/security/KeyStore/PKCS12/KeytoolReaderP12Test.java new file mode 100644 index 0000000000000000000000000000000000000000..4c7e55b642cce1d5c9e1bdc6047119fd864e3cf2 --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/KeytoolReaderP12Test.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2012, 2016, 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. + * + * 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. + */ + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.StandardOpenOption; +import java.util.Base64; +import jdk.testlibrary.OutputAnalyzer; +import static java.lang.System.out; +import java.nio.file.Paths; +import java.util.List; + +/** + * @test + * @bug 8048830 + * @summary Test for PKCS12 keystore list , export commands. Refer README for + * keystore files information + * @library /lib/testlibrary ../ + * @run main KeytoolReaderP12Test + */ +public class KeytoolReaderP12Test { + private static final String WORKING_DIRECTORY = System.getProperty( + "test.classes", "."+ File.separator); + private static final String KS_PASSWD = "storepass"; + private static final String CERT_CHAIN_PASSWD = "password"; + private static final String SOURCE_DIRECTORY = + System.getProperty("test.src", "." + File.separator); + + public static void main(String[] args) throws Exception { + List expectedValues = null; + out.println("Self signed test"); + expectedValues = Files.readAllLines(Paths.get(SOURCE_DIRECTORY, + "api_private_key.p12_expected.data")); + readTest("api_private_key.p12.data", KS_PASSWD, expectedValues); + out.println("Self signed test Passed"); + + out.println("private key with selfsigned cert, key pair not match"); + expectedValues = Files.readAllLines(Paths.get(SOURCE_DIRECTORY, + "api_private_key_not_match.p12_expected.data")); + readTest("api_private_key_not_match.p12.data", KS_PASSWD, + expectedValues); + out.println("private key with selfsigned cert, key pair " + + "not match passed"); + + out.println("cert chain test"); + expectedValues = Files.readAllLines(Paths.get(SOURCE_DIRECTORY, + "api_cert_chain.p12_expected.data")); + readTest("api_cert_chain.p12.data", CERT_CHAIN_PASSWD, expectedValues); + out.println("cert chain test passed"); + + out.println("IE self test"); + expectedValues = Files.readAllLines(Paths.get(SOURCE_DIRECTORY, + "ie_self.pfx.pem")); + exportTest("ie_self.pfx.data", "pkcs12testenduser1", + KS_PASSWD, expectedValues); + out.println("IE self test passed"); + + out.println("IE chain test"); + expectedValues = Files.readAllLines(Paths.get(SOURCE_DIRECTORY, + "ie_chain.pfx.pem")); + exportTest("ie_chain.pfx.data", "servercert", + CERT_CHAIN_PASSWD, expectedValues); + out.println("IE chain test passed"); + + out.println("Netscape self"); + expectedValues = Files.readAllLines(Paths.get(SOURCE_DIRECTORY, + "netscape_self.p12.pem")); + exportTest("netscape_self.p12.data", "pkcs12testenduser1", + KS_PASSWD, expectedValues); + out.println("Netscape self passed"); + + out.println("Mozilla self test"); + expectedValues = Files.readAllLines(Paths.get(SOURCE_DIRECTORY, + "mozilla_self.p12.pem")); + exportTest("mozilla_self.p12.data", "pkcs12testenduser1", + KS_PASSWD, expectedValues); + out.println("Mozilla self test passed"); + + out.println("Openssl test"); + expectedValues = Files.readAllLines(Paths.get(SOURCE_DIRECTORY, + "openssl.p12.pem")); + exportTest("openssl.p12.data", "servercert", CERT_CHAIN_PASSWD, expectedValues); + out.println("openssl test passed"); + + out.println("with different keystore and entrykey password"); + expectedValues = Files.readAllLines(Paths.get(SOURCE_DIRECTORY, + "api_two_pass.p12_expected.data")); + readTest("api_two_pass.p12.data", KS_PASSWD, + expectedValues); + out.println("two pass test passed"); + } + + private static void readTest(String name, String password, + List expectedValues) + throws IOException { + convertToPFX(name); + final String[] command = new String[]{"-debug", "-list", "-v", + "-keystore", WORKING_DIRECTORY + File.separator + name, + "-storetype", "pkcs12", "-storepass", password}; + runAndValidate(command, expectedValues); + } + + private static void exportTest(String name, String alias, + String password, List expectedValues) + throws IOException { + convertToPFX(name); + final String[] command = new String[]{"-debug", "-export", "-alias", + alias, "-keystore", WORKING_DIRECTORY + File.separator + name, + "-storepass", password, "-storetype", "pkcs12", "-rfc"}; + runAndValidate(command, expectedValues); + } + + private static void runAndValidate(String[] command, + List expectedValues) throws IOException { + OutputAnalyzer output = Utils.executeKeytoolCommand(command); + if (expectedValues != null) { + expectedValues.stream().forEach(line -> { + output.shouldContain(line); + }); + } + } + + /** + * Decodes the base64 encoded keystore and writes into new file + * @param name base64 encoded keystore name + */ + private static void convertToPFX(String name) throws IOException{ + File base64File = new File(SOURCE_DIRECTORY, name); + File pkcs12File = new File(WORKING_DIRECTORY, name); + byte[] input = Files.readAllBytes(base64File.toPath()); + Files.write(pkcs12File.toPath(), Base64.getMimeDecoder(). + decode(input), StandardOpenOption.CREATE); + } +} diff --git a/test/java/security/KeyStore/PKCS12/KeytoolWriteP12Test.java b/test/java/security/KeyStore/PKCS12/KeytoolWriteP12Test.java new file mode 100644 index 0000000000000000000000000000000000000000..b35751fcb893ee8ea8099204814ac32ea77aa1ae --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/KeytoolWriteP12Test.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2012, 2016, 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. + */ + +import java.io.File; +import jdk.testlibrary.OutputAnalyzer; +import static java.lang.System.out; + +/** + * @test + * @bug 8048830 + * @summary Tests for creating pkcs12 keystore with various algorithms + * @library /lib/testlibrary ../ + * @run main KeytoolWriteP12Test + */ +public class KeytoolWriteP12Test { + private static final String ALIAS = "pkcs12testCA"; + private static final Utils.KeyStoreType PKCS12 = Utils.KeyStoreType.pkcs12; + private static final int FAILED_EXIT_CODE = 1; + private static final String CERT_FILE_NAME = "cert.data"; + private static final String DNAME = "CN=PKCS12 Test CA, OU=Security SQE, " + + "O=JavaSoft, C=US"; + private static final String WORKING_DIRECTORY = System. + getProperty("test.classes", "." + File.separator); + private enum Algorithm { + DSA, RSA, ECC + }; + private void run() { + out.println("Running DSA Test"); + keytoolListTest("kt_DSA.p12", Algorithm.DSA); + out.println("DSA Test passed"); + + out.println("Running RSA Test"); + final String rsaKeyStoreName = "kt_RSA_MD5.p12"; + keytoolListTest(rsaKeyStoreName, Algorithm.RSA); + out.println("RSA Test passed"); + + out.println("Running RSA and Signing Algorithm SHA1withRSA Test"); + keytoolListTest("kt_RSA_SHA1.p12", Algorithm.RSA, + "-sigalg", "SHA1withRSA"); + out.println("RSA and Signing Algorithm SHA1withRSA Test Passed"); + + out.println("Running Keysize 256 Test"); + keytoolListNegativeTest("kt_DSA_256.p12", Algorithm.DSA, "-keysize", + "256"); + out.println("Keysize 256 Test Passed"); + + out.println("Running Keysize 1023 Test"); + keytoolListTest("kt_RSA_MD5_1023.p12", Algorithm.RSA, "-keysize", + "1023"); + out.println("Keysize 1023 Test Passed"); + out.println("Running Export certificate Test"); + exportTest(rsaKeyStoreName); + out.println("Export certificate Test Passed"); + } + + private void exportTest(String keyStore) { + final String keyStoreName = WORKING_DIRECTORY + File.separator + + keyStore; + deleteKeyStoreFile(keyStoreName); + Utils.createKeyStore(DNAME, PKCS12, keyStore, ALIAS, + Algorithm.RSA.name()); + final String certFilePath = WORKING_DIRECTORY + File.separator + + CERT_FILE_NAME; + Utils.exportCert(PKCS12, keyStore, + ALIAS, certFilePath); + final String[] command = new String[]{"-debug", "-printcert", "-v", + "-file", certFilePath}; + Utils.executeKeytoolCommand(command); + } + + private void keytoolListTest(String keyStore, Algorithm algorithm, + String ...optionalArgs) { + final String keyStoreName = WORKING_DIRECTORY + File.separator + + keyStore; + final String[] command = new String[]{"-debug", "-list", "-v", "-alias", + ALIAS, "-keystore", keyStoreName, "-storetype", "pkcs12", + "-storepass", Utils.DEFAULT_PASSWD}; + deleteKeyStoreFile(keyStoreName); + Utils.createKeyStore(DNAME, PKCS12, keyStoreName, ALIAS, + algorithm.name(), optionalArgs); + OutputAnalyzer output = Utils.executeKeytoolCommand(command); + output.shouldContain(DNAME); + } + + private void keytoolListNegativeTest(String keyStore, Algorithm algorithm, + String... optionalArgs) { + final String keyStoreName = WORKING_DIRECTORY + File.separator + + keyStore; + deleteKeyStoreFile(keyStoreName); + Utils.createKeyStore(DNAME, PKCS12, keyStoreName, ALIAS, + algorithm.name(), optionalArgs, FAILED_EXIT_CODE); + } + + public static void main(String[] args) { + KeytoolWriteP12Test test = new KeytoolWriteP12Test(); + test.run(); + out.println("Test Passed"); + } + + private void deleteKeyStoreFile(String fileName) { + File file = new File(fileName); + if (file.exists()) { + file.delete(); + } + } +} diff --git a/test/java/security/KeyStore/PKCS12/MetadataEmptyTest.java b/test/java/security/KeyStore/PKCS12/MetadataEmptyTest.java new file mode 100644 index 0000000000000000000000000000000000000000..18742418c96ea7b8c37b23701490cc3afcff27fd --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/MetadataEmptyTest.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2012, 2016, 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. + */ + +import java.io.File; +import java.security.Key; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.UnrecoverableKeyException; +import java.security.cert.Certificate; +import java.io.IOException; +import java.security.cert.CertificateException; +import static java.lang.System.out; + +/** + * @test + * @bug 8048830 + * @summary Entry's attribute set should be empty + * @library /lib/testlibrary ../ + * @run main MetadataEmptyTest + */ +public class MetadataEmptyTest { + private static final char[] PASSWORD = "passwd".toCharArray(); + private static final String ALIAS = "testkey"; + private static final String KEYSTORE_PATH = System.getProperty( + "test.classes" + File.separator + "ks.pkcs12", + "." + File.separator + "ks.pkcs12"); + + private void runTest() throws IOException, KeyStoreException, + NoSuchAlgorithmException, CertificateException, + UnrecoverableKeyException { + KeyStore ks = Utils.loadKeyStore(KEYSTORE_PATH, + Utils.KeyStoreType.pkcs12, PASSWORD); + Key key = ks.getKey(ALIAS, PASSWORD); + Certificate cert = ks + .getCertificate(ALIAS); + KeyStore.Entry entry = new KeyStore.PrivateKeyEntry( + (PrivateKey) key, + new Certificate[]{cert}); + if (!entry.getAttributes().isEmpty()) { + throw new RuntimeException("Entry's attributes set " + + "must be empty"); + } + out.println("Test Passed"); + } + + public static void main(String[] args) throws Exception{ + MetadataEmptyTest test = new MetadataEmptyTest(); + test.setUp(); + test.runTest(); + } + + private void setUp() { + Utils.createKeyStore(Utils.KeyStoreType.pkcs12, KEYSTORE_PATH, ALIAS); + } +} diff --git a/test/java/security/KeyStore/PKCS12/MetadataStoreLoadTest.java b/test/java/security/KeyStore/PKCS12/MetadataStoreLoadTest.java new file mode 100644 index 0000000000000000000000000000000000000000..729c5fbe4b5a617ef05b5cb3074628c82c1b5f58 --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/MetadataStoreLoadTest.java @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2012, 2016, 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. + */ + +import java.io.File; +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.security.Key; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.PKCS12Attribute; +import java.security.PrivateKey; +import java.security.UnrecoverableEntryException; +import java.security.cert.Certificate; +import java.util.Arrays; +import java.util.Set; +import static java.lang.System.out; +import java.util.HashSet; + +/** + * @test + * @bug 8048830 + * @summary Test store metadata attributes to PKCS12 keystore. + * @library /lib/testlibrary ../ + * @run main MetadataStoreLoadTest + */ +public class MetadataStoreLoadTest { + private static final char[] PASSWORD = "passwd".toCharArray(); + private static final char[] KEY_PASSWORD = "keypasswd".toCharArray(); + private static final String ALIAS = "testkey_metadata"; + private static final String KEYSTORE = "ks.pkcs12"; + private static final String KESTORE_NEW = "ks-attr.pkcs12"; + private static final int MAX_HUGE_SIZE = 2000000; + private static final String WORKING_DIRECTORY = System.getProperty( + "test.classes", "." + File.separator); + private static final String KEYSTORE_PATH = WORKING_DIRECTORY + + File.separator + KEYSTORE; + private static KeyStore.Entry.Attribute[] ATTR_SET; + + private void runTest() throws GeneralSecurityException, + UnrecoverableEntryException, NoSuchAlgorithmException, + KeyStoreException, IOException { + storeAttrs(); + checkAttrs(); + } + + private void storeAttrs() throws UnrecoverableEntryException, + GeneralSecurityException, NoSuchAlgorithmException, + KeyStoreException, IOException { + KeyStore ksIn = Utils.loadKeyStore(KEYSTORE_PATH, + Utils.KeyStoreType.pkcs12, PASSWORD); + KeyStore ksAttr = KeyStore + .getInstance(Utils.KeyStoreType.pkcs12.name()); + ksAttr.load(null); + Key key = ksIn.getKey(ALIAS, PASSWORD); + Certificate cert = ksIn.getCertificate(ALIAS); + Set attrs = + new HashSet<>(Arrays.asList(ATTR_SET)); + KeyStore.Entry e = new KeyStore.PrivateKeyEntry((PrivateKey) key, + new Certificate[]{cert}, attrs); + ksAttr.setEntry(ALIAS, e, new KeyStore.PasswordProtection( + KEY_PASSWORD)); + + out.println("Attributes before store:"); + e.getAttributes().stream().forEach((attr) -> { + out.println(attr.getName() + ", '" + attr.getValue() + "'"); + }); + Utils.saveKeyStore(ksAttr, WORKING_DIRECTORY + File.separator + + KESTORE_NEW, PASSWORD); + } + + private void checkAttrs() throws UnrecoverableEntryException, + GeneralSecurityException, NoSuchAlgorithmException, + KeyStoreException, IOException { + KeyStore ks = Utils.loadKeyStore(WORKING_DIRECTORY + + File.separator + + KESTORE_NEW, Utils.KeyStoreType.pkcs12, PASSWORD); + KeyStore.Entry keyStoreEntry = ks.getEntry(ALIAS, + new KeyStore.PasswordProtection(KEY_PASSWORD)); + out.println("Attributes after store:"); + //print attribute values + keyStoreEntry.getAttributes().stream().forEach((attr) -> { + out.println(attr.getName() + ", '" + attr.getValue() + "'"); + }); + Arrays.stream(ATTR_SET).forEach((attr) -> { + if (!keyStoreEntry.getAttributes().contains(attr)) { + throw new RuntimeException("Entry doesn't contain attribute: (" + + attr.getName() + ", '" + attr.getValue() + "')"); + } + }); + } + + public static void main(String[] args) throws Exception { + MetadataStoreLoadTest test = new MetadataStoreLoadTest(); + test.setUp(); + test.runTest(); + out.println("Test Passed"); + } + + private void setUp() { + Utils.createKeyStore(Utils.KeyStoreType.pkcs12, KEYSTORE_PATH, ALIAS); + final String allCharsString = "`1234567890-=qwertyuiop[]asdfghjkl;'\\zx" + + "cvbnm,./!@#$%^&*()_+QWERTYUIOP{}ASDFGHJKL:|>ZXCVBNM<>?\""; + StringBuilder sbPrintable = new StringBuilder(); + while (sbPrintable.length() < MAX_HUGE_SIZE) { + sbPrintable.append(allCharsString); + } + final String hugePrintable = sbPrintable.toString(); + final String binaryString = "00:11:22:33:44:55:66:77:88:99:AA:BB:DD:" + + "EE:FF:"; + StringBuilder sbBinary = new StringBuilder(); + sbBinary.append(binaryString); + while (sbBinary.length() < MAX_HUGE_SIZE) { + sbBinary.append(":").append(binaryString); + } + sbBinary.insert(0, "[").append("]"); + final String hugeBinary = sbBinary.toString(); + ATTR_SET = new PKCS12Attribute[5]; + ATTR_SET[0] = new PKCS12Attribute("1.2.840.113549.1.9.1", + "Test email addres attr "); + ATTR_SET[1] = new PKCS12Attribute("1.2.110.1", "not registered attr"); + ATTR_SET[2] = new PKCS12Attribute("1.2.110.2", hugePrintable); + ATTR_SET[3] = new PKCS12Attribute("1.2.110.3", hugeBinary); + ATTR_SET[4] = new PKCS12Attribute("1.2.110.2", " "); + } +} diff --git a/test/java/security/KeyStore/PKCS12/ReadP12Test.java b/test/java/security/KeyStore/PKCS12/ReadP12Test.java new file mode 100644 index 0000000000000000000000000000000000000000..429a49857e5d1e4cab035255eae3b6804386c8fb --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/ReadP12Test.java @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2003,2014, 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. + * + * 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. + */ + +import static java.lang.System.out; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.Key; +import java.security.KeyStore; +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; +import java.util.Base64; +import java.util.Enumeration; + +/* + * @test + * @bug 8048617 + * @author Bill Situ + * @summary Read different types p12 key store to Check the read related APIs. + * including following test cases: + * ReadP12_IE_Chain: Read p12 key store (contains private key and associated + * certificate chain) from IE. + * ReadP12_IE_Self: Read p12 key store (contains only private key and + * self-signed certificate) from IE. + * ReadP12_JDK_Chain: Read p12 key store (contains private key and associated + * certificate chain) from JDK + * ReadP12_JDK_Self: Read p12 key store (contains only private key and + * self-signed certificate) from JDK. + * ReadP12_Mozilla_Self: Read p12 key store (contains only private key and + * self-signed certificate) from Mozilla. + * ReadP12_Mozilla_Chain: Read p12 key store (contains private key and + * associated certificate chain) from Mozilla. + * ReadP12_Mozilla_TwoEntries: Read p12 key store (contains 2 entries) from + * Mozilla. + * ReadP12_Netscape_Chain: Read p12 key store (contains private key and + * associated certificate chain) from Netscape. + * ReadP12_Netscape_Self: Read p12 key store (contains only private key and + * self-signed certificate) from Netscape. + * ReadP12_Netscape_TwoEntries: Read p12 key store (contains 2 entries) from + * Netscape. + * ReadP12_OpenSSL: Read p12 key store from OpenSSL. + */ + +public class ReadP12Test { + + private final static String IN_KETYSTORE_TYPE = "pkcs12"; + private final static String IN_KEYSTORE_PRV = "SunJSSE"; + private final static String IN_STORE_PASS = "pass"; + + public static void main(String args[]) throws Exception { + + ReadP12Test jstest = new ReadP12Test(); + String testCase = ""; + try { + testCase = "ReadP12_IE_Chain"; + jstest.readTest("ie_chain.pfx.data"); + + testCase = "ReadP12_IE_Self"; + jstest.readTest("ie_self.pfx.data"); + + testCase = "ReadP12_JDK_Chain"; + jstest.readTest("jdk_chain.p12.data"); + + testCase = "ReadP12_JDK_Self"; + jstest.readTest("jdk_self.p12.data"); + + testCase = "ReadP12_Mozilla_Chain"; + jstest.readTest("mozilla_chain.p12.data"); + + testCase = "ReadP12_Mozilla_Self"; + jstest.readTest("mozilla_self.p12.data"); + + testCase = "ReadP12_Mozilla_TwoEntries"; + jstest.readTest("mozilla_twoentries.p12.data"); + + testCase = "ReadP12_Netscape_Chain"; + jstest.readTest("netscape_chain.p12.data"); + + testCase = "ReadP12_Netscape_Self"; + jstest.readTest("netscape_self.p12.data"); + + testCase = "ReadP12_Netscape_TwoEntries"; + jstest.readTest("netscape_twoentries.p12.data"); + + testCase = "ReadP12_openssl"; + jstest.readTest("openssl.p12.data"); + + } catch (Exception e) { + System.err.println(testCase + ": failed with execption: " + + e.getMessage()); + throw e; + + } + out.println(testCase + ": Pass!!"); + } + + private void readTest(String inKeyStore) throws Exception { + + KeyStore inputKeyStore; + + // Initialize KeyStore + String dir = System.getProperty("test.src", "."); + String keystorePath = dir + File.separator + "certs" + File.separator + + "readP12"; + inputKeyStore = KeyStore + .getInstance(IN_KETYSTORE_TYPE, IN_KEYSTORE_PRV); + // KeyStore have encoded by Base64.getMimeEncoder().encode(),need decode + // first. + byte[] input = Files.readAllBytes(Paths.get(keystorePath, inKeyStore)); + ByteArrayInputStream arrayIn = new ByteArrayInputStream(Base64 + .getMimeDecoder().decode(input)); + inputKeyStore.load(arrayIn, IN_STORE_PASS.toCharArray()); + out.println("Initialize KeyStore : " + inKeyStore + " success"); + + out.println("getProvider : " + inputKeyStore.getProvider()); + out.println("getType : " + inputKeyStore.getType()); + out.println("getDefaultType : " + KeyStore.getDefaultType()); + + int idx = 0; + Enumeration e = inputKeyStore.aliases(); + String alias; + while (e.hasMoreElements()) { + alias = e.nextElement(); + out.println("Alias " + idx + " : " + alias); + if (inputKeyStore.containsAlias(alias) == false) { + throw new RuntimeException("Alias not found"); + } + + out.println("getCreationDate : " + + inputKeyStore.getCreationDate(alias)); + + X509Certificate cert = (X509Certificate) inputKeyStore + .getCertificate(alias); + out.println("getCertificate : " + cert.getSubjectDN()); + String retAlias = inputKeyStore.getCertificateAlias(cert); + if (!retAlias.equals(alias)) { + throw new RuntimeException("Alias mismatch"); + } + out.println("getCertificateAlias : " + retAlias); + + Certificate[] certs = inputKeyStore.getCertificateChain(alias); + for (int i = 0; i < certs.length; i++) { + out.println("getCertificateChain " + i + " : " + + ((X509Certificate) certs[i]).getSubjectDN()); + } + + boolean isCertEntry = inputKeyStore.isCertificateEntry(alias); + // test KeyStore only contain key pair entries. + if (isCertEntry == true) { + throw new RuntimeException( + "inputKeystore should not be certEntry because test keystore only contain key pair entries."); + } + + boolean isKeyEntry = inputKeyStore.isKeyEntry(alias); + if (isKeyEntry) { + Key key = inputKeyStore.getKey(alias, + IN_STORE_PASS.toCharArray()); + out.println("Key : " + key.toString()); + } else { + throw new RuntimeException("Entry type unknown\n"); + } + idx++; + } + + int size = inputKeyStore.size(); + if (idx != size) { + throw new RuntimeException("Size not match"); + } + + } +} diff --git a/test/java/security/KeyStore/PKCS12/StoreTrustedCertAPITest.java b/test/java/security/KeyStore/PKCS12/StoreTrustedCertAPITest.java new file mode 100644 index 0000000000000000000000000000000000000000..68efa2bed04c59340a3fd34492a27aa2fcaf2517 --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/StoreTrustedCertAPITest.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2012, 2016, 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. + */ + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import static java.lang.System.err; +import static java.lang.System.out; + +/** + * @test + * @bug 8048830 + * @summary Test imports certificate from file to PKCS12 keystore store it as + * trusted certificate Check import errors (must be not errors) & check keystore + * content after import + * @library /lib/testlibrary ../ + * @run main StoreTrustedCertAPITest + */ +public class StoreTrustedCertAPITest { + private static final char[] PASSWORD = "passwd".toCharArray(); + private static final String ALIAS = "testkey_stcapi"; + private static final String WORKING_DIRECTORY = System.getProperty( + "test.classes", "." + File.separator); + private static final String CERT_PATH = WORKING_DIRECTORY + File.separator + + "cert.data"; + private static final String KEYSTORE_PATH = WORKING_DIRECTORY + + File.separator + "ks.pkcs12"; + + /** + * Test logic (environment has set up) + */ + private void runTest() throws FileNotFoundException, CertificateException, + KeyStoreException, IOException, NoSuchAlgorithmException { + Certificate cert; + CertificateFactory cf; + try (FileInputStream fi = new FileInputStream(CERT_PATH)) { + cf = CertificateFactory.getInstance("X.509"); + cert = cf.generateCertificate(fi); + KeyStore ks = KeyStore.getInstance( + Utils.KeyStoreType.pkcs12.name()); + ks.load(null, null); + ks.setCertificateEntry(ALIAS, cert); + Utils.saveKeyStore(ks, KEYSTORE_PATH, PASSWORD); + ks = Utils.loadKeyStore(KEYSTORE_PATH, Utils.KeyStoreType.pkcs12, + PASSWORD); + final Certificate ksCert = ks.getCertificate(ALIAS); + if (!ksCert.equals(cert)) { + err.println("Orig cert: " + cert.toString()); + err.println("Cert from keystore: " + ksCert.toString()); + throw new RuntimeException("Certificates don't match"); + } + } + } + + public static void main(String[] args) throws Exception { + StoreTrustedCertAPITest test = new StoreTrustedCertAPITest(); + test.setUp(); + test.runTest(); + out.println("Test Passed"); + } + + private void setUp() { + Utils.createKeyStore(Utils.KeyStoreType.pkcs12, KEYSTORE_PATH, ALIAS); + Utils.exportCert(Utils.KeyStoreType.pkcs12, KEYSTORE_PATH, + ALIAS, CERT_PATH); + new File(KEYSTORE_PATH).delete(); + } +} diff --git a/test/java/security/KeyStore/PKCS12/StoreTrustedCertKeytool.java b/test/java/security/KeyStore/PKCS12/StoreTrustedCertKeytool.java new file mode 100644 index 0000000000000000000000000000000000000000..1b1672d4bd0b3b74693d3b038945b3f6ecbd4bbc --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/StoreTrustedCertKeytool.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2012, 2016, 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. + */ + +import java.io.File; +import java.io.IOException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import jdk.testlibrary.OutputAnalyzer; +import static java.lang.System.out; + +/** + * @test + * @bug 8048830 + * @summary Tests keytool command imports certificate , list keystore, print + * certificate and import password help. + * @library /lib/testlibrary ../ + * @run main StoreTrustedCertKeytool + */ +public class StoreTrustedCertKeytool { + private static final String PASSWORD = "passwd"; + private static final String ALIAS = "testkey_stckey"; + private static final String FILE_SEPARATOR = File.separator; + private static final String WORKING_DIRECTORY = System.getProperty( + "test.classes", "." + FILE_SEPARATOR); + private static final String CERT_PATH = WORKING_DIRECTORY + + FILE_SEPARATOR + + "cert.data"; + private static final String KEYSTORE_PATH = WORKING_DIRECTORY + + FILE_SEPARATOR + "ks.pkcs12"; + + protected void run() throws IOException, KeyStoreException, + NoSuchAlgorithmException, CertificateException { + setUp(); + importCert(); + out.println("Import Cert test passed"); + listCerts(); + out.println("listCerts test passed"); + printCert(); + out.println("print cert test passed"); + helpImportPassword(); + out.println("help import test passed"); + } + + private void importCert() { + final String[] command = new String[]{"-debug", "-importcert", + "-alias", ALIAS, "-file", CERT_PATH, "-noprompt", "-keystore", + KEYSTORE_PATH, "-storetype", "pkcs12", "-storepass", PASSWORD}; + // If the keystore exists delete it. + File keystoreFile = new File(KEYSTORE_PATH); + if (keystoreFile.exists()) { + keystoreFile.delete(); + } + Utils.executeKeytoolCommand(command); + } + + private void listCerts() throws IOException, KeyStoreException, + NoSuchAlgorithmException, CertificateException { + final String[] command = new String[]{"-debug", "-list", "-v", + "-alias", ALIAS, "-keystore", KEYSTORE_PATH, "-storetype", "pkcs12", + "-storepass", PASSWORD}; + OutputAnalyzer output = Utils.executeKeytoolCommand(command); + if (output == null) { + throw new RuntimeException("Keystore print fails"); + } + X509Certificate ksCert = null; + final KeyStore ks = Utils.loadKeyStore(KEYSTORE_PATH, + Utils.KeyStoreType.pkcs12, PASSWORD.toCharArray()); + ksCert = (X509Certificate) ks.getCertificate(ALIAS); + + if (ksCert == null) { + throw new RuntimeException("Certificate " + ALIAS + + " not found in Keystore " + KEYSTORE_PATH); + } + String serialNumber = ksCert.getSerialNumber().toString(16); + output.shouldContain(serialNumber); + } + + private void printCert() { + final String[] command = new String[]{"-debug", "-printcert", + "-file", CERT_PATH}; + Utils.executeKeytoolCommand(command); + + } + + private void helpImportPassword() { + final String[] command = new String[]{"-debug", "-help", + "-importpassword"}; + Utils.executeKeytoolCommand(command); + } + + public static void main(String[] args) throws Exception { + final StoreTrustedCertKeytool test = new StoreTrustedCertKeytool(); + test.run(); + out.println("Test Passed"); + } + + private void setUp() { + Utils.createKeyStore(Utils.KeyStoreType.pkcs12, KEYSTORE_PATH, ALIAS); + Utils.exportCert(Utils.KeyStoreType.pkcs12, KEYSTORE_PATH, ALIAS, + CERT_PATH); + new File(KEYSTORE_PATH).delete(); + } +} diff --git a/test/java/security/KeyStore/PKCS12/Utils.java b/test/java/security/KeyStore/PKCS12/Utils.java new file mode 100644 index 0000000000000000000000000000000000000000..26894157c3f14dd626ba157ff04469cab2c04580 --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/Utils.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2012, 2016, 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. + */ + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.util.Arrays; +import java.util.List; +import jdk.testlibrary.ProcessTools; +import jdk.testlibrary.OutputAnalyzer; +import jdk.testlibrary.JDKToolFinder; +import static java.lang.System.out; +import java.util.ArrayList; + +/** + * Helper class for creating keystore and executing keytool commands + */ +public class Utils { + public enum KeyStoreType { + jks, pkcs12; + } + public static final String DEFAULT_DNAME + = "CN=TestKey, T=FuncTestCertKey, O=Oracle, OU=JDKSQE, C=US"; + public static final String DEFAULT_PASSWD = "passwd"; + public static final String RSA = "rsa"; + public static final String JAVA_HOME = System.getProperty("java.home"); + public static final String KEYTOOL = "keytool"; + private static final int SUCCESS_EXIT_CODE = 0; + + public static OutputAnalyzer executeKeytoolCommand(String[] command) { + return executeKeytoolCommand(command, SUCCESS_EXIT_CODE); + } + + public static OutputAnalyzer executeKeytoolCommand(String[] command, + int exitCode) { + String[] keytoolCmd = new String[command.length + 1]; + OutputAnalyzer output = null; + try { + keytoolCmd[0] = JDKToolFinder.getJDKTool(KEYTOOL); + System.arraycopy(command, 0, keytoolCmd, 1, command.length); + output = ProcessTools.executeCommand(keytoolCmd); + output.shouldHaveExitValue(exitCode); + out.println("Executed keytool command sucessfully:" + + Arrays.toString(keytoolCmd)); + } catch (Throwable e) { + e.printStackTrace(System.err); + throw new RuntimeException("Keytool Command execution failed : " + + Arrays.toString(keytoolCmd), e); + } + return output; + } + + public static void createKeyStore(KeyStoreType type, String name, + String alias) { + createKeyStore(DEFAULT_DNAME, type, name, alias, RSA); + } + + public static void createKeyStore(String dName, KeyStoreType type, + String name, String alias, String algorithm, + String... optionalArgs) { + createKeyStore(dName, type, name, alias, algorithm, optionalArgs, + SUCCESS_EXIT_CODE); + } + + public static void createKeyStore(String dName, KeyStoreType type, + String name, String alias, String algorithm, + String[] optionalArgs, int exitCode) { + String[] command = new String[]{"-debug", "-genkeypair", "-alias", + alias, "-keystore", name, "-dname", dName, "-storepass", + DEFAULT_PASSWD, "-keypass", DEFAULT_PASSWD, "-validity", "7300", + "-keyalg", algorithm, "-storetype", type.name()}; + if (optionalArgs != null && optionalArgs.length > 0) { + List commandArgs = new ArrayList<>(Arrays.asList(command)); + List temp = Arrays.asList(optionalArgs); + commandArgs.addAll(temp); + if (!commandArgs.contains(("-keysize"))) { + commandArgs.add("-keysize"); + commandArgs.add("1024"); + } + command = commandArgs.toArray(new String[commandArgs.size()]); + } + executeKeytoolCommand(command, exitCode); + } + + public static void exportCert(KeyStoreType type, String name, + String alias, String cert) { + String[] command = {"-debug", "-exportcert", "-keystore", name, + "-storetype", type.name(), "-storepass", DEFAULT_PASSWD, "-alias", + alias,"-file",cert,"-noprompt"}; + executeKeytoolCommand(command); + } + + public static KeyStore loadKeyStore(String file, KeyStoreType type, + char[] passwd) + throws IOException, KeyStoreException, + NoSuchAlgorithmException, CertificateException { + KeyStore ks = KeyStore.getInstance(type.name()); + try (FileInputStream fin = new FileInputStream(file)) { + ks.load(fin, passwd); + } + return ks; + } + + public static void saveKeyStore(KeyStore ks, String file, char[] passwd) + throws IOException, KeyStoreException, NoSuchAlgorithmException, + CertificateException { + try (FileOutputStream fout = new FileOutputStream(file)) { + ks.store(fout, passwd); + } + } +} diff --git a/test/java/security/KeyStore/PKCS12/WriteP12Test.java b/test/java/security/KeyStore/PKCS12/WriteP12Test.java new file mode 100644 index 0000000000000000000000000000000000000000..f4024090f2f6398cb9077ea8aad10c7f3f9b34b3 --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/WriteP12Test.java @@ -0,0 +1,371 @@ +/* + * Copyright (c) 2003, 2015, 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. + * + * 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. + */ + +import static java.lang.System.out; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.Key; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.UnrecoverableKeyException; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.Arrays; +import java.util.Base64; +import java.util.Enumeration; + +/* + * @test + * @bug 8048618 + * @summary Write different types p12 key store to Check the write related + * APIs. + * @run main WriteP12Test + */ + +public class WriteP12Test { + + private static final String IN_KEYSTORE_TYPE = "jks"; + private static final String IN_KEYSTORE_PRV = "SUN"; + + private static final String IN_KEYSTORE_ENDUSER = "keystoreEU.jks.data"; + private static final String IN_KEYSTORE_CA = "keystoreCA.jks.data"; + private static final String OUT_KEYSTORE = "outKeyStore.p12"; + + private static final String IN_STORE_PASS = "storepass"; + private static final String IN_KEY_PASS = "keypass"; + + private static final String CERT_PATH = System.getProperty("test.src", ".") + + File.separator + "certs" + File.separator + "writeP12" + + File.separator; + + private static final String CA_CERT_STR = "-----BEGIN CERTIFICATE-----\n" + + "MIIDFzCCAf8CBD8+0nAwDQYJKoZIhvcNAQEFBQAwUDELMAkGA1UEBhMCV\n" + + "VMxETAPBgNVBAoTCEphdmFTb2Z0MRUwEwYDVQQLEwxTZWN1cml0eSBTUU\n" + + "UxFzAVBgNVBAMTDlBLQ1MxMiBUZXN0IENBMB4XDTAzMDgxNzAwNTUxMlo\n" + + "XDTEzMDgxNDAwNTUxMlowUDELMAkGA1UEBhMCVVMxETAPBgNVBAoTCEph\n" + + "dmFTb2Z0MRUwEwYDVQQLEwxTZWN1cml0eSBTUUUxFzAVBgNVBAMTDlBLQ\n" + + "1MxMiBUZXN0IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQ\n" + + "EAk7Sh+K/yGsmJacZnjfkZfuWxGNJCPW0q69exwoRP+eBHMQwG00yi9aL\n" + + "SsZAqNpJSCDvpgySOAUmBd+f8WFhHqJfRVREVfv3mradDKZCjhqtsUI7I\n" + + "wRTYYy9clFkeeK4dHaxbuFMPpUu7yQfwSTXgvOA/UJ4kJuGtaYAdTJI4e\n" + + "f1mUASo6+dea0UZA/FHCuV7O6z3hr5VHlyhJL2/o/8M5tGBTBISODJSnn\n" + + "GNBvtQLNHnWYvs470UAE2BtuCGYh1V/3HAH1tRirS3MBBcb1XnIkiiXR3\n" + + "tjaBSB+XhoCfuG8KtInXXFaAnvKfY9mYFw6VJt9JYQpY2VDC7281/Pbz0\n" + + "dQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQBzXZ8zHWrnC8/E+N/n2Czhx\n" + + "i18YQc2LPWBDLYTTxoFEazWmYLv1k/JT7Nta1qu1quvxXJ4uV1XHbd9NF\n" + + "AJWKwtFQEpfv4o6I7qWUPoxnfA+jyqKXxv27z25tzt+Y4xOEhqvO03G0Q\n" + + "imhkiNt9MF7L69y2U0/U73+uFNGzdAEDiI9EibvICiOnr1TeQ5GekK3Yb\n" + + "k5qe3lviMZPkkSXepTJI8m0AiXCji+eXj97jVLeH+RxeBchBY+uELrqUr\n" + + "sVOVWh7IBCqC/V7FqUTkmD1IFlzkkinatpl42s1MbhJId2yQkzaeBRc\n" + + "suE63bDEtuRWp9ynMO3QA4Yu85uBRWGzQ1Di\n" + + "-----END CERTIFICATE-----"; + private static final String LEAD_CERT = "-----BEGIN CERTIFICATE-----\n" + + "MIICwDCCAaigAwIBAgIEPz7S1jANBgkqhkiG9w0BAQQFADBQMQswCQYDV\n" + + "QQGEwJVUzERMA8GA1UEChMISmF2YVNvZnQxFTATBgNVBAsTDFNlY3VyaX\n" + + "R5IFNRRTEXMBUGA1UEAxMOUEtDUzEyIFRlc3QgQ0EwHhcNMDAwODA5MDc\n" + + "wMDAwWhcNMTAwODA3MDcwMDAwWjBSMQswCQYDVQQGEwJVUzERMA8GA1UE\n" + + "ChMISmF2YVNvZnQxFTATBgNVBAsTDFNlY3VyaXR5IFNRRTEZMBcGA1UEA\n" + + "xMQUEtDUzEyIFRlc3QgTGVhZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgY\n" + + "kCgYEAzq9X2USz/WjDhT+jUyZWqB5h4A33tS11YqH5qYvqjTXjcUI6gOp\n" + + "moXMafDG9RHRlIccvp51xLp7Ap3WMrv411lWBttqtZi5c1/DEC1cEM/Sl\n" + + "PCk1r2zFbkJu7QKieXeMcrjZEo6LcBHMwQjIpI+up9cr3VjuyqG/olQkU\n" + + "mXVuS0CAwEAAaMkMCIwDwYDVR0PAQH/BAUDAweAADAPBgNVHRMBAf8EBT\n" + + "ADAQH/MA0GCSqGSIb3DQEBBAUAA4IBAQBhbuim98TWmtv9vSldRE7RvQ8\n" + + "FlS0TyZVO7kcSNtfCUE4R76J1ElN74Koc5pQnUtduLeQJs2ao/mEcCZsE\n" + + "zVcwI3mSZrSzPhc8s7w5gOQA4TUwVLSSjKgBCaZ7R3+qJ3QeqPJ5O6sFz\n" + + "pvBYkgSa4MWptK41jbmT8cwZQJXFCi8WxFFJ+p97F1Ppm3LgmYmtiUP4M\n" + + "ZQwOBvpTZWXU0WrqFXpzWQx0mg4SX19fZm4nLcJAerCEUphf8ILagtpQM\n" + + "EErT3/jg6mfCdT3Rj055QXPfF4OiRFevPF5a1fZgrCePCukRQZcd7s8K5\n" + + "OBIaryuM0MdFtlzxi6XWeUNpVFFHURcy\n" + + "-----END CERTIFICATE-----"; + private static final String END_CERT = "-----BEGIN CERTIFICATE-----\n" + + "MIICNjCCAZ+gAwIBAgIEPz7WtzANBgkqhkiG9w0BAQQFADBSMQswCQYDV\n" + + "QQGEwJVUzERMA8GA1UEChMISmF2YVNvZnQxFTATBgNVBAsTDFNlY3VyaX\n" + + "R5IFNRRTEZMBcGA1UEAxMQUEtDUzEyIFRlc3QgTGVhZDAeFw0wMDA4MDk\n" + + "wNzAwMDBaFw0xMDA4MDcwNzAwMDBaMFgxCzAJBgNVBAYTAlVTMREwDwYD\n" + + "VQQKEwhKYXZhU29mdDEVMBMGA1UECxMMU2VjdXJpdHkgU1FFMR8wHQYDV\n" + + "QQDExZQS0NTMTIgVGVzdCBFbmQgVXNlciAxMIGfMA0GCSqGSIb3DQEBAQ\n" + + "UAA4GNADCBiQKBgQDIKomSYomDzH/V63eDQEG7od0DLcnnVZ81pbWhDss\n" + + "8gHV2m8pADdRqdihBmnSQEaMW4D3uZ4sFE1LtkQls6hjd7SdOsG5Y24L8\n" + + "15jot9a2JcB73H8H0VKirrObL5BZdt7BtASPDnYtW4Spt++YjDoJFxyF0\n" + + "HchkavzXaVTlexakwIDAQABoxMwETAPBgNVHQ8BAf8EBQMDB4AAMA0GCS\n" + + "qGSIb3DQEBBAUAA4GBAIFA3JXEmb9AXn3RD7t+Mn6DoyVDIy5jsn6xOKT\n" + + "JV25I0obpDUzgw4QaAMmM0ZvusOmZ2wZNS8MtyTUgdANyakbzn5SdxbTy\n" + + "TLEqQsFbX8UVC38fx5ZM6ExA5YSAvgmXudZpOVC0ATccoZS3JFU8CxSfW\n" + + "+Q3IC2MLh+QTg3hUJ5b\n-----END CERTIFICATE-----"; + + private final Certificate testerCert; + private final Certificate testLeadCert; + private final Certificate caCert; + + WriteP12Test() throws CertificateException { + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + caCert = cf.generateCertificate(new ByteArrayInputStream(CA_CERT_STR + .getBytes())); + testLeadCert = cf.generateCertificate(new ByteArrayInputStream( + LEAD_CERT.getBytes())); + testerCert = cf.generateCertificate(new ByteArrayInputStream(END_CERT + .getBytes())); + } + + public static void main(String[] args) throws CertificateException, + UnrecoverableKeyException, KeyStoreException, + NoSuchProviderException, NoSuchAlgorithmException, IOException { + WriteP12Test jstest = new WriteP12Test(); + out.println("test WriteP12CertChain"); + /* + * WriteP12CertChain: This test creates a p12 keystore contains one + * entry with private key and a certificate chains contains three + * certificates in the order of user->lead->ca. This case expects to + * pass. + */ + jstest.test(new Certificate[] { jstest.testerCert, jstest.testLeadCert, + jstest.caCert }, IN_KEYSTORE_ENDUSER, "pkcs12testenduser1", + "pass", "pass"); + + /* + * WriteP12CertChainBad: same as WriteP12CertChain but chains order is + * user-ca-lead, the order is wrong so expects to fail. + */ + out.println("test WriteP12CertChainBad"); + try { + jstest.test(new Certificate[] { jstest.testerCert, jstest.caCert, + jstest.testLeadCert }, IN_KEYSTORE_ENDUSER, + "pkcs12testenduser1", "pass", "pass"); + throw new RuntimeException( + " Certificate chain is not valid, test should not pass." + + " Test failed."); + } catch (KeyStoreException e) { + e.printStackTrace(); + out.println(" Certificate chain is not valid,exception is" + + " expected. Test passed."); + } + /* + * WriteP12PrivateKey:This test creates a p12 contains a self-signed + * cert and private key,expects no exception + */ + out.println("test WriteP12PrivateKey"); + jstest.test(null, IN_KEYSTORE_ENDUSER, "pkcs12testenduser1", "pass", + "pass"); + + /* + * WriteP12TwoEntry: This test creates a p12 keystore with different + * storepass and keypass, and contains two entries. + */ + out.println("test WriteP12TwoEntry"); + jstest.testTwoEntry(IN_KEYSTORE_ENDUSER, IN_KEYSTORE_CA, + "pkcs12testenduser1", "pass", "pass"); + /* + * WriteP12TwoPass: This test creates a p12 keystore with different + * storepass and keypass, and contains one entry with private key and a + * certificate + */ + out.println("test WriteP12TwoPass"); + jstest.test(null, IN_KEYSTORE_CA, "pkcs12testCA", "storepass", + "keypass"); + } + + private void test(Certificate certs[], String inKeyStorePath, + String userAlias, String outStorePass, String outKeyPass) + throws KeyStoreException, NoSuchProviderException, IOException, + CertificateException, UnrecoverableKeyException, + NoSuchAlgorithmException { + // init output key store + KeyStore outputKeyStore = KeyStore.getInstance("pkcs12", "SunJSSE"); + outputKeyStore.load(null, null); + try (FileOutputStream fout = new FileOutputStream(OUT_KEYSTORE)) { + // KeyStore have encoded by Base64.getMimeEncoder().encode(),need + // decode first. + byte[] input = Files.readAllBytes(Paths.get(CERT_PATH, + inKeyStorePath)); + ByteArrayInputStream arrayIn = new ByteArrayInputStream(Base64 + .getMimeDecoder().decode(input)); + // input key store + KeyStore inputKeyStore = KeyStore.getInstance(IN_KEYSTORE_TYPE, + IN_KEYSTORE_PRV); + inputKeyStore.load(arrayIn, IN_STORE_PASS.toCharArray()); + // add key/certificate to output key store + Key key = inputKeyStore + .getKey(userAlias, IN_KEY_PASS.toCharArray()); + out.println("Input Key Algorithm " + key.getAlgorithm()); + out.println("====Input Certs====="); + if (certs == null) { + certs = new Certificate[] { inputKeyStore + .getCertificate(userAlias) }; + } + for (Certificate cert : certs) { + out.println(((X509Certificate) cert).getSubjectDN()); + } + outputKeyStore.setKeyEntry(userAlias, key, + outKeyPass.toCharArray(), certs); + Certificate retCerts[] = outputKeyStore + .getCertificateChain(userAlias); + out.println("====Output Certs====="); + for (Certificate retCert : retCerts) { + out.println(((X509Certificate) retCert).getSubjectDN()); + } + out.println("====Output Key Algorithm====="); + Key outKey = outputKeyStore.getKey(userAlias, + outKeyPass.toCharArray()); + out.println(outKey.getAlgorithm()); + + if (!key.equals(outKey)) { + throw new RuntimeException("key don't match"); + } + if (!Arrays.equals(certs, retCerts)) { + throw new RuntimeException("certs don't match"); + } + // save output + outputKeyStore.store(fout, outStorePass.toCharArray()); + // test output + testKeyStore(outputKeyStore, outKeyPass.toCharArray()); + } + } + + private void testTwoEntry(String inKeyStoreOnePath, + String inKeyStoreTwoPath, String userAlias, String outStorePass, + String outKeyPass) throws KeyStoreException, + NoSuchProviderException, NoSuchAlgorithmException, + CertificateException, IOException, UnrecoverableKeyException { + // initial KeyStore + KeyStore outputKeyStore = KeyStore.getInstance("pkcs12", "SunJSSE"); + try (FileOutputStream fout = new FileOutputStream(OUT_KEYSTORE);) { + outputKeyStore.load(null, null); + KeyStore inputKeyStoreOne, inputKeyStoreTwo; + inputKeyStoreOne = KeyStore.getInstance(IN_KEYSTORE_TYPE, + IN_KEYSTORE_PRV); + // KeyStore have encoded by Base64.getMimeEncoder().encode(),need + // decode first. + byte[] inputBytes = Files.readAllBytes(Paths.get(CERT_PATH, + inKeyStoreOnePath)); + ByteArrayInputStream arrayIn = new ByteArrayInputStream(Base64 + .getMimeDecoder().decode(inputBytes)); + // input key store + inputKeyStoreOne.load(arrayIn, IN_STORE_PASS.toCharArray()); + + inputBytes = Files.readAllBytes(Paths.get(CERT_PATH, + inKeyStoreTwoPath)); + arrayIn = new ByteArrayInputStream(Base64.getMimeDecoder().decode( + inputBytes)); + inputKeyStoreTwo = KeyStore.getInstance(IN_KEYSTORE_TYPE, + IN_KEYSTORE_PRV); + inputKeyStoreTwo.load(arrayIn, IN_STORE_PASS.toCharArray()); + + // add key/certificate to output key store + out.println("====First Entry====="); + Key inputKey = inputKeyStoreOne.getKey(userAlias, + IN_KEY_PASS.toCharArray()); + Certificate cert = inputKeyStoreOne.getCertificate(userAlias); + Certificate certs[] = new Certificate[1]; + certs[0] = cert; + + out.println("====Input1 Key====="); + out.println(inputKey.getAlgorithm()); + out.println("====Input1 Certs====="); + out.println("Certificate :"); + out.println(((X509Certificate) cert).getSubjectDN()); + outputKeyStore.setKeyEntry("USER", inputKey, + outKeyPass.toCharArray(), certs); + out.println("====Second Entry====="); + String caAlias = "pkcs12testca"; + inputKey = inputKeyStoreTwo.getKey(caAlias, + IN_KEY_PASS.toCharArray()); + cert = inputKeyStoreTwo.getCertificate(caAlias); + certs[0] = cert; + out.println("====Input2 Key====="); + out.println(inputKey.getAlgorithm()); + out.println("====Input2 Certs====="); + out.println("Certificate :"); + out.println(((X509Certificate) cert).getSubjectDN()); + outputKeyStore.setKeyEntry("CA", inputKey, + outKeyPass.toCharArray(), certs); + // save output + outputKeyStore.store(fout, outStorePass.toCharArray()); + // test output + testKeyStore(outputKeyStore, outKeyPass.toCharArray()); + } + } + + private void testKeyStore(KeyStore inputKeyStore, char[] keypass) + throws KeyStoreException, UnrecoverableKeyException, + NoSuchAlgorithmException { + out.println("========== Key Store =========="); + out.println("getProvider : " + inputKeyStore.getProvider()); + out.println("getType : " + inputKeyStore.getType()); + out.println("getDefaultType : " + KeyStore.getDefaultType()); + + int idx = 0; + Enumeration e = inputKeyStore.aliases(); + String alias; + while (e.hasMoreElements()) { + alias = e.nextElement(); + if (!inputKeyStore.containsAlias(alias)) { + throw new RuntimeException("Alias not found"); + } + out.println("Alias " + idx + " : " + alias); + out.println("getCreationDate : " + + inputKeyStore.getCreationDate(alias)); + X509Certificate cert = (X509Certificate) inputKeyStore + .getCertificate(alias); + out.println("getCertificate : " + cert.getSubjectDN()); + String retAlias = inputKeyStore.getCertificateAlias(cert); + if (!retAlias.equals(alias)) { + throw new RuntimeException("Alias mismatch, actually " + + retAlias + ", expected " + alias); + } + out.println("getCertificateAlias : " + retAlias); + Certificate[] certs = inputKeyStore.getCertificateChain(alias); + int i = 0; + for (Certificate certification : certs) { + out.println("getCertificateChain " + i + + ((X509Certificate) certification).getSubjectDN()); + i++; + } + if (inputKeyStore.isCertificateEntry(alias)) { + throw new RuntimeException( + "inputKeystore should not be certEntry because this" + + " keystore only contain key pair entries."); + } + if (!inputKeyStore.isKeyEntry(alias)) { + throw new RuntimeException("Entry type unknown."); + } + idx++; + } + int size = inputKeyStore.size(); + if (idx != size) { + throw new RuntimeException("Size not match, actually " + idx + + ", expected " + size); + } + } + +} diff --git a/test/java/security/KeyStore/PKCS12/api_cert_chain.p12.data b/test/java/security/KeyStore/PKCS12/api_cert_chain.p12.data new file mode 100644 index 0000000000000000000000000000000000000000..b4da4794d4eef5e04f45f9a5985bae23aafce3ac --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/api_cert_chain.p12.data @@ -0,0 +1,76 @@ +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 diff --git a/test/java/security/KeyStore/PKCS12/api_cert_chain.p12_expected.data b/test/java/security/KeyStore/PKCS12/api_cert_chain.p12_expected.data new file mode 100644 index 0000000000000000000000000000000000000000..7cf01d69e0f79ce7599ab8ca7b6a0e86e62ea9e2 --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/api_cert_chain.p12_expected.data @@ -0,0 +1,7 @@ +SHA1: 09:F1:08:B1:B3:28:22:23:22:F7:5F:6D:4A:8D:0E:0A:5E:6D:56:FB +SHA256: AD:57:47:67:20:96:49:86:53:E4:10:EF:BD:4D:D2:B0:81:C0:B0:BB:62:AE:BE:47:80:DC:00:F8:E3:E7:66:B5 +SHA1: 2B:CE:0C:E1:35:B9:9D:FE:5A:6E:25:88:01:F7:E9:E5:7B:89:17:42 +SHA256: 65:F3:0A:64:F2:52:B2:4E:F8:76:C5:D0:6D:53:7C:E8:00:AE:F4:95:3C:CC:CB:01:6B:22:AF:46:36:50:CF:FF +SHA1: 7D:48:4D:1C:F8:55:E8:79:6A:B0:19:E1:26:4F:AC:FD:57:6B:38:A0 +SHA256: 0A:14:3F:88:8D:C2:D6:97:3E:02:0F:5F:17:E3:D9:FE:CF:93:10:2C:3C:8D:81:AC:06:2F:32:39:4D:0E:CB:6A +Alias name: servercert diff --git a/test/java/security/KeyStore/PKCS12/api_private_key.p12.data b/test/java/security/KeyStore/PKCS12/api_private_key.p12.data new file mode 100644 index 0000000000000000000000000000000000000000..4daf0299c1dfa6755d322eb3d90cd621467884e5 --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/api_private_key.p12.data @@ -0,0 +1,31 @@ +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 diff --git a/test/java/security/KeyStore/PKCS12/api_private_key.p12_expected.data b/test/java/security/KeyStore/PKCS12/api_private_key.p12_expected.data new file mode 100644 index 0000000000000000000000000000000000000000..d579bc5ae60b1b48c56fde7185b062b67b939743 --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/api_private_key.p12_expected.data @@ -0,0 +1,3 @@ +SHA1: 48:22:E2:C2:47:9F:75:E3:52:56:9C:20:37:DF:03:7F:CD:9F:87:38 +SHA256: 9B:DF:B9:EC:DB:3E:EF:BD:61:8F:C3:62:BD:3E:95:FE:E5:B6:A3:F9:94:3D:8D:C1:AE:E9:44:86:25:FA:C1:1B +Alias name: pkcs12testenduser1 diff --git a/test/java/security/KeyStore/PKCS12/api_private_key_not_match.p12.data b/test/java/security/KeyStore/PKCS12/api_private_key_not_match.p12.data new file mode 100644 index 0000000000000000000000000000000000000000..899a4e34d519c4015e473c20cc409fda049e7ea8 --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/api_private_key_not_match.p12.data @@ -0,0 +1,21 @@ +MIIEpAIBAzCCBF4GCSqGSIb3DQEHAaCCBE8EggRLMIIERzCCBEMGCSqGSIb3DQEHBqCCBDQwggQw +AgEAMIIEKQYJKoZIhvcNAQcBMCgGCiqGSIb3DQEMAQYwGgQUgIXKrki/1oMI4cCRpYWa/iQtL0cC +AgQAgIID8L1nh0C0Gmm9/AbAYbiwBJeb5oCAHa5E6BXJO9DP+m7774lUoQFuAmHJRoqr9hRzJulD +FfdkmRO9JdCs1tRgmnik66ybBb2wqr9gsAhPHFhDWuYIQTJcYqYlBTS8hbg5stDYWCeyaqK3+Zyp +bV3nHZtCe0AO+Rd3derZ3qhluPhc2FWX05fIomTZNiJsbi5wp95ejH4tGX5OdQoWXBjDzlrxopUd +pmdmHfJvRRTEtMr45VPfuHOkAX8Fe2tPFUgkE2tUalUth90AuPXVlMm5Ne+OdKcj+V2EN2s5JxA6 +28H1IL753Hov3R80/+Rzn+NIN/BCwLfHyTFa4Ur7Z2dyOJHvM5qeaz580RR8MwsEjqSpmXiyVhQW +3LNuziqs21woC7ueDW7TLiLhHp2Mt8BqFyfUYqBoS29lchRTHZbWTN2h66xycXlzbUCGIOHDXPXB +mqgxQWIltgluel+9Uf//D5yzIkXbtnW9dkMwKkybctAUs9VN8V44UBxv4+noSxepUs0iG+07c5Uu +dfvzwYtnKqKUrtTT8tA/MBNd4P1paYJR2Angx5tInyNKp8TwOaSrFUfg9stMYMh2fbWHLJFS9RDz +P7BDkrBgEO7jDu3O/XyyXzgUQRcQBv/Mw7sCFQ8BBMFzwf/dc6q277w+DJmwz2ex23iXQXQi/b6Y +iHbPwYHVwURWpVAq3P36pCTYjnUpPHMgRKo/9Iy+tL39H46SyGqBFlriM4jDEu7dbi7n1MuMxRYD +zocSkdsnlsJUBOhHLFFYIUIqx6jOgnOESKPWbG9XIHCTZJYnpasmP/VidrQMljzC7c3piePsI03D +8NcJq+BqCRrX+7Z5vPAU022hMryQqHesgnx0T0dWXaCyabzjjjOaWvacxRRCiJ4+EFZqAahMNQp/ +XTNlpW1eI0oQ3YBlJl5FWuwhk6YuoNSoi8ya1wp42rFnTwXIG8enfa0wyx/ORAvfypW4wcohsCdP +oRjc9foQsdcjxv2e1yMn9TlgjTOemY81mFfaSMa+4OIhSgLnIYI96QztrY9n8WHJer1hxVdKrb+8 +Mhf2vcNEToVF9ypst1C7fXSeOKdAYlNDskPAAm3prcuLMf1dzceIADr+4JOYxzdz6lLvjR+tpAHo +zWO1xh73P+p+Bo82wxnoWCopqOUCEoAYhsy+JBGZNM4AHvPAo4g0Sett3qixZhvbmw9kzKsiFAjf +wQHYPUfl0O02HvBizHK7dRDqJ94G/djGBhqfe34P0hKrCzW+n0u5nFmkFEdk50LpsTu0z3AaaaNh +E6485FDeW3R3/67pGXglNJHBWPsl2AYFimUTzxQqOfoCzBiw9St7hNvuCJBv5jA9MCEwCQYFKw4D +AhoFAAQUczIrgX5A0QTP7tpYDiY3MaSbEM8EFAprSM643ml+k9DGSQKZ7MG0UEhKAgIEAA== diff --git a/test/java/security/KeyStore/PKCS12/api_private_key_not_match.p12_expected.data b/test/java/security/KeyStore/PKCS12/api_private_key_not_match.p12_expected.data new file mode 100644 index 0000000000000000000000000000000000000000..d25641f6294ff624ac71f34ddfbb4fba684b29f7 --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/api_private_key_not_match.p12_expected.data @@ -0,0 +1,3 @@ +SHA1: 2B:CE:0C:E1:35:B9:9D:FE:5A:6E:25:88:01:F7:E9:E5:7B:89:17:42 +SHA256: 65:F3:0A:64:F2:52:B2:4E:F8:76:C5:D0:6D:53:7C:E8:00:AE:F4:95:3C:CC:CB:01:6B:22:AF:46:36:50:CF:FF +Alias name: pkcs12testenduser1 diff --git a/test/java/security/KeyStore/PKCS12/api_two_pass.p12.data b/test/java/security/KeyStore/PKCS12/api_two_pass.p12.data new file mode 100644 index 0000000000000000000000000000000000000000..453b66e89faaa59146b1a9bc682071fd76b66674 --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/api_two_pass.p12.data @@ -0,0 +1,46 @@ +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 ++FjQ0fq7d/D+Ilu6e2EBG1y/ngICBAA= diff --git a/test/java/security/KeyStore/PKCS12/api_two_pass.p12_expected.data b/test/java/security/KeyStore/PKCS12/api_two_pass.p12_expected.data new file mode 100644 index 0000000000000000000000000000000000000000..4113adea2090692348ac2cf46a6bdde2b9112099 --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/api_two_pass.p12_expected.data @@ -0,0 +1,3 @@ +SHA1: 77:90:EC:65:C5:0C:FD:F2:1E:B0:3A:BD:43:21:1A:C6:FD:18:8C:AB +SHA256: 8E:C8:49:82:B8:4B:89:8E:61:2D:CD:F6:D6:34:96:04:91:6F:1B:08:F5:CD:BD:23:ED:94:22:5A:B4:7A:39:DD +Alias name: pkcs12testenduser1 diff --git a/test/java/security/KeyStore/PKCS12/certs/convertP12/ie_jceks_chain.pfx.data b/test/java/security/KeyStore/PKCS12/certs/convertP12/ie_jceks_chain.pfx.data new file mode 100644 index 0000000000000000000000000000000000000000..3dbe7e4fcb31e0bb09b686271b835e4238934c5b --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/certs/convertP12/ie_jceks_chain.pfx.data @@ -0,0 +1,61 @@ +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 +CxwCAgfQ \ No newline at end of file diff --git a/test/java/security/KeyStore/PKCS12/certs/convertP12/ie_jks_chain.pfx.data b/test/java/security/KeyStore/PKCS12/certs/convertP12/ie_jks_chain.pfx.data new file mode 100644 index 0000000000000000000000000000000000000000..3dbe7e4fcb31e0bb09b686271b835e4238934c5b --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/certs/convertP12/ie_jks_chain.pfx.data @@ -0,0 +1,61 @@ +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 +CxwCAgfQ \ No newline at end of file diff --git a/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jceks_selfsigned.p12.data b/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jceks_selfsigned.p12.data new file mode 100644 index 0000000000000000000000000000000000000000..e64b3b4dff827740b013d3e77b8e50ee45335095 --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jceks_selfsigned.p12.data @@ -0,0 +1,30 @@ +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 \ No newline at end of file diff --git a/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jceks_twoentry.p12.data b/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jceks_twoentry.p12.data new file mode 100644 index 0000000000000000000000000000000000000000..9d58b00fc262cb5a25e94cdea4e9e8f83b6a19cd --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jceks_twoentry.p12.data @@ -0,0 +1,69 @@ +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 \ No newline at end of file diff --git a/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jceks_twopass.p12.data b/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jceks_twopass.p12.data new file mode 100644 index 0000000000000000000000000000000000000000..e26169fa7e98a23b8e6a42aa747bcfe1de37706e --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jceks_twopass.p12.data @@ -0,0 +1,45 @@ +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 +1QoCAgQA \ No newline at end of file diff --git a/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jks_selfsigned.p12.data b/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jks_selfsigned.p12.data new file mode 100644 index 0000000000000000000000000000000000000000..362a88ef4e105ad61bc3052b1ad1f9252b5198e4 --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jks_selfsigned.p12.data @@ -0,0 +1,45 @@ +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 +xp4CAgQA \ No newline at end of file diff --git a/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jks_twoentry.p12.data b/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jks_twoentry.p12.data new file mode 100644 index 0000000000000000000000000000000000000000..9d58b00fc262cb5a25e94cdea4e9e8f83b6a19cd --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jks_twoentry.p12.data @@ -0,0 +1,69 @@ +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 \ No newline at end of file diff --git a/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jks_twopass.p12.data b/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jks_twopass.p12.data new file mode 100644 index 0000000000000000000000000000000000000000..e26169fa7e98a23b8e6a42aa747bcfe1de37706e --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jks_twopass.p12.data @@ -0,0 +1,45 @@ +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 +1QoCAgQA \ No newline at end of file diff --git a/test/java/security/KeyStore/PKCS12/certs/convertP12/keystoreCA.jceks.data b/test/java/security/KeyStore/PKCS12/certs/convertP12/keystoreCA.jceks.data new file mode 100644 index 0000000000000000000000000000000000000000..be06f6abfaee0c9feb2aff393e10288af3204628 --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/certs/convertP12/keystoreCA.jceks.data @@ -0,0 +1,38 @@ +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 +FgNW1MI40XfEdWafFXeJ+yQTHPyoNdk= \ No newline at end of file diff --git a/test/java/security/KeyStore/PKCS12/certs/readP12/ie_chain.pfx.data b/test/java/security/KeyStore/PKCS12/certs/readP12/ie_chain.pfx.data new file mode 100644 index 0000000000000000000000000000000000000000..3dbe7e4fcb31e0bb09b686271b835e4238934c5b --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/certs/readP12/ie_chain.pfx.data @@ -0,0 +1,61 @@ +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 +CxwCAgfQ \ No newline at end of file diff --git a/test/java/security/KeyStore/PKCS12/certs/readP12/ie_self.pfx.data b/test/java/security/KeyStore/PKCS12/certs/readP12/ie_self.pfx.data new file mode 100644 index 0000000000000000000000000000000000000000..acde65c2ebe6da97b0b917633e0ea5ae4edfca83 --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/certs/readP12/ie_self.pfx.data @@ -0,0 +1,47 @@ +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 +/FfU1hlVl8YCAgfQ \ No newline at end of file diff --git a/test/java/security/KeyStore/PKCS12/certs/readP12/jdk_chain.p12.data b/test/java/security/KeyStore/PKCS12/certs/readP12/jdk_chain.p12.data new file mode 100644 index 0000000000000000000000000000000000000000..f379d2ba3806320f4d44d954e1855490dc96fc5f --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/certs/readP12/jdk_chain.p12.data @@ -0,0 +1,62 @@ +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 +IsNed5PjTXd1/rQmWIcCDOy9lgICBAA= \ No newline at end of file diff --git a/test/java/security/KeyStore/PKCS12/certs/readP12/jdk_self.p12.data b/test/java/security/KeyStore/PKCS12/certs/readP12/jdk_self.p12.data new file mode 100644 index 0000000000000000000000000000000000000000..b643ba4f20a4bd82aa615b4f436bb8e4e95e08d9 --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/certs/readP12/jdk_self.p12.data @@ -0,0 +1,45 @@ +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 +I6oCAgQA \ No newline at end of file diff --git a/test/java/security/KeyStore/PKCS12/certs/readP12/mozilla_chain.p12.data b/test/java/security/KeyStore/PKCS12/certs/readP12/mozilla_chain.p12.data new file mode 100644 index 0000000000000000000000000000000000000000..623d470c86be6006383bc9e642aad7077b8c4b0d --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/certs/readP12/mozilla_chain.p12.data @@ -0,0 +1,73 @@ +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 \ No newline at end of file diff --git a/test/java/security/KeyStore/PKCS12/certs/readP12/mozilla_self.p12.data b/test/java/security/KeyStore/PKCS12/certs/readP12/mozilla_self.p12.data new file mode 100644 index 0000000000000000000000000000000000000000..c36f26b516b1a28f07cce834a7ba1b936fa1636e --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/certs/readP12/mozilla_self.p12.data @@ -0,0 +1,54 @@ +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 +0AQQxrOtDDKIzjpW4+rATcwNPAAA \ No newline at end of file diff --git a/test/java/security/KeyStore/PKCS12/certs/readP12/mozilla_twoentries.p12.data b/test/java/security/KeyStore/PKCS12/certs/readP12/mozilla_twoentries.p12.data new file mode 100644 index 0000000000000000000000000000000000000000..d0c451b24c3167106e9442142543c2dabe22b8e1 --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/certs/readP12/mozilla_twoentries.p12.data @@ -0,0 +1,125 @@ +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 +AoiyQ6u3imI281gAAA== \ No newline at end of file diff --git a/test/java/security/KeyStore/PKCS12/certs/readP12/netscape_chain.p12.data b/test/java/security/KeyStore/PKCS12/certs/readP12/netscape_chain.p12.data new file mode 100644 index 0000000000000000000000000000000000000000..af0557ab30d011373a1adf145d4dcd69f8a3dd38 --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/certs/readP12/netscape_chain.p12.data @@ -0,0 +1,73 @@ +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 \ No newline at end of file diff --git a/test/java/security/KeyStore/PKCS12/certs/readP12/netscape_self.p12.data b/test/java/security/KeyStore/PKCS12/certs/readP12/netscape_self.p12.data new file mode 100644 index 0000000000000000000000000000000000000000..bdc94837e17ba2c1b9098b719d20e4beaf471eae --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/certs/readP12/netscape_self.p12.data @@ -0,0 +1,54 @@ +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 +HwQQ6Vxq63yfCeamza5PZKytWQAA \ No newline at end of file diff --git a/test/java/security/KeyStore/PKCS12/certs/readP12/netscape_twoentries.p12.data b/test/java/security/KeyStore/PKCS12/certs/readP12/netscape_twoentries.p12.data new file mode 100644 index 0000000000000000000000000000000000000000..cdc8438d0c07529a5b9cc5eda3d807ba3716f2fb --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/certs/readP12/netscape_twoentries.p12.data @@ -0,0 +1,125 @@ +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 +LK2fdlxrCGzUHTgAAA== \ No newline at end of file diff --git a/test/java/security/KeyStore/PKCS12/certs/readP12/openssl.p12.data b/test/java/security/KeyStore/PKCS12/certs/readP12/openssl.p12.data new file mode 100644 index 0000000000000000000000000000000000000000..101a03993c55a0e57ccab082e3531137885ffd31 --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/certs/readP12/openssl.p12.data @@ -0,0 +1,41 @@ +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 \ No newline at end of file diff --git a/test/java/security/KeyStore/PKCS12/certs/writeP12/keystoreCA.jks.data b/test/java/security/KeyStore/PKCS12/certs/writeP12/keystoreCA.jks.data new file mode 100644 index 0000000000000000000000000000000000000000..1d6b5a4b6ac9a77d76b66ce3aea0350e37e298ba --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/certs/writeP12/keystoreCA.jks.data @@ -0,0 +1,38 @@ +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 \ No newline at end of file diff --git a/test/java/security/KeyStore/PKCS12/certs/writeP12/keystoreEU.jks.data b/test/java/security/KeyStore/PKCS12/certs/writeP12/keystoreEU.jks.data new file mode 100644 index 0000000000000000000000000000000000000000..c8e4ecf4705ef4bc66820d62d2b73e22559017da --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/certs/writeP12/keystoreEU.jks.data @@ -0,0 +1,79 @@ +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 +VL+NWQOgtME= \ No newline at end of file diff --git a/test/java/security/KeyStore/PKCS12/ie_chain.pfx.data b/test/java/security/KeyStore/PKCS12/ie_chain.pfx.data new file mode 100644 index 0000000000000000000000000000000000000000..a509e05b75e5596d2a0931394d0669b5ac2ddcf2 --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/ie_chain.pfx.data @@ -0,0 +1,65 @@ +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 +fAQEFPL7KYm4NrHpQSKpto5+pPs7NgLWAgIEAA== diff --git a/test/java/security/KeyStore/PKCS12/ie_chain.pfx.pem b/test/java/security/KeyStore/PKCS12/ie_chain.pfx.pem new file mode 100644 index 0000000000000000000000000000000000000000..6caea3f49895c9366b24fb152544b338b601c590 --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/ie_chain.pfx.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID7DCCAtSgAwIBAgIBBDANBgkqhkiG9w0BAQsFADBXMQswCQYDVQQGEwJJTjEL +MAkGA1UECAwCS0ExDDAKBgNVBAcMA2JscjEPMA0GA1UECgwGT3JhY2xlMQ0wCwYD +VQQLDARKYXZhMQ0wCwYDVQQDDARMZWFkMB4XDTE1MDUyODAzNDMwN1oXDTI1MDUy +NTAzNDMwN1owSzELMAkGA1UEBhMCSU4xCzAJBgNVBAgMAktBMQ8wDQYDVQQKDAZP +cmFjbGUxDTALBgNVBAsMBEphdmExDzANBgNVBAMMBk1lbWJlcjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAMr07JoRV0kR5mNKgLFKLYeUQ2eFEyV8alkC +3OL2Ew9tP9CT+60kqlbyLfxa8+8XU/SClch6yf7R4majR85PgfJuZKRvyUdWgw5y +K0wbxWkRVqRAgSo0Zp8hkhV9BDe1R7s4r4XBI/rSVTQmDsMVZdigDtIDYKMS0BtW +DnW4ueWbZHdNHyxlTEJc6trsvU2KH5pY69VgGZzonNuMa9p17aQpOnVbWNhS6Mcs +mHonU5d19Xh543T8ovbA8cj0osdYgcOQ42FEBqON4Lih8SyhqZQyi4UvkiHek3Pu +i5Q0dwwVT1lnorUwH3bXp4boMaUmh7bvKMe/BQ5T18wkXlgYuVECAwEAAaOBzjCB +yzAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBD +ZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUWDsl+9vHtuuQRhb+Zyd//f6qSXEwcQYDVR0j +BGowaKFbpFkwVzELMAkGA1UEBhMCSU4xCzAJBgNVBAgMAktBMQwwCgYDVQQHDANi +bHIxDzANBgNVBAoMBk9yYWNsZTENMAsGA1UECwwESmF2YTENMAsGA1UEAwwETGVh +ZIIJAIQbGsfQ2qikMA0GCSqGSIb3DQEBCwUAA4IBAQABEg/vV+ckqMwwA6QLdk6i +Q+oaYcjz2C7wcZmvmrdYGHUrtlf4aWQd4G/TDBtqKZ6MfA2AaciDe7lAI2agdKCM +MFG6XeqtjElCa77b8KrE3Ha+N07pmYnU42vZrqMpayjj/Eey9bOuSaTgLVTA00BI +5wiTbLokTrYW3lhMityeFyvGw7bEvfGbXLs/7hyZ6wEXindgaGT9adL9jz2LT2Tt +YorRvxRSRMbBWCc6o+ICfawU226ZOetGVfdTSYgL3a9AQ+zAMhgdJq+ac077G1vA +HzKZgygYAHIr1G0DxwEPOAHBQFtbTbAQURpjzKWFYeGiZuCEBwwsKgDIT0kGF76E +-----END CERTIFICATE----- diff --git a/test/java/security/KeyStore/PKCS12/ie_self.pfx.data b/test/java/security/KeyStore/PKCS12/ie_self.pfx.data new file mode 100644 index 0000000000000000000000000000000000000000..0500db588fb39e282b2e5b6ae8aa08d402f17f64 --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/ie_self.pfx.data @@ -0,0 +1,31 @@ +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 +qHeo0noP26ViWalg3FeT8Lk+AgIEAA== diff --git a/test/java/security/KeyStore/PKCS12/ie_self.pfx.pem b/test/java/security/KeyStore/PKCS12/ie_self.pfx.pem new file mode 100644 index 0000000000000000000000000000000000000000..b8778935cb03fdc9f46f0c1fa1e551b3c55be6b8 --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/ie_self.pfx.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICRTCCAa6gAwIBAgIEFjfyzjANBgkqhkiG9w0BAQQFADBWMQswCQYDVQQGEwJV +UzEPMA0GA1UEChMGT3JhY2xlMRUwEwYDVQQLEwxTZWN1cml0eSBTUUUxHzAdBgNV +BAMTFlBLQ1MxMiBUZXN0IEVuZCBVc2VyIDEwHhcNMTUwNTI3MDUyMTUyWhcNMzUw +MjExMDUyMTUyWjBWMQswCQYDVQQGEwJVUzEPMA0GA1UEChMGT3JhY2xlMRUwEwYD +VQQLEwxTZWN1cml0eSBTUUUxHzAdBgNVBAMTFlBLQ1MxMiBUZXN0IEVuZCBVc2Vy +IDEwgZ4wDQYJKoZIhvcNAQEBBQADgYwAMIGIAoGAUPl3dSLSQd+ocj4oDJI6qdt+ +iIamUd6aDHllX/vNfguuX5G1/NO/aas5XofV9Zfy+XCdqGI/rUE294vod1BkBOiP +UmsgHl30nWCwEq5FuFWLwLWgm2DkNMGVJnvvCVLDzuYhvkymNbOoppHywIMVAryP +Xi2082vRKvW677VqcT0CAwEAAaMhMB8wHQYDVR0OBBYEFLpLVS5KZoGIDGmden5r +AK3/D9+5MA0GCSqGSIb3DQEBBAUAA4GBAEomR40Sj+BvNYiL8Lfr2vMadCF23R3X +fjPd3TCGuMJtI78N9lSTnrZCnrxn4ep7FuVl59jqEX7mBQcVtUNPqw/xrFI/sv4z +Nwxa18TG78i85OXapvVsX1fWx0GeeK2XTKetHLMEc8zcW8IHcukSX+5Z6Y/pg+lB +mqEx9bvLCJTW +-----END CERTIFICATE----- diff --git a/test/java/security/KeyStore/PKCS12/mozilla_self.p12.data b/test/java/security/KeyStore/PKCS12/mozilla_self.p12.data new file mode 100644 index 0000000000000000000000000000000000000000..03ef9553bb3a13f28cfd431ca6efce80a32a9ea9 --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/mozilla_self.p12.data @@ -0,0 +1,31 @@ +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 diff --git a/test/java/security/KeyStore/PKCS12/mozilla_self.p12.pem b/test/java/security/KeyStore/PKCS12/mozilla_self.p12.pem new file mode 100644 index 0000000000000000000000000000000000000000..fb0c5d15d93b221120a98d86b844fbfc15a66c12 --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/mozilla_self.p12.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICRTCCAa6gAwIBAgIEL8ZaXTANBgkqhkiG9w0BAQQFADBWMQswCQYDVQQGEwJV +UzEPMA0GA1UEChMGT3JhY2xlMRUwEwYDVQQLEwxTZWN1cml0eSBTUUUxHzAdBgNV +BAMTFlBLQ1MxMiBUZXN0IEVuZCBVc2VyIDEwHhcNMTUwNTI3MDUzNTI1WhcNMzUw +MjExMDUzNTI1WjBWMQswCQYDVQQGEwJVUzEPMA0GA1UEChMGT3JhY2xlMRUwEwYD +VQQLEwxTZWN1cml0eSBTUUUxHzAdBgNVBAMTFlBLQ1MxMiBUZXN0IEVuZCBVc2Vy +IDEwgZ4wDQYJKoZIhvcNAQEBBQADgYwAMIGIAoGARub+B5xAEtoE2Sv9+oRnKYIC +AZZ5dpTdMUWiExsXBcK6KQ61X5GftMz4a5io7PoxJxsDkPyTPNaHov2dzOBblbn2 +Gd0YgRdI3jcmm6ELDN7CqzsO7FK48L8maLeIj/0hYPBZPxKohjChi2GUNKn97OMf +Y0LTeDqpO6+oc2E25XECAwEAAaMhMB8wHQYDVR0OBBYEFLC2ChLxDu/yacB3s0ON +NNDusz2SMA0GCSqGSIb3DQEBBAUAA4GBADhG2wSf4KHMspsKv8bkjWrDA6wTjwnx +pQES8E2dMmmp/LybH0CerpcShGGw35uh8wnCaWA1hBgMAs1mfghTt9X8tZCG5MmA +VmkR7VPu1lNbdB1sswXAy3/423ncWbPJKIvbXBLJrzvC3Ri6d/AiH/0Tud0H15IN +YQ+ThBRF5iQC +-----END CERTIFICATE----- diff --git a/test/java/security/KeyStore/PKCS12/netscape_self.p12.data b/test/java/security/KeyStore/PKCS12/netscape_self.p12.data new file mode 100644 index 0000000000000000000000000000000000000000..5c4a0b0883b2a5eb110d0ffb765a1cc90c6c5221 --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/netscape_self.p12.data @@ -0,0 +1,31 @@ +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 diff --git a/test/java/security/KeyStore/PKCS12/netscape_self.p12.pem b/test/java/security/KeyStore/PKCS12/netscape_self.p12.pem new file mode 100644 index 0000000000000000000000000000000000000000..cd303ff7576ccb1ac6399024916a773d95987c1e --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/netscape_self.p12.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICRTCCAa6gAwIBAgIECrE+nTANBgkqhkiG9w0BAQQFADBWMQswCQYDVQQGEwJV +UzEPMA0GA1UEChMGT3JhY2xlMRUwEwYDVQQLEwxTZWN1cml0eSBTUUUxHzAdBgNV +BAMTFlBLQ1MxMiBUZXN0IEVuZCBVc2VyIDEwHhcNMTUwNTI3MDUzMDEyWhcNMzUw +MjExMDUzMDEyWjBWMQswCQYDVQQGEwJVUzEPMA0GA1UEChMGT3JhY2xlMRUwEwYD +VQQLEwxTZWN1cml0eSBTUUUxHzAdBgNVBAMTFlBLQ1MxMiBUZXN0IEVuZCBVc2Vy +IDEwgZ4wDQYJKoZIhvcNAQEBBQADgYwAMIGIAoGAUJKwuZJOuG+EZ9d8L4BDYOzv +2sFCyCTrDbw6lH/vaG/kkhJgZdYMV1pwqxmsspUrSYwATx3usPElv+OOjEJlwuLo +wj+/6Ob9LirwUAHb9LbcF5r9dRxLBcFUaTnDlqzgOuS1gn9dnD9z4CugId9t9IjF +tLiump5zXNcZw/+/JKMCAwEAAaMhMB8wHQYDVR0OBBYEFOKLf8ckktSBUTDRoYxV +b56vtgd8MA0GCSqGSIb3DQEBBAUAA4GBACgrbEqfqtgKx0iLiQEgKb4K+O4Gg8Td +wuSjtXn9WQR5Fux7XNoM8f3xRw95CROg1/JEYhsH7fzeG/Aq6BbFooyHZsQ7yGXJ +ujJ3O7hl0MuFZRChf9QP7YQjYb4toj1wdE0EvA9lNWomr2Ox9b3+QFTdxPcBElv6 ++ImhOPtF6/lt +-----END CERTIFICATE----- + diff --git a/test/java/security/KeyStore/PKCS12/openssl.p12.data b/test/java/security/KeyStore/PKCS12/openssl.p12.data new file mode 100644 index 0000000000000000000000000000000000000000..b4da4794d4eef5e04f45f9a5985bae23aafce3ac --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/openssl.p12.data @@ -0,0 +1,76 @@ +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 diff --git a/test/java/security/KeyStore/PKCS12/openssl.p12.pem b/test/java/security/KeyStore/PKCS12/openssl.p12.pem new file mode 100644 index 0000000000000000000000000000000000000000..0243a379e38817bb2ed1c23de04c644736477914 --- /dev/null +++ b/test/java/security/KeyStore/PKCS12/openssl.p12.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIBAzANBgkqhkiG9w0BAQsFADBMMQswCQYDVQQGEwJJTjEL +MAkGA1UECAwCS0ExDzANBgNVBAoMBk9yYWNsZTENMAsGA1UECwwESmF2YTEQMA4G +A1UEAwwHQ2xpZW50MTAeFw0xNTA1MjYyMjE3MThaFw0yNTA1MjMyMjE3MThaMEwx +CzAJBgNVBAYTAklOMQswCQYDVQQIDAJLQTEPMA0GA1UECgwGT3JhY2xlMQ0wCwYD +VQQLDARKYXZhMRAwDgYDVQQDDAdDbGllbnQyMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA2HADVMaKPd7xAYK0BTsCcQzglk8H2qp0Sg5nDYgb7KqB/1cb +RyMB3g3FG4Isv6L0Lp2GLAeHVn35YljHNrcBUU5fG/+DNJPNiM+srevblMeksOcA +frPnxmog+GMgiO97O2/3Xtgl0ailsOHidPH9hBXr+WikNu7ITPXkJiYi0d1n8p2N +e/p4W4cBitxIUlZm2OTSW4d3EDW86saf657kSpTlb2zBT/r9fjWluHlTg+jGnGIz +UdpYP7sSnye8oym5PxT2IMPU6vRgF9Gzwg+6bPaZnrYNURifGJIuQH+/wDaqA+Ix +g2Q2Ij8SiDhkNrCoeLf77Aot9d5ZPtledJPSRQIDAQABo3sweTAJBgNVHRMEAjAA +MCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAd +BgNVHQ4EFgQUhxNmvHpNjpjnl/vMVkEnyF5Msk0wHwYDVR0jBBgwFoAUHyFP2xAx +0GeDCQPTzfxG7M8di7QwDQYJKoZIhvcNAQELBQADggEBAD4rXzKq8PdSK7rzuwfu +q+RzeYZnNM7OsoBGhMfHQKnnI3LH5bgyttuCoV665X2mgy6+LZcrXqom/ZrLXQ6x +JVtGxNHr7rqbnC/9tB2/s9HHN3YiRs966shWHGkhCubsUGre7Z25Pq55K6Pyl+nU +hb+K8aQ54z4oDt+raAdbuILq91fUjw5j1qex3d62fHvf4IO3spcKY4HhnwBPifg2 +YZCiZRZOoVysi2FTdsvW2NfQCYgtUftbkfNrKglkRuIa9rQEduhDy1cwn4fc9S1f +6WTvuJNoIp3o1nQppFjfO7fzfIDCrlaEkkXU7O54KQ5HTKu62tZp9xKW71oolOnZ +bZQ= +-----END CERTIFICATE----- diff --git a/test/java/security/MessageDigest/TestDigestIOStream.java b/test/java/security/MessageDigest/TestDigestIOStream.java new file mode 100644 index 0000000000000000000000000000000000000000..46028e85af840ab4067b2e51067638798435f735 --- /dev/null +++ b/test/java/security/MessageDigest/TestDigestIOStream.java @@ -0,0 +1,335 @@ +/* + * Copyright (c) 2003, 2014, 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. + * + * 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. + */ + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.security.DigestInputStream; +import java.security.DigestOutputStream; +import java.security.MessageDigest; +import java.util.Arrays; +import java.util.Random; +import static java.lang.System.out; + +/** + * @test + * @bug 8050370 + * @summary MessageDigest tests with DigestIOStream + * @author Kevin Liu + */ + +enum ReadModel { + READ, BUFFER_READ, MIX_READ +} + +public class TestDigestIOStream { + + private static final int[] DATA_LEN_ARRAY = { + 1, 50, 2500, 125000, 6250000 + }; + private static final String[] ALGORITHM_ARRAY = { + "MD2", "MD5", "SHA1", "SHA-224", "SHA-256", "SHA-384", "SHA-512" + }; + + private static byte[] data; + + private static MessageDigest md = null; + + public static void main(String argv[]) throws Exception { + TestDigestIOStream test = new TestDigestIOStream(); + test.run(); + } + + public void run() throws Exception { + for (String algorithm: ALGORITHM_ARRAY) { + + md = MessageDigest.getInstance(algorithm); + + for (int length: DATA_LEN_ARRAY) { + + Random rdm = new Random(); + data = new byte[length]; + rdm.nextBytes(data); + + if (!testMDChange(algorithm, length)) { + throw new RuntimeException("testMDChange failed at:" + + algorithm + "/" + length); + } + if (!testMDShare(algorithm, length)) { + throw new RuntimeException("testMDShare failed at:" + + algorithm + "/" + length); + } + for (ReadModel readModel: ReadModel.values()) { + // test Digest function when digest switch on + if (!testDigestOnOff(algorithm, readModel, true, length)) { + throw new RuntimeException("testDigestOn failed at:" + + algorithm + "/" + length + "/" + readModel); + } + // test Digest function when digest switch off + if (!testDigestOnOff(algorithm, readModel, false, length)) { + throw new RuntimeException("testDigestOff failed at:" + + algorithm + "/" + length + "/" + readModel); + } + } + } + } + int testNumber = ALGORITHM_ARRAY.length * ReadModel.values().length + * DATA_LEN_ARRAY.length * 2 + ALGORITHM_ARRAY.length + * DATA_LEN_ARRAY.length * 2; + out.println("All " + testNumber + " Tests Passed"); + } + + /** + * Test DigestInputStream and DigestOutputStream digest function when digest + * set on and off + * + * @param algo + * Message Digest algorithm + * @param readModel + * which read method used(READ, BUFFER_READ, MIX_READ) + * @param on + * digest switch(on and off) + * @param dataLength + * plain test data length. + * @exception Exception + * throw unexpected exception + */ + public boolean testDigestOnOff(String algo, ReadModel readModel, + boolean on, int dataLength) throws Exception { + + // Generate the DigestInputStream/DigestOutputStream object + try (ByteArrayInputStream bais = new ByteArrayInputStream(data); + DigestInputStream dis = new DigestInputStream(bais, + MessageDigest.getInstance(algo)); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DigestOutputStream dos = new DigestOutputStream(baos, + MessageDigest.getInstance(algo)); + ByteArrayOutputStream baOut = new ByteArrayOutputStream();) { + + // Perform the update using all available/possible update methods + int k = 0; + byte[] buffer = new byte[5]; + boolean enDigest = true; + // Make sure the digest function is on (default) + dis.on(enDigest); + dos.on(enDigest); + + switch (readModel) { + case READ: // use only read() + while ((k = dis.read()) != -1) { + if (on) { + dos.write(k); + } else { + dos.write(k); + if (enDigest) { + baOut.write(k); + } + enDigest = !enDigest; + dos.on(enDigest); + dis.on(enDigest); + } + } + break; + case BUFFER_READ: // use only read(byte[], int, int) + while ((k = dis.read(buffer, 0, buffer.length)) != -1) { + if (on) { + dos.write(buffer, 0, k); + } else { + dos.write(buffer, 0, k); + if (enDigest) { + baOut.write(buffer, 0, k); + } + enDigest = !enDigest; + dis.on(enDigest); + dos.on(enDigest); + } + } + break; + case MIX_READ: // use both read() and read(byte[], int, int) + while ((k = dis.read()) != -1) { + if (on) { + dos.write(k); + if ((k = dis.read(buffer, 0, buffer.length)) != -1) { + dos.write(buffer, 0, k); + } + } else { + dos.write(k); + if (enDigest) { + baOut.write(k); + } + enDigest = !enDigest; + dis.on(enDigest); + dos.on(enDigest); + if ((k = dis.read(buffer, 0, buffer.length)) != -1) { + dos.write(buffer, 0, k); + if (enDigest) { + baOut.write(buffer, 0, k); + } + enDigest = !enDigest; + dis.on(enDigest); + dos.on(enDigest); + } + } + } + break; + default: + out.println("ERROR: Invalid read/write combination choice!"); + return false; + } + + // Get the output and the "correct" digest values + byte[] output1 = dis.getMessageDigest().digest(); + byte[] output2 = dos.getMessageDigest().digest(); + byte[] standard; + if (on) { + standard = md.digest(data); + } else { + byte[] dataDigested = baOut.toByteArray(); + standard = md.digest(dataDigested); + } + + // Compare the output byte array value to the input data + if (!MessageDigest.isEqual(data, baos.toByteArray())) { + out.println("ERROR of " + readModel + + ": output and input data unexpectedly changed"); + return false; + } + // Compare generated digest values + if (!MessageDigest.isEqual(output1, standard) + || !MessageDigest.isEqual(output2, standard)) { + out.println("ERROR" + readModel + + ": generated digest data unexpectedly changed"); + return false; + } + + return true; + } catch (Exception ex) { + out.println("testDigestOnOff failed at:" + algo + "/" + readModel + + "/" + dataLength + " with unexpected exception"); + throw ex; + } + } + + /** + * Test DigestInputStream and DigestOutputStream digest function when Swap + * the message digest engines between DigestIn/OutputStream + * + * @param algo + * Message Digest algorithm + * @param dataLength + * plain test data length. + * @exception Exception + * throw unexpected exception + */ + public boolean testMDChange(String algo, int dataLength) throws Exception { + // Generate the DigestInputStream/DigestOutputStream object + MessageDigest mdIn = MessageDigest.getInstance(algo); + MessageDigest mdOut = MessageDigest.getInstance(algo); + try (ByteArrayInputStream bais = new ByteArrayInputStream(data); + DigestInputStream dis = new DigestInputStream(bais, mdIn); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DigestOutputStream dos = new DigestOutputStream(baos, mdOut);) { + + // Perform the update using all available/possible update methods + int k = 0; + byte[] buffer = new byte[10]; + + // use both read() and read(byte[], int, int) + while ((k = dis.read()) != -1) { + dos.write(k); + if ((k = dis.read(buffer, 0, buffer.length)) != -1) { + dos.write(buffer, 0, k); + } + + // Swap the message digest engines between + // DigestIn/OutputStream objects + dis.setMessageDigest(mdOut); + dos.setMessageDigest(mdIn); + mdIn = dis.getMessageDigest(); + mdOut = dos.getMessageDigest(); + } + + // Get the output and the "correct" digest values + byte[] output1 = mdIn.digest(); + byte[] output2 = mdOut.digest(); + byte[] standard = md.digest(data); + + // Compare generated digest values + return MessageDigest.isEqual(output1, standard) + && MessageDigest.isEqual(output2, standard); + } catch (Exception ex) { + out.println("testMDChange failed at:" + algo + "/" + dataLength + + " with unexpected exception"); + throw ex; + } + } + + /** + * Test DigestInputStream and DigestOutputStream digest function when use + * same message digest object. + * + * @param algo + * Message Digest algorithm + * @param dataLength + * plain test data length. + * @exception Exception + * throw unexpected exception + */ + public boolean testMDShare(String algo, int dataLength) throws Exception { + MessageDigest mdCommon = MessageDigest.getInstance(algo); + // Generate the DigestInputStream/DigestOutputStream object + try (ByteArrayInputStream bais = new ByteArrayInputStream(data); + DigestInputStream dis = new DigestInputStream(bais, mdCommon); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DigestOutputStream dos = new DigestOutputStream(baos, mdCommon);) { + + // Perform the update using all available/possible update methods + int k = 0; + byte[] buffer = new byte[10]; + + // use both read() and read(byte[], int, int) + while (k < data.length) { + int len = dis.read(buffer, 0, buffer.length); + if (len != -1) { + k += len; + if (k < data.length) { + dos.write(data[k]); + k++; + dis.skip(1); + } + } + } + + // Get the output and the "correct" digest values + byte[] output = mdCommon.digest(); + byte[] standard = md.digest(data); + + // Compare generated digest values + return MessageDigest.isEqual(output, standard); + } catch (Exception ex) { + out.println("TestMDShare failed at:" + algo + "/" + dataLength + + " with unexpected exception"); + throw ex; + } + } +} diff --git a/test/java/security/MessageDigest/TestSameLength.java b/test/java/security/MessageDigest/TestSameLength.java new file mode 100644 index 0000000000000000000000000000000000000000..eb59815c9bdea9d148c002af0494202d37ff9727 --- /dev/null +++ b/test/java/security/MessageDigest/TestSameLength.java @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +import static java.lang.System.out; + +import java.nio.ByteBuffer; +import java.security.MessageDigest; +import java.util.Random; + +/** + * @test + * @bug 8050371 + * @summary Check md.getDigestLength() equal digest output length with various + * algorithm/dataLen/(update,digest methods). + * @author Kevin Liu + */ + +public class TestSameLength { + + public static void main(String[] args) throws Exception { + TestSameLength test = new TestSameLength(); + test.run(); + } + + private void run() throws Exception { + String[] algorithmArr = { + "SHA", "Sha", "SHA-1", "sha-1", "SHA1", "sha1", "MD5", "md5", + "SHA-224", "SHA-256", "SHA-384", "SHA-512" + }; + int[] nUpdatesArr = { + 0, 1, 2, 3 + }; + int[] dataLenArr = { + 1, 50, 2500, 125000, 6250000 + }; + + for (String algorithm: algorithmArr) { + for (UpdateMethod update: UpdateMethod.values()) { + for (int dataLen: dataLenArr) { + if (!runTest(algorithm, dataLen, update)) { + throw new RuntimeException( + "Test failed at algorithm/dataLen/numUpdate:" + + algorithm + "/" + dataLen + "/" + + update.toString()); + } + } + } + } + + out.println("All " + algorithmArr.length * nUpdatesArr.length + * dataLenArr.length + " tests Passed"); + } + + private boolean runTest(String algo, long dataLen, + UpdateMethod whichUpdate) throws Exception { + try { + // Do initialization + byte[] data = new byte[(int) dataLen]; + new Random().nextBytes(data); + MessageDigest md = MessageDigest.getInstance(algo); + int outputLen = md.getDigestLength(); + + // Perform the update using all available/possible update methods + whichUpdate.updateDigest(data, md, dataLen); + // Get the output + byte[] output = md.digest(); + + // Compare input and output + return outputLen == output.length; + } catch (Exception ex) { + System.err.println("Testing: " + algo + "/" + dataLen + "/" + + whichUpdate.toString() + + " failed with unexpected exception"); + ex.printStackTrace(); + throw ex; + } + } + + private static enum UpdateMethod { + UPDATE_BYTE { + @Override + public void updateDigest(byte[] data, + MessageDigest md, long dataLen) { + + for (int i = 0; i < dataLen; i++) { + md.update(data[i]); + } + } + }, + + UPDATE_BUFFER { + @Override + public void updateDigest(byte[] data, + MessageDigest md, long dataLen) { + + md.update(data); + } + }, + + UPDATE_BUFFER_LEN { + @Override + public void updateDigest(byte[] data, + MessageDigest md, long dataLen) { + + for (int i = 0; i < dataLen; i++) { + md.update(data, i, 1); + } + } + }, + + UPDATE_BYTE_BUFFER { + @Override + public void updateDigest(byte[] data, + MessageDigest md, long dataLen) { + + md.update(ByteBuffer.wrap(data)); + } + }; + + public abstract void updateDigest(byte[] data, + MessageDigest md, long dataLen); + } +} diff --git a/test/java/security/MessageDigest/TestSameValue.java b/test/java/security/MessageDigest/TestSameValue.java new file mode 100644 index 0000000000000000000000000000000000000000..aef4ceae402c9c9a500caea571411d0cd76eaf7e --- /dev/null +++ b/test/java/security/MessageDigest/TestSameValue.java @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +import static java.lang.System.out; + +import java.nio.ByteBuffer; +import java.security.DigestException; +import java.security.MessageDigest; +import java.util.Random; + +/** + * @test + * @bug 8050371 + * @summary Check md.digest(data) value whether same with digest output value + * with various update/digest methods. + * @author Kevin Liu + */ + +public class TestSameValue { + + public static void main(String[] args) throws Exception { + TestSameValue test1 = new TestSameValue(); + test1.run(); + } + + private void run() throws Exception { + + byte[] data = new byte[6706]; + MessageDigest md = null; + // Initialize input data + new Random().nextBytes(data); + + String[] providers = { + null, "SUN" + }; + String[] algorithmArr = { + "SHA", "Sha", "MD5", "md5", "SHA-224", "SHA-256", "SHA-384", + "SHA-512" + }; + + for (String algorithm: algorithmArr) { + for (String provider: providers) { + if (provider != null) { + md = MessageDigest.getInstance(algorithm, provider); + } else { + md = MessageDigest.getInstance(algorithm); + } + for (UpdateDigestMethod updateMethod: UpdateDigestMethod + .values()) { + byte[] output = updateMethod.updateDigest(data, md); + // Get the output and the "correct" one + byte[] standard = md.digest(data); + // Compare input and output + if (!MessageDigest.isEqual(output, standard)) { + throw new RuntimeException( + "Test failed at algorithm/provider/numUpdate:" + + algorithm + "/" + provider + "/" + + updateMethod); + } + } + } + } + + out.println("All " + algorithmArr.length + * UpdateDigestMethod.values().length * providers.length + + " tests Passed"); + } + + private static enum UpdateDigestMethod { + + /* + * update the data one by one using method update(byte input) then + * do digest (giving the output buffer, offset, and the number of + * bytes to put in the output buffer) + */ + UPDATE_DIGEST_BUFFER { + @Override + public byte[] updateDigest(byte[] data, MessageDigest md) + throws DigestException { + for (byte element: data) { + md.update(element); + } + byte[] output = new byte[md.getDigestLength()]; + int len = md.digest(output, 0, output.length); + if (len != output.length) { + throw new RuntimeException( + "ERROR" + ": digest length differs!"); + } + return output; + } + }, + + /* + * update the data one by one using method update(byte input) + * then do digest + */ + UPDATE_DIGEST { + @Override + public byte[] updateDigest(byte[] data, MessageDigest md) { + for (byte element: data) { + md.update(element); + } + return md.digest(); + } + }, + + /* + * update all the data at once as a block, then do digest ( giving the + * output buffer, offset, and the number of bytes to put in the output + * buffer) + */ + UPDATE_BLOCK_DIGEST_BUFFER { + @Override + public byte[] updateDigest(byte[] data, MessageDigest md) + throws DigestException { + md.update(data); + byte[] output = new byte[md.getDigestLength()]; + int len = md.digest(output, 0, output.length); + if (len != output.length) { + throw new RuntimeException( + "ERROR" + ": digest length differs!"); + } + return output; + } + }, + + // update all the data at once as a block, then do digest + UPDATE_BLOCK_DIGEST { + @Override + public byte[] updateDigest(byte[] data, MessageDigest md) { + md.update(data); + return md.digest(); + } + }, + + /* + * update the leading bytes (length is "data.length-LASTNBYTES") + * at once as a block, then do digest (do a final update using + * the left LASTNBYTES bytes which is passed as a parameter for + * the digest method, then complete the digest) + */ + UPDATE_LEADING_BLOCK_DIGEST_REMAIN { + @Override + public byte[] updateDigest(byte[] data, MessageDigest md) { + byte[] mainPart = new byte[data.length - LASTNBYTES]; + for (int i = 0; i < mainPart.length; i++) { + mainPart[i] = data[i]; + } + for (int j = 0; j < LASTNBYTES; j++) { + REMAIN[j] = data[data.length - LASTNBYTES + j]; + } + md.update(mainPart); + return md.digest(REMAIN); + } + }, + + /* + * update the data 2 bytes each time, after finishing updating, + * do digest (giving the output buffer, offset, and the number + * of bytes to put in the output buffer) + */ + UPDATE_BYTES_DIGEST_BUFFER { + @Override + public byte[] updateDigest(byte[] data, MessageDigest md) + throws DigestException { + + for (int i = 0; i < data.length / 2; i++) { + md.update(data, i * 2, 2); + } + byte[] output = new byte[md.getDigestLength()]; + int len = md.digest(output, 0, output.length); + if (len != output.length) { + throw new RuntimeException( + "ERROR" + ": digest length differs!"); + } + return output; + } + }, + + /* + * update the data 2 bytes each time, after finishing updating, + * do digest + */ + UPDATE_BYTES_DIGEST { + @Override + public byte[] updateDigest(byte[] data, MessageDigest md) { + for (int i=0;i { + try { + AccessController.checkPermission(perm); + return (Boolean) false; + } catch (AccessControlException ex) { + return (Boolean) true; + } + }); + + if (expectException ^ getException) { + String message = "Check Permission :" + perm + "\n ExpectException = " + + expectException + "\n getException = " + getException; + throw new RuntimeException(message); + } + + } + +} diff --git a/test/java/security/Policy/SignedJar/SignedJarTest_1.policy b/test/java/security/Policy/SignedJar/SignedJarTest_1.policy new file mode 100644 index 0000000000000000000000000000000000000000..6094fe56bb2a2705242d808b2b34597f02635110 --- /dev/null +++ b/test/java/security/Policy/SignedJar/SignedJarTest_1.policy @@ -0,0 +1,10 @@ +keystore "file:both.jks"; +keystorePasswordURL "file:keypass"; + +grant signedBy "first" { + permission java.lang.RuntimePermission "setIO"; +}; + +grant signedBy "second" { + permission java.lang.RuntimePermission "setFactory"; +}; diff --git a/test/java/security/Policy/SignedJar/SignedJarTest_2.policy b/test/java/security/Policy/SignedJar/SignedJarTest_2.policy new file mode 100644 index 0000000000000000000000000000000000000000..596dd3832eb0e360c465c30e86ad701eac883c50 --- /dev/null +++ b/test/java/security/Policy/SignedJar/SignedJarTest_2.policy @@ -0,0 +1,11 @@ +keystore "file:first.jks"; +keystorePasswordURL "file:keypass"; + +grant signedBy "first" { + permission java.lang.RuntimePermission "setIO"; +}; + +grant signedBy "second" { + permission java.lang.RuntimePermission "setFactory"; +}; + diff --git a/test/java/security/Policy/SignedJar/keypass b/test/java/security/Policy/SignedJar/keypass new file mode 100644 index 0000000000000000000000000000000000000000..f3097ab13082b70f67202aab7dd9d1b35b7ceac2 --- /dev/null +++ b/test/java/security/Policy/SignedJar/keypass @@ -0,0 +1 @@ +password diff --git a/test/java/security/SecureRandom/DefaultProvider.java b/test/java/security/SecureRandom/DefaultProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..50b4719acc620a22d549e5983fd89ce8c9bf74ec --- /dev/null +++ b/test/java/security/SecureRandom/DefaultProvider.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +import static java.lang.System.out; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; + +/** + * @test + * @bug 8048356 + * @summary Assert default provider used on all OS for SecureRandom + */ +public class DefaultProvider { + + private static final String OS_NAME = System.getProperty("os.name"); + private static final String SUNOS = "SunOS"; + private static final String WINDOWS = "Windows"; + + public static void main(String[] args) throws NoSuchAlgorithmException { + out.println("Operating System: " + OS_NAME); + + /* Test default provider used with constructor */ + out.println("TEST: Default provider with constructor"); + SecureRandom secureRandom = new SecureRandom(); + String provider = secureRandom.getProvider().getName(); + if (OS_NAME.startsWith(SUNOS)) { + if (!provider.startsWith("SunPKCS11-")) { + throw new RuntimeException("Unexpected provider name: " + + provider); + } + } else if (!provider.equals("SUN")) { + throw new RuntimeException("Unexpected provider name: " + + provider); + } + out.println("Passed, default provider with constructor: " + provider); + + /* Test default provider with getInstance(String algorithm) */ + out.println("TEST: SHA1PRNG supported on all platforms by SUN provider"); + String algorithm = "SHA1PRNG"; + provider = "SUN"; + + SecureRandom instance = SecureRandom.getInstance(algorithm); + assertInstance(instance, algorithm, provider); + out.println("Passed."); + + if (!OS_NAME.startsWith(WINDOWS)) { + out.println("TEST: NativePRNG supported on all platforms" + + "(except Windows), by SUN provider"); + algorithm = "NativePRNG"; + provider = "SUN"; + } else { + out.println( + "TEST: Windows-PRNG supported on windows by SunMSCAPI provider"); + algorithm = "Windows-PRNG"; + provider = "SunMSCAPI"; + } + instance = SecureRandom.getInstance(algorithm); + assertInstance(instance, algorithm, provider); + out.println("Passed."); + + if (OS_NAME.startsWith(SUNOS)) { + out.println( + "TEST: PKCS11 is supported on Solaris by SunPKCS11 provider"); + algorithm = "PKCS11"; + provider = "SunPKCS11-Solaris"; + instance = SecureRandom.getInstance(algorithm); + assertInstance(instance, algorithm, provider); + out.println("Passed."); + } + } + + private static void assertInstance(SecureRandom instance, + String expectedAlgorithm, + String expectedProvider) { + if (instance != null) { + if (!expectedAlgorithm.equalsIgnoreCase(instance.getAlgorithm())) { + throw new RuntimeException("Expected algorithm:" + + expectedAlgorithm + " actual: " + instance.getAlgorithm()); + } + + if (!expectedProvider.equalsIgnoreCase(instance.getProvider().getName())) { + throw new RuntimeException("Expected provider: " + + expectedProvider + " actual: " + + instance.getProvider().getName()); + } + } else { + throw new RuntimeException("Secure instance is not created"); + } + } +} diff --git a/test/java/security/Signature/Offsets.java b/test/java/security/Signature/Offsets.java new file mode 100644 index 0000000000000000000000000000000000000000..9e71690ea4f588e05e9888d3eab11232c5bebcb6 --- /dev/null +++ b/test/java/security/Signature/Offsets.java @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +import java.security.InvalidKeyException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.Signature; +import java.security.SignatureException; +import jdk.testlibrary.RandomFactory; + +/* + * @test + * @bug 8050374 + * @key randomness + * @summary This test validates signature verification + * Signature.verify(byte[], int, int). The test uses RandomFactory to + * get random set of clear text data to sign. After the signature + * generation, the test tries to verify signature with the above API + * and passing in different signature offset (0, 33, 66, 99). + * @library /lib/testlibrary + * @run main Offsets SUN NONEwithDSA + * @run main Offsets SUN SHA1withDSA + * @run main Offsets SUN SHA224withDSA + * @run main Offsets SUN SHA256withDSA + */ +public class Offsets { + + private final int size; + private final byte[] cleartext; + private final PublicKey pubkey; + private final Signature signature; + private final byte[] signed; + + private Offsets(Signature signature, PublicKey pubkey, PrivateKey privkey, + int size, byte[] cleartext) throws InvalidKeyException, + SignatureException { + this.pubkey = pubkey; + this.signature = signature; + this.size = size; + this.cleartext = cleartext; + + signature.initSign(privkey); + signature.update(cleartext, 0, size); + signed = signature.sign(); + } + + int getDataSize() { + return size; + } + + int getSignatureLength() { + return signed.length; + } + + byte[] shiftSignData(int offset) { + byte[] testSignData = new byte[offset + signed.length]; + System.arraycopy(signed, 0, testSignData, offset, + signed.length); + return testSignData; + } + + boolean verifySignature(byte[] sigData, int sigOffset, int sigLength, + int updateOffset, int updateLength) + throws InvalidKeyException, SignatureException { + signature.initVerify(pubkey); + signature.update(cleartext, updateOffset, updateLength); + return signature.verify(sigData, sigOffset, sigLength); + } + + static Offsets init(String provider, String algorithm) + throws NoSuchAlgorithmException, NoSuchProviderException, + InvalidKeyException, SignatureException { + // fill the cleartext data with random bytes + byte[] cleartext = new byte[100]; + RandomFactory.getRandom().nextBytes(cleartext); + + // NONEwith requires input to be of 20 bytes + int size = algorithm.contains("NONEwith") ? 20 : 100; + + // create signature instance + Signature signature = Signature.getInstance(algorithm, provider); + + String keyAlgo; + if (algorithm.contains("RSA")) { + keyAlgo = "RSA"; + } else if (algorithm.contains("ECDSA")) { + keyAlgo = "EC"; + } else if (algorithm.contains("DSA")) { + keyAlgo = "DSA"; + } else { + throw new RuntimeException("Test doesn't support this signature " + + "algorithm: " + algorithm); + } + + KeyPairGenerator kpg = KeyPairGenerator.getInstance(keyAlgo, provider); + KeyPair kp = kpg.generateKeyPair(); + PublicKey pubkey = kp.getPublic(); + PrivateKey privkey = kp.getPrivate(); + + return new Offsets(signature, pubkey, privkey, size, cleartext); + } + + public static void main(String[] args) throws NoSuchAlgorithmException, + InvalidKeyException, SignatureException { + if (args.length < 2) { + throw new RuntimeException("Wrong parameters"); + } + + boolean result = true; + try { + Offsets test = init(args[0], args[1]); + + // We are trying 3 different offsets, data size has nothing to do + // with signature length + for (int chunk = 3; chunk > 0; chunk--) { + int signOffset = test.getDataSize() / chunk; + + System.out.println("Running test with offset " + signOffset); + byte[] signData = test.shiftSignData(signOffset); + + boolean success = test.verifySignature(signData, signOffset, + test.getSignatureLength(), 0, test.getDataSize()); + + if (success) { + System.out.println("Successfully verified with offset " + + signOffset); + } else { + System.out.println("Verification failed with offset " + + signOffset); + result = false; + } + } + + // save signature to offset 0 + byte[] signData = test.shiftSignData(0); + + // Negative tests + + // Test signature offset 0. + // Wrong test data will be passed to update, + // so signature verification should fail. + for (int chunk = 3; chunk > 0; chunk--) { + int dataOffset = (test.getDataSize() - 1) / chunk; + boolean success; + try { + success = test.verifySignature(signData, 0, + test.getSignatureLength(), dataOffset, + (test.getDataSize() - dataOffset)); + } catch (SignatureException e) { + // Since we are trying different data size, it can throw + // SignatureException + success = false; + } + + if (!success) { + System.out.println("Signature verification failed " + + "as expected, with data offset " + dataOffset + + " and length " + + (test.getDataSize() - dataOffset)); + } else { + System.out.println("Signature verification " + + "should not succeed, with data offset " + + dataOffset + " and length " + + (test.getDataSize() - dataOffset)); + result = false; + } + } + + // Tests with manipulating offset and length + result &= Offsets.checkFailure(test, signData, -1, + test.getSignatureLength()); + + result &= Offsets.checkFailure(test, signData, 0, + test.getSignatureLength() - 1); + + result &= Offsets.checkFailure(test, signData, + test.getSignatureLength() + 1, test.getSignatureLength()); + + result &= Offsets.checkFailure(test, signData, 0, + test.getSignatureLength() + 1); + + result &= Offsets.checkFailure(test, signData, 0, 0); + + result &= Offsets.checkFailure(test, signData, 0, -1); + + result &= Offsets.checkFailure(test, signData, + 2147483646, test.getSignatureLength()); + + result &= Offsets.checkFailure(test, null, 0, + test.getSignatureLength()); + } catch (NoSuchProviderException nspe) { + System.out.println("No such provider: " + nspe); + } + + if (!result) { + throw new RuntimeException("Some test cases failed"); + } + } + + static boolean checkFailure(Offsets test, byte[] signData, int offset, + int length) { + boolean success; + try { + success = test.verifySignature(signData, offset, length, 0, + test.getDataSize()); + } catch (IllegalArgumentException | SignatureException e) { + System.out.println("Expected exception: " + e); + success = false; + } catch (InvalidKeyException e) { + System.out.println("Unexpected exception: " + e); + return false; + } + + if (!success) { + System.out.println("Signature verification failed as expected, " + + "with signature offset " + offset + " and length " + + length); + return true; + } else { + System.out.println("Signature verification should not succeed, " + + "with signature offset " + offset + " and length " + + length); + return false; + } + } + +} diff --git a/test/java/security/SignedObject/Chain.java b/test/java/security/SignedObject/Chain.java new file mode 100644 index 0000000000000000000000000000000000000000..e6c423cbb0287a9bfab9a4ae881776968d2d0980 --- /dev/null +++ b/test/java/security/SignedObject/Chain.java @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +import java.security.Signature; +import java.security.SignedObject; +import java.security.KeyPairGenerator; +import java.security.KeyPair; +import java.security.NoSuchProviderException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.util.Arrays; + +/* + * @test + * @bug 8050374 + * @summary Verify a chain of signed objects + */ +public class Chain { + + static enum KeyAlg { + RSA("RSA"), + DSA("DSA"), + EC("EC"); + + final String name; + + KeyAlg(String alg) { + this.name = alg; + } + } + + static enum Provider { + Default("default"), + SunRsaSign("SunRsaSign"), + Sun("SUN"), + SunEC("SunEC"), + SunJSSE("SunJSSE"), + SunMSCAPI("SunMSCAPI"); + + final String name; + + Provider(String name) { + this.name = name; + } + } + + static enum SigAlg { + MD2withRSA("MD2withRSA"), + MD5withRSA("md5withRSA"), + + SHA1withDSA("SHA1withDSA"), + SHA224withDSA("SHA224withDSA"), + SHA256withDSA("SHA256withDSA"), + + SHA1withRSA("Sha1withrSA"), + SHA224withRSA("SHA224withRSA"), + SHA256withRSA("SHA256withRSA"), + SHA384withRSA("SHA384withRSA"), + SHA512withRSA("SHA512withRSA"), + + SHA1withECDSA("SHA1withECDSA"), + SHA256withECDSA("SHA256withECDSA"), + SHA224withECDSA("SHA224withECDSA"), + SHA384withECDSA("SHA384withECDSA"), + SHA512withECDSA("SHA512withECDSA"), + + MD5andSHA1withRSA("MD5andSHA1withRSA"); + + final String name; + + SigAlg(String name) { + this.name = name; + } + } + + static class Test { + final Provider provider; + final KeyAlg keyAlg; + final SigAlg sigAlg; + + Test(SigAlg sigAlg, KeyAlg keyAlg, Provider privider) { + this.provider = privider; + this.keyAlg = keyAlg; + this.sigAlg = sigAlg; + } + } + + private static final Test[] tests = { + new Test(SigAlg.SHA1withDSA, KeyAlg.DSA, Provider.Default), + new Test(SigAlg.MD2withRSA, KeyAlg.RSA, Provider.Default), + new Test(SigAlg.MD5withRSA, KeyAlg.RSA, Provider.Default), + new Test(SigAlg.SHA1withRSA, KeyAlg.RSA, Provider.Default), + new Test(SigAlg.SHA1withDSA, KeyAlg.DSA, Provider.Sun), + new Test(SigAlg.SHA224withDSA, KeyAlg.DSA, Provider.Sun), + new Test(SigAlg.SHA256withDSA, KeyAlg.DSA, Provider.Sun), + }; + + private static final String str = "to-be-signed"; + private static final int N = 3; + + public static void main(String argv[]) { + boolean result = Arrays.stream(tests).allMatch((test) -> runTest(test)); + if(result) { + System.out.println("All tests passed"); + } else { + throw new RuntimeException("Some tests failed"); + } + } + + static boolean runTest(Test test) { + System.out.format("Test: provider = %s, signature algorithm = %s, " + + "key algorithm = %s\n", + test.provider, test.sigAlg, test.keyAlg); + try { + // Generate all private/public key pairs + PrivateKey[] privKeys = new PrivateKey[N]; + PublicKey[] pubKeys = new PublicKey[N]; + PublicKey[] anotherPubKeys = new PublicKey[N]; + KeyPairGenerator kpg = KeyPairGenerator.getInstance( + test.keyAlg.name); + for (int j=0; j < N; j++) { + KeyPair kp = kpg.genKeyPair(); + KeyPair anotherKp = kpg.genKeyPair(); + privKeys[j] = kp.getPrivate(); + pubKeys[j] = kp.getPublic(); + anotherPubKeys[j] = anotherKp.getPublic(); + + if (Arrays.equals(pubKeys[j].getEncoded(), + anotherPubKeys[j].getEncoded())) { + System.out.println("Failed: it should not get " + + "the same pair of public key"); + return false; + } + } + + Signature signature; + if (test.provider != Provider.Default) { + signature = Signature.getInstance(test.sigAlg.name, + test.provider.name); + } else { + signature = Signature.getInstance(test.sigAlg.name); + } + + // Create a chain of signed objects + SignedObject[] objects = new SignedObject[N]; + objects[0] = new SignedObject(str, privKeys[0], signature); + for (int j = 1; j < N; j++) { + objects[j] = new SignedObject(objects[j - 1], privKeys[j], + signature); + } + + // Verify the chain + int n = objects.length - 1; + SignedObject object = objects[n]; + do { + if (!object.verify(pubKeys[n], signature)) { + System.out.println("Failed: verification failed, n = " + n); + return false; + } + + if (object.verify(anotherPubKeys[n], signature)) { + System.out.println("Failed: verification should not " + + "succeed with wrong public key, n = " + n); + return false; + } + + object = (SignedObject) object.getObject(); + n--; + } while (n > 0); + + System.out.println("signed data: " + object.getObject()); + if (!str.equals(object.getObject())) { + System.out.println("Failed: signed data is not equal to " + + "original one"); + return false; + } + + System.out.println("Test passed"); + return true; + } catch (NoSuchProviderException nspe) { + if (test.provider == Provider.SunMSCAPI + && !System.getProperty("os.name").startsWith("Windows")) { + System.out.println("SunMSCAPI is available only on Windows: " + + nspe); + return true; + } + System.out.println("Unexpected exception: " + nspe); + return false; + } catch (Exception e) { + System.out.println("Unexpected exception: " + e); + e.printStackTrace(System.out); + return false; + } + } +} + diff --git a/test/java/security/SignedObject/Copy.java b/test/java/security/SignedObject/Copy.java new file mode 100644 index 0000000000000000000000000000000000000000..22406ea2a846cb23cb49180095beae4c3de78f32 --- /dev/null +++ b/test/java/security/SignedObject/Copy.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +import java.io.Serializable; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.Signature; +import java.security.SignedObject; + +/* + * @test + * @bug 8050374 + * @summary Checks if a signed object is a copy of an original object + */ +public class Copy { + + private static final String DSA = "DSA"; + private static final int KEY_SIZE = 512; + private static final int MAGIC = 123; + + public static void main(String args[]) throws Exception { + KeyPairGenerator kg = KeyPairGenerator.getInstance(DSA); + kg.initialize(KEY_SIZE); + KeyPair kp = kg.genKeyPair(); + + Signature signature = Signature.getInstance(DSA); + Test original = new Test(); + SignedObject so = new SignedObject(original, kp.getPrivate(), + signature); + System.out.println("Signature algorithm: " + so.getAlgorithm()); + + signature = Signature.getInstance(DSA, "SUN"); + if (!so.verify(kp.getPublic(), signature)) { + throw new RuntimeException("Verification failed"); + } + + kg = KeyPairGenerator.getInstance(DSA); + kg.initialize(KEY_SIZE); + kp = kg.genKeyPair(); + + if (so.verify(kp.getPublic(), signature)) { + throw new RuntimeException("Unexpected success"); + } + + Object copy = so.getObject(); + if (!original.equals(copy)) { + throw new RuntimeException("Signed object is not equal " + + "to original one: " + copy); + } + + /* + * The signed object is a copy of an original one. + * Once the copy is made, further manipulation + * of the original object shouldn't has any effect on the copy. + */ + original.set(MAGIC - 1); + copy = so.getObject(); + if (original.equals(copy)) { + throw new RuntimeException("Signed object is not a copy " + + "of original one: " + copy); + } + + System.out.println("Test passed"); + } + + private static class Test implements Serializable { + private int number = MAGIC; + + public int get() { + return number; + } + + public void set(int magic) { + this.number = magic; + } + + @Override + public int hashCode() { + return number; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + + if (!(obj instanceof Test)) { + return false; + } + + Test other = (Test) obj; + return number == other.number; + } + + @Override + public String toString() { + return "" + number; + } + } +} + + diff --git a/test/java/security/cert/CertPathEncodingTest.java b/test/java/security/cert/CertPathEncodingTest.java new file mode 100644 index 0000000000000000000000000000000000000000..2bcfcc76824ec1c93cb55592fea6cce818086382 --- /dev/null +++ b/test/java/security/cert/CertPathEncodingTest.java @@ -0,0 +1,253 @@ +/* + * Copyright (c) 1998, 2015, 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. + * + * 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. + */ +import java.io.ByteArrayInputStream; +import java.security.cert.CertPath; +import java.security.cert.Certificate; +import java.security.cert.CertificateFactory; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Base64; +import java.util.List; + +/* + * @test + * @bug 8074931 + * @summary CertPathEncodingTest tests the ability of the CertPath and + * CertificateFactory to encode and decode CertPaths. + */ +public final class CertPathEncodingTest { + /* + Certificate: + Data: + Version: 3 (0x2) + Serial Number: 935438132 (0x37c1a734) + Signature Algorithm: dsaWithSHA1 + Issuer: C=us, O=sun, OU=east, OU=bcn, CN=yassir + Validity + Not Before: Aug 23 19:55:32 1999 GMT + Not After : Aug 22 19:55:32 2000 GMT + Subject: C=us, O=sun, OU=east, OU=bcn + Subject Public Key Info: + Public Key Algorithm: dsaEncryption + pub: + 63:47:4f:f6:29:e5:98:a2:21:fd:da:97:9e:3f:ca: + b0:17:49:8d:8a:a7:06:0d:a6:78:97:39:59:33:72: + a2:a5:74:d5:3a:ef:e6:7c:07:d7:8e:8e:d1:66:73: + 99:14:04:96:f5:31:d6:72:ee:d2:53:f8:90:b5:f3: + c3:f1:64:ba:1a:9e:c0:0a:da:92:48:c5:d3:84:7e: + 48:09:66:d9:51:ba:74:56:5a:77:8a:8c:9a:9c:f6: + 84:12:61:12:51:dc:c6:4f:84:94:ec:cb:78:51:83: + 8c:20:8a:53:7b:d2:b6:36:df:50:35:95:1f:cb:50: + 55:8b:3f:fb:e2:77:cb + P: + 00:fd:7f:53:81:1d:75:12:29:52:df:4a:9c:2e:ec: + e4:e7:f6:11:b7:52:3c:ef:44:00:c3:1e:3f:80:b6: + 51:26:69:45:5d:40:22:51:fb:59:3d:8d:58:fa:bf: + c5:f5:ba:30:f6:cb:9b:55:6c:d7:81:3b:80:1d:34: + 6f:f2:66:60:b7:6b:99:50:a5:a4:9f:9f:e8:04:7b: + 10:22:c2:4f:bb:a9:d7:fe:b7:c6:1b:f8:3b:57:e7: + c6:a8:a6:15:0f:04:fb:83:f6:d3:c5:1e:c3:02:35: + 54:13:5a:16:91:32:f6:75:f3:ae:2b:61:d7:2a:ef: + f2:22:03:19:9d:d1:48:01:c7 + Q: + 00:97:60:50:8f:15:23:0b:cc:b2:92:b9:82:a2:eb: + 84:0b:f0:58:1c:f5 + G: + 00:f7:e1:a0:85:d6:9b:3d:de:cb:bc:ab:5c:36:b8: + 57:b9:79:94:af:bb:fa:3a:ea:82:f9:57:4c:0b:3d: + 07:82:67:51:59:57:8e:ba:d4:59:4f:e6:71:07:10: + 81:80:b4:49:16:71:23:e8:4c:28:16:13:b7:cf:09: + 32:8c:c8:a6:e1:3c:16:7a:8b:54:7c:8d:28:e0:a3: + ae:1e:2b:b3:a6:75:91:6e:a3:7f:0b:fa:21:35:62: + f1:fb:62:7a:01:24:3b:cc:a4:f1:be:a8:51:90:89: + a8:83:df:e1:5a:e5:9f:06:92:8b:66:5e:80:7b:55: + 25:64:01:4c:3b:fe:cf:49:2a + X509v3 extensions: + X509v3 Key Usage: critical + Digital Signature, Key Encipherment, Certificate Sign + Signature Algorithm: dsaWithSHA1 + r: + 52:80:52:2b:2c:3d:02:66:58:b4:dc:ef:52:26:70: + 1b:53:ca:b3:7d + s: + 62:03:b2:ab:3e:18:2a:66:09:b6:ce:d4:05:a5:8e: + a5:7a:0d:55:67 + */ + private static final String cert1 = + "-----BEGIN CERTIFICATE-----\n" + + "MIICzTCCAougAwIBAgIEN8GnNDALBgcqhkjOOAQDBQAwSTELMAkGA1UEBhMCdXMx\n" + + "DDAKBgNVBAoTA3N1bjENMAsGA1UECxMEZWFzdDEMMAoGA1UECxMDYmNuMQ8wDQYD\n" + + "VQQDEwZ5YXNzaXIwHhcNOTkwODIzMTk1NTMyWhcNMDAwODIyMTk1NTMyWjA4MQsw\n" + + "CQYDVQQGEwJ1czEMMAoGA1UEChMDc3VuMQ0wCwYDVQQLEwRlYXN0MQwwCgYDVQQL\n" + + "EwNiY24wggG1MIIBLAYHKoZIzjgEATCCAR8CgYEA/X9TgR11EilS30qcLuzk5/YR\n" + + "t1I870QAwx4/gLZRJmlFXUAiUftZPY1Y+r/F9bow9subVWzXgTuAHTRv8mZgt2uZ\n" + + "UKWkn5/oBHsQIsJPu6nX/rfGG/g7V+fGqKYVDwT7g/bTxR7DAjVUE1oWkTL2dfOu\n" + + "K2HXKu/yIgMZndFIAccCFQCXYFCPFSMLzLKSuYKi64QL8Fgc9QKBgQD34aCF1ps9\n" + + "3su8q1w2uFe5eZSvu/o66oL5V0wLPQeCZ1FZV4661FlP5nEHEIGAtEkWcSPoTCgW\n" + + "E7fPCTKMyKbhPBZ6i1R8jSjgo64eK7OmdZFuo38L+iE1YvH7YnoBJDvMpPG+qFGQ\n" + + "iaiD3+Fa5Z8GkotmXoB7VSVkAUw7/s9JKgOBggACf2NHT/Yp5ZiiIf3al54/yrAX\n" + + "SY2KpwYNpniXOVkzcqKldNU67+Z8B9eOjtFmc5kUBJb1MdZy7tJT+JC188PxZLoa\n" + + "nsAK2pJIxdOEfkgJZtlRunRWWneKjJqc9oQSYRJR3MZPhJTsy3hRg4wgilN70rY2\n" + + "31A1lR/LUFWLP/vid8ujEzARMA8GA1UdDwEB/wQFAwMHpAAwCwYHKoZIzjgEAwUA\n" + + "Ay8AMCwCFFKAUissPQJmWLTc71ImcBtTyrN9AhRiA7KrPhgqZgm2ztQFpY6leg1V\n" + + "Zw==\n" + + "-----END CERTIFICATE-----\n" + + ""; + + /* + Certificate: + Data: + Version: 3 (0x2) + Serial Number: 935095671 (0x37bc6d77) + Signature Algorithm: dsaWithSHA1 + Issuer: C=us, O=sun, OU=east, OU=bcn, CN=yassir + Validity + Not Before: Aug 19 20:47:51 1999 GMT + Not After : Aug 18 20:47:51 2000 GMT + Subject: C=us, O=sun, OU=east, OU=bcn, CN=yassir + Subject Public Key Info: + Public Key Algorithm: dsaEncryption + pub: + 0a:cc:a4:ec:d6:88:45:c2:24:6b:0d:78:f1:82:f3: + 5e:3e:31:5d:fb:64:d5:06:5e:39:16:f1:0a:85:d1: + ff:d1:a4:74:c5:e6:b0:ba:93:1c:ee:69:51:be:3b: + a6:66:44:50:b4:f0:5e:0e:dd:9f:08:71:fe:a1:91: + 2e:d4:9e:6b:b2:c0:82:3c:91:6c:18:b0:d9:bc:a3: + 48:91:3f:8b:59:01:61:00:02:ab:22:31:bc:7c:6c: + 0d:9f:ed:be:33:e6:5c:44:9e:62:30:95:f8:6d:22: + d7:e5:85:4c:b0:98:6e:ad:cc:ca:3b:ad:cb:fa:f7: + 9f:37:13:f7:ca:e2:22:ba + P: + 00:fd:7f:53:81:1d:75:12:29:52:df:4a:9c:2e:ec: + e4:e7:f6:11:b7:52:3c:ef:44:00:c3:1e:3f:80:b6: + 51:26:69:45:5d:40:22:51:fb:59:3d:8d:58:fa:bf: + c5:f5:ba:30:f6:cb:9b:55:6c:d7:81:3b:80:1d:34: + 6f:f2:66:60:b7:6b:99:50:a5:a4:9f:9f:e8:04:7b: + 10:22:c2:4f:bb:a9:d7:fe:b7:c6:1b:f8:3b:57:e7: + c6:a8:a6:15:0f:04:fb:83:f6:d3:c5:1e:c3:02:35: + 54:13:5a:16:91:32:f6:75:f3:ae:2b:61:d7:2a:ef: + f2:22:03:19:9d:d1:48:01:c7 + Q: + 00:97:60:50:8f:15:23:0b:cc:b2:92:b9:82:a2:eb: + 84:0b:f0:58:1c:f5 + G: + 00:f7:e1:a0:85:d6:9b:3d:de:cb:bc:ab:5c:36:b8: + 57:b9:79:94:af:bb:fa:3a:ea:82:f9:57:4c:0b:3d: + 07:82:67:51:59:57:8e:ba:d4:59:4f:e6:71:07:10: + 81:80:b4:49:16:71:23:e8:4c:28:16:13:b7:cf:09: + 32:8c:c8:a6:e1:3c:16:7a:8b:54:7c:8d:28:e0:a3: + ae:1e:2b:b3:a6:75:91:6e:a3:7f:0b:fa:21:35:62: + f1:fb:62:7a:01:24:3b:cc:a4:f1:be:a8:51:90:89: + a8:83:df:e1:5a:e5:9f:06:92:8b:66:5e:80:7b:55: + 25:64:01:4c:3b:fe:cf:49:2a + X509v3 extensions: + X509v3 Key Usage: critical + Digital Signature, Key Encipherment, Certificate Sign + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:5 + Signature Algorithm: dsaWithSHA1 + r: + 2f:88:46:37:94:92:b2:02:07:5b:8d:76:e5:81:23: + 85:7f:bc:8d:b9 + s: + 00:8b:d7:41:fa:11:c7:ab:27:92:5d:0a:03:98:56: + 36:42:5f:f5:1f:9d + */ + private static final String cert2 = + "-----BEGIN CERTIFICATE-----\n" + + "MIIC9TCCArKgAwIBAgIEN7xtdzALBgcqhkjOOAQDBQAwSTELMAkGA1UEBhMCdXMx\n" + + "DDAKBgNVBAoTA3N1bjENMAsGA1UECxMEZWFzdDEMMAoGA1UECxMDYmNuMQ8wDQYD\n" + + "VQQDEwZ5YXNzaXIwHhcNOTkwODE5MjA0NzUxWhcNMDAwODE4MjA0NzUxWjBJMQsw\n" + + "CQYDVQQGEwJ1czEMMAoGA1UEChMDc3VuMQ0wCwYDVQQLEwRlYXN0MQwwCgYDVQQL\n" + + "EwNiY24xDzANBgNVBAMTBnlhc3NpcjCCAbcwggEsBgcqhkjOOAQBMIIBHwKBgQD9\n" + + "f1OBHXUSKVLfSpwu7OTn9hG3UjzvRADDHj+AtlEmaUVdQCJR+1k9jVj6v8X1ujD2\n" + + "y5tVbNeBO4AdNG/yZmC3a5lQpaSfn+gEexAiwk+7qdf+t8Yb+DtX58aophUPBPuD\n" + + "9tPFHsMCNVQTWhaRMvZ1864rYdcq7/IiAxmd0UgBxwIVAJdgUI8VIwvMspK5gqLr\n" + + "hAvwWBz1AoGBAPfhoIXWmz3ey7yrXDa4V7l5lK+7+jrqgvlXTAs9B4JnUVlXjrrU\n" + + "WU/mcQcQgYC0SRZxI+hMKBYTt88JMozIpuE8FnqLVHyNKOCjrh4rs6Z1kW6jfwv6\n" + + "ITVi8ftiegEkO8yk8b6oUZCJqIPf4VrlnwaSi2ZegHtVJWQBTDv+z0kqA4GEAAKB\n" + + "gArMpOzWiEXCJGsNePGC814+MV37ZNUGXjkW8QqF0f/RpHTF5rC6kxzuaVG+O6Zm\n" + + "RFC08F4O3Z8Icf6hkS7UnmuywII8kWwYsNm8o0iRP4tZAWEAAqsiMbx8bA2f7b4z\n" + + "5lxEnmIwlfhtItflhUywmG6tzMo7rcv69583E/fK4iK6oycwJTAPBgNVHQ8BAf8E\n" + + "BQMDB6QAMBIGA1UdEwEB/wQIMAYBAf8CAQUwCwYHKoZIzjgEAwUAAzAAMC0CFC+I\n" + + "RjeUkrICB1uNduWBI4V/vI25AhUAi9dB+hHHqyeSXQoDmFY2Ql/1H50=\n" + + "-----END CERTIFICATE-----\n" + + ""; + + private static final String pkcs7path = + "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\n" + + ""; + + // Runs test of CertPath encoding and decoding. + public static void main(String[] args) throws Exception { + // Make the CertPath whose encoded form has already been stored + CertificateFactory certFac = CertificateFactory.getInstance("X509"); + + final List certs = new ArrayList<>(); + certs.add(certFac.generateCertificate(new ByteArrayInputStream(cert1.getBytes()))); + certs.add(certFac.generateCertificate(new ByteArrayInputStream(cert2.getBytes()))); + + CertPath cp = certFac.generateCertPath(certs); + + // Get the encoded form of the CertPath we made + byte[] encoded = cp.getEncoded("PKCS7"); + + // check if it matches the encoded value + if (!Arrays.equals(encoded, Base64.getMimeDecoder().decode(pkcs7path.getBytes()))) { + throw new RuntimeException("PKCS#7 encoding doesn't match stored value"); + } + + // Generate a CertPath from the encoded value and check if it equals + // the CertPath generated from the certificates + CertPath decodedCP = certFac.generateCertPath(new ByteArrayInputStream(encoded), "PKCS7"); + if (!decodedCP.equals(cp)) { + throw new RuntimeException("CertPath decoded from PKCS#7 isn't equal to original"); + } + } +} diff --git a/test/java/security/cert/X509CertSelectorTest.java b/test/java/security/cert/X509CertSelectorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..f41c52cfaa43c8ea65e2c6d35b7eb0ea3a6e97d8 --- /dev/null +++ b/test/java/security/cert/X509CertSelectorTest.java @@ -0,0 +1,536 @@ +/* + * Copyright (c) 2000, 2016, 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. + * + * 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. + */ +import static sun.security.x509.GeneralNameInterface.NAME_DIRECTORY; +import static sun.security.x509.NameConstraintsExtension.EXCLUDED_SUBTREES; +import static sun.security.x509.NameConstraintsExtension.PERMITTED_SUBTREES; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.math.BigInteger; +import java.security.GeneralSecurityException; +import java.security.KeyFactory; +import java.security.PublicKey; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509CertSelector; +import java.security.cert.X509Certificate; +import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; +import java.util.Calendar; +import java.util.Date; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import sun.security.util.DerInputStream; +import sun.security.util.DerOutputStream; +import sun.security.util.DerValue; +import sun.security.util.ObjectIdentifier; +import sun.security.x509.AlgorithmId; +import sun.security.x509.AuthorityKeyIdentifierExtension; +import sun.security.x509.CertificatePoliciesExtension; +import sun.security.x509.DNSName; +import sun.security.x509.GeneralName; +import sun.security.x509.GeneralNameInterface; +import sun.security.x509.GeneralNames; +import sun.security.x509.GeneralSubtree; +import sun.security.x509.GeneralSubtrees; +import sun.security.x509.KeyIdentifier; +import sun.security.x509.NameConstraintsExtension; +import sun.security.x509.PolicyInformation; +import sun.security.x509.PrivateKeyUsageExtension; +import sun.security.x509.SubjectAlternativeNameExtension; +import sun.security.x509.X500Name; + +/* + * @test + * @bug 8074931 + * @summary This class tests the X509CertSelector. The tests check particular criteria + * by setting them to a value that should match our test certificate and + * ensuring that they do match, then setting them to a value that should not + * match our test certificate and ensuring that they do not match. + */ +public class X509CertSelectorTest { + /* + Certificate: + Data: + Version: 3 (0x2) + Serial Number: 954172088 (0x38df82b8) + Signature Algorithm: dsaWithSHA1 + Issuer: C=us, O=sun, OU=testing + Validity + Not Before: Mar 27 15:48:08 2000 GMT + Not After : Jun 25 14:48:08 2000 GMT + Subject: C=us, O=sun, OU=testing, CN=mullan + Subject Public Key Info: + Public Key Algorithm: dsaEncryption + pub: 0 + P: 0 + Q: 0 + G: 0 + X509v3 extensions: + X509v3 Name Constraints: critical + 0D.B0@.>1.0...U....us1.0 + ..U. + ..sun1.0...U....testing1.0 + ..U....mullan + X509v3 Subject Key Identifier: + 56:E8:88:AE:9D:B5:3F:2B:CB:A0:4C:4B:E2:87:53:07:33:77:1B:DF + X509v3 Authority Key Identifier: + keyid:8E:DD:AF:6F:EE:02:12:F4:61:E9:2F:E3:64:1A:6F:71:32:25:20:C0 + + X509v3 Subject Alternative Name: + email:mullan@east.sun.com + X509v3 Private Key Usage Period: + Not Before: Jan 1 05:00:00 2000 GMT, Not After: Jan 1 05:00:00 2001 GMT + X509v3 Key Usage: critical + Digital Signature + X509v3 Certificate Policies: + 0$0\..*...0.0...+.......0.. + Testing... + Signature Algorithm: dsaWithSHA1 + r: + 44:c7:35:40:5d:6c:28:75:7f:73:b2:f8:0d:72:6c: + 09:65:b8:81:14 + s: + 76:79:f5:c7:37:3b:0d:9b:db:70:2f:20:80:36:e3: + 80:e8:a6:c6:71 + */ + private static final String testCert = + "-----BEGIN CERTIFICATE-----\n" + + "MIICLjCCAeygAwIBAgIEON+CuDALBgcqhkjOOAQDBQAwLTELMAkGA1UEBhMCdXMx\n" + + "DDAKBgNVBAoTA3N1bjEQMA4GA1UECxMHdGVzdGluZzAeFw0wMDAzMjcxNTQ4MDha\n" + + "Fw0wMDA2MjUxNDQ4MDhaMD4xCzAJBgNVBAYTAnVzMQwwCgYDVQQKEwNzdW4xEDAO\n" + + "BgNVBAsTB3Rlc3RpbmcxDzANBgNVBAMTBm11bGxhbjAcMBQGByqGSM44BAEwCQIB\n" + + "AAIBAAIBAAMEAAIBAKOCASMwggEfMFAGA1UdHgEB/wRGMESgQjBApD4xCzAJBgNV\n" + + "BAYTAnVzMQwwCgYDVQQKEwNzdW4xEDAOBgNVBAsTB3Rlc3RpbmcxDzANBgNVBAMT\n" + + "Bm11bGxhbjAdBgNVHQ4EFgQUVuiIrp21PyvLoExL4odTBzN3G98wHwYDVR0jBBgw\n" + + "FoAUjt2vb+4CEvRh6S/jZBpvcTIlIMAwHgYDVR0RBBcwFYETbXVsbGFuQGVhc3Qu\n" + + "c3VuLmNvbTArBgNVHRAEJDAigA8yMDAwMDEwMTA1MDAwMFqBDzIwMDEwMTAxMDUw\n" + + "MDAwWjAPBgNVHQ8BAf8EBQMDB4AAMC0GA1UdIAQmMCQwIgYEKoSAADAaMBgGCCsG\n" + + "AQUFBwICMAwSClRlc3RpbmcuLi4wCwYHKoZIzjgEAwUAAy8AMCwCFETHNUBdbCh1\n" + + "f3Oy+A1ybAlluIEUAhR2efXHNzsNm9twLyCANuOA6KbGcQ==\n" + + "-----END CERTIFICATE-----\n" + + ""; + + private static final String testKey = + "MIIBtjCCASsGByqGSM44BAEwggEeAoGBAIVWPEkcxbxhQRCqVzg55tNqbP5j0K4kdu4bkmXvfqC5\n" + + "+qA75DvnfzsOJseb+9AuKXWk/DvCzFDmrY1YaU3scZC3OQEO9lEO3F4VDKOaudY6OT1SI22pAIwz\n" + + "j5pvq+i7zOp4xUqkQUeh/4iQSfxOT5UrFGjkcbnbpVkCXD/GxAz7AhUAjtnm3dVIddUUHl6wxpZ7\n" + + "GcA6gSsCgYAf/PXzQtemgIDjpFrNNSgTEKkLposBXKatAM+gUKlMUjf8SQvquqPxDtRrscGjXkoL\n" + + "oTkaR7/akULYFpBvUcFkeIFiCnJg8M9XhCWdLvn9MPt+jR2oxookvCb9xLtD6WvIM/wd/nZ1iK4u\n" + + "iY1+q85xvns/Awbtwl7oZDAwE2TUKAOBhAACgYBDc9UZ+3xsZubUZvRG5cpyJceYpJp2exOPVJXn\n" + + "jR4CcR+cT9bAJpFSxqE/8KtNHXxHdu4f3DU67IMOVDpugzihyzXJvNm3w2H9x+6xczHG2wjvAJeh\n" + + "X62EWbUatxPXFAoVKZWuUbaYaZzdWBDtNRrCuKKsLo0GFy8g2BZISuD3jw==\n" + + ""; + + // Certificate to run tests on + private final X509Certificate cert; + + public static void main(String[] args) throws Exception { + X509CertSelectorTest test = new X509CertSelectorTest(); + test.doTest(); + } + + public X509CertSelectorTest() throws CertificateException, IOException { + cert = (X509Certificate) CertificateFactory.getInstance("X.509") + .generateCertificate(new ByteArrayInputStream(testCert.getBytes())); + } + + // Runs the test. + private void doTest() throws Exception { + System.out.println("START OF TESTS FOR " + "X509CertSelector"); + + testSerialNumber(); + testIssuer(); + testSubjectKeyIdentifier(); + testAuthorityKeyIdentifier(); + testCertificateValid(); + testPrivateKeyValid(); + testSubjectPublicKeyAlgID(); + testKeyUsage(); + testSubjectAltName(); + testPolicy(); + testPathToName(); + testSubject(); + testSubjectPublicKey(); + testNameConstraints(); + testBasicConstraints(); + testCertificate(); + } + + // Tests matching on the serial number contained in the certificate. + private void testSerialNumber() { + System.out.println("X.509 Certificate Match on serialNumber"); + // bad match + X509CertSelector selector = new X509CertSelector(); + selector.setSerialNumber(new BigInteger("999999999")); + checkMatch(selector, cert, false); + + // good match + selector.setSerialNumber(cert.getSerialNumber()); + checkMatch(selector, cert, true); + } + + // Tests matching on the issuer name contained in the certificate. + private void testIssuer() throws IOException { + System.out.println("X.509 Certificate Match on issuer"); + // bad match + X509CertSelector selector = new X509CertSelector(); + selector.setIssuer("ou=bogus,ou=east,o=sun,c=us"); + checkMatch(selector, cert, false); + + // good match + selector.setIssuer((cert.getIssuerX500Principal()).getName("RFC2253")); + checkMatch(selector, cert, true); + } + + /* + * Tests matching on the subject key identifier contained in the + * certificate. + */ + private void testSubjectKeyIdentifier() throws IOException { + System.out.println("X.509 Certificate Match on subjectKeyIdentifier"); + // bad match + X509CertSelector selector = new X509CertSelector(); + byte[] b = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + selector.setSubjectKeyIdentifier(b); + checkMatch(selector, cert, false); + + // good match + DerInputStream in = new DerInputStream(cert.getExtensionValue("2.5.29.14")); + byte[] encoded = in.getOctetString(); + selector.setSubjectKeyIdentifier(encoded); + checkMatch(selector, cert, true); + } + + /* + * Tests matching on the authority key identifier contained in the + * certificate. + */ + private void testAuthorityKeyIdentifier() throws IOException { + System.out.println("X.509 Certificate Match on authorityKeyIdentifier"); + // bad match + X509CertSelector selector = new X509CertSelector(); + byte[] b = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + AuthorityKeyIdentifierExtension a = new AuthorityKeyIdentifierExtension(new KeyIdentifier(b), null, null); + selector.setAuthorityKeyIdentifier(a.getExtensionValue()); + checkMatch(selector, cert, false); + + // good match + DerInputStream in = new DerInputStream(cert.getExtensionValue("2.5.29.35")); + byte[] encoded = in.getOctetString(); + selector.setAuthorityKeyIdentifier(encoded); + checkMatch(selector, cert, true); + } + + /* + * Tests matching on the certificate validity component contained in the + * certificate. + */ + private void testCertificateValid() { + System.out.println("X.509 Certificate Match on certificateValid"); + // bad match + X509CertSelector selector = new X509CertSelector(); + Calendar cal = Calendar.getInstance(); + cal.set(1968, 12, 31); + selector.setCertificateValid(cal.getTime()); + checkMatch(selector, cert, false); + + // good match + selector.setCertificateValid(cert.getNotBefore()); + checkMatch(selector, cert, true); + } + + /* + * Tests matching on the private key validity component contained in the + * certificate. + */ + private void testPrivateKeyValid() throws IOException, CertificateException { + System.out.println("X.509 Certificate Match on privateKeyValid"); + // bad match + X509CertSelector selector = new X509CertSelector(); + Calendar cal = Calendar.getInstance(); + cal.set(1968, 12, 31); + selector.setPrivateKeyValid(cal.getTime()); + checkMatch(selector, cert, false); + + // good match + DerInputStream in = new DerInputStream(cert.getExtensionValue("2.5.29.16")); + byte[] encoded = in.getOctetString(); + PrivateKeyUsageExtension ext = new PrivateKeyUsageExtension(false, encoded); + Date validDate = (Date) ext.get(PrivateKeyUsageExtension.NOT_BEFORE); + selector.setPrivateKeyValid(validDate); + checkMatch(selector, cert, true); + + } + + private ObjectIdentifier getCertPubKeyAlgOID(X509Certificate xcert) throws IOException { + byte[] encodedKey = xcert.getPublicKey().getEncoded(); + DerValue val = new DerValue(encodedKey); + if (val.tag != DerValue.tag_Sequence) { + throw new RuntimeException("invalid key format"); + } + + return AlgorithmId.parse(val.data.getDerValue()).getOID(); + } + + /* + * Tests matching on the subject public key algorithm ID component contained + * in the certificate. + */ + private void testSubjectPublicKeyAlgID() throws IOException { + System.out.println("X.509 Certificate Match on subjectPublicKeyAlgID"); + // bad match + X509CertSelector selector = new X509CertSelector(); + selector.setSubjectPublicKeyAlgID("2.5.29.14"); + checkMatch(selector, cert, false); + + // good match + selector.setSubjectPublicKeyAlgID(getCertPubKeyAlgOID(cert).toString()); + checkMatch(selector, cert, true); + + } + + // Tests matching on the key usage extension contained in the certificate. + private void testKeyUsage() { + System.out.println("X.509 Certificate Match on keyUsage"); + // bad match + X509CertSelector selector = new X509CertSelector(); + boolean[] keyUsage = { true, false, true, false, true, false, true, false }; + selector.setKeyUsage(keyUsage); + System.out.println("Selector = " + selector.toString()); + checkMatch(selector, cert, false); + + // good match + selector.setKeyUsage(cert.getKeyUsage()); + System.out.println("Selector = " + selector.toString()); + checkMatch(selector, cert, true); + } + + /* + * Tests matching on the subject alternative name extension contained in the + * certificate. + */ + private void testSubjectAltName() throws IOException { + System.out.println("X.509 Certificate Match on subjectAltName"); + // bad match + X509CertSelector selector = new X509CertSelector(); + GeneralNameInterface dnsName = new DNSName("foo.com"); + DerOutputStream tmp = new DerOutputStream(); + dnsName.encode(tmp); + selector.addSubjectAlternativeName(2, tmp.toByteArray()); + checkMatch(selector, cert, false); + + // good match + DerInputStream in = new DerInputStream(cert.getExtensionValue("2.5.29.17")); + byte[] encoded = in.getOctetString(); + SubjectAlternativeNameExtension ext = new SubjectAlternativeNameExtension(false, encoded); + GeneralNames names = (GeneralNames) ext.get(SubjectAlternativeNameExtension.SUBJECT_NAME); + GeneralName name = (GeneralName) names.get(0); + selector.setSubjectAlternativeNames(null); + DerOutputStream tmp2 = new DerOutputStream(); + name.getName().encode(tmp2); + selector.addSubjectAlternativeName(name.getType(), tmp2.toByteArray()); + checkMatch(selector, cert, true); + + // good match 2 (matches at least one) + selector.setMatchAllSubjectAltNames(false); + selector.addSubjectAlternativeName(2, "foo.com"); + checkMatch(selector, cert, true); + } + + /* + * Tests matching on the policy constraints extension contained in the + * certificate. + */ + private void testPolicy() throws IOException { + System.out.println("X.509 Certificate Match on certificatePolicies"); + // test encoding of CertificatePoliciesExtension because we wrote the + // code + // bad match + X509CertSelector selector = new X509CertSelector(); + Set s = new HashSet<>(); + s.add(new String("1.2.5.7.68")); + selector.setPolicy(s); + checkMatch(selector, cert, false); + + // good match + DerInputStream in = new DerInputStream(cert.getExtensionValue("2.5.29.32")); + CertificatePoliciesExtension ext = new CertificatePoliciesExtension(false, in.getOctetString()); + List policies = ext.get(CertificatePoliciesExtension.POLICIES); + // match on the first policy id + PolicyInformation policyInfo = (PolicyInformation) policies.get(0); + s.clear(); + s.add(policyInfo.getPolicyIdentifier().getIdentifier().toString()); + selector.setPolicy(s); + checkMatch(selector, cert, true); + } + + /* + * Tests matching on the name constraints extension contained in the + * certificate. + */ + private void testPathToName() throws IOException { + System.out.println("X.509 Certificate Match on pathToName"); + + X509CertSelector selector = null; + DerInputStream in = new DerInputStream(cert.getExtensionValue("2.5.29.30")); + byte[] encoded = in.getOctetString(); + NameConstraintsExtension ext = new NameConstraintsExtension(false, encoded); + GeneralSubtrees permitted = (GeneralSubtrees) ext.get(PERMITTED_SUBTREES); + GeneralSubtrees excluded = (GeneralSubtrees) ext.get(EXCLUDED_SUBTREES); + + // bad matches on pathToName within excluded subtrees + if (excluded != null) { + Iterator e = excluded.iterator(); + while (e.hasNext()) { + GeneralSubtree tree = e.next(); + if (tree.getName().getType() == NAME_DIRECTORY) { + X500Name excludedDN1 = new X500Name(tree.getName().toString()); + X500Name excludedDN2 = new X500Name("CN=Bogus, " + tree.getName().toString()); + DerOutputStream derDN1 = new DerOutputStream(); + DerOutputStream derDN2 = new DerOutputStream(); + excludedDN1.encode(derDN1); + excludedDN2.encode(derDN2); + selector = new X509CertSelector(); + selector.addPathToName(NAME_DIRECTORY, derDN1.toByteArray()); + checkMatch(selector, cert, false); + selector.setPathToNames(null); + selector.addPathToName(NAME_DIRECTORY, derDN2.toByteArray()); + checkMatch(selector, cert, false); + } + } + } + + // good matches on pathToName within permitted subtrees + if (permitted != null) { + Iterator e = permitted.iterator(); + while (e.hasNext()) { + GeneralSubtree tree = e.next(); + if (tree.getName().getType() == NAME_DIRECTORY) { + X500Name permittedDN1 = new X500Name(tree.getName().toString()); + X500Name permittedDN2 = new X500Name("CN=good, " + tree.getName().toString()); + DerOutputStream derDN1 = new DerOutputStream(); + DerOutputStream derDN2 = new DerOutputStream(); + permittedDN1.encode(derDN1); + permittedDN2.encode(derDN2); + selector = new X509CertSelector(); + selector.addPathToName(NAME_DIRECTORY, derDN1.toByteArray()); + checkMatch(selector, cert, true); + selector.setPathToNames(null); + selector.addPathToName(NAME_DIRECTORY, derDN2.toByteArray()); + checkMatch(selector, cert, true); + } + } + } + } + + // Tests matching on the subject name contained in the certificate. + private void testSubject() throws IOException { + System.out.println("X.509 Certificate Match on subject"); + // bad match + X509CertSelector selector = new X509CertSelector(); + selector.setSubject("ou=bogus,ou=east,o=sun,c=us"); + checkMatch(selector, cert, false); + + // good match + selector.setSubject(cert.getSubjectX500Principal().getName("RFC2253")); + checkMatch(selector, cert, true); + } + + // Tests matching on the subject public key contained in the certificate. + private void testSubjectPublicKey() throws IOException, GeneralSecurityException { + System.out.println("X.509 Certificate Match on subject public key"); + // bad match + X509CertSelector selector = new X509CertSelector(); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec( + Base64.getMimeDecoder().decode(testKey.getBytes())); + KeyFactory keyFactory = KeyFactory.getInstance("DSA"); + PublicKey pubKey = keyFactory.generatePublic(keySpec); + selector.setSubjectPublicKey(pubKey); + checkMatch(selector, cert, false); + + // good match + selector.setSubjectPublicKey(cert.getPublicKey()); + checkMatch(selector, cert, true); + } + + // Tests matching on the name constraints contained in the certificate. + private void testNameConstraints() throws IOException { + System.out.println("X.509 Certificate Match on name constraints"); + // bad match + GeneralSubtrees subjectTree = new GeneralSubtrees(); + subjectTree.add(getGeneralSubtree((X500Name) cert.getSubjectDN())); + NameConstraintsExtension ext = new NameConstraintsExtension((GeneralSubtrees) null, subjectTree); + X509CertSelector selector = new X509CertSelector(); + selector.setNameConstraints(ext.getExtensionValue()); + checkMatch(selector, cert, false); + + // good match + ext = new NameConstraintsExtension(subjectTree, null); + selector.setNameConstraints(ext.getExtensionValue()); + checkMatch(selector, cert, true); + } + + // Tests matching on basic constraints. + private void testBasicConstraints() { + System.out.println("X.509 Certificate Match on basic constraints"); + // bad match + X509CertSelector selector = new X509CertSelector(); + int mpl = cert.getBasicConstraints(); + selector.setBasicConstraints(0); + checkMatch(selector, cert, false); + + // good match + selector.setBasicConstraints(mpl); + checkMatch(selector, cert, true); + } + + // Tests certificateEquals criterion + private void testCertificate() { + System.out.println("X.509 Certificate Match on certificateEquals criterion"); + + X509CertSelector selector = new X509CertSelector(); + // good match + selector.setCertificate(cert); + checkMatch(selector, cert, true); + } + + private void checkMatch(X509CertSelector selector, X509Certificate cert, boolean match) { + boolean result = selector.match(cert); + if (match != result) + throw new RuntimeException(selector + " match " + cert + " is " + result + ", but expect " + match); + } + + private static GeneralSubtree getGeneralSubtree(GeneralNameInterface gni) { + // Create a new GeneralSubtree with the specified name, 0 base, and + // unlimited length + GeneralName gn = new GeneralName(gni); + GeneralSubtree subTree = new GeneralSubtree(gn, 0, -1); + return subTree; + } +} diff --git a/test/java/text/Format/DateFormat/Bug8141243.java b/test/java/text/Format/DateFormat/Bug8141243.java new file mode 100644 index 0000000000000000000000000000000000000000..8d156b1f777c1e80a81b5ec5dcedf46b82b772d5 --- /dev/null +++ b/test/java/text/Format/DateFormat/Bug8141243.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2016, 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. + * + * 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. + */ + +/* + * @test + * @bug 8141243 + * @summary Make sure that SimpleDateFormat parses "UTC" as the UTC time zone. + * @run main Bug8141243 + */ + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Locale; +import java.util.TimeZone; +import static java.util.TimeZone.*; + +public class Bug8141243 { + public static void main(String[] args) { + TimeZone UTC = TimeZone.getTimeZone("UTC"); + TimeZone initTz = TimeZone.getDefault(); + + List errors = new ArrayList<>(); + try { + TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles")); + for (Locale locale : DateFormat.getAvailableLocales()) { + // exclude any locales which localize "UTC". + String utc = UTC.getDisplayName(false, SHORT, locale); + if (!"UTC".equals(utc)) { + System.out.println("Skipping " + locale + " due to localized UTC name: " + utc); + continue; + } + SimpleDateFormat fmt = new SimpleDateFormat("z", locale); + try { + Date date = fmt.parse("UTC"); + // Parsed one may not exactly be UTC. Universal, UCT, etc. are equivalents. + if (!fmt.getTimeZone().getID().matches("(Etc/)?(UTC|Universal|UCT|Zulu)")) { + errors.add("timezone: " + fmt.getTimeZone().getID() + + ", locale: " + locale); + } + } catch (ParseException e) { + errors.add("parse exception: " + e + ", locale: " + locale); + } + } + } finally { + // Restore the default time zone + TimeZone.setDefault(initTz); + } + + if (!errors.isEmpty()) { + System.out.println("Got unexpected results:"); + for (String s : errors) { + System.out.println(" " + s); + } + throw new RuntimeException("Test failed."); + } else { + System.out.println("Test passed."); + } + } +} diff --git a/test/java/text/Format/DateFormat/DateFormatSymbolsCloneTest.java b/test/java/text/Format/DateFormat/DateFormatSymbolsCloneTest.java new file mode 100644 index 0000000000000000000000000000000000000000..7214d1fa8d5173ba876d09032c1f91b1c0402944 --- /dev/null +++ b/test/java/text/Format/DateFormat/DateFormatSymbolsCloneTest.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2016, 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. + * + * 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. + */ + +/* + * @test + * @bug 8151431 + * @summary Make sure that clone() of a DateFormatSymbols subclass is not + * called from DateFormatSymbols constructor. + */ +import java.text.DateFormatSymbols; + +public class DateFormatSymbolsCloneTest extends DateFormatSymbols { + private int value; + + public DateFormatSymbolsCloneTest() { + value = 1; + } + + @Override + public Object clone() { + if (this.value == 0) { + throw new RuntimeException("clone() should not be called from a DateFormatSymbols constructor"); + } + return super.clone(); + } + + public static void main(String[] args) { + new DateFormatSymbolsCloneTest(); + } +} diff --git a/test/java/time/test/java/time/format/TestZoneTextPrinterParser.java b/test/java/time/test/java/time/format/TestZoneTextPrinterParser.java index 079af06d9d6928a7f4f7533d307cb7b142db2083..78086243747e0931f5fac28685c94cf1e774ad93 100644 --- a/test/java/time/test/java/time/format/TestZoneTextPrinterParser.java +++ b/test/java/time/test/java/time/format/TestZoneTextPrinterParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2016, 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 @@ -49,7 +49,7 @@ import org.testng.annotations.Test; /* * @test - * @bug 8081022 + * @bug 8081022 8151876 * @key randomness */ @@ -84,6 +84,14 @@ public class TestZoneTextPrinterParser extends AbstractTestPrinterParser { TimeZone tz = TimeZone.getTimeZone(zid); boolean isDST = tz.inDaylightTime(new Date(zdt.toInstant().toEpochMilli())); for (Locale locale : locales) { + String longDisplayName = tz.getDisplayName(isDST, TimeZone.LONG, locale); + String shortDisplayName = tz.getDisplayName(isDST, TimeZone.SHORT, locale); + if ((longDisplayName.startsWith("GMT+") && shortDisplayName.startsWith("GMT+")) + || (longDisplayName.startsWith("GMT-") && shortDisplayName.startsWith("GMT-"))) { + printText(locale, zdt, TextStyle.FULL, tz, tz.getID()); + printText(locale, zdt, TextStyle.SHORT, tz, tz.getID()); + continue; + } printText(locale, zdt, TextStyle.FULL, tz, tz.getDisplayName(isDST, TimeZone.LONG, locale)); printText(locale, zdt, TextStyle.SHORT, tz, diff --git a/test/java/util/Hashtable/DeserializedLength.java b/test/java/util/Hashtable/DeserializedLength.java new file mode 100644 index 0000000000000000000000000000000000000000..1497eb8d00f50d3ed57642bc1d2b2df0dacc00a9 --- /dev/null +++ b/test/java/util/Hashtable/DeserializedLength.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2014, 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. + * + * 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. + */ + +import java.io.*; +import java.lang.reflect.Field; +import java.util.Hashtable; + +/** + * @test + * @bug 8068427 + * @summary Hashtable deserialization reconstitutes table with wrong capacity + */ +public class DeserializedLength { + + static boolean testDeserializedLength(int elements, float loadFactor) throws Exception { + + // construct Hashtable with minimal initial capacity and given loadFactor + Hashtable ht1 = new Hashtable<>(1, loadFactor); + + // add given number of unique elements + for (int i = 0; i < elements; i++) { + ht1.put(i, i); + } + + // serialize and deserialize into a deep clone + Hashtable ht2 = serialClone(ht1); + + // compare lengths of internal tables + Object[] table1 = (Object[]) hashtableTableField.get(ht1); + Object[] table2 = (Object[]) hashtableTableField.get(ht2); + assert table1 != null; + assert table2 != null; + + int minLength = (int) (ht1.size() / loadFactor) + 1; + int maxLength = minLength * 2; + + boolean ok = (table2.length >= minLength && table2.length <= maxLength); + + System.out.printf( + "%7d %5.2f %7d %7d %7d...%7d %s\n", + ht1.size(), loadFactor, + table1.length, table2.length, + minLength, maxLength, + (ok ? "OK" : "NOT-OK") + ); + + return ok; + } + + static T serialClone(T o) throws IOException, ClassNotFoundException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + try (ObjectOutputStream oos = new ObjectOutputStream(bos)) { + oos.writeObject(o); + } + @SuppressWarnings("unchecked") + T clone = (T) new ObjectInputStream( + new ByteArrayInputStream(bos.toByteArray())).readObject(); + return clone; + } + + private static final Field hashtableTableField; + + static { + try { + hashtableTableField = Hashtable.class.getDeclaredField("table"); + hashtableTableField.setAccessible(true); + } catch (NoSuchFieldException e) { + throw new Error(e); + } + } + + public static void main(String[] args) throws Exception { + boolean ok = true; + + System.out.printf("Results:\n" + + " ser. deser.\n" + + " size load lentgh length valid range ok?\n" + + "------- ----- ------- ------- ----------------- ------\n" + ); + + for (int elements : new int[]{10, 50, 500, 5000}) { + for (float loadFactor : new float[]{0.15f, 0.5f, 0.75f, 1.0f, 2.5f}) { + ok &= testDeserializedLength(elements, loadFactor); + } + } + if (!ok) { + throw new AssertionError("Test failed."); + } + } +} diff --git a/test/java/util/concurrent/ConcurrentLinkedQueue/RemoveLeak.java b/test/java/util/concurrent/ConcurrentLinkedQueue/RemoveLeak.java new file mode 100644 index 0000000000000000000000000000000000000000..fd1e52d197b88586c20ff691330ead269b298a51 --- /dev/null +++ b/test/java/util/concurrent/ConcurrentLinkedQueue/RemoveLeak.java @@ -0,0 +1,60 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Written by Martin Buchholz with assistance from members of JCP + * JSR-166 Expert Group and released to the public domain, as + * explained at http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* + * @test + * @bug 8054446 8137184 8137185 + * @summary Regression test for memory leak in remove(Object) + * @run main/othervm -Xmx2200k RemoveLeak + */ + +import java.util.concurrent.ConcurrentLinkedQueue; + +public class RemoveLeak { + public static void main(String[] args) { + int i = 0; + // Without bug fix, OutOfMemoryError was observed at iteration 65120 + int iterations = 10 * 65120; + try { + ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue<>(); + queue.add(0L); + while (i++ < iterations) { + queue.add(1L); + queue.remove(1L); + } + } catch (Error t) { + System.err.printf("failed at iteration %d/%d%n", i, iterations); + throw t; + } + } +} diff --git a/test/java/util/logging/LogManagerAppContextDeadlock.java b/test/java/util/logging/LogManagerAppContextDeadlock.java index 3e4918e5feec81718818b1cc16c843383d830f4e..bb6c4714e7e43298a63dee97743f7758e95d2465 100644 --- a/test/java/util/logging/LogManagerAppContextDeadlock.java +++ b/test/java/util/logging/LogManagerAppContextDeadlock.java @@ -136,6 +136,7 @@ public class LogManagerAppContextDeadlock { t1.setDaemon(true); t1.start(); Thread t2 = new Thread() { + public Object logger; public void run() { sem3.release(); try { @@ -146,7 +147,10 @@ public class LogManagerAppContextDeadlock { Thread.interrupted(); } System.out.println("Logger.getLogger(name).info(name)"); - Logger.getLogger(test.name());//.info(name); + // stick the logger in an instance variable to prevent it + // from being garbage collected before the main thread + // calls LogManager.getLogger() below. + logger = Logger.getLogger(test.name());//.info(name); System.out.println("Done: Logger.getLogger(name).info(name)"); } }; diff --git a/test/javax/crypto/JceSecurity/FinalRestricted.java b/test/javax/crypto/JceSecurity/FinalRestricted.java new file mode 100644 index 0000000000000000000000000000000000000000..fdfa76de0686dbc170d031a47de832b3de1369db --- /dev/null +++ b/test/javax/crypto/JceSecurity/FinalRestricted.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2016, 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. + * + * 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. + */ + +/* + * @test + * @bug 8149417 + * @summary Use final restricted flag + */ + +import java.security.*; +import java.lang.reflect.*; + +public class FinalRestricted { + + public static void main(String[] args) throws Exception { + + int modifiers = Class.forName("javax.crypto.JceSecurity") + .getDeclaredField("isRestricted").getModifiers(); + if (!(Modifier.isFinal(modifiers) && Modifier.isStatic(modifiers) && + Modifier.isPrivate(modifiers))) { + throw new Exception("JceSecurity.isRestricted is not " + + "a private static final field!"); + } + } +} diff --git a/test/javax/crypto/KeyGenerator/TestKGParity.java b/test/javax/crypto/KeyGenerator/TestKGParity.java new file mode 100644 index 0000000000000000000000000000000000000000..0f4c8a5d46e4246161632429a9bf375422865238 --- /dev/null +++ b/test/javax/crypto/KeyGenerator/TestKGParity.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +import java.io.PrintStream; +import java.lang.String; +import java.lang.System; +import java.security.Provider; +import java.security.SecureRandom; +import java.security.Security; +import javax.crypto.KeyGenerator; +import static java.lang.System.out; + +/* + * @test + * @bug 8048607 + * @compile ../../../com/sun/crypto/provider/Cipher/DES/TestUtility.java + * @run main TestKGParity + * @summary Test key generation of DES and DESEDE + */ +public class TestKGParity { + + private static final String[] ALGORITHM_ARR = { + "deS", "DesEDE" + }; + + public static void main(String argv[]) throws Exception { + + TestKGParity test = new TestKGParity(); + test.run(); + } + + private void run() throws Exception { + Provider[] providers = Security.getProviders(); + for (Provider p : providers) { + String prvName = p.getName(); + if (prvName.startsWith("SunJCE") + || prvName.startsWith("SunPKCS11-")) { + for (String algorithm : ALGORITHM_ARR) { + if (!runTest(p, algorithm)) { + throw new RuntimeException( + "Test failed with provider/algorithm:" + + p.getName() + "/" + algorithm); + } else { + out.println("Test passed with provider/algorithm:" + + p.getName() + "/" + algorithm); + } + } + } + } + } + + public boolean runTest(Provider p, String algo) throws Exception { + byte[] keyValue = null; + try { + // Initialization + SecureRandom sRdm = new SecureRandom(); + KeyGenerator kg = KeyGenerator.getInstance(algo, p); + kg.init(sRdm); + + // Generate a SecretKey and retrieve its value + keyValue = kg.generateKey().getEncoded(); + + // Verify its parity in the unit of byte + for (int i = 0; i < keyValue.length; i++) { + if (!checkParity(keyValue[i])) { + out.println("Testing: " + + p.getName() + + "/" + + algo + + " failed when verify its parity in the unit of byte:" + + TestUtility.hexDump(keyValue, i)); + return false; + } + } + return true; + } catch (Exception ex) { + out.println("Testing: " + p.getName() + "/" + algo + + " failed with unexpected exception"); + ex.printStackTrace(); + throw ex; + } + } + + private boolean checkParity(byte keyByte) { + boolean even = false; + byte[] PARITY_BIT_MASK = { + (byte) 0x40, (byte) 0x20, (byte) 0x10, (byte) 0x08, + (byte) 0x04, (byte) 0x02, (byte) 0x01 + }; + + for (int i = 0; i < 7; i++) { + if ((keyByte & PARITY_BIT_MASK[i]) > 0) { + even = !even; + } + } + if (keyByte < 0) { + even = !even; + } + + return even; + } +} diff --git a/test/javax/crypto/SealedObject/TestSealedObjectNull.java b/test/javax/crypto/SealedObject/TestSealedObjectNull.java new file mode 100644 index 0000000000000000000000000000000000000000..4b6eff27cfb1a23816afdab205736fff98a1bbdb --- /dev/null +++ b/test/javax/crypto/SealedObject/TestSealedObjectNull.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +import java.io.IOException; +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NullCipher; +import javax.crypto.SealedObject; + +/* + * @test + * @bug 8048624 + * @summary This test instantiate a NullCipher, seal and unseal a String + * object using the SealedObject with the initialized NullCipher, + * and then compare the String content. + */ +public class TestSealedObjectNull { + + private static final String SEAL_STR = "Any String!@#$%^"; + + public static void main(String[] args) throws IOException, + IllegalBlockSizeException, ClassNotFoundException, + BadPaddingException { + Cipher nullCipher = new NullCipher(); + + // Seal + SealedObject so = new SealedObject(SEAL_STR, nullCipher); + + // Unseal and compare + if (!(SEAL_STR.equals(so.getObject(nullCipher)))) { + throw new RuntimeException("Unseal and compare failed."); + } + + System.out.println("Test passed."); + } +} diff --git a/test/javax/crypto/SecretKeyFactory/PBKDF2TranslateTest.java b/test/javax/crypto/SecretKeyFactory/PBKDF2TranslateTest.java new file mode 100644 index 0000000000000000000000000000000000000000..acd2081b0f6f05e7af3dbc904409529642b34115 --- /dev/null +++ b/test/javax/crypto/SecretKeyFactory/PBKDF2TranslateTest.java @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2003, 2015, 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. + * + * 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. + */ + +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.spec.InvalidKeySpecException; +import java.util.Arrays; +import java.util.Random; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.interfaces.PBEKey; +import javax.crypto.spec.PBEKeySpec; +import javax.security.auth.DestroyFailedException; + +import static java.lang.System.out; + +/* + * @test + * @bug 8048820 + * @summary The test verifies if the SecretKeyFactory.translateKey() method + * works as expected for the PBKDF2 algorithms. + */ + +public class PBKDF2TranslateTest { + + private static final String PASS_PHRASE = "some hidden string"; + private static final int ITERATION_COUNT = 1000; + private static final int KEY_SIZE = 128; + private static final String[] TEST_ALGOS = { "PBKDF2WithHmacSHA1", + "PBKDF2WithHmacSHA224", "PBKDF2WithHmacSHA256", + "PBKDF2WithHmacSHA384", "PBKDF2WithHmacSHA512" }; + private final String algoForTest; + + public static void main(String[] args) throws Exception { + for (String algo : TEST_ALGOS) { + PBKDF2TranslateTest theTest = new PBKDF2TranslateTest(algo); + byte[] salt = new byte[8]; + new Random().nextBytes(salt); + theTest.testMyOwnSecretKey(salt); + theTest.generateAndTranslateKey(salt); + theTest.translateSpoiledKey(salt); + } + } + + public PBKDF2TranslateTest(String algo) { + algoForTest = algo; + } + + /** + * The test case scenario implemented in the method: - derive PBKDF2 key + * using the given algorithm; - translate the key - check if the translated + * and original keys have the same key value. + * + */ + public void generateAndTranslateKey(byte[] salt) + throws NoSuchAlgorithmException, InvalidKeySpecException, + InvalidKeyException { + // derive PBKDF2 key + SecretKey key1 = getSecretKeyForPBKDF2(algoForTest, salt); + + // translate key + SecretKeyFactory skf = SecretKeyFactory.getInstance(algoForTest); + SecretKey key2 = skf.translateKey(key1); + + // Check if it still the same after translation + if (!Arrays.equals(key1.getEncoded(), key2.getEncoded())) { + System.out.println("Key1=" + new String(key1.getEncoded()) + + " key2=" + new String(key2.getEncoded()) + " salt=" + + new String(salt)); + throw new RuntimeException( + "generateAndTranslateKey test case failed: the key1 and" + + " key2 values in its primary encoding format are" + + " not the same for " + algoForTest + + " algorithm."); + } + } + + /** + * The test case scenario implemented in the method: - derive Key1 for the + * given PBKDF2 algorithm - create my own secret Key2 as an instance of a + * class implements PBEKey - translate Key2 - check if the key value of the + * translated key and Key1 are the same. + */ + private void testMyOwnSecretKey(byte[] salt) + throws NoSuchAlgorithmException, InvalidKeySpecException, + InvalidKeyException { + SecretKey key1 = getSecretKeyForPBKDF2(algoForTest, salt); + SecretKey key2 = getMyOwnSecretKey(salt); + + // Is it actually the same? + if (!Arrays.equals(key1.getEncoded(), key2.getEncoded())) { + throw new RuntimeException( + "We shouldn't be here. The key1 and key2 values in its" + + " primary encoding format have to be the same!"); + } + + // translate key + SecretKeyFactory skf = SecretKeyFactory.getInstance(algoForTest); + SecretKey key3 = skf.translateKey(key2); + + // Check if it still the same after translation + if (!Arrays.equals(key1.getEncoded(), key3.getEncoded())) { + System.out.println("Key1=" + new String(key1.getEncoded()) + + " key3=" + new String(key3.getEncoded()) + " salt=" + + new String(salt)); + throw new RuntimeException( + "testMyOwnSecretKey test case failed: the key1 and key3" + + " values in its primary encoding format are not" + + " the same for " + algoForTest + " algorithm."); + } + + } + + /** + * The test case scenario implemented in the method: - create my own secret + * Key2 as an instance of a class implements PBEKey - spoil the key (set + * iteration count to 0, for example) - try to translate key - + * InvalidKeyException is expected. + */ + public void translateSpoiledKey(byte[] salt) + throws NoSuchAlgorithmException, InvalidKeySpecException { + // derive the key + SecretKey key1 = getMyOwnSecretKey(salt); + + // spoil the key + ((MyPBKDF2SecretKey) key1).spoil(); + + // translate key + SecretKeyFactory skf = SecretKeyFactory.getInstance(algoForTest); + try { + skf.translateKey(key1); + throw new RuntimeException( + "translateSpoiledKey test case failed, should throw" + + " InvalidKeyException when spoil the key"); + } catch (InvalidKeyException ike) { + out.println("Expected exception when spoil the key"); + } + + } + + /** + * Generate a PBKDF2 secret key using given algorithm. + */ + private SecretKey getSecretKeyForPBKDF2(String algoDeriveKey, byte[] salt) + throws NoSuchAlgorithmException, InvalidKeySpecException { + + SecretKeyFactory skf = SecretKeyFactory.getInstance(algoDeriveKey); + PBEKeySpec spec = new PBEKeySpec(PASS_PHRASE.toCharArray(), salt, + ITERATION_COUNT, KEY_SIZE); + + return skf.generateSecret(spec); + } + + /** + * Generate a secrete key as an instance of a class implements PBEKey. + */ + private SecretKey getMyOwnSecretKey(byte[] salt) + throws InvalidKeySpecException, NoSuchAlgorithmException { + return new MyPBKDF2SecretKey(PASS_PHRASE, algoForTest, salt, + ITERATION_COUNT, KEY_SIZE); + } + + /** + * An utility class to check the SecretKeyFactory.translateKey() method. + */ + class MyPBKDF2SecretKey implements PBEKey { + private final byte[] key; + private final byte[] salt; + private final String algorithm; + private final int keyLength; + private final String pass; + private int itereationCount; + + /** + * The key is generating by SecretKeyFactory and its value just copying + * in the key field of MySecretKey class. So, this is real key derived + * using the given algo. + */ + public MyPBKDF2SecretKey(String passPhrase, String algo, byte[] salt1, + int iterationCount, int keySize) + throws InvalidKeySpecException, NoSuchAlgorithmException { + algorithm = algo; + salt = salt1; + itereationCount = iterationCount; + pass = passPhrase; + + PBEKeySpec spec = new PBEKeySpec(passPhrase.toCharArray(), salt, + iterationCount, keySize); + + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(algo); + + SecretKey realKey = keyFactory.generateSecret(spec); + + keyLength = realKey.getEncoded().length; + + key = new byte[keyLength]; + System.arraycopy(realKey.getEncoded(), 0, key, 0, keyLength); + } + + @Override + public String getAlgorithm() { + return algorithm; + } + + @Override + public String getFormat() { + return "RAW"; + } + + @Override + public byte[] getEncoded() { + byte[] copy = new byte[keyLength]; + System.arraycopy(key, 0, copy, 0, keyLength); + return copy; + } + + @Override + public int getIterationCount() { + return itereationCount; + } + + @Override + public byte[] getSalt() { + return salt; + } + + @Override + public char[] getPassword() { + return pass.toCharArray(); + } + + /** + * Spoil the generated key (before translation) to cause an + * InvalidKeyException + */ + public void spoil() { + itereationCount = -1; + } + + @Override + public void destroy() throws DestroyFailedException { + } + + @Override + public boolean isDestroyed() { + return false; + } + + } +} \ No newline at end of file diff --git a/test/javax/crypto/SecretKeyFactory/SecKFTranslateTest.java b/test/javax/crypto/SecretKeyFactory/SecKFTranslateTest.java new file mode 100644 index 0000000000000000000000000000000000000000..f1b5c825798896b7e5e2d8a1f55b53193a9a60cc --- /dev/null +++ b/test/javax/crypto/SecretKeyFactory/SecKFTranslateTest.java @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2003, 2015, 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. + * + * 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. + */ + +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SecureRandom; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.InvalidKeySpecException; +import java.util.Arrays; +import java.util.Random; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.ShortBufferException; +import javax.crypto.spec.PBEKeySpec; +import javax.crypto.spec.PBEParameterSpec; +import javax.security.auth.DestroyFailedException; + +/* + * @test + * @bug 8048820 + * @summary The test verifies SecretKey values should remain the same after + * translation with SecretKeyFactory.translateKey(). + */ + +public class SecKFTranslateTest { + private static final String SUN_JCE = "SunJCE"; + + public static void main(String[] args) throws Exception { + + SecKFTranslateTest test = new SecKFTranslateTest(); + test.run(); + } + + private void run() throws Exception { + + for (Algorithm algorithm : Algorithm.values()) { + runTest(algorithm); + } + } + + private void runTest(Algorithm algo) throws NoSuchAlgorithmException, + NoSuchProviderException, InvalidKeyException, + InvalidKeySpecException, NoSuchPaddingException, + InvalidAlgorithmParameterException, ShortBufferException, + IllegalBlockSizeException, BadPaddingException { + AlgorithmParameterSpec[] aps = new AlgorithmParameterSpec[1]; + byte[] plainText = new byte[800]; + + SecretKey key1 = algo.intSecurityKey(aps); + Random random = new Random(); + // Initialization + SecretKeyFactory skf = SecretKeyFactory.getInstance(algo.toString(), + SUN_JCE); + + random.nextBytes(plainText); + Cipher ci = Cipher.getInstance(algo.toString(), SUN_JCE); + // Encryption + ci.init(Cipher.ENCRYPT_MODE, key1, aps[0]); + byte[] cipherText = new byte[ci.getOutputSize(plainText.length)]; + int offset = ci.update(plainText, 0, plainText.length, cipherText, 0); + ci.doFinal(cipherText, offset); + // translate key + SecretKey key2 = skf.translateKey(key1); + + // Decryption + ci.init(Cipher.DECRYPT_MODE, key2, aps[0]); + byte[] recoveredText = new byte[ci.getOutputSize(plainText.length)]; + ci.doFinal(cipherText, 0, cipherText.length, recoveredText); + + // Comparison + if (!Arrays.equals(plainText, recoveredText)) { + System.out.println("Key1:" + new String(key1.getEncoded()) + + " Key2:" + new String(key2.getEncoded())); + throw new RuntimeException("Testing translate key failed with " + + algo); + } + + } +} + +class MyOwnSecKey implements SecretKey { + + private static final String DEFAULT_ALGO = "PBEWithMD5AndDES"; + private final byte[] key; + private final String algorithm; + private final int keySize; + + public MyOwnSecKey(byte[] key1, int offset, String algo) + throws InvalidKeyException { + algorithm = algo; + if (algo.equalsIgnoreCase("DES")) { + keySize = 8; + } else if (algo.equalsIgnoreCase("DESede")) { + keySize = 24; + } else { + throw new InvalidKeyException( + "Inappropriate key format and algorithm"); + } + + if (key1 == null || key1.length - offset < keySize) { + throw new InvalidKeyException("Wrong key size"); + } + key = new byte[keySize]; + System.arraycopy(key, offset, key, 0, keySize); + } + + public MyOwnSecKey(PBEKeySpec ks) throws InvalidKeySpecException { + algorithm = DEFAULT_ALGO; + key = new String(ks.getPassword()).getBytes(); + keySize = key.length; + } + + @Override + public String getAlgorithm() { + return algorithm; + } + + @Override + public String getFormat() { + return "RAW"; + } + + @Override + public byte[] getEncoded() { + byte[] copy = new byte[keySize]; + System.arraycopy(key, 0, copy, 0, keySize); + return copy; + } + + @Override + public void destroy() throws DestroyFailedException { + } + + @Override + public boolean isDestroyed() { + return false; + } +} + +enum Algorithm { + DES { + @Override + SecretKey intSecurityKey(AlgorithmParameterSpec[] spec) + throws InvalidKeyException { + int keyLength = 8; + byte[] keyVal = new byte[keyLength]; + new SecureRandom().nextBytes(keyVal); + SecretKey key1 = new MyOwnSecKey(keyVal, 0, this.toString()); + return key1; + } + }, + DESEDE { + @Override + SecretKey intSecurityKey(AlgorithmParameterSpec[] spec) + throws InvalidKeyException { + int keyLength = 24; + byte[] keyVal = new byte[keyLength]; + new SecureRandom().nextBytes(keyVal); + SecretKey key1 = new MyOwnSecKey(keyVal, 0, this.toString()); + return key1; + } + }, + PBEWithMD5ANDdes { + @Override + SecretKey intSecurityKey(AlgorithmParameterSpec[] spec) + throws InvalidKeySpecException { + byte[] salt = new byte[8]; + int iterCnt = 6; + new Random().nextBytes(salt); + spec[0] = new PBEParameterSpec(salt, iterCnt); + PBEKeySpec pbeKS = new PBEKeySpec( + new String("So far so good").toCharArray()); + SecretKey key1 = new MyOwnSecKey(pbeKS); + return key1; + } + }; + abstract SecretKey intSecurityKey(AlgorithmParameterSpec[] spec) + throws InvalidKeyException, InvalidKeySpecException; +} diff --git a/test/javax/net/ssl/TLS/CipherTestUtils.java b/test/javax/net/ssl/TLS/CipherTestUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..3b6664bbf904be5c3bac43fe14792d78b080da66 --- /dev/null +++ b/test/javax/net/ssl/TLS/CipherTestUtils.java @@ -0,0 +1,689 @@ +/** + * Copyright (c) 2010, 2014, 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. + * + * 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. + */ + +import java.io.ByteArrayInputStream; +import java.io.EOFException; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.Socket; +import java.security.KeyFactory; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.Principal; +import java.security.PrivateKey; +import java.security.SecureRandom; +import java.security.UnrecoverableKeyException; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.security.interfaces.RSAPrivateKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Base64; +import java.util.Collections; +import java.util.List; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLServerSocket; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509ExtendedKeyManager; +import javax.net.ssl.X509TrustManager; + +/** + * Test that all ciphersuites work in all versions and all client authentication + * types. The way this is setup the server is stateless and all checking is done + * on the client side. + */ + +public class CipherTestUtils { + + public static final int TIMEOUT = 20 * 1000; + public static final SecureRandom secureRandom = new SecureRandom(); + public static char[] PASSWORD = "passphrase".toCharArray(); + private static final List TESTS = new ArrayList<>(3); + private static final List EXCEPTIONS + = Collections.synchronizedList(new ArrayList<>(1)); + private static final String CLIENT_PUBLIC_KEY + = "-----BEGIN CERTIFICATE-----\n" + + "MIICtTCCAh4CCQDkYJ46DMcGRjANBgkqhkiG9w0BAQUFADCBnDELMAkGA1UEBhMC\n" + + "VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MR8wHQYDVQQK\n" + + "DBZTdW4gTWljcm9zeXN0ZW1zLCBJbmMuMSYwJAYDVQQLDB1TdW4gTWljcm9zeXN0\n" + + "ZW1zIExhYm9yYXRvcmllczEfMB0GA1UEAwwWVGVzdCBDQSAoMTAyNCBiaXQgUlNB\n" + + "KTAeFw0wOTA0MjcwNDA0MDhaFw0xMzA2MDUwNDA0MDhaMIGgMQswCQYDVQQGEwJV\n" + + "UzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxHzAdBgNVBAoM\n" + + "FlN1biBNaWNyb3N5c3RlbXMsIEluYy4xJjAkBgNVBAsMHVN1biBNaWNyb3N5c3Rl\n" + + "bXMgTGFib3JhdG9yaWVzMSMwIQYDVQQDDBpUZXN0IENsaWVudCAoMTAyNCBiaXQg\n" + + "UlNBKTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAm5rwjmhO7Nwd5GWs+KvQ\n" + + "UnDiqpRDvRriOUFdF0rCI2Op24C+iwUMDGxPsgP7VkUpOdJhw3c72aP0CAWcZ5dN\n" + + "UCW7WVDAxnogCahLCir1jjoGdEjiNGOy0L9sypsM9UvBzJN8uvXsxsTZX4Z88cKU\n" + + "G7RUvN8LQ88zDljk5zr3c2MCAwEAATANBgkqhkiG9w0BAQUFAAOBgQA7LUDrzHln\n" + + "EXuGmwZeeroACB6DVtkClMskF/Pj5GnTxoeNN9DggycX/eOeIDKRloHuMpBeZPJH\n" + + "NUwFu4LB6HBDeldQD9iRp8zD/fPakOdN+1Gk5hciIZZJ5hQmeCl7Va2Gr64vUqZG\n" + + "MkVU755t+7ByLgzWuhPhhsX9QCuPR5FjvQ==\n" + + "-----END CERTIFICATE-----"; + + private static final String CLIENT_PRIVATE_KEY + = "-----BEGIN PRIVATE KEY-----\n" + + "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJua8I5oTuzcHeRl\n" + + "rPir0FJw4qqUQ70a4jlBXRdKwiNjqduAvosFDAxsT7ID+1ZFKTnSYcN3O9mj9AgF\n" + + "nGeXTVAlu1lQwMZ6IAmoSwoq9Y46BnRI4jRjstC/bMqbDPVLwcyTfLr17MbE2V+G\n" + + "fPHClBu0VLzfC0PPMw5Y5Oc693NjAgMBAAECgYA5w73zj8Nk6J3sMNaShe3S/PcY\n" + + "TewLopRCnwI46FbDnnbq9pNFtnzvi7HWKuY983THc1M5peTA+b1Y0QRr7F4Vg4x9\n" + + "9UM0B/tZcIIcJJ3LS+9fXKCbYLQWq5F05JqeZu+i+QLmJFO5+2p7laeQ4oQfW7QE\n" + + "YR4u2mSaLe0SsqHvOQJBAMhgcye9C6pJO0eo2/VtRxAXI7zxNAIjHwKo1cva7bhu\n" + + "GdrMaEAJBAsMJ1GEk7/WDI+3KEbTjQdfIJuAvOR4FXUCQQDGzNn/tl2k93v/ugyM\n" + + "/tBhCKDipYDIbyJMoG2AOtOGmCsiGo5L7idO4OAcm/QiHBQMXjFIVgTUcH8MhGj4\n" + + "blJ3AkA5fUqsxRV6tuYWKkFpif/QgwMS65VDY7Y6+hvVECwSNSyf1PO4I54QWV1S\n" + + "ixok+RHDjgY1Q+77hXSCiQ4o8rcdAkBHvjfR+5sx5IpgUGElJPRIgFenU3j1XH3x\n" + + "T1gVFaWuhg3S4eiGaGzRH4BhcrqY8K8fg4Kfi0N08yA2gTZsqUujAkEAjuNPTuKx\n" + + "ti0LXI09kbGUqOpRMm1zW5TD6LFeEaUN6oxrSZI2YUvu7VyotAqsxX5O0u0f3VQw\n" + + "ySF0Q1oZ6qu7cg==\n" + + "-----END PRIVATE KEY-----"; + private static final String SERVER_PUBLIC_KEY + = "-----BEGIN CERTIFICATE-----\n" + + "MIICtTCCAh4CCQDkYJ46DMcGRTANBgkqhkiG9w0BAQUFADCBnDELMAkGA1UEBhMC\n" + + "VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MR8wHQYDVQQK\n" + + "DBZTdW4gTWljcm9zeXN0ZW1zLCBJbmMuMSYwJAYDVQQLDB1TdW4gTWljcm9zeXN0\n" + + "ZW1zIExhYm9yYXRvcmllczEfMB0GA1UEAwwWVGVzdCBDQSAoMTAyNCBiaXQgUlNB\n" + + "KTAeFw0wOTA0MjcwNDA0MDhaFw0xMzA2MDUwNDA0MDhaMIGgMQswCQYDVQQGEwJV\n" + + "UzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxHzAdBgNVBAoM\n" + + "FlN1biBNaWNyb3N5c3RlbXMsIEluYy4xJjAkBgNVBAsMHVN1biBNaWNyb3N5c3Rl\n" + + "bXMgTGFib3JhdG9yaWVzMSMwIQYDVQQDDBpUZXN0IFNlcnZlciAoMTAyNCBiaXQg\n" + + "UlNBKTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArsHHeZ1O67yuxQKDSAOC\n" + + "Xm271ViwBrXkxe5cvhG8MCCem6Z3XeZ/m6c2ucRwLaQxnmG1m0G6/OYaUXTivjcG\n" + + "/K4bc1I+yjghAWQNLBtsOiP9w0LKibg3TSDehpeuuz/lmB5A4HMqQr8KkY4K7peD\n" + + "1QkJ2Dn3zhbwQ/0d8f5CCbkCAwEAATANBgkqhkiG9w0BAQUFAAOBgQBOd8XojEnu\n" + + "eTUHBwqfmnvRQvbICFDNbbL4KuX/JNPSy1WMGAEbNCTLZ+5yP69js8aUYqAk5vVf\n" + + "dWRLU3MDiEzW7zxE1ubuKWjVuyGbG8Me0G01Hw+evBcZqB64Fz3OFISVfQh7MqE/\n" + + "O0AeakRMH350FRLNl4o6KBSXmF/AADfqQQ==\n" + + "-----END CERTIFICATE-----"; + + private static final String SERVER_PRIVATE_KEY + = "-----BEGIN PRIVATE KEY-----\n" + + "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAK7Bx3mdTuu8rsUC\n" + + "g0gDgl5tu9VYsAa15MXuXL4RvDAgnpumd13mf5unNrnEcC2kMZ5htZtBuvzmGlF0\n" + + "4r43BvyuG3NSPso4IQFkDSwbbDoj/cNCyom4N00g3oaXrrs/5ZgeQOBzKkK/CpGO\n" + + "Cu6Xg9UJCdg5984W8EP9HfH+Qgm5AgMBAAECgYAXUv+3qJo+9mjxHHu/IdDFn6nB\n" + + "ONwNmTtWe5DfQWi3l7LznU0zOC9x6+hu9NvwC4kf1XSyqxw04tVCZ/JXZurEmEBz\n" + + "YtcQ5idRQDkKYXEDOeVUfvtHO6xilzrhPKxxd0GG/sei2pozikkqnYF3OcP0qL+a\n" + + "3nWixZQBRoF2nIRLcQJBAN97TJBr0XTRmE7OCKLUy1+ws7vZB9uQ2efHMsgwOpsY\n" + + "3cEW5qd95hrxLU72sBeu9loHQgBrT2Q3OAxnsPXmgO0CQQDIL3u9kS/O3Ukx+n1H\n" + + "JdPFQCRxrDm/vtJpQEmq+mLqxxnxCFRIYQ2ieAPokBxWeMDtdWJGD3VxhahjPfZm\n" + + "5K59AkEAuDVl0tVMfUIWjT5/F9jXGjUIsZofQ/iN5OLpFOHMLPO+Nd6umPjJpwON\n" + + "GT11wM/S+DprSPUrJ6vsYy1FTCuHsQJBAMXtnO07xgdE6AAQaRmVnyMiXmY+IQMj\n" + + "CyuhsrToyDDWFyIoWB0QSMjg3QxuoHYnAqpGK5qV4ksSGgG13BCz/okCQQCRHTgn\n" + + "DuFG2f7GYLFjI4NaTEzHGp+J9LiNYY1kYYLonpwAC3Z5hzJVanYT3/g23AUZ/fdF\n" + + "v5PDIViuPo5ZB1eD\n" + + "-----END PRIVATE KEY-----"; + + private static final String CA_PUBLIC_KEY + = "-----BEGIN CERTIFICATE-----\n" + + "MIIDCDCCAnGgAwIBAgIJAIYlGfwNBY6NMA0GCSqGSIb3DQEBBQUAMIGcMQswCQYD\n" + + "VQQGEwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxHzAd\n" + + "BgNVBAoMFlN1biBNaWNyb3N5c3RlbXMsIEluYy4xJjAkBgNVBAsMHVN1biBNaWNy\n" + + "b3N5c3RlbXMgTGFib3JhdG9yaWVzMR8wHQYDVQQDDBZUZXN0IENBICgxMDI0IGJp\n" + + "dCBSU0EpMB4XDTA5MDQyNzA0MDQwOFoXDTEzMDYwNTA0MDQwOFowgZwxCzAJBgNV\n" + + "BAYTAlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEfMB0G\n" + + "A1UECgwWU3VuIE1pY3Jvc3lzdGVtcywgSW5jLjEmMCQGA1UECwwdU3VuIE1pY3Jv\n" + + "c3lzdGVtcyBMYWJvcmF0b3JpZXMxHzAdBgNVBAMMFlRlc3QgQ0EgKDEwMjQgYml0\n" + + "IFJTQSkwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOK4DJxxb0XX6MJ1CVjp\n" + + "9Gmr/Ua8MS12R58F9lDpSKuq8cFexA4W7OdZ4jtbKv0tRHX5YxmbnXedwS+gdcOA\n" + + "GRgXMoeXlgTFGpdL+TR8xKIlMGRSjnR7MpR2tRyIYI2p+UTEiD6LTlIm5Wh4z1q8\n" + + "LYbxyMVD1XNNNymvPM44OjsBAgMBAAGjUDBOMB0GA1UdDgQWBBT27BLUflmfdtbi\n" + + "WTgjwWnoxop2MTAfBgNVHSMEGDAWgBT27BLUflmfdtbiWTgjwWnoxop2MTAMBgNV\n" + + "HRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAEQELNzhZpjnSgigd+QJ6I/3CPDo\n" + + "SDkMLdP1BHlT/DkMIZvABm+M09ePNlWiLYCNCsL9nWmX0gw0rFDKsTklZyKTUzaM\n" + + "oy/AZCrAaoIc6SO5m1xE1RMyVxd/Y/kg6cbfWxxCJFlMeU5rsSdC97HTE/lDyuoh\n" + + "BmlOBB7SdR+1ScjA\n" + + "-----END CERTIFICATE-----"; + + private static final String CA_PRIVATE_KEY + = "-----BEGIN PRIVATE KEY-----\n" + + "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAOK4DJxxb0XX6MJ1\n" + + "CVjp9Gmr/Ua8MS12R58F9lDpSKuq8cFexA4W7OdZ4jtbKv0tRHX5YxmbnXedwS+g\n" + + "dcOAGRgXMoeXlgTFGpdL+TR8xKIlMGRSjnR7MpR2tRyIYI2p+UTEiD6LTlIm5Wh4\n" + + "z1q8LYbxyMVD1XNNNymvPM44OjsBAgMBAAECgYEApmMOlk3FrQtsvjGof4GLp3Xa\n" + + "tmvs54FzxKhagj0C4UHelNyYpAJ9MLjNiGQ7I31yTeaNrUCAi0XSfsKTSrwbLSnJ\n" + + "qsUPKMBrnzcWrOyui2+cupHZXaTlNeYB97teLJYpa6Ql9CZLoTHoim1+//s7diBh\n" + + "03Vls+M6Poi5PMvv59UCQQD+k/BiokmbBgWHfBY5cZSlx3Z4VTwSHJmHDTO3Tjso\n" + + "EVErXUSVvqD/KHX6eM4VPM8lySV5djWV8lDsESCWMtiLAkEA4/xFNsiOLMQpxW/O\n" + + "bt2tukxJkAxldD4lPoFZR+zbXtMtt8OjERtX2wD+nj6h7jfIeSyVuBEcBN8Uj8xe\n" + + "kgfgIwJAPbKG4LCqHAsCjgpRrIxNVTwZByLJEy6hOqzFathn19cSj+rjs1Lm28/n\n" + + "f9OFRnpdTbAJB/3REM0QNZYVCrG57wJBAN0KuTytZJNouaswhPCew5Kt5mDgc/kp\n" + + "S8j3dk2zCto8W8Ygy1iJrzuqEjPxO+UQdrFtlde51vWuKGxnVIW3VwsCQEldqk7r\n" + + "8y7PgquPP+k3L0OXno5wGBrPcW1+U0mhIZGnwSzE4SPX2ddqUSEUA/Av4RjAckL/\n" + + "fpqmCkpTanyYW9U=\n" + + "-----END PRIVATE KEY-----"; + + private final SSLSocketFactory factory; + private final X509ExtendedKeyManager clientKeyManager; + private final X509ExtendedKeyManager serverKeyManager; + private final X509TrustManager clientTrustManager; + private final X509TrustManager serverTrustManager; + + static abstract class Server implements Runnable { + + final CipherTestUtils cipherTest; + + Server(CipherTestUtils cipherTest) throws Exception { + this.cipherTest = cipherTest; + } + + @Override + public abstract void run(); + + void handleRequest(InputStream in, OutputStream out) + throws IOException { + boolean newline = false; + StringBuilder sb = new StringBuilder(); + while (true) { + int ch = in.read(); + if (ch < 0) { + throw new EOFException(); + } + sb.append((char) ch); + if (ch == '\r') { + // empty + } else if (ch == '\n') { + if (newline) { + // 2nd newline in a row, end of request + break; + } + newline = true; + } else { + newline = false; + } + } + String request = sb.toString(); + if (request.startsWith("GET / HTTP/1.") == false) { + throw new IOException("Invalid request: " + request); + } + out.write("HTTP/1.0 200 OK\r\n\r\n".getBytes()); + out.write("Tested Scenario: ".getBytes()); + TestParameters tp = (TestParameters) CipherTestUtils.TESTS.get(0); + out.write(tp.toString().getBytes()); + out.write(" Test PASSED.".getBytes()); + } + } + + public static class TestParameters { + + String cipherSuite; + String protocol; + String clientAuth; + + TestParameters(String cipherSuite, String protocol, + String clientAuth) { + this.cipherSuite = cipherSuite; + this.protocol = protocol; + this.clientAuth = clientAuth; + } + + boolean isEnabled() { + return true; + } + + @Override + public String toString() { + String s = cipherSuite + " in " + protocol + " mode"; + if (clientAuth != null) { + s += " with " + clientAuth + " client authentication"; + } + return s; + } + } + + private static volatile CipherTestUtils instance = null; + + public static CipherTestUtils getInstance() throws IOException, + FileNotFoundException, KeyStoreException, + NoSuchAlgorithmException, CertificateException, + UnrecoverableKeyException, InvalidKeySpecException { + if (instance == null) { + synchronized (CipherTestUtils.class) { + if (instance == null) { + instance = new CipherTestUtils(); + } + } + } + return instance; + } + + public static void setTestedArguments(String testedProtocol, + String testedCipherSuite) { + + TestParameters testedParams; + + String cipherSuite = testedCipherSuite.trim(); + if (cipherSuite.startsWith("SSL_")) { + testedParams = + new TestParameters(cipherSuite, testedProtocol, null); + TESTS.add(testedParams); + + } else { + System.out.println("Your input Cipher suites is not correct, " + + "please try another one ."); + } + } + + public X509ExtendedKeyManager getClientKeyManager() { + return clientKeyManager; + } + + public X509TrustManager getClientTrustManager() { + return clientTrustManager; + } + + public X509ExtendedKeyManager getServerKeyManager() { + return serverKeyManager; + } + + public X509TrustManager getServerTrustManager() { + return serverTrustManager; + } + + public static void addFailure(Exception e) { + EXCEPTIONS.add(e); + } + + private CipherTestUtils() + throws IOException, FileNotFoundException, KeyStoreException, + NoSuchAlgorithmException, CertificateException, + UnrecoverableKeyException, InvalidKeySpecException { + factory = (SSLSocketFactory) SSLSocketFactory.getDefault(); + KeyStore serverKeyStore = createServerKeyStore(SERVER_PUBLIC_KEY, + SERVER_PRIVATE_KEY); + KeyStore serverTrustStore = createServerKeyStore(CA_PUBLIC_KEY, + CA_PRIVATE_KEY); + + if (serverKeyStore != null) { + KeyManagerFactory keyFactory1 + = KeyManagerFactory.getInstance( + KeyManagerFactory.getDefaultAlgorithm()); + keyFactory1.init(serverKeyStore, PASSWORD); + serverKeyManager = (X509ExtendedKeyManager) keyFactory1. + getKeyManagers()[0]; + } else { + serverKeyManager = null; + } + serverTrustManager = serverTrustStore != null + ? new AlwaysTrustManager(serverTrustStore) : null; + + KeyStore clientKeyStore, clientTrustStore; + clientTrustStore = serverTrustStore; + clientKeyStore = + createServerKeyStore(CLIENT_PUBLIC_KEY,CLIENT_PRIVATE_KEY); + if (clientKeyStore != null) { + KeyManagerFactory keyFactory + = KeyManagerFactory.getInstance( + KeyManagerFactory.getDefaultAlgorithm()); + keyFactory.init(clientKeyStore, PASSWORD); + clientKeyManager = (X509ExtendedKeyManager) keyFactory. + getKeyManagers()[0]; + } else { + clientKeyManager = null; + } + clientTrustManager = (clientTrustStore != null) + ? new AlwaysTrustManager(clientTrustStore) : null; + } + + void checkResult(String exception) throws Exception { + if (EXCEPTIONS.size() >= 1) { + Exception actualException = EXCEPTIONS.get(0); + if (exception == null) { + throw new RuntimeException("FAILED: got unexpected exception: " + + actualException); + } + if (!exception.equals(actualException.getClass().getName())) { + throw new RuntimeException("FAILED: got unexpected exception: " + + actualException); + } + + System.out.println("PASSED: got expected exception: " + + actualException); + } else { + if (exception != null) { + throw new RuntimeException("FAILED: " + exception + + " was expected"); + } + System.out.println("PASSED"); + } + } + + SSLSocketFactory getFactory() { + return factory; + } + + static abstract class Client implements Runnable { + + final CipherTestUtils cipherTest; + TestParameters testedParams; + + Client(CipherTestUtils cipherTest) throws Exception { + this.cipherTest = cipherTest; + } + + Client(CipherTestUtils cipherTest, + String testedCipherSuite) throws Exception { + this.cipherTest = cipherTest; + } + + @Override + public final void run() { + + TESTS.stream().map((params) -> { + if (!params.isEnabled()) { + System.out.println("Skipping disabled test " + params); + } + return params; + }).forEach((params) -> { + try { + runTest(params); + System.out.println("Passed " + params); + } catch (Exception e) { + CipherTestUtils.addFailure(e); + System.out.println("** Failed " + params + + "**, got exception:"); + e.printStackTrace(System.err); + } + }); + } + + abstract void runTest(TestParameters params) throws Exception; + + void sendRequest(InputStream in, OutputStream out) throws IOException { + out.write("GET / HTTP/1.0\r\n\r\n".getBytes()); + out.flush(); + StringBuilder sb = new StringBuilder(); + while (true) { + int ch = in.read(); + if (ch < 0) { + break; + } + sb.append((char) ch); + } + String response = sb.toString(); + if (response.startsWith("HTTP/1.0 200 ") == false) { + throw new IOException("Invalid response: " + response); + } else { + System.out.println(); + System.out.println("--- Response --- "); + System.out.println(response); + System.out.println("---------------- "); + } + } + } + + public static void printStringArray(String[] stringArray) { + System.out.print(stringArray.length + " : "); + for (String stringArray1 : stringArray) { + System.out.print(stringArray1); + System.out.print(","); + } + System.out.println(); + } + + public static void printInfo(SSLServerSocket socket) { + System.out.println(); + System.out.println("--- SSL ServerSocket Info ---"); + System.out.print("SupportedProtocols : "); + printStringArray(socket.getSupportedProtocols()); + System.out.print("SupportedCipherSuites : "); + printStringArray(socket.getSupportedCipherSuites()); + System.out.print("EnabledProtocols : "); + printStringArray(socket.getEnabledProtocols()); + System.out.print("EnabledCipherSuites : "); + String[] supportedCipherSuites = socket.getEnabledCipherSuites(); + Arrays.sort(supportedCipherSuites); + printStringArray(supportedCipherSuites); + System.out.println("NeedClientAuth : " + + socket.getNeedClientAuth()); + System.out.println("WantClientAuth : " + + socket.getWantClientAuth()); + System.out.println("-----------------------"); + } + + public static void printInfo(SSLSocket socket) { + System.out.println(); + System.out.println("--- SSL Socket Info ---"); + System.out.print(" SupportedProtocols : "); + printStringArray(socket.getSupportedProtocols()); + System.out.println(" EnabledProtocols : " + + socket.getEnabledProtocols()[0]); + System.out.print(" SupportedCipherSuites : "); + String[] supportedCipherSuites = socket.getEnabledCipherSuites(); + Arrays.sort(supportedCipherSuites); + printStringArray(supportedCipherSuites); + System.out.println(" EnabledCipherSuites : " + + socket.getEnabledCipherSuites()[0]); + System.out.println(" NeedClientAuth : " + + socket.getNeedClientAuth()); + System.out.println(" WantClientAuth : " + + socket.getWantClientAuth()); + System.out.println("-----------------------"); + } + + private static KeyStore createServerKeyStore(String publicKeyStr, + String keySpecStr) throws KeyStoreException, IOException, + NoSuchAlgorithmException, CertificateException, + InvalidKeySpecException { + + KeyStore ks = KeyStore.getInstance("JKS"); + ks.load(null, null); + if (publicKeyStr == null || keySpecStr == null) { + throw new IllegalArgumentException("publicKeyStr or " + + "keySpecStr cannot be null"); + } + String strippedPrivateKey = keySpecStr.substring( + keySpecStr.indexOf("\n"), keySpecStr.lastIndexOf("\n")); + + // generate the private key. + PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec( + Base64.getMimeDecoder().decode(strippedPrivateKey)); + KeyFactory kf = KeyFactory.getInstance("RSA"); + RSAPrivateKey priKey + = (RSAPrivateKey) kf.generatePrivate(priKeySpec); + + // generate certificate chain + try (InputStream is = + new ByteArrayInputStream(publicKeyStr.getBytes())) { + // generate certificate from cert string + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + Certificate keyCert = cf.generateCertificate(is); + Certificate[] chain = {keyCert}; + ks.setKeyEntry("TestEntry", priKey, PASSWORD, chain); + } + + return ks; + } + + public static void main(PeerFactory peerFactory, String mode, + String expectedException) + throws Exception { + long time = System.currentTimeMillis(); + setTestedArguments(peerFactory.getTestedProtocol(), + peerFactory.getTestedCipher()); + + System.out.print( + " Initializing test '" + peerFactory.getName() + "'..."); + secureRandom.nextInt(); + + CipherTestUtils cipherTest = CipherTestUtils.getInstance(); + if (mode.equalsIgnoreCase("Server")) { // server mode + Thread serverThread = new Thread(peerFactory.newServer(cipherTest), + "Server"); + serverThread.start(); + } else if (mode.equalsIgnoreCase("Client")) { + peerFactory.newClient(cipherTest).run(); + cipherTest.checkResult(expectedException); + JSSEServer.closeServer = true; + } else { + throw new RuntimeException("unsupported mode"); + } + time = System.currentTimeMillis() - time; + System.out.println("Elapsed time " + time); + + } + + public static abstract class PeerFactory { + + abstract String getName(); + + abstract String getTestedProtocol(); + + abstract String getTestedCipher(); + + abstract Client newClient(CipherTestUtils cipherTest) throws Exception; + + abstract Server newServer(CipherTestUtils cipherTest) throws Exception; + + boolean isSupported(String cipherSuite) { + return true; + } + } +} + +class AlwaysTrustManager implements X509TrustManager { + + X509TrustManager trustManager; + + public AlwaysTrustManager(KeyStore keyStore) + throws NoSuchAlgorithmException, KeyStoreException { + + TrustManagerFactory tmf + = TrustManagerFactory.getInstance(TrustManagerFactory. + getDefaultAlgorithm()); + tmf.init(keyStore); + + TrustManager tms[] = tmf.getTrustManagers(); + for (TrustManager tm : tms) { + trustManager = (X509TrustManager) tm; + return; + } + + } + + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) + throws CertificateException { + try { + trustManager.checkClientTrusted(chain, authType); + } catch (CertificateException excep) { + System.out.println("ERROR in client trust manager"); + } + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) + throws CertificateException { + try { + trustManager.checkServerTrusted(chain, authType); + } catch (CertificateException excep) { + System.out.println("ERROR in server Trust manger"); + } + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + return trustManager.getAcceptedIssuers(); + } +} + +class MyX509KeyManager extends X509ExtendedKeyManager { + + private final X509ExtendedKeyManager keyManager; + private String authType; + + MyX509KeyManager(X509ExtendedKeyManager keyManager) { + this.keyManager = keyManager; + } + + void setAuthType(String authType) { + this.authType = "ECDSA".equals(authType) ? "EC" : authType; + } + + @Override + public String[] getClientAliases(String keyType, Principal[] issuers) { + if (authType == null) { + return null; + } + return keyManager.getClientAliases(authType, issuers); + } + + @Override + public String chooseClientAlias(String[] keyType, Principal[] issuers, + Socket socket) { + if (authType == null) { + return null; + } + return keyManager.chooseClientAlias(new String[]{authType}, + issuers, socket); + } + + @Override + public String chooseEngineClientAlias(String[] keyType, + Principal[] issuers, SSLEngine engine) { + if (authType == null) { + return null; + } + return keyManager.chooseEngineClientAlias(new String[]{authType}, + issuers, engine); + } + + @Override + public String[] getServerAliases(String keyType, Principal[] issuers) { + throw new UnsupportedOperationException("Servers not supported"); + } + + @Override + public String chooseServerAlias(String keyType, Principal[] issuers, + Socket socket) { + throw new UnsupportedOperationException("Servers not supported"); + } + + @Override + public String chooseEngineServerAlias(String keyType, Principal[] issuers, + SSLEngine engine) { + throw new UnsupportedOperationException("Servers not supported"); + } + + @Override + public X509Certificate[] getCertificateChain(String alias) { + return keyManager.getCertificateChain(alias); + } + + @Override + public PrivateKey getPrivateKey(String alias) { + return keyManager.getPrivateKey(alias); + } +} diff --git a/test/javax/net/ssl/TLS/JSSEClient.java b/test/javax/net/ssl/TLS/JSSEClient.java new file mode 100644 index 0000000000000000000000000000000000000000..b08ae917249577c4975fb4f6578012b9c821247a --- /dev/null +++ b/test/javax/net/ssl/TLS/JSSEClient.java @@ -0,0 +1,120 @@ +/** + * Copyright (c) 2010, 2014, 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. + * + * 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. + */ + +import java.io.InputStream; +import java.io.OutputStream; +import java.security.cert.Certificate; +import javax.net.ssl.KeyManager; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; + +class JSSEClient extends CipherTestUtils.Client { + + private static final String DEFAULT = "DEFAULT"; + private static final String TLS = "TLS"; + + private final SSLContext sslContext; + private final MyX509KeyManager keyManager; + private final int serverPort; + private final String serverHost; + private final String testedProtocol; + + JSSEClient(CipherTestUtils cipherTest, String serverHost, int serverPort, + String testedProtocols, String testedCipherSuite) throws Exception { + super(cipherTest, testedCipherSuite); + this.serverHost = serverHost; + this.serverPort = serverPort; + this.testedProtocol = testedProtocols; + this.keyManager = + new MyX509KeyManager(cipherTest.getClientKeyManager()); + sslContext = SSLContext.getInstance(TLS); + } + + @Override + void runTest(CipherTestUtils.TestParameters params) throws Exception { + SSLSocket socket = null; + try { + System.out.println("Connecting to server..."); + keyManager.setAuthType(params.clientAuth); + sslContext.init(new KeyManager[]{keyManager}, + new TrustManager[]{cipherTest.getClientTrustManager()}, + CipherTestUtils.secureRandom); + SSLSocketFactory factory = (SSLSocketFactory) sslContext. + getSocketFactory(); + socket = (SSLSocket) factory.createSocket(serverHost, + serverPort); + socket.setSoTimeout(CipherTestUtils.TIMEOUT); + socket.setEnabledCipherSuites(params.cipherSuite.split(",")); + if (params.protocol != null && !params.protocol.trim().equals("") + && !params.protocol.trim().equals(DEFAULT)) { + socket.setEnabledProtocols(params.protocol.split(",")); + } + CipherTestUtils.printInfo(socket); + InputStream in = socket.getInputStream(); + OutputStream out = socket.getOutputStream(); + sendRequest(in, out); + SSLSession session = socket.getSession(); + session.invalidate(); + String cipherSuite = session.getCipherSuite(); + if (params.cipherSuite.equals(cipherSuite) == false) { + throw new RuntimeException("Negotiated ciphersuite mismatch: " + + cipherSuite + " != " + params.cipherSuite); + } + String protocol = session.getProtocol(); + if (!DEFAULT.equals(params.protocol) + && !params.protocol.contains(protocol)) { + throw new RuntimeException("Negotiated protocol mismatch: " + + protocol + " != " + params.protocol); + } + if (!cipherSuite.contains("DH_anon")) { + session.getPeerCertificates(); + } + Certificate[] certificates = session.getLocalCertificates(); + if (params.clientAuth == null) { + if (certificates != null) { + throw new RuntimeException("Local certificates " + + "should be null"); + } + } else { + if ((certificates == null) || (certificates.length == 0)) { + throw new RuntimeException("Certificates missing"); + } + String keyAlg = certificates[0].getPublicKey().getAlgorithm(); + if ("EC".equals(keyAlg)) { + keyAlg = "ECDSA"; + } + if (params.clientAuth == null ? keyAlg != null + : !params.clientAuth.equals(keyAlg)) { + throw new RuntimeException("Certificate type mismatch: " + + keyAlg + " != " + params.clientAuth); + } + } + } finally { + if (socket != null) { + socket.close(); + } + } + } +} diff --git a/test/javax/net/ssl/TLS/JSSEServer.java b/test/javax/net/ssl/TLS/JSSEServer.java new file mode 100644 index 0000000000000000000000000000000000000000..f6e55a317061d50a5c9b40597ff0e51eb25e4971 --- /dev/null +++ b/test/javax/net/ssl/TLS/JSSEServer.java @@ -0,0 +1,80 @@ +/** + * Copyright (c) 2010, 2014, 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. + * + * 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. + */ + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import javax.net.ssl.KeyManager; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLServerSocket; +import javax.net.ssl.SSLServerSocketFactory; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.TrustManager; + +public class JSSEServer extends CipherTestUtils.Server { + + private final SSLServerSocket serverSocket; + private final int serverPort; + static volatile boolean closeServer = false; + + JSSEServer(CipherTestUtils cipherTest, int serverPort, + String protocol, String cipherSuite) throws Exception { + super(cipherTest); + this.serverPort = serverPort; + SSLContext serverContext = SSLContext.getInstance("TLS"); + serverContext.init(new KeyManager[]{cipherTest.getServerKeyManager()}, + new TrustManager[]{cipherTest.getServerTrustManager()}, + CipherTestUtils.secureRandom); + SSLServerSocketFactory factory = + (SSLServerSocketFactory)serverContext.getServerSocketFactory(); + serverSocket = + (SSLServerSocket) factory.createServerSocket(serverPort); + serverSocket.setEnabledProtocols(protocol.split(",")); + serverSocket.setEnabledCipherSuites(cipherSuite.split(",")); + + CipherTestUtils.printInfo(serverSocket); + } + + @Override + public void run() { + System.out.println("JSSE Server listening on port " + serverPort); + while (!closeServer) { + try (final SSLSocket socket = (SSLSocket) serverSocket.accept()) { + socket.setSoTimeout(CipherTestUtils.TIMEOUT); + + try (InputStream in = socket.getInputStream(); + OutputStream out = socket.getOutputStream()) { + handleRequest(in, out); + out.flush(); + } catch (IOException e) { + CipherTestUtils.addFailure(e); + System.out.println("Got IOException:"); + e.printStackTrace(System.err); + } + } catch (Exception e) { + CipherTestUtils.addFailure(e); + System.out.println("Exception:"); + e.printStackTrace(System.err); + } + } + } +} diff --git a/test/javax/net/ssl/TLS/TLSClientPropertyTest.java b/test/javax/net/ssl/TLS/TLSClientPropertyTest.java new file mode 100644 index 0000000000000000000000000000000000000000..8d7c1b2a71637b6568da66f2508406a384826b90 --- /dev/null +++ b/test/javax/net/ssl/TLS/TLSClientPropertyTest.java @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2014, 2015, 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. + * + * 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. + */ + +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; +import java.util.List; +import javax.net.ssl.SSLContext; + +/* + * @test + * @bug 8049432 8069038 + * @summary New tests for TLS property jdk.tls.client.protocols + * @summary javax/net/ssl/TLS/TLSClientPropertyTest.java needs to be + * updated for JDK-8061210 + * @run main/othervm TLSClientPropertyTest NoProperty + * @run main/othervm TLSClientPropertyTest SSLv3 + * @run main/othervm TLSClientPropertyTest TLSv1 + * @run main/othervm TLSClientPropertyTest TLSv11 + * @run main/othervm TLSClientPropertyTest TLSv12 + * @run main/othervm TLSClientPropertyTest WrongProperty + */ + +/** + * Sets the property jdk.tls.client.protocols to one of this protocols: + * SSLv3,TLSv1,TLSv1.1,TLSv1.2 and TLSV(invalid) or removes this + * property (if any),then validates the default, supported and current + * protocols in the SSLContext. + */ +public class TLSClientPropertyTest { + private final String[] expectedSupportedProtos = new String[] { + "SSLv2Hello", "SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2" + }; + + public static void main(String[] args) throws Exception { + + if (args.length < 1) { + throw new RuntimeException( + "Incorrect arguments,expected arguments: testCase"); + } + + String[] expectedDefaultProtos; + String testCase = args[0]; + String contextProtocol; + switch (testCase) { + case "NoProperty": + if (System.getProperty("jdk.tls.client.protocols") != null) { + System.getProperties().remove("jdk.tls.client.protocols"); + } + contextProtocol = null; + expectedDefaultProtos = new String[] { + "TLSv1", "TLSv1.1", "TLSv1.2" + }; + break; + case "SSLv3": + contextProtocol = "SSLv3"; + expectedDefaultProtos = new String[] { + }; + break; + case "TLSv1": + contextProtocol = "TLSv1"; + expectedDefaultProtos = new String[] { + "TLSv1" + }; + break; + case "TLSv11": + contextProtocol = "TLSv1.1"; + expectedDefaultProtos = new String[] { + "TLSv1", "TLSv1.1" + }; + break; + case "TLSv12": + contextProtocol = "TLSv1.2"; + expectedDefaultProtos = new String[] { + "TLSv1", "TLSv1.1", "TLSv1.2" + }; + break; + case "WrongProperty": + expectedDefaultProtos = new String[] {}; + contextProtocol = "TLSV"; + break; + default: + throw new RuntimeException("test case is wrong"); + } + if (contextProtocol != null) { + System.setProperty("jdk.tls.client.protocols", contextProtocol); + } + try { + TLSClientPropertyTest test = new TLSClientPropertyTest(); + test.test(contextProtocol, expectedDefaultProtos); + if (testCase.equals("WrongProperty")) { + throw new RuntimeException( + "Test failed: NoSuchAlgorithmException " + + "is expected when input wrong protocol"); + } else { + System.out.println("Test " + contextProtocol + " passed"); + } + } catch (NoSuchAlgorithmException nsae) { + if (testCase.equals("WrongProperty")) { + System.out.println("NoSuchAlgorithmException is expected," + + contextProtocol + " test passed"); + } else { + throw nsae; + } + } + + } + + /** + * The parameter passed is the user enforced protocol. Does not catch + * NoSuchAlgorithmException, WrongProperty test will use it. + */ + public void test(String expectedContextProto, + String[] expectedDefaultProtos) throws NoSuchAlgorithmException { + + SSLContext context = null; + try { + if (expectedContextProto != null) { + context = SSLContext.getInstance(expectedContextProto); + context.init(null, null, null); + } else { + context = SSLContext.getDefault(); + } + printContextDetails(context); + } catch (KeyManagementException ex) { + error(null, ex); + } + + validateContext(expectedContextProto, expectedDefaultProtos, context); + } + + /** + * Simple print utility for SSLContext's protocol details. + */ + private void printContextDetails(SSLContext context) { + System.out.println("Default Protocols: " + + Arrays.toString(context.getDefaultSSLParameters() + .getProtocols())); + System.out.println("Supported Protocols: " + + Arrays.toString(context.getSupportedSSLParameters() + .getProtocols())); + System.out.println("Current Protocol : " + context.getProtocol()); + + } + + /** + * Error handler. + */ + private void error(String msg, Throwable tble) { + String finalMsg = "FAILED " + (msg != null ? msg : ""); + if (tble != null) { + throw new RuntimeException(finalMsg, tble); + } + throw new RuntimeException(finalMsg); + } + + /** + * Validates the SSLContext's protocols against the user enforced protocol. + */ + private void validateContext(String expectedProto, + String[] expectedDefaultProtos, SSLContext context) { + if (expectedProto == null) { + expectedProto = "Default"; + } + if (!context.getProtocol().equals(expectedProto)) { + error("Invalid current protocol: " + context.getProtocol() + + ", Expected:" + expectedProto, null); + } + List actualDefaultProtos = Arrays.asList(context + .getDefaultSSLParameters().getProtocols()); + for (String p : expectedDefaultProtos) { + if (!actualDefaultProtos.contains(p)) { + error("Default protocol " + p + "missing", null); + } + } + List actualSupportedProtos = Arrays.asList(context + .getSupportedSSLParameters().getProtocols()); + + for (String p : expectedSupportedProtos) { + if (!actualSupportedProtos.contains(p)) { + error("Expected to support protocol:" + p, null); + } + } + } +} diff --git a/test/javax/net/ssl/TLS/TestJSSE.java b/test/javax/net/ssl/TLS/TestJSSE.java new file mode 100644 index 0000000000000000000000000000000000000000..7a776aa6c6a2bf51f84ff1df9eb3048e04a637c1 --- /dev/null +++ b/test/javax/net/ssl/TLS/TestJSSE.java @@ -0,0 +1,188 @@ +/** + * Copyright (c) 2010, 2016, 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. + * + * 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. + */ + +import static java.lang.System.out; +import java.security.Provider; +import java.security.Security; + +/** + * @test + * @bug 8049429 + * @library ../../../../lib/testlibrary/ + * @build jdk.testlibrary.Utils + * @compile CipherTestUtils.java JSSEClient.java JSSEServer.java + * @summary Test that all cipher suites work in all versions and all client + * authentication types. The way this is setup the server is stateless and + * all checking is done on the client side. + * @run main/othervm -DSERVER_PROTOCOL=SSLv3 + * -DCLIENT_PROTOCOL=SSLv3 + * -DCIPHER=SSL_RSA_WITH_RC4_128_MD5 TestJSSE + * @run main/othervm -DSERVER_PROTOCOL=TLSv1 + * -DCLIENT_PROTOCOL=SSLv3,TLSv1,TLSv1.1,TLSv1.2 + * -DCIPHER=SSL_RSA_WITH_RC4_128_MD5 TestJSSE + * @run main/othervm -DSERVER_PROTOCOL=TLSv1.1 + * -DCLIENT_PROTOCOL=SSLv3,TLSv1,TLSv1.1,TLSv1.2 + * -DCIPHER=SSL_RSA_WITH_RC4_128_MD5 TestJSSE + * @run main/othervm -DSERVER_PROTOCOL=TLSv1.2 + * -DCLIENT_PROTOCOL=SSLv3,TLSv1,TLSv1.1,TLSv1.2 + * -DCIPHER=SSL_RSA_WITH_RC4_128_MD5 TestJSSE + * @run main/othervm -DSERVER_PROTOCOL=SSLv3,TLSv1 + * -DCLIENT_PROTOCOL=TLSv1 -DCIPHER=SSL_RSA_WITH_RC4_128_MD5 TestJSSE + * @run main/othervm -DSERVER_PROTOCOL=SSLv3,TLSv1,TLSv1.1 + * -DCLIENT_PROTOCOL=TLSv1.1 -DCIPHER=SSL_RSA_WITH_RC4_128_MD5 TestJSSE + * @run main/othervm -DSERVER_PROTOCOL=SSLv3 + * -DCLIENT_PROTOCOL=TLSv1.1,TLSv1.2 + * -DCIPHER=SSL_RSA_WITH_RC4_128_MD5 + * TestJSSE javax.net.ssl.SSLHandshakeException + * @run main/othervm -DSERVER_PROTOCOL=TLSv1 + * -DCLIENT_PROTOCOL=TLSv1.1,TLSv1.2 + * -DCIPHER=SSL_RSA_WITH_RC4_128_MD5 + * TestJSSE javax.net.ssl.SSLHandshakeException + * @run main/othervm -DSERVER_PROTOCOL=SSLv3,TLSv1,TLSv1.1,TLSv1.2 + * -DCLIENT_PROTOCOL=TLSv1.2 -DCIPHER=SSL_RSA_WITH_RC4_128_MD5 TestJSSE + * @run main/othervm -DSERVER_PROTOCOL=SSLv2Hello,SSLv3,TLSv1 + * -DCLIENT_PROTOCOL=DEFAULT -DCIPHER=SSL_RSA_WITH_RC4_128_MD5 TestJSSE + * @run main/othervm -DSERVER_PROTOCOL=SSLv2Hello,SSLv3,TLSv1,TLSv1.1,TLSv1.2 + * -DCLIENT_PROTOCOL=DEFAULT -DCIPHER=SSL_RSA_WITH_RC4_128_MD5 TestJSSE + * @run main/othervm -DSERVER_PROTOCOL=SSLv2Hello,SSLv3,TLSv1,TLSv1.1,TLSv1.2 + * -DCLIENT_PROTOCOL=DEFAULT -Djdk.tls.client.protocols=TLSv1 + * -DCIPHER=SSL_RSA_WITH_RC4_128_MD5 TestJSSE + * @run main/othervm -DSERVER_PROTOCOL=SSLv2Hello,SSLv3,TLSv1 + * -DCLIENT_PROTOCOL=DEFAULT -Djdk.tls.client.protocols=TLSv1.2 + * -DCIPHER=SSL_RSA_WITH_RC4_128_MD5 + * TestJSSE javax.net.ssl.SSLHandshakeException + * + */ + +public class TestJSSE { + + private static final String LOCAL_IP = "127.0.0.1"; + + public static void main(String... args) throws Exception { + // reset the security property to make sure that the algorithms + // and keys used in this test are not disabled. + Security.setProperty("jdk.tls.disabledAlgorithms", ""); + + String serverProtocol = System.getProperty("SERVER_PROTOCOL"); + String clientProtocol = System.getProperty("CLIENT_PROTOCOL"); + int port = jdk.testlibrary.Utils.getFreePort(); + String cipher = System.getProperty("CIPHER"); + if (serverProtocol == null + || clientProtocol == null + || cipher == null) { + throw new IllegalArgumentException("SERVER_PROTOCOL " + + "or CLIENT_PROTOCOL or CIPHER is missing"); + } + out.println("ServerProtocol =" + serverProtocol); + out.println("ClientProtocol =" + clientProtocol); + out.println("Cipher =" + cipher); + server(serverProtocol, cipher, port, args); + client(port, clientProtocol, cipher, args); + + } + + public static void client(int testPort, + String testProtocols, String testCipher, + String... exception) throws Exception { + String expectedException = exception.length >= 1 + ? exception[0] : null; + out.println("========================================="); + out.println(" Testing - https://" + LOCAL_IP + ":" + testPort); + out.println(" Testing - Protocol : " + testProtocols); + out.println(" Testing - Cipher : " + testCipher); + Provider p = new sun.security.ec.SunEC(); + Security.insertProviderAt(p, 1); + try { + CipherTestUtils.main(new JSSEFactory(LOCAL_IP, + testPort, testProtocols, + testCipher, "client JSSE"), + "client", expectedException); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public static void server(String testProtocol, String testCipher, + int testPort, + String... exception) throws Exception { + String expectedException = exception.length >= 1 + ? exception[0] : null; + out.println(" This is Server"); + out.println(" Testing Protocol: " + testProtocol); + out.println(" Testing Cipher: " + testCipher); + out.println(" Testing Port: " + testPort); + Provider p = new sun.security.ec.SunEC(); + Security.insertProviderAt(p, 1); + try { + CipherTestUtils.main(new JSSEFactory(null, testPort, + testProtocol, testCipher, "Server JSSE"), + "Server", expectedException); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private static class JSSEFactory extends CipherTestUtils.PeerFactory { + + final String testedCipherSuite, testedProtocol, testHost; + final int testPort; + final String name; + + JSSEFactory(String testHost, int testPort, String testedProtocol, + String testedCipherSuite, String name) { + this.testedCipherSuite = testedCipherSuite; + this.testedProtocol = testedProtocol; + this.testHost = testHost; + this.testPort = testPort; + this.name = name; + } + + @Override + String getName() { + return name; + } + + @Override + String getTestedCipher() { + return testedCipherSuite; + } + + @Override + String getTestedProtocol() { + return testedProtocol; + } + + @Override + CipherTestUtils.Client newClient(CipherTestUtils cipherTest) + throws Exception { + return new JSSEClient(cipherTest, testHost, testPort, + testedProtocol, testedCipherSuite); + } + + @Override + CipherTestUtils.Server newServer(CipherTestUtils cipherTest) + throws Exception { + return new JSSEServer(cipherTest, testPort, + testedProtocol, testedCipherSuite); + } + } +} diff --git a/test/javax/net/ssl/TLSv12/SignatureAlgorithms.java b/test/javax/net/ssl/TLSv12/SignatureAlgorithms.java new file mode 100644 index 0000000000000000000000000000000000000000..cf5ba4773249ed2bc4a84d34199d8dbc68ef5d71 --- /dev/null +++ b/test/javax/net/ssl/TLSv12/SignatureAlgorithms.java @@ -0,0 +1,595 @@ +/* + * Copyright (c) 2015, 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. + */ + +// +// SunJSSE does not support dynamic system properties, no way to re-use +// system properties in samevm/agentvm mode. +// + +/* + * @test + * @bug 8049321 + * @summary Support SHA256WithDSA in JSSE + * @modules java.base/sun.misc + * @run main/othervm SignatureAlgorithms PKIX "SHA-224,SHA-256" + * TLS_DHE_DSS_WITH_AES_128_CBC_SHA + * @run main/othervm SignatureAlgorithms PKIX "SHA-1,SHA-224" + * TLS_DHE_DSS_WITH_AES_128_CBC_SHA + * @run main/othervm SignatureAlgorithms PKIX "SHA-1,SHA-256" + * TLS_DHE_DSS_WITH_AES_128_CBC_SHA + * @run main/othervm SignatureAlgorithms PKIX "SHA-224,SHA-256" + * TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 + * @run main/othervm SignatureAlgorithms PKIX "SHA-1,SHA-224" + * TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 + * @run main/othervm SignatureAlgorithms PKIX "SHA-1,SHA-256" + * TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 + */ + +import java.net.*; +import java.util.*; +import java.io.*; +import javax.net.ssl.*; +import java.security.Security; +import java.security.KeyStore; +import java.security.KeyFactory; +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; +import java.security.cert.CertificateFactory; +import java.security.spec.*; +import java.security.interfaces.*; +import sun.misc.BASE64Decoder; + + +public class SignatureAlgorithms { + + /* + * ============================================================= + * Set the various variables needed for the tests, then + * specify what tests to run on each side. + */ + + /* + * Should we run the client or server in a separate thread? + * Both sides can throw exceptions, but do you have a preference + * as to which side should be the main thread. + */ + static boolean separateServerThread = true; + + /* + * Where do we find the keystores? + */ + // Certificates and key (DSA) used in the test. + static String trustedCertStr = + "-----BEGIN CERTIFICATE-----\n" + + "MIIDYTCCAyGgAwIBAgIJAK8/gw6zg/DPMAkGByqGSM44BAMwOzELMAkGA1UEBhMC\n" + + "VVMxDTALBgNVBAoTBEphdmExHTAbBgNVBAsTFFN1bkpTU0UgVGVzdCBTZXJpdmNl\n" + + "MB4XDTE1MTIwMzEzNTIyNVoXDTM2MTExMjEzNTIyNVowOzELMAkGA1UEBhMCVVMx\n" + + "DTALBgNVBAoTBEphdmExHTAbBgNVBAsTFFN1bkpTU0UgVGVzdCBTZXJpdmNlMIIB\n" + + "uDCCASwGByqGSM44BAEwggEfAoGBAPH+b+GSMX6KS7jXDRevzc464DFG4X+uxu5V\n" + + "b3U4yhsU8A8cuH4gwin6L/IDkmZQ7N0zC0jRsiGVSMsFETTq10F39pH2eBfUv/hJ\n" + + "cLfBnIjBEtVqV/dExK88Hul2sZ4mQihQ4issPl7hsroS9EWYicnX0oNAqAB9PO5Y\n" + + "zKbfpL7TAhUA13WW48rln2UP/LaAgtnzKhqcNtMCgYEA3Rv0GirTbAaor8iURd82\n" + + "b5FlDTevOCTuq7ZIpfZVV30neS7cBYNet6m/3/4cfUlbbrqhbqIJ2I+I81drnN0Y\n" + + "lyN4KkuxEcB6OTwfWkIUj6rvPaCQrBH8Q213bDq3HHtYNaP8OoeQUyVXW+SEGADC\n" + + "J1+z8uqP3lIB6ltdgOiV/GQDgYUAAoGBAOXRppuJSGdt6AiZkb81P1DCUgIUlZFI\n" + + "J9GxWrjbbHDmGllMwPNhK6dU7LJKJJuYVPW+95rUGlSJEjRqSlHuyHkNb6e3e7qx\n" + + "tmx1/oIyq+oLult50hBS7uBvLLR0JbIKjBzzkudL8Rjze4G/Wq7KDM2T1JOP49tW\n" + + "eocCvaC8h8uQo4GtMIGqMB0GA1UdDgQWBBT17HcqLllsqnZzP+kElcGcBGmubjBr\n" + + "BgNVHSMEZDBigBT17HcqLllsqnZzP+kElcGcBGmubqE/pD0wOzELMAkGA1UEBhMC\n" + + "VVMxDTALBgNVBAoTBEphdmExHTAbBgNVBAsTFFN1bkpTU0UgVGVzdCBTZXJpdmNl\n" + + "ggkArz+DDrOD8M8wDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwCQYHKoZI\n" + + "zjgEAwMvADAsAhQ6Y1I6LtIEBMqNo8o6GIe4LLEJuwIUbVQUKi8tvtWyRoxm8AFV\n" + + "0axJYUU=\n" + + "-----END CERTIFICATE-----"; + + static String[] targetCertStr = { + // DSA-SHA1 + "-----BEGIN CERTIFICATE-----\n" + + "MIIDKTCCAumgAwIBAgIJAOy5c0b+8stFMAkGByqGSM44BAMwOzELMAkGA1UEBhMC\n" + + "VVMxDTALBgNVBAoTBEphdmExHTAbBgNVBAsTFFN1bkpTU0UgVGVzdCBTZXJpdmNl\n" + + "MB4XDTE1MTIwMzEzNTIyNVoXDTM1MDgyMDEzNTIyNVowTzELMAkGA1UEBhMCVVMx\n" + + "DTALBgNVBAoMBEphdmExHTAbBgNVBAsMFFN1bkpTU0UgVGVzdCBTZXJpdmNlMRIw\n" + + "EAYDVQQDDAlsb2NhbGhvc3QwggG3MIIBLAYHKoZIzjgEATCCAR8CgYEA8f5v4ZIx\n" + + "fopLuNcNF6/NzjrgMUbhf67G7lVvdTjKGxTwDxy4fiDCKfov8gOSZlDs3TMLSNGy\n" + + "IZVIywURNOrXQXf2kfZ4F9S/+Elwt8GciMES1WpX90TErzwe6XaxniZCKFDiKyw+\n" + + "XuGyuhL0RZiJydfSg0CoAH087ljMpt+kvtMCFQDXdZbjyuWfZQ/8toCC2fMqGpw2\n" + + "0wKBgQDdG/QaKtNsBqivyJRF3zZvkWUNN684JO6rtkil9lVXfSd5LtwFg163qb/f\n" + + "/hx9SVtuuqFuognYj4jzV2uc3RiXI3gqS7ERwHo5PB9aQhSPqu89oJCsEfxDbXds\n" + + "Orcce1g1o/w6h5BTJVdb5IQYAMInX7Py6o/eUgHqW12A6JX8ZAOBhAACgYB+zYqn\n" + + "jJwG4GZpBIN/6qhzbp0flChsV+Trlu0SL0agAQzb6XdI/4JnO87Pgbxaxh3VNAj3\n" + + "3+Ghr1NLBuBfTKzJ4j9msWT3EpLupkMyNtXvBYM0iyMrll67lSjMdv++wLEw35Af\n" + + "/bzVcjGyA5Q0i0cuEzDmHTVfi0OydynbwSLxtKNjMGEwCwYDVR0PBAQDAgPoMB0G\n" + + "A1UdDgQWBBQXJI8AxM0qsYCbbkIMuI5zJ+nMEDAfBgNVHSMEGDAWgBT17HcqLlls\n" + + "qnZzP+kElcGcBGmubjASBgNVHREBAf8ECDAGhwR/AAABMAkGByqGSM44BAMDLwAw\n" + + "LAIUXgyJ0xll4FrZAKXi8bj7Kiz+SA4CFH9WCSZIBYA9lmJkiTgRS7iM/6IC\n" + + "-----END CERTIFICATE-----", + + // DSA-SHA224 + "-----BEGIN CERTIFICATE-----\n" + + "MIIDLzCCAuugAwIBAgIJAOy5c0b+8stGMAsGCWCGSAFlAwQDATA7MQswCQYDVQQG\n" + + "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" + + "Y2UwHhcNMTUxMjAzMTU0NDM5WhcNMzUwODIwMTU0NDM5WjBPMQswCQYDVQQGEwJV\n" + + "UzENMAsGA1UECgwESmF2YTEdMBsGA1UECwwUU3VuSlNTRSBUZXN0IFNlcml2Y2Ux\n" + + "EjAQBgNVBAMMCWxvY2FsaG9zdDCCAbcwggEsBgcqhkjOOAQBMIIBHwKBgQDx/m/h\n" + + "kjF+iku41w0Xr83OOuAxRuF/rsbuVW91OMobFPAPHLh+IMIp+i/yA5JmUOzdMwtI\n" + + "0bIhlUjLBRE06tdBd/aR9ngX1L/4SXC3wZyIwRLValf3RMSvPB7pdrGeJkIoUOIr\n" + + "LD5e4bK6EvRFmInJ19KDQKgAfTzuWMym36S+0wIVANd1luPK5Z9lD/y2gILZ8yoa\n" + + "nDbTAoGBAN0b9Boq02wGqK/IlEXfNm+RZQ03rzgk7qu2SKX2VVd9J3ku3AWDXrep\n" + + "v9/+HH1JW266oW6iCdiPiPNXa5zdGJcjeCpLsRHAejk8H1pCFI+q7z2gkKwR/ENt\n" + + "d2w6txx7WDWj/DqHkFMlV1vkhBgAwidfs/Lqj95SAepbXYDolfxkA4GEAAKBgA81\n" + + "CJKEv+pwiqYgxtw/9rkQ9748WP3mKrEC06kjUG+94/Z9dQloNFFfj6LiO1bymc5l\n" + + "6QIR8XCi4Po3N80K3+WxhBGFhY+RkVWTh43JV8epb41aH2qiWErarBwBGEh8LyGT\n" + + "i30db+Nkz2gfvyz9H/9T0jmYgfLEOlMCusali1qHo2MwYTALBgNVHQ8EBAMCA+gw\n" + + "HQYDVR0OBBYEFBqSP0S4+X+zOCTEnlp2hbAjV/W5MB8GA1UdIwQYMBaAFPXsdyou\n" + + "WWyqdnM/6QSVwZwEaa5uMBIGA1UdEQEB/wQIMAaHBH8AAAEwCwYJYIZIAWUDBAMB\n" + + "AzEAMC4CFQChiRaOnAnsCSJFwdpK22jSxU/mhQIVALgLbj/G39+1Ej8UuSWnEQyU\n" + + "4DA+\n" + + "-----END CERTIFICATE-----", + + // DSA-SHA256 + "-----BEGIN CERTIFICATE-----\n" + + "MIIDLTCCAuugAwIBAgIJAOy5c0b+8stHMAsGCWCGSAFlAwQDAjA7MQswCQYDVQQG\n" + + "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" + + "Y2UwHhcNMTUxMjAzMTU0NjUxWhcNMzUwODIwMTU0NjUxWjBPMQswCQYDVQQGEwJV\n" + + "UzENMAsGA1UECgwESmF2YTEdMBsGA1UECwwUU3VuSlNTRSBUZXN0IFNlcml2Y2Ux\n" + + "EjAQBgNVBAMMCWxvY2FsaG9zdDCCAbcwggEsBgcqhkjOOAQBMIIBHwKBgQDx/m/h\n" + + "kjF+iku41w0Xr83OOuAxRuF/rsbuVW91OMobFPAPHLh+IMIp+i/yA5JmUOzdMwtI\n" + + "0bIhlUjLBRE06tdBd/aR9ngX1L/4SXC3wZyIwRLValf3RMSvPB7pdrGeJkIoUOIr\n" + + "LD5e4bK6EvRFmInJ19KDQKgAfTzuWMym36S+0wIVANd1luPK5Z9lD/y2gILZ8yoa\n" + + "nDbTAoGBAN0b9Boq02wGqK/IlEXfNm+RZQ03rzgk7qu2SKX2VVd9J3ku3AWDXrep\n" + + "v9/+HH1JW266oW6iCdiPiPNXa5zdGJcjeCpLsRHAejk8H1pCFI+q7z2gkKwR/ENt\n" + + "d2w6txx7WDWj/DqHkFMlV1vkhBgAwidfs/Lqj95SAepbXYDolfxkA4GEAAKBgEF7\n" + + "2qiYxGrjX4KCOy0k5nK/RYlgLy4gYDChihQpiaa+fbA5JOBOxPWsh7rdtmJuDrEJ\n" + + "keacU223+DIhOKC49fa+EvhLNqo6U1oPn8n/yvBsvvnWkcynw5KfNzaLlaPmzugh\n" + + "v9xl/GhyZNAXc1QUcW3C+ceHVNrKnkfbTKZz5eRSo2MwYTALBgNVHQ8EBAMCA+gw\n" + + "HQYDVR0OBBYEFNMkPrt40oO9Dpy+bcbQdEvOlNlyMB8GA1UdIwQYMBaAFPXsdyou\n" + + "WWyqdnM/6QSVwZwEaa5uMBIGA1UdEQEB/wQIMAaHBH8AAAEwCwYJYIZIAWUDBAMC\n" + + "Ay8AMCwCFCvA2QiKSe/n+6GqSYQwgQ/zL5M9AhQfSiuWdMJKWpgPJKakvzhBUbMb\n" + + "vA==\n" + + "-----END CERTIFICATE-----"}; + + // Private key in the format of PKCS#8, key size is 1024 bits. + static String[] targetPrivateKey = { + // For cert DSA-SHA1 + "MIIBSwIBADCCASwGByqGSM44BAEwggEfAoGBAPH+b+GSMX6KS7jXDRevzc464DFG\n" + + "4X+uxu5Vb3U4yhsU8A8cuH4gwin6L/IDkmZQ7N0zC0jRsiGVSMsFETTq10F39pH2\n" + + "eBfUv/hJcLfBnIjBEtVqV/dExK88Hul2sZ4mQihQ4issPl7hsroS9EWYicnX0oNA\n" + + "qAB9PO5YzKbfpL7TAhUA13WW48rln2UP/LaAgtnzKhqcNtMCgYEA3Rv0GirTbAao\n" + + "r8iURd82b5FlDTevOCTuq7ZIpfZVV30neS7cBYNet6m/3/4cfUlbbrqhbqIJ2I+I\n" + + "81drnN0YlyN4KkuxEcB6OTwfWkIUj6rvPaCQrBH8Q213bDq3HHtYNaP8OoeQUyVX\n" + + "W+SEGADCJ1+z8uqP3lIB6ltdgOiV/GQEFgIUOiB7J/lrFrNduQ8nDNTe8VspoAI=", + + // For cert DSA-SHA224 + "MIIBSwIBADCCASwGByqGSM44BAEwggEfAoGBAPH+b+GSMX6KS7jXDRevzc464DFG\n" + + "4X+uxu5Vb3U4yhsU8A8cuH4gwin6L/IDkmZQ7N0zC0jRsiGVSMsFETTq10F39pH2\n" + + "eBfUv/hJcLfBnIjBEtVqV/dExK88Hul2sZ4mQihQ4issPl7hsroS9EWYicnX0oNA\n" + + "qAB9PO5YzKbfpL7TAhUA13WW48rln2UP/LaAgtnzKhqcNtMCgYEA3Rv0GirTbAao\n" + + "r8iURd82b5FlDTevOCTuq7ZIpfZVV30neS7cBYNet6m/3/4cfUlbbrqhbqIJ2I+I\n" + + "81drnN0YlyN4KkuxEcB6OTwfWkIUj6rvPaCQrBH8Q213bDq3HHtYNaP8OoeQUyVX\n" + + "W+SEGADCJ1+z8uqP3lIB6ltdgOiV/GQEFgIUOj9F5mxWd9W1tiLSdsOAt8BUBzE=", + + // For cert DSA-SHA256 + "MIIBSwIBADCCASwGByqGSM44BAEwggEfAoGBAPH+b+GSMX6KS7jXDRevzc464DFG\n" + + "4X+uxu5Vb3U4yhsU8A8cuH4gwin6L/IDkmZQ7N0zC0jRsiGVSMsFETTq10F39pH2\n" + + "eBfUv/hJcLfBnIjBEtVqV/dExK88Hul2sZ4mQihQ4issPl7hsroS9EWYicnX0oNA\n" + + "qAB9PO5YzKbfpL7TAhUA13WW48rln2UP/LaAgtnzKhqcNtMCgYEA3Rv0GirTbAao\n" + + "r8iURd82b5FlDTevOCTuq7ZIpfZVV30neS7cBYNet6m/3/4cfUlbbrqhbqIJ2I+I\n" + + "81drnN0YlyN4KkuxEcB6OTwfWkIUj6rvPaCQrBH8Q213bDq3HHtYNaP8OoeQUyVX\n" + + "W+SEGADCJ1+z8uqP3lIB6ltdgOiV/GQEFgIUQ2WGgg+OO39Aujj0e4lM4pP4/9g="}; + + + static char passphrase[] = "passphrase".toCharArray(); + + /* + * Turn on SSL debugging? + */ + static boolean debug = false; + + /* + * Is the server ready to serve? + */ + volatile boolean serverReady = false; + + /* + * Define the server side of the test. + * + * If the server prematurely exits, serverReady will be set to true + * to avoid infinite hangs. + */ + void doServerSide() throws Exception { + + SSLContext context = generateSSLContext( + null, targetCertStr, targetPrivateKey); + SSLServerSocketFactory sslssf = context.getServerSocketFactory(); + try (SSLServerSocket sslServerSocket = + (SSLServerSocket)sslssf.createServerSocket(serverPort)) { + + serverPort = sslServerSocket.getLocalPort(); + + /* + * Signal Client, we're ready for his connect. + */ + serverReady = true; + + try (SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept()) { + sslSocket.setEnabledCipherSuites( + sslSocket.getSupportedCipherSuites()); + InputStream sslIS = sslSocket.getInputStream(); + OutputStream sslOS = sslSocket.getOutputStream(); + + sslIS.read(); + sslOS.write('A'); + sslOS.flush(); + + dumpSignatureAlgorithms(sslSocket); + } + } + } + + /* + * Define the client side of the test. + * + * If the server prematurely exits, serverReady will be set to true + * to avoid infinite hangs. + */ + void doClientSide() throws Exception { + + /* + * Wait for server to get started. + */ + while (!serverReady) { + Thread.sleep(50); + } + + SSLContext context = generateSSLContext(trustedCertStr, null, null); + SSLSocketFactory sslsf = context.getSocketFactory(); + + try (SSLSocket sslSocket = + (SSLSocket)sslsf.createSocket("localhost", serverPort)) { + + // enable TLSv1.2 only + sslSocket.setEnabledProtocols(new String[] {"TLSv1.2"}); + + // enable a block cipher + sslSocket.setEnabledCipherSuites(new String[] {cipherSuite}); + + InputStream sslIS = sslSocket.getInputStream(); + OutputStream sslOS = sslSocket.getOutputStream(); + + sslOS.write('B'); + sslOS.flush(); + sslIS.read(); + + dumpSignatureAlgorithms(sslSocket); + } + } + + static void dumpSignatureAlgorithms(SSLSocket sslSocket) throws Exception { + + boolean isClient = sslSocket.getUseClientMode(); + String mode = "[" + (isClient ? "Client" : "Server") + "]"; + ExtendedSSLSession session = + (ExtendedSSLSession)sslSocket.getSession(); + String[] signAlgs = session.getLocalSupportedSignatureAlgorithms(); + System.out.println( + mode + " local supported signature algorithms: " + + Arrays.asList(signAlgs)); + + if (!isClient) { + signAlgs = session.getPeerSupportedSignatureAlgorithms(); + System.out.println( + mode + " peer supported signature algorithms: " + + Arrays.asList(signAlgs)); + } else { + Certificate[] serverCerts = session.getPeerCertificates(); + + // server should always send the authentication cert. + String sigAlg = ((X509Certificate)serverCerts[0]).getSigAlgName(); + System.out.println( + mode + " the signature algorithm of server certificate: " + + sigAlg); + if (sigAlg.contains("SHA1")) { + if (disabledAlgorithms.contains("SHA-1")) { + throw new Exception( + "Not the expected server certificate. " + + "SHA-1 should be disabled"); + } + } else if (sigAlg.contains("SHA224")) { + if (disabledAlgorithms.contains("SHA-224")) { + throw new Exception( + "Not the expected server certificate. " + + "SHA-224 should be disabled"); + } + } else { // SHA-256 + if (disabledAlgorithms.contains("SHA-256")) { + throw new Exception( + "Not the expected server certificate. " + + "SHA-256 should be disabled"); + } + } + } + } + + /* + * ============================================================= + * The remainder is just support stuff + */ + private static String tmAlgorithm; // trust manager + private static String disabledAlgorithms; // disabled algorithms + private static String cipherSuite; // cipher suite + + private static void parseArguments(String[] args) { + tmAlgorithm = args[0]; + disabledAlgorithms = args[1]; + cipherSuite = args[2]; + } + + private static SSLContext generateSSLContext(String trustedCertStr, + String[] keyCertStrs, String[] keySpecStrs) throws Exception { + + // generate certificate from cert string + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + + // create a key store + KeyStore ks = KeyStore.getInstance("JKS"); + ks.load(null, null); + + // import the trused cert + Certificate trusedCert = null; + ByteArrayInputStream is = null; + if (trustedCertStr != null) { + is = new ByteArrayInputStream(trustedCertStr.getBytes()); + trusedCert = cf.generateCertificate(is); + is.close(); + + ks.setCertificateEntry("DSA Signer", trusedCert); + } + + if (keyCertStrs != null && keyCertStrs.length != 0) { + for (int i = 0; i < keyCertStrs.length; i++) { + String keyCertStr = keyCertStrs[i]; + String keySpecStr = keySpecStrs[i]; + + // generate the private key. + PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec( + new BASE64Decoder().decodeBuffer(keySpecStr)); + KeyFactory kf = KeyFactory.getInstance("DSA"); + DSAPrivateKey priKey = + (DSAPrivateKey)kf.generatePrivate(priKeySpec); + + // generate certificate chain + is = new ByteArrayInputStream(keyCertStr.getBytes()); + Certificate keyCert = cf.generateCertificate(is); + is.close(); + + Certificate[] chain = null; + if (trusedCert != null) { + chain = new Certificate[2]; + chain[0] = keyCert; + chain[1] = trusedCert; + } else { + chain = new Certificate[1]; + chain[0] = keyCert; + } + + // import the key entry. + ks.setKeyEntry("DSA Entry " + i, priKey, passphrase, chain); + } + } + + // create SSL context + TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmAlgorithm); + tmf.init(ks); + + SSLContext ctx = SSLContext.getInstance("TLS"); + if (keyCertStrs != null && keyCertStrs.length != 0) { + KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509"); + kmf.init(ks, passphrase); + + ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + ks = null; + } else { + ctx.init(null, tmf.getTrustManagers(), null); + } + + return ctx; + } + + + // use any free port by default + volatile int serverPort = 0; + + volatile Exception serverException = null; + volatile Exception clientException = null; + + public static void main(String[] args) throws Exception { + /* + * debug option + */ + if (debug) { + System.setProperty("javax.net.debug", "all"); + } + + /* + * Get the customized arguments. + */ + parseArguments(args); + + + /* + * Ignore testing on Windows if only SHA-224 is available. + */ + if ((Security.getProvider("SunMSCAPI") != null) && + (disabledAlgorithms.contains("SHA-1")) && + (disabledAlgorithms.contains("SHA-256"))) { + + System.out.println( + "Windows system does not support SHA-224 algorithms yet. " + + "Ignore the testing"); + + return; + } + + /* + * Expose the target algorithms by diabling unexpected algorithms. + */ + Security.setProperty( + "jdk.certpath.disabledAlgorithms", disabledAlgorithms); + + /* + * Reset the security property to make sure that the algorithms + * and keys used in this test are not disabled by default. + */ + Security.setProperty( "jdk.tls.disabledAlgorithms", ""); + + /* + * Start the tests. + */ + new SignatureAlgorithms(); + } + + Thread clientThread = null; + Thread serverThread = null; + + /* + * Primary constructor, used to drive remainder of the test. + * + * Fork off the other side, then do your work. + */ + SignatureAlgorithms() throws Exception { + try { + if (separateServerThread) { + startServer(true); + startClient(false); + } else { + startClient(true); + startServer(false); + } + } catch (Exception e) { + // swallow for now. Show later + } + + /* + * Wait for other side to close down. + */ + if (separateServerThread) { + serverThread.join(); + } else { + clientThread.join(); + } + + /* + * When we get here, the test is pretty much over. + * Which side threw the error? + */ + Exception local; + Exception remote; + String whichRemote; + + if (separateServerThread) { + remote = serverException; + local = clientException; + whichRemote = "server"; + } else { + remote = clientException; + local = serverException; + whichRemote = "client"; + } + + /* + * If both failed, return the curthread's exception, but also + * print the remote side Exception + */ + if ((local != null) && (remote != null)) { + System.out.println(whichRemote + " also threw:"); + remote.printStackTrace(); + System.out.println(); + throw local; + } + + if (remote != null) { + throw remote; + } + + if (local != null) { + throw local; + } + } + + void startServer(boolean newThread) throws Exception { + if (newThread) { + serverThread = new Thread() { + public void run() { + try { + doServerSide(); + } catch (Exception e) { + /* + * Our server thread just died. + * + * Release the client, if not active already... + */ + System.err.println("Server died..." + e); + serverReady = true; + serverException = e; + } + } + }; + serverThread.start(); + } else { + try { + doServerSide(); + } catch (Exception e) { + serverException = e; + } finally { + serverReady = true; + } + } + } + + void startClient(boolean newThread) throws Exception { + if (newThread) { + clientThread = new Thread() { + public void run() { + try { + doClientSide(); + } catch (Exception e) { + /* + * Our client thread just died. + */ + System.err.println("Client died..." + e); + clientException = e; + } + } + }; + clientThread.start(); + } else { + try { + doClientSide(); + } catch (Exception e) { + clientException = e; + } + } + } +} diff --git a/test/javax/security/auth/Subject/doAs/NestedActions.java b/test/javax/security/auth/Subject/doAs/NestedActions.java new file mode 100644 index 0000000000000000000000000000000000000000..f02b2ff47dc4390ce157231818bb398bfd79b255 --- /dev/null +++ b/test/javax/security/auth/Subject/doAs/NestedActions.java @@ -0,0 +1,539 @@ +/* + * Copyright (c) 2001, 2016, 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. + * + * 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. + */ + +import jdk.testlibrary.ProcessTools; + +import javax.security.auth.Subject; +import javax.security.auth.x500.X500Principal; +import java.io.*; +import java.security.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.jar.JarEntry; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; + +/** + * @test + * @bug 8048147 + * @summary Check if proper AccessControlException is thrown + * in case of nested Subject.doAs() invocations + * when one of protection domains doesn't have permissions + * + * @library /lib/testlibrary + * + * @run main NestedActions jar NestedActionsACE.jar + * NestedActionsACE.class Utils.class + * @run main NestedActions jar NestedActionsPAE.jar + * NestedActionsPAE.class Utils.class + * @run main NestedActions jar NestedActionsOnePrincipal.jar + * NestedActionsOnePrincipal.class Utils.class + * @run main NestedActions jar NestedActionsTwoPrincipals.jar + * NestedActionsTwoPrincipals.class Utils.class + * @run main NestedActions jar WriteToFileAction.jar + * WriteToFileAction.class + * @run main NestedActions jar WriteToFileNegativeAction.jar + * WriteToFileNegativeAction.class + * @run main NestedActions jar WriteToFileExceptionAction.jar + * WriteToFileExceptionAction.class + * @run main NestedActions jar ReadFromFileAction.jar + * ReadFromFileAction.class + * @run main NestedActions jar ReadFromFileNegativeAction.jar + * ReadFromFileNegativeAction.class + * @run main NestedActions jar ReadFromFileExceptionAction.jar + * ReadFromFileExceptionAction.class + * @run main NestedActions jar ReadPropertyAction.jar + * ReadPropertyAction.class + * @run main NestedActions jar ReadPropertyNegativeAction.jar + * ReadPropertyNegativeAction.class + * @run main NestedActions jar ReadPropertyExceptionAction.jar + * ReadPropertyExceptionAction.class ReadPropertyException.class + * + * @run main NestedActions NestedActionsACE policy.expect.ace + * NestedActionsACE.jar WriteToFileNegativeAction.jar + * ReadFromFileNegativeAction.jar ReadPropertyNegativeAction.jar + * @run main NestedActions NestedActionsPAE policy.expect.pae + * NestedActionsPAE.jar WriteToFileExceptionAction.jar + * ReadFromFileExceptionAction.jar ReadPropertyExceptionAction.jar + * @run main NestedActions NestedActionsOnePrincipal policy.one.principal + * NestedActionsOnePrincipal.jar WriteToFileAction.jar + * ReadFromFileAction.jar ReadPropertyAction.jar + * @run main NestedActions NestedActionsTwoPrincipals policy.two.principals + * NestedActionsTwoPrincipals.jar WriteToFileAction.jar + * ReadFromFileAction.jar ReadPropertyAction.jar + */ +public class NestedActions { + + static final String file = "NestedActions.tmp"; + static final String PS = System.getProperty("path.separator"); + static final String FS = System.getProperty("file.separator"); + static final String TEST_CLASSES = System.getProperty("test.classes"); + static final String TEST_SOURCES = System.getProperty("test.src"); + static final String JAVA_OPTS = System.getProperty("test.java.opts"); + static final String JAVA = System.getProperty("java.home") + + FS + "bin" + FS + "java"; + + public static void main(String[] args) throws IOException { + if (args.length > 0) { + if ("jar".equals(args[0]) && args.length > 2) { + createJar(args[1], + Arrays.copyOfRange(args, 2, args.length)); + } else { + runJava(args); + } + } else { + throw new RuntimeException("Wrong parameters"); + } + } + + static void createJar(String dest, String... files) throws IOException { + System.out.println("Create " + dest + " with the following content:"); + try (JarOutputStream jos = new JarOutputStream( + new FileOutputStream(dest), new Manifest())) { + for (String file : files) { + System.out.println(" " + file); + jos.putNextEntry(new JarEntry(file)); + try (FileInputStream fis = new FileInputStream( + TEST_CLASSES + FS + file)) { + byte[] buffer = new byte[1024]; + int read; + while ((read = fis.read(buffer, 0, buffer.length)) > 0) { + jos.write(buffer, 0, read); + } + } + } + } + } + + static void runJava(String[] args) { + if (args == null || args.length < 3) { + throw new IllegalArgumentException("wrong parameters"); + } + + List cmds = new ArrayList<>(); + cmds.add(JAVA); + StringBuilder sb = new StringBuilder(); + cmds.add("-classpath"); + for (int i=2; i + * ReadFromFileAction (CN=Duke principal) -> + * ReadPropertyAction (CN=Duke principal) + * + * The test expects PrivilegedActionException + * that caused by AccessControlEception. + */ +class NestedActionsPAE { + + public static void main(String args[]) { + Subject subject = new Subject(); + subject.getPrincipals().add(new X500Principal("CN=Duke")); + try { + WriteToFileExceptionAction writeToFile = + new WriteToFileExceptionAction(NestedActions.file); + Subject.doAs(subject, writeToFile); + throw new RuntimeException( + "Test failed: no PrivilegedActionException thrown"); + } catch (PrivilegedActionException pae) { + System.out.println( + "PrivilegedActionException thrown as expected: " + + pae); + + // check if AccessControlException caused PrivilegedActionException + Throwable exception = pae.getException(); + do { + if (!(exception instanceof PrivilegedActionException)) { + break; + } + exception = ((PrivilegedActionException) exception). + getException(); + } while (true); + + if (!(exception instanceof ReadPropertyException)) { + throw new RuntimeException( + "Test failed: PrivilegedActionException " + + "was not caused by ReadPropertyException"); + } + + exception = exception.getCause(); + if (!(exception instanceof AccessControlException)) { + throw new RuntimeException( + "Test failed: PrivilegedActionException " + + "was not caused by ReadPropertyException"); + } + + System.out.println( + "Test passed: PrivilegedActionException " + + "was caused by AccessControlException"); + } + } +} + +/** + * Test for nested Subject.doAs() invocation: + * + * WriteToFileAction (CN=Duke principal) -> + * ReadFromFileAction (CN=Duke principal) -> + * ReadPropertyAction (CN=Duke principal) + */ +class NestedActionsOnePrincipal { + + public static void main(String args[]) { + Subject subject = new Subject(); + subject.getPrincipals().add(new X500Principal("CN=Duke")); + WriteToFileAction writeToFile = + new WriteToFileAction(NestedActions.file); + Subject.doAs(subject, writeToFile); + } +} + +/** + * Test for nested Subject.doAs() invocation: + * + * WriteToFileAction (CN=Duke principal) -> + * ReadFromFileAction (CN=Duke principal) -> + * ReadPropertyAction (CN=Java principal) + */ +class NestedActionsTwoPrincipals { + + public static void main(String args[]) { + Subject subject = new Subject(); + subject.getPrincipals().add(new X500Principal("CN=Duke")); + Subject anotherSubject = new Subject(); + anotherSubject.getPrincipals().add(new X500Principal("CN=Java")); + ReadFromFileAction readFromFile + = new ReadFromFileAction(NestedActions.file, anotherSubject); + WriteToFileAction writeToFile + = new WriteToFileAction(NestedActions.file, readFromFile); + Subject.doAs(subject, writeToFile); + } +} + +/** + * Helper class. + */ +class Utils { + + static void readFile(String filename) { + System.out.println("ReadFromFileAction: try to read " + filename); + AccessControlContext acc = AccessController.getContext(); + Subject subject = Subject.getSubject(acc); + System.out.println("principals = " + subject.getPrincipals()); + try (FileInputStream fis = new FileInputStream(filename)) { + // do nothing + } catch (IOException e) { + throw new RuntimeException("Unexpected IOException", e); + } + } + + static void writeFile(String filename) { + System.out.println("WriteToFileAction: try to write to " + filename); + AccessControlContext acc = AccessController.getContext(); + Subject subject = Subject.getSubject(acc); + System.out.println("principals = " + subject.getPrincipals()); + try (BufferedOutputStream bos = new BufferedOutputStream( + new FileOutputStream(filename))) { + bos.write(0); + bos.flush(); + } catch (IOException e) { + throw new RuntimeException("Unexpected IOException", e); + } + } + +} + +class WriteToFileAction implements PrivilegedAction { + + private final String filename; + private final PrivilegedAction nextAction; + + WriteToFileAction(String filename, PrivilegedAction nextAction) { + this.filename = filename; + this.nextAction = nextAction; + } + + WriteToFileAction(String filename) { + this(filename, new ReadFromFileAction(filename)); + } + + @Override + public Object run() { + Utils.writeFile(filename); + AccessControlContext acc = AccessController.getContext(); + Subject subject = Subject.getSubject(acc); + return Subject.doAs(subject, nextAction); + } + +} + +class ReadFromFileAction implements PrivilegedAction { + + private final String filename; + private final Subject anotherSubject; + + ReadFromFileAction(String filename) { + this(filename, null); + } + + ReadFromFileAction(String filename, Subject anotherSubject) { + this.filename = filename; + this.anotherSubject = anotherSubject; + } + + @Override + public Object run() { + Utils.readFile(filename); + + AccessControlContext acc = AccessController.getContext(); + Subject subject = Subject.getSubject(acc); + ReadPropertyAction readProperty = new ReadPropertyAction(); + if (anotherSubject != null) { + return Subject.doAs(anotherSubject, readProperty); + } else { + return Subject.doAs(subject, readProperty); + } + } + +} + +class ReadPropertyAction implements PrivilegedAction { + + @Override + public java.lang.Object run() { + System.out.println("ReadPropertyAction: " + + "try to read 'java.class.path' property"); + + AccessControlContext acc = AccessController.getContext(); + Subject s = Subject.getSubject(acc); + System.out.println("principals = " + s.getPrincipals()); + System.out.println("java.class.path = " + + System.getProperty("java.class.path")); + + return null; + } + +} + +class WriteToFileNegativeAction implements PrivilegedAction { + + private final String filename; + + public WriteToFileNegativeAction(String filename) { + this.filename = filename; + } + + @Override + public Object run() { + AccessControlContext acc = AccessController.getContext(); + Subject subject = Subject.getSubject(acc); + System.out.println("principals = " + subject.getPrincipals()); + + try { + Utils.writeFile(filename); + new File(filename).delete(); + throw new RuntimeException( + "Test failed: no AccessControlException thrown"); + } catch (AccessControlException ace) { + System.out.println( + "AccessControlException thrown as expected: " + + ace.getMessage()); + } + + ReadFromFileNegativeAction readFromFile + = new ReadFromFileNegativeAction(filename); + return Subject.doAs(subject, readFromFile); + } + +} + +class ReadFromFileNegativeAction implements PrivilegedAction { + + private final String filename; + + public ReadFromFileNegativeAction(String filename) { + this.filename = filename; + } + + @Override + public Object run() { + AccessControlContext acc = AccessController.getContext(); + Subject subject = Subject.getSubject(acc); + System.out.println("principals = " + subject.getPrincipals()); + + try { + Utils.readFile(filename); + throw new RuntimeException( + "Test failed: no AccessControlException thrown"); + } catch (AccessControlException ace) { + System.out.println( + "AccessControlException thrown as expected: " + + ace.getMessage()); + } + + ReadPropertyNegativeAction readProperty = + new ReadPropertyNegativeAction(); + return Subject.doAs(subject, readProperty); + } + +} + +class ReadPropertyNegativeAction implements PrivilegedAction { + + @Override + public java.lang.Object run() { + System.out.println("Try to read 'java.class.path' property"); + + AccessControlContext acc = AccessController.getContext(); + Subject s = Subject.getSubject(acc); + System.out.println("principals = " + s.getPrincipals()); + + try { + System.out.println("java.class.path = " + + System.getProperty("java.class.path")); + throw new RuntimeException( + "Test failed: no AccessControlException thrown"); + } catch (AccessControlException ace) { + System.out.println( + "AccessControlException thrown as expected: " + + ace.getMessage()); + } + + return null; + } + +} + +class WriteToFileExceptionAction implements PrivilegedExceptionAction { + + private final String filename; + + WriteToFileExceptionAction(String filename) { + this.filename = filename; + } + + @Override + public Object run() throws Exception { + Utils.writeFile(filename); + AccessControlContext acc = AccessController.getContext(); + Subject subject = Subject.getSubject(acc); + ReadFromFileExceptionAction readFromFile = + new ReadFromFileExceptionAction(filename); + return Subject.doAs(subject, readFromFile); + } + +} + +class ReadFromFileExceptionAction implements PrivilegedExceptionAction { + + private final String filename; + + ReadFromFileExceptionAction(String filename) { + this.filename = filename; + } + + @Override + public Object run() throws Exception { + Utils.readFile(filename); + AccessControlContext acc = AccessController.getContext(); + Subject subject = Subject.getSubject(acc); + ReadPropertyExceptionAction readProperty = + new ReadPropertyExceptionAction(); + return Subject.doAs(subject, readProperty); + } + +} + +class ReadPropertyExceptionAction implements PrivilegedExceptionAction { + + @Override + public java.lang.Object run() throws Exception { + System.out.println("Try to read 'java.class.path' property"); + + AccessControlContext acc = AccessController.getContext(); + Subject s = Subject.getSubject(acc); + System.out.println("principals = " + s.getPrincipals()); + + try { + System.out.println("java.class.path = " + + System.getProperty("java.class.path")); + throw new RuntimeException( + "Test failed: no AccessControlException thrown"); + } catch (AccessControlException ace) { + System.out.println( + "AccessControlException thrown as expected: " + + ace.getMessage()); + throw new ReadPropertyException(ace); + } + } + +} + +class ReadPropertyException extends Exception { + + ReadPropertyException(Throwable cause) { + super(cause); + } +} diff --git a/test/javax/security/auth/Subject/doAs/policy.expect.ace b/test/javax/security/auth/Subject/doAs/policy.expect.ace new file mode 100644 index 0000000000000000000000000000000000000000..ac336192d3cb90f9a6a27e169da9a3579b87c36a --- /dev/null +++ b/test/javax/security/auth/Subject/doAs/policy.expect.ace @@ -0,0 +1,27 @@ +// this code has limited permissions that should cause ACE +grant codeBase "file:NestedActionsACE.jar" { + permission javax.security.auth.AuthPermission "getSubject"; + permission javax.security.auth.AuthPermission "modifyPrincipals"; + permission javax.security.auth.AuthPermission "doAs"; + permission java.util.PropertyPermission "path.separator", "read"; + permission java.util.PropertyPermission "file.separator", "read"; + permission java.util.PropertyPermission "test.classes", "read"; + permission java.util.PropertyPermission "test.src", "read"; + permission java.util.PropertyPermission "test.java.opts", "read"; + permission java.util.PropertyPermission "java.home", "read"; +}; + +grant codeBase "file:WriteToFileNegativeAction.jar" + Principal javax.security.auth.x500.X500Principal "cn=Duke" { + permission java.security.AllPermission; +}; + +grant codeBase "file:ReadFromFileNegativeAction.jar" + Principal javax.security.auth.x500.X500Principal "cn=Duke" { + permission java.security.AllPermission; +}; + +grant codeBase "file:ReadPropertyNegativeAction.jar" + Principal javax.security.auth.x500.X500Principal "cn=Duke" { + permission java.security.AllPermission; +}; \ No newline at end of file diff --git a/test/javax/security/auth/Subject/doAs/policy.expect.pae b/test/javax/security/auth/Subject/doAs/policy.expect.pae new file mode 100644 index 0000000000000000000000000000000000000000..c37cd7ec132b75d59c33ff7525150aead3167af6 --- /dev/null +++ b/test/javax/security/auth/Subject/doAs/policy.expect.pae @@ -0,0 +1,19 @@ +grant codeBase "file:NestedActionsPAE.jar" { + permission java.security.AllPermission; +}; + +grant codeBase "file:WriteToFileExceptionAction.jar" + Principal javax.security.auth.x500.X500Principal "cn=Duke" { + permission java.security.AllPermission; +}; + +grant codeBase "file:ReadFromFileExceptionAction.jar" + Principal javax.security.auth.x500.X500Principal "cn=Duke" { + permission java.security.AllPermission; +}; + +// this code has limited permissions that should cause ACE +grant codeBase "file:ReadPropertyExceptionAction.jar" + Principal javax.security.auth.x500.X500Principal "cn=Duke" { + permission javax.security.auth.AuthPermission "getSubject"; +}; diff --git a/test/javax/security/auth/Subject/doAs/policy.one.principal b/test/javax/security/auth/Subject/doAs/policy.one.principal new file mode 100644 index 0000000000000000000000000000000000000000..1f560edb25a1db1fe369ff5ed4ce495aa2fceca2 --- /dev/null +++ b/test/javax/security/auth/Subject/doAs/policy.one.principal @@ -0,0 +1,36 @@ +grant codeBase "file:NestedActionsOnePrincipal.jar" { + permission javax.security.auth.AuthPermission "getSubject"; + permission javax.security.auth.AuthPermission "modifyPrincipals"; + permission javax.security.auth.AuthPermission "doAs"; + permission java.util.PropertyPermission "path.separator", "read"; + permission java.util.PropertyPermission "file.separator", "read"; + permission java.util.PropertyPermission "test.classes", "read"; + permission java.util.PropertyPermission "test.src", "read"; + permission java.util.PropertyPermission "test.java.opts", "read"; + permission java.util.PropertyPermission "java.home", "read"; + permission java.util.PropertyPermission "java.class.path", "read"; + permission java.io.FilePermission "NestedActions.tmp", "read,write"; +}; + +grant codeBase "file:WriteToFileAction.jar" + Principal javax.security.auth.x500.X500Principal "cn=Duke" { + permission javax.security.auth.AuthPermission "getSubject"; + permission javax.security.auth.AuthPermission "doAs"; + permission java.util.PropertyPermission "java.class.path", "read"; + permission java.io.FilePermission "NestedActions.tmp", "read,write"; +}; + +grant codeBase "file:ReadFromFileAction.jar" + Principal javax.security.auth.x500.X500Principal "cn=Duke" { + permission javax.security.auth.AuthPermission "getSubject"; + permission javax.security.auth.AuthPermission "doAs"; + permission java.util.PropertyPermission "java.class.path", "read"; + permission java.io.FilePermission "NestedActions.tmp", "read"; +}; + +grant codeBase "file:ReadPropertyAction.jar" + Principal javax.security.auth.x500.X500Principal "cn=Duke" { + permission javax.security.auth.AuthPermission "getSubject"; + permission javax.security.auth.AuthPermission "doAs"; + permission java.util.PropertyPermission "java.class.path", "read"; +}; \ No newline at end of file diff --git a/test/javax/security/auth/Subject/doAs/policy.two.principals b/test/javax/security/auth/Subject/doAs/policy.two.principals new file mode 100644 index 0000000000000000000000000000000000000000..c260781261c825175371c711383b455e3c059423 --- /dev/null +++ b/test/javax/security/auth/Subject/doAs/policy.two.principals @@ -0,0 +1,37 @@ +grant codeBase "file:NestedActionsTwoPrincipals.jar" { + permission javax.security.auth.AuthPermission "getSubject"; + permission javax.security.auth.AuthPermission "modifyPrincipals"; + permission javax.security.auth.AuthPermission "doAs"; + permission java.util.PropertyPermission "path.separator", "read"; + permission java.util.PropertyPermission "file.separator", "read"; + permission java.util.PropertyPermission "test.classes", "read"; + permission java.util.PropertyPermission "test.src", "read"; + permission java.util.PropertyPermission "test.java.opts", "read"; + permission java.util.PropertyPermission "java.home", "read"; + permission java.util.PropertyPermission "java.class.path", "read"; + permission java.io.FilePermission "NestedActions.tmp", "read,write,delete"; +}; + +grant codeBase "file:WriteToFileAction.jar" + Principal javax.security.auth.x500.X500Principal "cn=Duke" { + permission javax.security.auth.AuthPermission "getSubject"; + permission javax.security.auth.AuthPermission "doAs"; + permission javax.security.auth.AuthPermission "modifyPrincipals"; + permission java.util.PropertyPermission "java.class.path", "read"; + permission java.io.FilePermission "NestedActions.tmp", "read,write"; +}; + +grant codeBase "file:ReadFromFileAction.jar" + Principal javax.security.auth.x500.X500Principal "cn=Duke"{ + permission javax.security.auth.AuthPermission "getSubject"; + permission javax.security.auth.AuthPermission "doAs"; + permission java.util.PropertyPermission "java.class.path", "read"; + permission java.io.FilePermission "NestedActions.tmp", "read"; +}; + +grant codeBase "file:ReadPropertyAction.jar" + Principal javax.security.auth.x500.X500Principal "cn=Java" { + permission javax.security.auth.AuthPermission "getSubject"; + permission javax.security.auth.AuthPermission "doAs"; + permission java.util.PropertyPermission "java.class.path", "read"; +}; \ No newline at end of file diff --git a/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASConfigSyntaxTest.java b/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASConfigSyntaxTest.java new file mode 100644 index 0000000000000000000000000000000000000000..1a649ea85a910d11a7cb7b9e134eafceafd6cb3c --- /dev/null +++ b/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASConfigSyntaxTest.java @@ -0,0 +1,57 @@ + +/** + * Copyright (c) 2007, 2015, 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. + * + * 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. + */ + +import javax.security.auth.login.LoginContext; + +/** + * @test + * @bug 8050461 + * @summary Test should throw Configuration error if configuration file contains + * syntax error + * @build SampleLoginModule JAASConfigSyntaxTest + * @run main/othervm -Djava.security.auth.login.config=file:${test.src}/JAASSynWithOutApplication.config JAASConfigSyntaxTest + * @run main/othervm -Djava.security.auth.login.config=file:${test.src}/JAASSynWithOutBraces.config JAASConfigSyntaxTest + * @run main/othervm -Djava.security.auth.login.config=file:${test.src}/JAASSynWithOutFlag.config JAASConfigSyntaxTest + * @run main/othervm -Djava.security.auth.login.config=file:${test.src}/JAASSynWithOutLoginModule.config JAASConfigSyntaxTest + * @run main/othervm -Djava.security.auth.login.config=file:${test.src}/JAASSynWithOutSemiColen.config JAASConfigSyntaxTest + */ +public class JAASConfigSyntaxTest { + + private static final String TEST_NAME = "JAASConfigSyntaxTest"; + + public static void main(String[] args) throws Exception { + try { + LoginContext lc = new LoginContext(TEST_NAME); + lc.login(); + throw new RuntimeException("Test Case Failed, did not get " + + "expected exception"); + } catch (Exception ex) { + if (ex.getMessage().contains("java.io.IOException: " + + "Configuration Error:")) { + System.out.println("Test case passed"); + } else { + throw new RuntimeException(ex); + } + } + } +} diff --git a/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutApplication.config b/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutApplication.config new file mode 100644 index 0000000000000000000000000000000000000000..6a7219fc5032ee21875af1c35cf7a2c427d5c64f --- /dev/null +++ b/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutApplication.config @@ -0,0 +1,5 @@ +{ +SampleLoginModule Required; +SampleLoginModule Required; +SampleLoginModule Required; +}; \ No newline at end of file diff --git a/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutBraces.config b/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutBraces.config new file mode 100644 index 0000000000000000000000000000000000000000..75b62325fe92c26e5cd2212910e2d974031dde56 --- /dev/null +++ b/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutBraces.config @@ -0,0 +1,5 @@ +JAASConfigSyntaxTest +SampleLoginModule Required; +SampleLoginModule Required; +SampleLoginModule Required; +; \ No newline at end of file diff --git a/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutFlag.config b/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutFlag.config new file mode 100644 index 0000000000000000000000000000000000000000..a3d4b2b5b48de9cb096fad39c744009319474a32 --- /dev/null +++ b/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutFlag.config @@ -0,0 +1,5 @@ +JAASConfigSyntaxTest{ +SampleLoginModule ; +SampleLoginModule ; +SampleLoginModule ; +}; \ No newline at end of file diff --git a/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutLoginModule.config b/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutLoginModule.config new file mode 100644 index 0000000000000000000000000000000000000000..7315d02fe17e05a728d67c4622f7f5f2694281e5 --- /dev/null +++ b/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutLoginModule.config @@ -0,0 +1,5 @@ +JAASConfigSyntaxTest{ +; +; +; +}; \ No newline at end of file diff --git a/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutSemiColen.config b/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutSemiColen.config new file mode 100644 index 0000000000000000000000000000000000000000..4ccf602e49709028b429400ae83d41ebb6b736c5 --- /dev/null +++ b/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutSemiColen.config @@ -0,0 +1,5 @@ +JAASConfigSyntaxTest{ +SampleLoginModule Required; +SampleLoginModule Required +SampleLoginModule Required; +}; \ No newline at end of file diff --git a/test/javax/security/auth/login/JAASConfigSyntaxCheck/SampleLoginModule.java b/test/javax/security/auth/login/JAASConfigSyntaxCheck/SampleLoginModule.java new file mode 100644 index 0000000000000000000000000000000000000000..7df77b0fa19db6c71b7ed6dbc3b6e4c49d683d6e --- /dev/null +++ b/test/javax/security/auth/login/JAASConfigSyntaxCheck/SampleLoginModule.java @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2007, 2015, 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. + * + * 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. + */ + +import static java.lang.System.out; +import java.util.Map; +import javax.security.auth.Subject; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.login.LoginException; +import javax.security.auth.spi.LoginModule; + +/** + * Login module which passes all the time + */ + +public class SampleLoginModule implements LoginModule { + + private final String name; + + public SampleLoginModule() { + name = this.getClass().getName(); + } + + @Override + public void initialize(Subject subject, CallbackHandler callbackHandler, + Map sharedState, Map options) { + } + + @Override + public boolean login() throws LoginException { + out.println(name + " Login method of AbstractLoginModule is called "); + out.println(name + ":login:PASS"); + return true; + } + + @Override + public boolean commit() throws LoginException { + out.println("Commit of AbstractLoginModule is called"); + out.println(name + ":commit:PASS"); + return true; + + } + + @Override + public boolean abort() throws LoginException { + out.println("Abourt is called in AbstractLoginModule"); + out.println(name + ":abort:PASS"); + return true; + } + + @Override + public boolean logout() throws LoginException { + out.println("logout is called in AbstractLoginModule"); + out.println(name + ":logout:PASS"); + return true; + } +} diff --git a/test/javax/security/auth/login/LoginContext/CustomLoginModule.java b/test/javax/security/auth/login/LoginContext/CustomLoginModule.java new file mode 100644 index 0000000000000000000000000000000000000000..e47f3de56e7e6b643eda293fc1a010a51f4ee685 --- /dev/null +++ b/test/javax/security/auth/login/LoginContext/CustomLoginModule.java @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +import java.io.IOException; +import java.security.Principal; +import java.util.Arrays; +import java.util.Locale; +import java.util.Map; +import javax.security.auth.Subject; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.ChoiceCallback; +import javax.security.auth.callback.ConfirmationCallback; +import javax.security.auth.callback.LanguageCallback; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.TextInputCallback; +import javax.security.auth.callback.TextOutputCallback; +import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.auth.login.FailedLoginException; +import javax.security.auth.login.LoginException; +import javax.security.auth.spi.LoginModule; + +public class CustomLoginModule implements LoginModule { + + static final String HELLO = "Hello"; + + private Subject subject; + private CallbackHandler callbackHandler; + private boolean loginSucceeded = false; + private String username; + private char[] password; + + /* + * Initialize this LoginModule. + */ + @Override + public void initialize(Subject subject, CallbackHandler callbackHandler, + Map sharedState, Map options) { + this.subject = subject; + this.callbackHandler = callbackHandler; + + // check if custom parameter is passed from comfiguration + if (options == null) { + throw new RuntimeException("options is null"); + } + + // read username/password from configuration + Object o = options.get("username"); + if (o == null) { + throw new RuntimeException("Custom parameter not passed"); + } + if (!(o instanceof String)) { + throw new RuntimeException("Password is not a string"); + } + username = (String) o; + + o = options.get("password"); + if (o == null) { + throw new RuntimeException("Custom parameter not passed"); + } + if (!(o instanceof String)) { + throw new RuntimeException("Password is not a string"); + } + password = ((String) o).toCharArray(); + } + + /* + * Authenticate the user. + */ + @Override + public boolean login() throws LoginException { + // prompt for a user name and password + if (callbackHandler == null) { + throw new LoginException("No CallbackHandler available"); + } + + // standard callbacks + NameCallback name = new NameCallback("username: ", "default"); + PasswordCallback passwd = new PasswordCallback("password: ", false); + + LanguageCallback language = new LanguageCallback(); + + TextOutputCallback error = new TextOutputCallback( + TextOutputCallback.ERROR, "This is an error"); + TextOutputCallback warning = new TextOutputCallback( + TextOutputCallback.WARNING, "This is a warning"); + TextOutputCallback info = new TextOutputCallback( + TextOutputCallback.INFORMATION, "This is a FYI"); + + TextInputCallback text = new TextInputCallback("Please type " + HELLO, + "Bye"); + + ChoiceCallback choice = new ChoiceCallback("Choice: ", + new String[] { "pass", "fail" }, 1, true); + + ConfirmationCallback confirmation = new ConfirmationCallback( + "confirmation: ", ConfirmationCallback.INFORMATION, + ConfirmationCallback.YES_NO_OPTION, ConfirmationCallback.NO); + + CustomCallback custom = new CustomCallback(); + + Callback[] callbacks = new Callback[] { + choice, info, warning, error, name, passwd, text, language, + confirmation, custom + }; + + boolean uce = false; + try { + callbackHandler.handle(callbacks); + } catch (UnsupportedCallbackException e) { + Callback callback = e.getCallback(); + if (custom.equals(callback)) { + uce = true; + System.out.println("CustomLoginModule: " + + "custom callback not supported as expected"); + } else { + throw new LoginException("Unsupported callback: " + callback); + } + } catch (IOException ioe) { + throw new LoginException(ioe.toString()); + } + + if (!uce) { + throw new RuntimeException("UnsupportedCallbackException " + + "not thrown"); + } + + if (!HELLO.equals(text.getText())) { + System.out.println("Text: " + text.getText()); + throw new FailedLoginException("No hello"); + } + + if (!Locale.GERMANY.equals(language.getLocale())) { + System.out.println("Selected locale: " + language.getLocale()); + throw new FailedLoginException("Achtung bitte"); + } + + String readUsername = name.getName(); + char[] readPassword = passwd.getPassword(); + if (readPassword == null) { + // treat a NULL password as an empty password + readPassword = new char[0]; + } + passwd.clearPassword(); + + // verify the username/password + if (!username.equals(readUsername) + || !Arrays.equals(password, readPassword)) { + loginSucceeded = false; + throw new FailedLoginException("Username/password is not correct"); + } + + // check chosen option + int[] selected = choice.getSelectedIndexes(); + if (selected == null || selected.length == 0) { + throw new FailedLoginException("Nothing selected"); + } + + if (selected[0] != 0) { + throw new FailedLoginException("Wrong choice: " + selected[0]); + } + + // check confirmation + if (confirmation.getSelectedIndex() != ConfirmationCallback.YES) { + throw new FailedLoginException("Not confirmed: " + + confirmation.getSelectedIndex()); + } + + loginSucceeded = true; + System.out.println("CustomLoginModule: authentication succeeded"); + return true; + } + + /* + * This method is called if the LoginContext's overall authentication + * succeeded. + */ + @Override + public boolean commit() throws LoginException { + if (loginSucceeded) { + // add a Principal to the Subject + Principal principal = new TestPrincipal(username); + if (!subject.getPrincipals().contains(principal)) { + subject.getPrincipals().add(principal); + } + return true; + } + + return false; + } + + /* + * This method is called if the LoginContext's overall authentication + * failed. + */ + @Override + public boolean abort() throws LoginException { + loginSucceeded = false; + return true; + } + + /* + * Logout the user. + */ + @Override + public boolean logout() throws LoginException { + loginSucceeded = false; + boolean removed = subject.getPrincipals().remove( + new TestPrincipal(username)); + if (!removed) { + throw new LoginException("Coundn't remove a principal: " + + username); + } + return true; + } + + static class TestPrincipal implements Principal { + + private final String name; + + public TestPrincipal(String name) { + this.name = name; + } + + @Override + public String getName() { + return name; + } + + @Override + public String toString() { + return("TestPrincipal [name =" + name + "]"); + } + + @Override + public int hashCode() { + return name.hashCode(); + } + + @Override + public boolean equals(Object o) { + if (o == null) { + return false; + } + if (!(o instanceof TestPrincipal)) { + return false; + } + TestPrincipal other = (TestPrincipal) o; + return name != null ? name.equals(other.name) : other.name == null; + } + } + + static class CustomCallback implements Callback {} +} diff --git a/test/javax/security/auth/login/LoginContext/DummyLoginModule.java b/test/javax/security/auth/login/LoginContext/DummyLoginModule.java new file mode 100644 index 0000000000000000000000000000000000000000..ae0334d2d217811d7d7c5916ff0c6116d16e0b77 --- /dev/null +++ b/test/javax/security/auth/login/LoginContext/DummyLoginModule.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2004, 2015, 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. + * + * 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. + */ + +import javax.security.auth.login.LoginException; + +/** + * Login module which passes all the time + */ + +public class DummyLoginModule extends SmartLoginModule { + private final String header; + + public DummyLoginModule() { + header = "DummyLoginModule: "; + } + + @Override + public boolean login() throws LoginException { + System.out.println("\t\t" + header + " login method is called "); + System.out.println("\t\t" + header + " login:PASS"); + return true; + } + + @Override + public boolean commit() throws LoginException { + System.out.println("\t\t" + header + " commit method is called"); + System.out.println("\t\t" + header + " commit:PASS"); + return true; + } + + @Override + public boolean abort() throws LoginException { + System.out.println("\t\t" + header + " abort method is called "); + System.out.println("\t\t" + header + " abort:PASS"); + + return true; + } + + @Override + public boolean logout() throws LoginException { + System.out.println("\t\t" + header + " logout method is called"); + System.out.println("\t\t" + header + " logout:PASS"); + return true; + } + +} diff --git a/test/javax/security/auth/login/LoginContext/DynamicConfigurationTest.java b/test/javax/security/auth/login/LoginContext/DynamicConfigurationTest.java new file mode 100644 index 0000000000000000000000000000000000000000..c0491bbda33359f49510cc4beb208968cfa1202c --- /dev/null +++ b/test/javax/security/auth/login/LoginContext/DynamicConfigurationTest.java @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2004, 2015, 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. + * + * 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. + */ + +import java.io.IOException; +import javax.security.auth.Subject; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.auth.login.Configuration; +import javax.security.auth.login.LoginContext; +import javax.security.auth.login.LoginException; + +/** + * @test + * @bug 8050427 4703361 + * @summary Test case for RFE: 4703361. Tests the Dynamic Configuration of + * Authentication Modules with different methods + * @compile SmartLoginModule.java DummyLoginModule.java MyConfiguration.java + * @run main/othervm DynamicConfigurationTest + */ +public class DynamicConfigurationTest { + + public static void main(String... args) { + String rightConfigName = "PT"; + String wrongConfigName = "NT"; + char[] rightPwd = new char[]{'t', 'e', 's', 't', 'P', 'a', 's', 's', + 'w', 'o', 'r', 'd', '1'}; + char[] wrongPwd = new char[]{'w', 'r', 'o', 'n', 'g', 'P', 'a', 's', + 's','w', 'o', 'r', 'd'}; + + // Test with wrong configuration name + // Expect LoginException when initiate a new LoginContext object + testConfigName(wrongConfigName, true); + System.out.println("Wrong Config Name Test passed "); + + // Spedify two loginModules: SmartLoginModule and DummyLoginModule + // Flags: required-required + // Test with right password for SmartLoginModule + // No exception is expected + Configuration cf = new MyConfiguration(); + testLogin(rightConfigName, rightPwd, cf, false); + System.out.println("Positive test passed"); + + // Spedify two loginModules: SmartLoginModule and DummyLoginModule + // Flags: required-required + // Test with wrong password for SmartLoginModule + // Expect LoginException by calling LoginContext.login() method + testLogin(rightConfigName, wrongPwd, cf, true); + System.out.println("Should fail test passed"); + + // Spedify two loginModules: SmartLoginModule and DummyLoginModule + // Change the flags from required-required to optional-sufficient + // Test with wrong password for SmartLoginModule, while DummyLoginModule + // always passes + // No Exception is expected + cf = new MyConfiguration(true); + testLogin(rightConfigName, wrongPwd, cf, false); + System.out.println("One module fails where are other module succeeeds " + + "Test passed with optional-sufficient flags"); + } + + public static void testConfigName(String confName, + boolean expectException) { + String expectedMsg = "No LoginModules configured for " + confName; + try { + LoginContext lc = new LoginContext(confName, new Subject(), + new MyCallbackHandler(), new MyConfiguration()); + + if (expectException) { + throw new RuntimeException("Wrong Config Name Test failed: " + + "expected LoginException not thrown."); + } + } catch (LoginException le) { + if (!expectException || !le.getMessage().equals(expectedMsg)) { + System.out.println("Wrong Config Name Test failed: " + + "received Unexpected exception."); + throw new RuntimeException(le); + } + } + } + + public static void testLogin(String confName, char[] passwd, + Configuration cf, boolean expectException) { + try { + CallbackHandler ch = new MyCallbackHandler("testUser", passwd); + LoginContext lc = new LoginContext(confName, new Subject(), + ch, cf); + lc.login(); + if (expectException) { + throw new RuntimeException("Login Test failed: " + + "expected LoginException not thrown"); + } + } catch (LoginException le) { + if (!expectException) { + System.out.println("Login Test failed: " + + "received Unexpected exception."); + throw new RuntimeException(le); + } + } + } +} + +/** + * The application simulates the CallbackHandler. It simulates! which means all + * process to get username and password is ignored. We have to take this + * approach for automation purpose. So, this is not a real world example at all. + */ +class MyCallbackHandler implements CallbackHandler { + + String userName; + char[] password; + + /** + * This is simply a workaround approach for IO approach to get username and + * password. For automation purpose only. + */ + public MyCallbackHandler() { + super(); + } + + public MyCallbackHandler(String username, char[] password) { + super(); + userName = username; + this.password = password; + } + + @Override + public void handle(Callback[] callbacks) throws IOException, + UnsupportedCallbackException { + for (Callback callback : callbacks) { + if (callback instanceof NameCallback) { + NameCallback nc = (NameCallback) callback; + nc.setName(userName); + } else if (callback instanceof PasswordCallback) { + PasswordCallback pc = (PasswordCallback) callback; + pc.setPassword(password); + } else { + throw new UnsupportedCallbackException(callback, + "Unrecognized Callback"); + } + } + } +} diff --git a/test/javax/security/auth/login/LoginContext/LCTest.jaas.config b/test/javax/security/auth/login/LoginContext/LCTest.jaas.config new file mode 100644 index 0000000000000000000000000000000000000000..f63cff5b04b6512c60e60bf27721efd4d21f933b --- /dev/null +++ b/test/javax/security/auth/login/LoginContext/LCTest.jaas.config @@ -0,0 +1,57 @@ + +"AbortRequired" { + LCTest$LoginModuleAllPass required; + LCTest$LoginModuleWithLoginException required; + LCTest$LoginModuleAllPass required; +}; + +"AbortRequisite" { + LCTest$LoginModuleWithLoginException required; + LCTest$LoginModuleWithAbortException requisite; + LCTest$LoginModuleAllPass required; +}; + +"AbortSufficient" { + LCTest$LoginModuleWithLoginException required; + LCTest$LoginModuleWithLoginException sufficient; + LCTest$LoginModuleAllPass required; +}; + +"LogoutRequisite" { + LCTest$LoginModuleAllPass required; + LCTest$LoginModuleWithLogoutException requisite; + LCTest$LoginModuleAllPass required; +}; + +"LogoutSufficient" { + LCTest$LoginModuleAllPass required; + LCTest$LoginModuleWithLoginException sufficient; + LCTest$LoginModuleAllPass required; +}; + +"LogoutRequired" { + LCTest$LoginModuleWithLogoutException required; + LCTest$LoginModuleWithAbortException required; + LCTest$LoginModuleAllPass required; +}; + +"LoginRequired" { + LCTest$LoginModuleWithLoginException required; + LCTest$LoginModuleWithAbortException required; + LCTest$LoginModuleAllPass required; +}; + +"LoginSufficient" { + LCTest$LoginModuleAllPass required; + LCTest$LoginModuleWithLoginException sufficient; + LCTest$LoginModuleAllPass required; +}; + +"LoginRequisite" { + LCTest$LoginModuleWithLoginException required; + LCTest$LoginModuleWithAbortException requisite; + LCTest$LoginModuleAllPass required; +}; + +"EmptyModuleConfig" { +}; diff --git a/test/javax/security/auth/login/LoginContext/LCTest.java b/test/javax/security/auth/login/LoginContext/LCTest.java new file mode 100644 index 0000000000000000000000000000000000000000..e5eeb6c1d7f1801240a1803b0447678b694302e3 --- /dev/null +++ b/test/javax/security/auth/login/LoginContext/LCTest.java @@ -0,0 +1,337 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +import com.sun.security.auth.UnixPrincipal; + +import javax.security.auth.Subject; +import javax.security.auth.callback.*; +import javax.security.auth.login.FailedLoginException; +import javax.security.auth.login.LoginContext; +import javax.security.auth.login.LoginException; +import javax.security.auth.spi.LoginModule; +import java.io.IOException; +import java.security.Principal; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/* + * @test + * @bug 8050460 + * @summary Test checks that proper methods associated with login/logout process + * of LoginContext are called for different configurations and circumstances. + * @modules jdk.security.auth + * + * @run main/othervm LCTest EmptyModuleConfig false + * @run main/othervm LCTest IncorrectName false + * @run main/othervm LCTest AbortRequisite false abort + * @run main/othervm LCTest AbortSufficient false abort + * @run main/othervm LCTest AbortRequired false abort + * @run main/othervm LCTest LogoutRequisite false logout + * @run main/othervm LCTest LogoutSufficient true logout + * @run main/othervm LCTest LogoutRequired false logout + * @run main/othervm LCTest LoginRequisite false login + * @run main/othervm LCTest LoginSufficient true login + * @run main/othervm LCTest LoginRequired false login + */ + +public class LCTest { + + private static final String USER_NAME = "testUser"; + private static final String PASSWORD = "testPassword"; + private static final List loggedActions = new ArrayList<>(); + + static { + System.setProperty("java.security.auth.login.config", + System.getProperty("test.src") + + System.getProperty("file.separator") + + "LCTest.jaas.config"); + } + + public static void main(String[] args) { + if (args.length < 2) { + throw new RuntimeException("Incorrect test params"); + } + String nameOfContext = args[0]; + boolean isPositive = Boolean.parseBoolean(args[1]); + String actionName = null; + if (args.length == 3) { + actionName = args[2]; + } + try { + LoginContext lc = new LoginContext(nameOfContext, + new MyCallbackHandler()); + lc.login(); + checkPrincipal(lc, true); + lc.logout(); + checkPrincipal(lc, false); + if (!isPositive) { + throw new RuntimeException("Test failed. Exception expected."); + } + } catch (LoginException le) { + if (isPositive) { + throw new RuntimeException("Test failed. Unexpected " + + "exception", le); + } + System.out.println("Expected exception: " + + le.getMessage()); + } + checkActions(actionName); + System.out.println("Test passed."); + } + + /* + * Log action from login modules + */ + private static void logAction(String actionName) { + loggedActions.add(actionName); + } + + /* + * Check if logged actions are as expected. We always expected 3 actions + * if any. + */ + private static void checkActions(String actionName) { + if (actionName == null) { + if (loggedActions.size() != 0) { + throw new RuntimeException("No logged actions expected"); + } + } else { + int loggedActionsFound = 0; + System.out.println("Logged actions : " + loggedActions); + for (String s : loggedActions) { + if (s.equals(actionName)) { + loggedActionsFound++; + } + } + if (loggedActionsFound != 3) { + throw new RuntimeException("Incorrect number of actions " + + actionName + " : " + loggedActionsFound); + } + } + } + + /* + * Check context for principal of the test user. + */ + private static void checkPrincipal(LoginContext loginContext, boolean + principalShouldExist) { + if (!principalShouldExist) { + if (loginContext.getSubject().getPrincipals().size() != 0) { + throw new RuntimeException("Test failed. Principal was not " + + "cleared."); + } + } else { + for (Principal p : loginContext.getSubject().getPrincipals()) { + if (p instanceof UnixPrincipal && + USER_NAME.equals(p.getName())) { + //Proper principal was found, return. + return; + } + } + throw new RuntimeException("Test failed. UnixPrincipal " + + USER_NAME + " expected."); + } + } + + private static class MyCallbackHandler implements CallbackHandler { + + @Override + public void handle(Callback[] callbacks) throws IOException, + UnsupportedCallbackException { + for (Callback callback : callbacks) { + if (callback instanceof NameCallback) { + ((NameCallback) callback).setName(USER_NAME); + } else if (callback instanceof PasswordCallback) { + ((PasswordCallback) callback).setPassword( + PASSWORD.toCharArray()); + } else { + throw new UnsupportedCallbackException(callback); + } + } + } + } + + /* ------------------------------------------------------------------------- + * Test login modules + * ------------------------------------------------------------------------- + */ + + /* + * Login module that should pass through all phases. + */ + public static class LoginModuleAllPass extends LoginModuleBase { + + } + + /* + * Login module that throws Exception in abort method. + */ + public static class LoginModuleWithAbortException extends LoginModuleBase { + + @Override + public boolean abort() throws LoginException { + super.abort(); + throw new LoginException("Abort failed!"); + } + } + + /* + * Login module that throws Exception in login method. + */ + public static class LoginModuleWithLoginException extends LoginModuleBase { + + @Override + public boolean login() throws LoginException { + super.login(); + throw new FailedLoginException("Login failed!"); + } + } + + /* + * Login module that throws Exception in logout method. + */ + public static class LoginModuleWithLogoutException extends LoginModuleBase { + + @Override + public boolean logout() throws LoginException { + super.logout(); + throw new FailedLoginException("Logout failed!"); + } + } + + /* + * Base class for login modules + */ + public static abstract class LoginModuleBase implements LoginModule { + // initial state + private Subject subject; + private CallbackHandler callbackHandler; + private Map sharedState; + private Map options; + private UnixPrincipal userPrincipal; + + // username and password + private String username; + private String password; + + // the authentication status + private boolean succeeded = false; + private boolean commitSucceeded = false; + + @Override + public void initialize(Subject subject, CallbackHandler callbackHandler, + Map sharedState, Map options) { + + this.subject = subject; + this.callbackHandler = callbackHandler; + this.sharedState = sharedState; + this.options = options; + System.out.println("Login module initialized."); + } + + /* + * Authenticate the user by prompting for a username and password. + */ + @Override + public boolean login() throws LoginException { + LCTest.logAction("login"); + if (callbackHandler == null) { + throw new LoginException("No CallbackHandler available"); + } + + Callback[] callbacks = new Callback[2]; + callbacks[0] = new NameCallback("Username: "); + callbacks[1] = new PasswordCallback("Password: ", false); + + try { + callbackHandler.handle(callbacks); + username = ((NameCallback) callbacks[0]).getName(); + password = new String(((PasswordCallback) callbacks[1]) + .getPassword()); + if (username.equals(LCTest.USER_NAME) && + password.equals(LCTest.PASSWORD)) { + succeeded = true; + return true; + } + throw new FailedLoginException("Incorrect username/password!"); + } catch (IOException | UnsupportedCallbackException e) { + throw new LoginException("Login failed: " + e.getMessage()); + } + } + + @Override + public boolean commit() throws LoginException { + LCTest.logAction("commit"); + if (succeeded == false) { + return false; + } + userPrincipal = new UnixPrincipal(username); + final Subject s = subject; + final UnixPrincipal up = userPrincipal; + java.security.AccessController.doPrivileged + ((java.security.PrivilegedAction) () -> { + if (!s.getPrincipals().contains(up)) { + s.getPrincipals().add(up); + } + return null; + }); + password = null; + commitSucceeded = true; + return true; + } + + @Override + public boolean abort() throws LoginException { + LCTest.logAction("abort"); + if (succeeded == false) { + return false; + } + clearState(); + return true; + } + + @Override + public boolean logout() throws LoginException { + LCTest.logAction("logout"); + clearState(); + return true; + } + + private void clearState() { + if (commitSucceeded) { + final Subject s = subject; + final UnixPrincipal up = userPrincipal; + java.security.AccessController.doPrivileged + ((java.security.PrivilegedAction) () -> { + s.getPrincipals().remove(up); + return null; + }); + } + username = null; + password = null; + userPrincipal = null; + } + } + +} diff --git a/test/javax/security/auth/login/LoginContext/MyConfiguration.java b/test/javax/security/auth/login/LoginContext/MyConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..5077279e7a9b47392914b3cfae8f9a4f69076271 --- /dev/null +++ b/test/javax/security/auth/login/LoginContext/MyConfiguration.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2004, 2015, 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. + * + * 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. + */ + +import java.util.HashMap; +import javax.security.auth.login.AppConfigurationEntry; +import static javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag.OPTIONAL; +import static javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag.REQUIRED; +import static javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT; +import javax.security.auth.login.Configuration; + +/** + * This class is used to test LoginContext constructor API. It simply contains + * one configuration entry: PT. + */ +public class MyConfiguration extends Configuration { + + private static final AppConfigurationEntry[] ptAE + = new AppConfigurationEntry[2]; + private static final HashMap map = new HashMap<>(); + private boolean optionOrder = false; + + public MyConfiguration() { + setupConfiguration(); + } + + public MyConfiguration(boolean optionOrder) { + this.optionOrder = optionOrder; + setupConfiguration(); + } + + private void setupConfiguration() { + ptAE[0] = new AppConfigurationEntry("SmartLoginModule", + optionOrder ? OPTIONAL : REQUIRED, + map); + ptAE[1] = new AppConfigurationEntry("DummyLoginModule", + optionOrder ? SUFFICIENT : REQUIRED, + map); + } + + @Override + public AppConfigurationEntry[] + getAppConfigurationEntry(String applicationName) { + if (applicationName.equals("PT")) { + return ptAE; + } else { + return null; + } + } + +} diff --git a/test/javax/security/auth/login/LoginContext/SharedState.java b/test/javax/security/auth/login/LoginContext/SharedState.java new file mode 100644 index 0000000000000000000000000000000000000000..d944e5a46db673aef8976006af06d24009d81b8e --- /dev/null +++ b/test/javax/security/auth/login/LoginContext/SharedState.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +import java.util.Map; +import javax.security.auth.Subject; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.login.LoginContext; +import javax.security.auth.login.LoginException; +import javax.security.auth.spi.LoginModule; + +/** + * @test + * @bug 8048138 + * @summary Check if shared state is passed to login module + * @run main/othervm SharedState + */ +public class SharedState { + + static final String NAME = "name"; + static final String VALUE = "shared"; + + public static void main(String[] args) throws LoginException { + System.setProperty("java.security.auth.login.config", + System.getProperty("test.src") + + System.getProperty("file.separator") + + "shared.config"); + + new LoginContext("SharedState").login(); + } + + public static abstract class Module implements LoginModule { + + @Override + public boolean login() throws LoginException { + return true; + } + + @Override + public boolean commit() throws LoginException { + return true; + } + + @Override + public boolean abort() throws LoginException { + return true; + } + + @Override + public boolean logout() throws LoginException { + return true; + } + } + + public static class FirstModule extends Module { + + @Override + public void initialize(Subject subject, CallbackHandler callbackHandler, + Map sharedState, Map options) { + ((Map)sharedState).put(NAME, VALUE); + } + + } + + public static class SecondModule extends Module { + + @Override + public void initialize(Subject subject, CallbackHandler callbackHandler, + Map sharedState, Map options) { + // check shared object + Object shared = sharedState.get(NAME); + if (!VALUE.equals(shared)) { + throw new RuntimeException("Unexpected shared object: " + + shared); + } + } + + } +} diff --git a/test/javax/security/auth/login/LoginContext/SmartLoginModule.java b/test/javax/security/auth/login/LoginContext/SmartLoginModule.java new file mode 100644 index 0000000000000000000000000000000000000000..aa43ea63caaadd2676d4b3865d80214988b29921 --- /dev/null +++ b/test/javax/security/auth/login/LoginContext/SmartLoginModule.java @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2004, 2015, 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. + * + * 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. + */ + +import java.security.Principal; +import java.util.Arrays; +import java.util.Map; +import javax.security.auth.Subject; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.auth.login.FailedLoginException; +import javax.security.auth.login.LoginException; +import javax.security.auth.spi.LoginModule; + +/** + * This code was based on JAAS demo code, small modification is made for testing + * purpose. + */ +public class SmartLoginModule implements LoginModule { + + // initial state + private Subject subject; + private CallbackHandler callbackHandler; + + // the authentication status + private boolean succeeded = false; + private boolean commitSucceeded = false; + + // username and password + private String username; + private char[] password; + + // Default values for this login module. In real world, + // don't do it in this way! + private String myUsername; + private char[] myPassword; + private String header; + + // testUser's SamplePrincipal + private SamplePrincipal userPrincipal; + + public SmartLoginModule() { + this("testUser", + new char[]{'t', 'e', 's', 't', 'P', 'a', 's', 's', + 'w', 'o', 'r', 'd', '1'}, + "SmartLoginModule1: "); + } + + public SmartLoginModule(String userName, char[] password, String header) { + myUsername = userName; + myPassword = password; + this.header = header; + } + + @Override + public boolean abort() throws LoginException { + if (!succeeded) { + return false; + } else if (succeeded && !commitSucceeded) { + // login succeeded but overall authentication failed + succeeded = false; + username = null; + password = null; + userPrincipal = null; + } else { + // overall authentication succeeded and commit succeeded, + // but someone else's commit failed + logout(); + } + return true; + } + + @Override + public boolean commit() throws LoginException { + if (!succeeded) { + return false; + } else { + // add a Principal (authenticated identity) to the Subject + // assume the user we authenticated is the SamplePrincipal + userPrincipal = new SamplePrincipal(username); + if (!subject.getPrincipals().contains(userPrincipal)) { + subject.getPrincipals().add(userPrincipal); + } + // in any case, clean out state + username = null; + password = null; + commitSucceeded = true; + return true; + } + } + + @Override + public void initialize(Subject subject, CallbackHandler callbackHandler, + Map sharedState, Map options) { + this.subject = subject; + this.callbackHandler = callbackHandler; + } + + @Override + public boolean login() throws LoginException { + if (callbackHandler == null) { + throw new LoginException("Error: no CallbackHandler available to " + + "garner authentication information from the user"); + } + + Callback[] callbacks = new Callback[2]; + callbacks[0] = new NameCallback(header + "user name: "); + callbacks[1] = new PasswordCallback(header + "password: ", false); + + try { + callbackHandler.handle(callbacks); + username = ((NameCallback) callbacks[0]).getName(); + char[] tmpPassword + = ((PasswordCallback) callbacks[1]).getPassword(); + if (tmpPassword == null) { + tmpPassword = new char[0]; + } + password = new char[tmpPassword.length]; + System.arraycopy(tmpPassword, 0, password, 0, tmpPassword.length); + ((PasswordCallback) callbacks[1]).clearPassword(); + } catch (java.io.IOException ioe) { + throw (LoginException) new LoginException().initCause(ioe); + } catch (UnsupportedCallbackException uce) { + throw new LoginException("Error: " + header + + uce.getCallback().toString() + + " not available to garner authentication information " + + "from the user"); + } + + // verify the username/password + if (username.equals(myUsername) + && Arrays.equals(password, myPassword)) { + System.out.println("\t\t" + header + " authentication succeeded"); + succeeded = true; + return true; + } else { + // authentication failed -- clean out state + System.out.println("\t\t" + header + " authentication failed"); + printDebugInfo(); + succeeded = false; + username = null; + password = null; + throw new FailedLoginException("User Name or Password Incorrect"); + } + } + + @Override + public boolean logout() throws LoginException { + subject.getPrincipals().remove(userPrincipal); + succeeded = false; + succeeded = commitSucceeded; + username = null; + password = null; + userPrincipal = null; + return true; + } + + // print debugging information + private void printDebugInfo() { + System.out.println("\t\t" + header + " correct user name: " + + myUsername); + System.out.println("\t\t" + header + " user entered user name: " + + username); + System.out.print("\t\t" + header + " correct password: "); + for (char c : myPassword) { + System.out.print(c); + } + System.out.println(); + System.out.print("\t\t" + header + " user entered password: "); + for (char c : password) { + System.out.print(c); + } + System.out.println(); + } +} + +class SamplePrincipal implements Principal, java.io.Serializable { + + /** + * @serial + */ + private String name; + + /** + * Create a SamplePrincipal with a Sample username. + * + * @param name the Sample username for this user. + * @exception NullPointerException if the name is + * null. + */ + public SamplePrincipal(String name) { + if (name == null) { + throw new NullPointerException("illegal null input"); + } + + this.name = name; + } + + @Override + public String getName() { + return name; + } + + @Override + public String toString() { + return "SamplePrincipal: " + name; + } + + @Override + public boolean equals(Object o) { + if (o == null) { + return false; + } + + if (this == o) { + return true; + } + + if (!(o instanceof SamplePrincipal)) { + return false; + } + SamplePrincipal that = (SamplePrincipal) o; + + return this.getName().equals(that.getName()); + } + + @Override + public int hashCode() { + return name.hashCode(); + } +} diff --git a/test/javax/security/auth/login/LoginContext/StandardCallbacks.java b/test/javax/security/auth/login/LoginContext/StandardCallbacks.java new file mode 100644 index 0000000000000000000000000000000000000000..4b69f84cdbf5cab1d6f2b955861e9fe0aa909b2d --- /dev/null +++ b/test/javax/security/auth/login/LoginContext/StandardCallbacks.java @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +import java.security.Principal; +import java.util.Arrays; +import java.util.Locale; +import javax.security.auth.Subject; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.ChoiceCallback; +import javax.security.auth.callback.ConfirmationCallback; +import javax.security.auth.callback.LanguageCallback; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.TextInputCallback; +import javax.security.auth.callback.TextOutputCallback; +import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.auth.login.LoginContext; +import javax.security.auth.login.LoginException; + +/* + * @test + * @bug 8048138 + * @summary Checks if JAAS login works fine with standard callbacks + * @compile DefaultHandlerModule.java + * @run main/othervm StandardCallbacks + */ +public class StandardCallbacks { + + private static final String USERNAME = "username"; + private static final char[] PASSWORD = "password".toCharArray(); + + public static void main(String[] args) throws LoginException { + System.setProperty("java.security.auth.login.config", + System.getProperty("test.src") + + System.getProperty("file.separator") + + "custom.config"); + + CustomCallbackHandler handler = new CustomCallbackHandler(USERNAME); + LoginContext context = new LoginContext("StandardCallbacks", handler); + + handler.setPassword(PASSWORD); + System.out.println("Try to login with correct password, " + + "successful authentication is expected"); + context.login(); + System.out.println("Authentication succeeded!"); + + Subject subject = context.getSubject(); + System.out.println("Authenticated user has the following principals [" + + subject.getPrincipals().size() + " ]:"); + boolean found = true; + for (Principal principal : subject.getPrincipals()) { + System.out.println("principal: " + principal); + if (principal instanceof CustomLoginModule.TestPrincipal) { + CustomLoginModule.TestPrincipal testPrincipal = + (CustomLoginModule.TestPrincipal) principal; + if (USERNAME.equals(testPrincipal.getName())) { + System.out.println("Found test principal: " + + testPrincipal); + found = true; + break; + } + } + } + + if (!found) { + throw new RuntimeException("TestPrincipal not found"); + } + + // check if all expected text output callbacks have been called + if (!handler.info) { + throw new RuntimeException("TextOutputCallback.INFO not called"); + } + + if (!handler.warning) { + throw new RuntimeException("TextOutputCallback.WARNING not called"); + } + + if (!handler.error) { + throw new RuntimeException("TextOutputCallback.ERROR not called"); + } + + System.out.println("Authenticated user has the following public " + + "credentials [" + subject.getPublicCredentials().size() + + "]:"); + subject.getPublicCredentials().stream(). + forEach((o) -> { + System.out.println("public credential: " + o); + }); + + context.logout(); + + System.out.println("Test passed"); + } + + private static class CustomCallbackHandler implements CallbackHandler { + + private final String username; + private char[] password; + private boolean info = false; + private boolean warning = false; + private boolean error = false; + + CustomCallbackHandler(String username) { + this.username = username; + } + + void setPassword(char[] password) { + this.password = password; + } + + @Override + public void handle(Callback[] callbacks) + throws UnsupportedCallbackException { + for (Callback callback : callbacks) { + if (callback instanceof TextOutputCallback) { + TextOutputCallback toc = (TextOutputCallback) callback; + switch (toc.getMessageType()) { + case TextOutputCallback.INFORMATION: + System.out.println("INFO: " + toc.getMessage()); + info = true; + break; + case TextOutputCallback.ERROR: + System.out.println("ERROR: " + toc.getMessage()); + error = true; + break; + case TextOutputCallback.WARNING: + System.out.println("WARNING: " + toc.getMessage()); + warning = true; + break; + default: + throw new UnsupportedCallbackException(toc, + "Unsupported message type: " + + toc.getMessageType()); + } + } else if (callback instanceof TextInputCallback) { + TextInputCallback tic = (TextInputCallback) callback; + System.out.println(tic.getPrompt()); + tic.setText(CustomLoginModule.HELLO); + } else if (callback instanceof LanguageCallback) { + LanguageCallback lc = (LanguageCallback) callback; + lc.setLocale(Locale.GERMANY); + } else if (callback instanceof ConfirmationCallback) { + ConfirmationCallback cc = (ConfirmationCallback) callback; + System.out.println(cc.getPrompt()); + cc.setSelectedIndex(ConfirmationCallback.YES); + } else if (callback instanceof ChoiceCallback) { + ChoiceCallback cc = (ChoiceCallback) callback; + System.out.println(cc.getPrompt() + + Arrays.toString(cc.getChoices())); + cc.setSelectedIndex(0); + } else if (callback instanceof NameCallback) { + NameCallback nc = (NameCallback) callback; + System.out.println(nc.getPrompt()); + nc.setName(username); + } else if (callback instanceof PasswordCallback) { + PasswordCallback pc = (PasswordCallback) callback; + System.out.println(pc.getPrompt()); + pc.setPassword(password); + } else { + throw new UnsupportedCallbackException(callback, + "Unknown callback"); + } + } + } + + } + +} diff --git a/test/javax/security/auth/login/LoginContext/custom.config b/test/javax/security/auth/login/LoginContext/custom.config new file mode 100644 index 0000000000000000000000000000000000000000..6ecdc56e928e2fbdf2ec8dba5e0fa1c74eca3a8a --- /dev/null +++ b/test/javax/security/auth/login/LoginContext/custom.config @@ -0,0 +1,4 @@ +StandardCallbacks { + DefaultHandlerModule required; + CustomLoginModule required username="username" password="password"; +}; diff --git a/test/javax/security/auth/login/LoginContext/shared.config b/test/javax/security/auth/login/LoginContext/shared.config new file mode 100644 index 0000000000000000000000000000000000000000..86201e224358fecda3cad73ae8e2d17251b83cee --- /dev/null +++ b/test/javax/security/auth/login/LoginContext/shared.config @@ -0,0 +1,4 @@ +SharedState { + SharedState$FirstModule required; + SharedState$SecondModule required; +}; \ No newline at end of file diff --git a/test/javax/security/sasl/Sasl/ClientServerTest.java b/test/javax/security/sasl/Sasl/ClientServerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..5d1222ad3426867ee88bc2fd5b2b7acb12fe98de --- /dev/null +++ b/test/javax/security/sasl/Sasl/ClientServerTest.java @@ -0,0 +1,477 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +import java.io.Closeable; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.StringJoiner; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.sasl.AuthorizeCallback; +import javax.security.sasl.RealmCallback; +import javax.security.sasl.RealmChoiceCallback; +import javax.security.sasl.Sasl; +import javax.security.sasl.SaslClient; +import javax.security.sasl.SaslException; +import javax.security.sasl.SaslServer; + +/* + * @test + * @bug 8049814 + * @summary JAVA SASL server and client tests with CRAM-MD5 and + * DIGEST-MD5 mechanisms. The tests try different QOP values on + * client and server side. + * @modules java.security.sasl/javax.security.sasl + */ +public class ClientServerTest { + + private static final int DELAY = 100; + private static final String LOCALHOST = "localhost"; + private static final String DIGEST_MD5 = "DIGEST-MD5"; + private static final String CRAM_MD5 = "CRAM-MD5"; + private static final String PROTOCOL = "saslservice"; + private static final String USER_ID = "sasltester"; + private static final String PASSWD = "password"; + private static final String QOP_AUTH = "auth"; + private static final String QOP_AUTH_CONF = "auth-conf"; + private static final String QOP_AUTH_INT = "auth-int"; + private static final String AUTHID_SASL_TESTER = "sasl_tester"; + private static final ArrayList SUPPORT_MECHS = new ArrayList<>(); + + static { + SUPPORT_MECHS.add(DIGEST_MD5); + SUPPORT_MECHS.add(CRAM_MD5); + } + + public static void main(String[] args) throws Exception { + String[] allQops = { QOP_AUTH_CONF, QOP_AUTH_INT, QOP_AUTH }; + String[] twoQops = { QOP_AUTH_INT, QOP_AUTH }; + String[] authQop = { QOP_AUTH }; + String[] authIntQop = { QOP_AUTH_INT }; + String[] authConfQop = { QOP_AUTH_CONF }; + String[] emptyQop = {}; + + boolean success = true; + + success &= runTest("", CRAM_MD5, new String[] { QOP_AUTH }, + new String[] { QOP_AUTH }, false); + success &= runTest("", DIGEST_MD5, new String[] { QOP_AUTH }, + new String[] { QOP_AUTH }, false); + success &= runTest(AUTHID_SASL_TESTER, DIGEST_MD5, + new String[] { QOP_AUTH }, new String[] { QOP_AUTH }, false); + success &= runTest("", DIGEST_MD5, allQops, authQop, false); + success &= runTest("", DIGEST_MD5, allQops, authIntQop, false); + success &= runTest("", DIGEST_MD5, allQops, authConfQop, false); + success &= runTest("", DIGEST_MD5, twoQops, authQop, false); + success &= runTest("", DIGEST_MD5, twoQops, authIntQop, false); + success &= runTest("", DIGEST_MD5, twoQops, authConfQop, true); + success &= runTest("", DIGEST_MD5, authIntQop, authQop, true); + success &= runTest("", DIGEST_MD5, authConfQop, authQop, true); + success &= runTest("", DIGEST_MD5, authConfQop, emptyQop, true); + success &= runTest("", DIGEST_MD5, authIntQop, emptyQop, true); + success &= runTest("", DIGEST_MD5, authQop, emptyQop, true); + + if (!success) { + throw new RuntimeException("At least one test case failed"); + } + + System.out.println("Test passed"); + } + + private static boolean runTest(String authId, String mech, + String[] clientQops, String[] serverQops, boolean expectException) + throws Exception { + + System.out.println("AuthId:" + authId + + " mechanism:" + mech + + " clientQops: " + Arrays.toString(clientQops) + + " serverQops: " + Arrays.toString(serverQops) + + " expect exception:" + expectException); + + try (Server server = Server.start(LOCALHOST, authId, serverQops)) { + new Client(LOCALHOST, server.getPort(), mech, authId, clientQops) + .run(); + if (expectException) { + System.out.println("Expected exception not thrown"); + return false; + } + } catch (SaslException e) { + if (!expectException) { + System.out.println("Unexpected exception: " + e); + return false; + } + System.out.println("Expected exception: " + e); + } + + return true; + } + + static enum SaslStatus { + SUCCESS, FAILURE, CONTINUE + } + + static class Message implements Serializable { + + private final SaslStatus status; + private final byte[] data; + + public Message(SaslStatus status, byte[] data) { + this.status = status; + this.data = data; + } + + public SaslStatus getStatus() { + return status; + } + + public byte[] getData() { + return data; + } + } + + static class SaslPeer { + + final String host; + final String mechanism; + final String qop; + final CallbackHandler callback; + + SaslPeer(String host, String authId, String... qops) { + this(host, null, authId, qops); + } + + SaslPeer(String host, String mechanism, String authId, String... qops) { + this.host = host; + this.mechanism = mechanism; + + StringJoiner sj = new StringJoiner(","); + for (String q : qops) { + sj.add(q); + } + qop = sj.toString(); + + callback = new TestCallbackHandler(USER_ID, PASSWD, host, authId); + } + + Message getMessage(Object ob) { + if (!(ob instanceof Message)) { + throw new RuntimeException("Expected an instance of Message"); + } + return (Message) ob; + } + } + + static class Server extends SaslPeer implements Runnable, Closeable { + + private volatile boolean ready = false; + private volatile ServerSocket ssocket; + + static Server start(String host, String authId, String[] serverQops) + throws UnknownHostException { + Server server = new Server(host, authId, serverQops); + Thread thread = new Thread(server); + thread.setDaemon(true); + thread.start(); + + while (!server.ready) { + try { + Thread.sleep(DELAY); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + + return server; + } + + Server(String host, String authId, String... qops) { + super(host, authId, qops); + } + + int getPort() { + return ssocket.getLocalPort(); + } + + private void processConnection(SaslEndpoint endpoint) + throws SaslException, IOException, ClassNotFoundException { + System.out.println("process connection"); + endpoint.send(SUPPORT_MECHS); + Object o = endpoint.receive(); + if (!(o instanceof String)) { + throw new RuntimeException("Received unexpected object: " + o); + } + String mech = (String) o; + SaslServer saslServer = createSaslServer(mech); + Message msg = getMessage(endpoint.receive()); + while (!saslServer.isComplete()) { + byte[] data = processData(msg.getData(), endpoint, + saslServer); + if (saslServer.isComplete()) { + System.out.println("server is complete"); + endpoint.send(new Message(SaslStatus.SUCCESS, data)); + } else { + System.out.println("server continues"); + endpoint.send(new Message(SaslStatus.CONTINUE, data)); + msg = getMessage(endpoint.receive()); + } + } + } + + private byte[] processData(byte[] data, SaslEndpoint endpoint, + SaslServer server) throws SaslException, IOException { + try { + return server.evaluateResponse(data); + } catch (SaslException e) { + endpoint.send(new Message(SaslStatus.FAILURE, null)); + System.out.println("Error while processing data"); + throw e; + } + } + + private SaslServer createSaslServer(String mechanism) + throws SaslException { + Map props = new HashMap<>(); + props.put(Sasl.QOP, qop); + return Sasl.createSaslServer(mechanism, PROTOCOL, host, props, + callback); + } + + @Override + public void run() { + try (ServerSocket ss = new ServerSocket(0)) { + ssocket = ss; + System.out.println("server started on port " + getPort()); + ready = true; + Socket socket = ss.accept(); + try (SaslEndpoint endpoint = new SaslEndpoint(socket)) { + System.out.println("server accepted connection"); + processConnection(endpoint); + } + } catch (Exception e) { + // ignore it for now, client will throw an exception + } + } + + @Override + public void close() throws IOException { + if (!ssocket.isClosed()) { + ssocket.close(); + } + } + } + + static class Client extends SaslPeer { + + private final int port; + + Client(String host, int port, String mech, String authId, + String... qops) { + super(host, mech, authId, qops); + this.port = port; + } + + public void run() throws Exception { + System.out.println("Host:" + host + " port: " + + port); + try (SaslEndpoint endpoint = SaslEndpoint.create(host, port)) { + negotiateMechanism(endpoint); + SaslClient client = createSaslClient(); + byte[] data = new byte[0]; + if (client.hasInitialResponse()) { + data = client.evaluateChallenge(data); + } + endpoint.send(new Message(SaslStatus.CONTINUE, data)); + Message msg = getMessage(endpoint.receive()); + while (!client.isComplete() + && msg.getStatus() != SaslStatus.FAILURE) { + switch (msg.getStatus()) { + case CONTINUE: + System.out.println("client continues"); + data = client.evaluateChallenge(msg.getData()); + endpoint.send(new Message(SaslStatus.CONTINUE, + data)); + msg = getMessage(endpoint.receive()); + break; + case SUCCESS: + System.out.println("client succeeded"); + data = client.evaluateChallenge(msg.getData()); + if (data != null) { + throw new SaslException("data should be null"); + } + break; + default: + throw new RuntimeException("Wrong status:" + + msg.getStatus()); + } + } + + if (msg.getStatus() == SaslStatus.FAILURE) { + throw new RuntimeException("Status is FAILURE"); + } + } + + System.out.println("Done"); + } + + private SaslClient createSaslClient() throws SaslException { + Map props = new HashMap<>(); + props.put(Sasl.QOP, qop); + return Sasl.createSaslClient(new String[] {mechanism}, USER_ID, + PROTOCOL, host, props, callback); + } + + private void negotiateMechanism(SaslEndpoint endpoint) + throws ClassNotFoundException, IOException { + Object o = endpoint.receive(); + if (o instanceof ArrayList) { + ArrayList list = (ArrayList) o; + if (!list.contains(mechanism)) { + throw new RuntimeException( + "Server does not support specified mechanism:" + + mechanism); + } + } else { + throw new RuntimeException( + "Expected an instance of ArrayList, but received " + o); + } + + endpoint.send(mechanism); + } + + } + + static class SaslEndpoint implements AutoCloseable { + + private final Socket socket; + private ObjectInputStream input; + private ObjectOutputStream output; + + static SaslEndpoint create(String host, int port) throws IOException { + return new SaslEndpoint(new Socket(host, port)); + } + + SaslEndpoint(Socket socket) throws IOException { + this.socket = socket; + } + + private ObjectInputStream getInput() throws IOException { + if (input == null && socket != null) { + input = new ObjectInputStream(socket.getInputStream()); + } + return input; + } + + private ObjectOutputStream getOutput() throws IOException { + if (output == null && socket != null) { + output = new ObjectOutputStream(socket.getOutputStream()); + } + return output; + } + + public Object receive() throws IOException, ClassNotFoundException { + return getInput().readObject(); + } + + public void send(Object obj) throws IOException { + getOutput().writeObject(obj); + getOutput().flush(); + } + + @Override + public void close() throws IOException { + if (socket != null && !socket.isClosed()) { + socket.close(); + } + } + + } + + static class TestCallbackHandler implements CallbackHandler { + + private final String userId; + private final char[] passwd; + private final String realm; + private String authId; + + TestCallbackHandler(String userId, String passwd, String realm, + String authId) { + this.userId = userId; + this.passwd = passwd.toCharArray(); + this.realm = realm; + this.authId = authId; + } + + @Override + public void handle(Callback[] callbacks) throws IOException, + UnsupportedCallbackException { + for (Callback callback : callbacks) { + if (callback instanceof NameCallback) { + System.out.println("NameCallback"); + ((NameCallback) callback).setName(userId); + } else if (callback instanceof PasswordCallback) { + System.out.println("PasswordCallback"); + ((PasswordCallback) callback).setPassword(passwd); + } else if (callback instanceof RealmCallback) { + System.out.println("RealmCallback"); + ((RealmCallback) callback).setText(realm); + } else if (callback instanceof RealmChoiceCallback) { + System.out.println("RealmChoiceCallback"); + RealmChoiceCallback choice = (RealmChoiceCallback) callback; + if (realm == null) { + choice.setSelectedIndex(choice.getDefaultChoice()); + } else { + String[] choices = choice.getChoices(); + for (int j = 0; j < choices.length; j++) { + if (realm.equals(choices[j])) { + choice.setSelectedIndex(j); + break; + } + } + } + } else if (callback instanceof AuthorizeCallback) { + System.out.println("AuthorizeCallback"); + ((AuthorizeCallback) callback).setAuthorized(true); + if (authId == null || authId.trim().length() == 0) { + authId = userId; + } + ((AuthorizeCallback) callback).setAuthorizedID(authId); + } else { + throw new UnsupportedCallbackException(callback); + } + } + } + } + +} diff --git a/test/javax/xml/bind/jxc/8073872/Foo.java b/test/javax/xml/bind/jxc/8073872/Foo.java new file mode 100644 index 0000000000000000000000000000000000000000..9a2e3d60b53c1089b9cfd3a6672a2bc61aca7415 --- /dev/null +++ b/test/javax/xml/bind/jxc/8073872/Foo.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2016, 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. + * + * 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. + */ + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = {"fooObject"}) +@XmlRootElement(name = "Foo") + +public class Foo { + + protected List fooObject; + + public List getFooObject() { + if (fooObject == null) { + fooObject = new ArrayList(); + } + return this.fooObject; + } +} diff --git a/test/javax/xml/bind/jxc/8073872/SchemagenStackOverflow.java b/test/javax/xml/bind/jxc/8073872/SchemagenStackOverflow.java new file mode 100644 index 0000000000000000000000000000000000000000..695fdefaae69cc05cc7d5cc33af624dfa0853e73 --- /dev/null +++ b/test/javax/xml/bind/jxc/8073872/SchemagenStackOverflow.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2016, 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. + * + * 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. + */ + +/* + * @test + * @bug 8073872 + * @summary test that stackoverflow is not observable when element + * references containing class + * @compile Foo.java + * @run testng/othervm SchemagenStackOverflow + */ + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.stream.Collectors; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.SchemaOutputResolver; +import javax.xml.transform.Result; +import javax.xml.transform.stream.StreamResult; +import org.testng.Assert; +import org.testng.annotations.Test; + +public class SchemagenStackOverflow { + + @Test + public void schemagenStackOverflowTest() throws Exception { + // Create new instance of JAXB context + JAXBContext context = JAXBContext.newInstance(Foo.class); + context.generateSchema(new TestOutputResolver()); + + // Read schema content from file + String content = Files.lines(resultSchemaFile).collect(Collectors.joining("")); + System.out.println("Generated schema content:" + content); + + // Check if schema was generated: check class and list object names + Assert.assertTrue(content.contains("name=\"Foo\"")); + Assert.assertTrue(content.contains("name=\"fooObject\"")); + } + + // Schemagen output resolver + class TestOutputResolver extends SchemaOutputResolver { + @Override + public Result createOutput(String namespaceUri, String fileName) + throws IOException { + return new StreamResult(resultSchemaFile.toFile()); + } + } + + // Schemagen output file name and path + static final String SCHEMA_FILENAME = "generatedSchema.xsd"; + Path resultSchemaFile = Paths.get(System.getProperty("user.dir", ".")) + .resolve(SCHEMA_FILENAME); + +} diff --git a/test/javax/xml/bind/marshal/8134111/UnmarshalTest.java b/test/javax/xml/bind/marshal/8134111/UnmarshalTest.java new file mode 100644 index 0000000000000000000000000000000000000000..e1f595f91fda7dfececc4147d78d83d98707f334 --- /dev/null +++ b/test/javax/xml/bind/marshal/8134111/UnmarshalTest.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2016, 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. + * + * 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. + */ + +/** + * @test + * @bug 8134111 + * @summary test that elements without namespace is ignored by unmarshaller + * when elementFormDefault is set to QUALIFIED. + * @compile testTypes/package-info.java testTypes/Root.java + * testTypes/WhenType.java testTypes/ObjectFactory.java + * @run testng/othervm UnmarshalTest + */ + +import java.io.StringReader; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Unmarshaller; +import org.testng.annotations.Test; +import static org.testng.Assert.assertNull; +import org.xml.sax.InputSource; +import testTypes.Root; + +public class UnmarshalTest { + + @Test + public void unmarshalUnexpectedNsTest() throws Exception { + JAXBContext context; + Unmarshaller unm; + // Create JAXB context from testTypes package + context = JAXBContext.newInstance("testTypes"); + // Create unmarshaller from JAXB context + unm = context.createUnmarshaller(); + // Unmarshall xml document with unqualified dtime element + Root r = (Root) unm.unmarshal(new InputSource(new StringReader(DOC))); + // Print dtime value and check if it is null + System.out.println("dtime is:"+r.getWhen().getDtime()); + assertNull(r.getWhen().getDtime()); + } + + //Xml document to unmarshall with unqualified dtime element + private final String DOC = + "" + + "" + + "2015-06-24T13:16:14.933-04:00" + + "" + + ""; +} diff --git a/test/javax/xml/bind/marshal/8134111/testTypes/ObjectFactory.java b/test/javax/xml/bind/marshal/8134111/testTypes/ObjectFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..5f933535b613ca7dfdef6f8ab5565c844bfb18aa --- /dev/null +++ b/test/javax/xml/bind/marshal/8134111/testTypes/ObjectFactory.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2016, 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. + * + * 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 testTypes; + +import javax.xml.bind.annotation.XmlRegistry; + +/** + * This object contains factory methods for each + * Java content interface and Java element interface + * generated in the testTypes package. + * + */ +@XmlRegistry +public class ObjectFactory { + + /** + * Create a new ObjectFactory that can be used to create + * new instances of schema derived classes for package: testTypes + * + */ + public ObjectFactory() { + } + + /** + * Create an instance of {@link Root } + * + */ + public Root createRoot() { + return new Root(); + } + + /** + * Create an instance of {@link WhenType } + * + */ + public WhenType createWhenType() { + return new WhenType(); + } + +} diff --git a/test/javax/xml/bind/marshal/8134111/testTypes/Root.java b/test/javax/xml/bind/marshal/8134111/testTypes/Root.java new file mode 100644 index 0000000000000000000000000000000000000000..d9b233526a198cd19cad45684b78e9ac508d8297 --- /dev/null +++ b/test/javax/xml/bind/marshal/8134111/testTypes/Root.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2016, 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. + * + * 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 testTypes; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + *

Java class for anonymous complex type. + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = {"when"}) +@XmlRootElement(name = "root", + namespace = "http://www.example.org/testNamespace/") +public class Root { + + @XmlElement(required = true, + namespace = "http://www.example.org/testNamespace/") + protected WhenType when; + + /** + * Gets the value of the when property. + * + * @return + * possible object is + * {@link WhenType } + * + */ + public WhenType getWhen() { + return when; + } + + /** + * Sets the value of the when property. + * + * @param value + * allowed object is + * {@link WhenType } + * + */ + public void setWhen(WhenType value) { + this.when = value; + } + +} diff --git a/test/javax/xml/bind/marshal/8134111/testTypes/WhenType.java b/test/javax/xml/bind/marshal/8134111/testTypes/WhenType.java new file mode 100644 index 0000000000000000000000000000000000000000..3e2b1b7bdce8b272043e5238fd5979d6eb0019ca --- /dev/null +++ b/test/javax/xml/bind/marshal/8134111/testTypes/WhenType.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2016, 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. + * + * 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 testTypes; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlSchemaType; +import javax.xml.bind.annotation.XmlType; +import javax.xml.datatype.XMLGregorianCalendar; + +/** + *

Java class for WhenType complex type. + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "WhenType", + propOrder = {"dtime"}) +public class WhenType { + + @XmlElement(required = true) + @XmlSchemaType(name = "dateTime") + protected XMLGregorianCalendar dtime; + + /** + * Gets the value of the dtime property. + * + * @return + * possible object is + * {@link XMLGregorianCalendar } + * + */ + public XMLGregorianCalendar getDtime() { + return dtime; + } + + /** + * Sets the value of the dtime property. + * + * @param value + * allowed object is + * {@link XMLGregorianCalendar } + * + */ + public void setDtime(XMLGregorianCalendar value) { + this.dtime = value; + } + +} diff --git a/test/javax/xml/bind/marshal/8134111/testTypes/package-info.java b/test/javax/xml/bind/marshal/8134111/testTypes/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..aedba8a2cd833c607770eabc4d880c29d581c2bd --- /dev/null +++ b/test/javax/xml/bind/marshal/8134111/testTypes/package-info.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2016, 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. + * + * 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. + */ + +@javax.xml.bind.annotation.XmlSchema( + namespace = "http://www.example.org/testNamespace/", + elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED) +package testTypes; diff --git a/test/javax/xml/bind/xjc/8145039/JaxbMarshallTest.java b/test/javax/xml/bind/xjc/8145039/JaxbMarshallTest.java new file mode 100644 index 0000000000000000000000000000000000000000..7de90ad3b5ceb51b2cc83a8bf171e2d3db77a601 --- /dev/null +++ b/test/javax/xml/bind/xjc/8145039/JaxbMarshallTest.java @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2016, 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. + * + * 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. + */ + +/* + * @test + * @bug 8145039 + * @summary Check that marshalling of xjc generated class doesn't throw + * ClassCast exception. + * @library /lib/testlibrary + * @run testng/othervm JaxbMarshallTest + */ + +import java.io.IOException; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; +import java.util.Arrays; +import java.util.List; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Marshaller; +import jdk.testlibrary.JDKToolLauncher; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +public class JaxbMarshallTest { + + @BeforeTest + public void setUp() throws IOException { + // Create test directory inside scratch + testWorkDir = Paths.get(System.getProperty("user.dir", ".")); + // Save its URL + testWorkDirUrl = testWorkDir.toUri().toURL(); + // Get test source directory path + testSrcDir = Paths.get(System.getProperty("test.src", ".")); + // Get path of xjc result folder + xjcResultDir = testWorkDir.resolve(TEST_PACKAGE); + // Copy schema document file to scratch directory + Files.copy(testSrcDir.resolve(XSD_FILENAME), testWorkDir.resolve(XSD_FILENAME), REPLACE_EXISTING); + } + + + /* + * Test does the following steps to reproduce problem reported by 8145039: + * 1. Copy test schema to JTREG scratch folder + * 2. Run xjc on test schema file + * 3. Compile generated java files with test javac + * 4. Marshall the new list instance to ensure that + * ClassCastException is not thrown + */ + @Test + public void marshallClassCastExceptionTest() throws Exception { + JAXBContext jaxbContext; + Marshaller marshaller; + URLClassLoader jaxbContextClassLoader; + // Generate java classes by xjc + runXjc(XSD_FILENAME); + // Compile xjc generated java files + compileXjcGeneratedClasses(); + + // Create JAXB context based on xjc generated package. + // Need to create URL class loader ot make compiled classes discoverable + // by JAXB context + jaxbContextClassLoader = URLClassLoader.newInstance(new URL[] {testWorkDirUrl}); + jaxbContext = JAXBContext.newInstance( TEST_PACKAGE, jaxbContextClassLoader); + + // Create instance of Xjc generated data type. + // Java classes were compiled during the test execution hence reflection + // is needed here + Class classLongListClass = jaxbContextClassLoader.loadClass(TEST_CLASS); + Object objectLongListClass = classLongListClass.newInstance(); + // Get 'getIn' method object + Method getInMethod = classLongListClass.getMethod( GET_LIST_METHOD, (Class [])null ); + // Invoke 'getIn' method + List inList = (List)getInMethod.invoke(objectLongListClass); + // Add values into the jaxb object list + inList.add(Long.valueOf(0)); + inList.add(Long.valueOf(43)); + inList.add(Long.valueOf(1000000123)); + + // Marshall constructed complex type variable to standard output. + // In case of failure the ClassCastException will be thrown + marshaller = jaxbContext.createMarshaller(); + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); + marshaller.marshal(objectLongListClass, System.out); + } + + // Compile schema file into java classes definitions + void runXjc(String xsdFileName) throws Exception { + // Prepare process builder to run schemagen tool and save its output + JDKToolLauncher xjcLauncher = JDKToolLauncher.createUsingTestJDK("xjc"); + xjcLauncher.addToolArg(xsdFileName); + System.out.println("Executing xjc command: " + Arrays.asList(xjcLauncher.getCommand())); + ProcessBuilder pb = new ProcessBuilder(xjcLauncher.getCommand()); + // Set xjc work directory with the input java file + pb.directory(testWorkDir.toFile()); + pb.inheritIO(); + Process p = pb.start(); + p.waitFor(); + p.destroy(); + } + + // Compile java classes with javac tool + void compileXjcGeneratedClasses() throws Exception { + JDKToolLauncher javacLauncher = JDKToolLauncher.createUsingTestJDK("javac"); + javacLauncher.addToolArg(xjcResultDir.resolve("ObjectFactory.java").toString()); + javacLauncher.addToolArg(xjcResultDir.resolve("TypesLongList.java").toString()); + javacLauncher.addToolArg(xjcResultDir.resolve("package-info.java").toString()); + System.out.println("Compiling xjc generated classes: " + Arrays.asList(javacLauncher.getCommand())); + ProcessBuilder pb = new ProcessBuilder(javacLauncher.getCommand()); + pb.inheritIO(); + pb.directory(testWorkDir.toFile()); + Process p = pb.start(); + p.waitFor(); + p.destroy(); + } + + // Test schema filename + static final String XSD_FILENAME = "testSchema.xsd"; + // Package of java classes generated by xjc + static final String TEST_PACKAGE = "testns_package"; + // Name of generated java class + static final String TEST_CLASS = TEST_PACKAGE+".TypesLongList"; + // Method to get the list from xjc generated class + static final String GET_LIST_METHOD = "getIn"; + // Test working directory + Path testWorkDir; + // Test working directory URL + URL testWorkDirUrl; + // Directory with test src + Path testSrcDir; + // Directory with java files generated by xjc + Path xjcResultDir; +} diff --git a/test/javax/xml/bind/xjc/8145039/testSchema.xsd b/test/javax/xml/bind/xjc/8145039/testSchema.xsd new file mode 100644 index 0000000000000000000000000000000000000000..f625d0607d0f0e0017b6951cddd630e890154ad0 --- /dev/null +++ b/test/javax/xml/bind/xjc/8145039/testSchema.xsd @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + diff --git a/test/javax/xml/crypto/dsig/ValidationTests.java b/test/javax/xml/crypto/dsig/ValidationTests.java index 5a86692f8c85320255db8f6b5d98c75d458e7328..278d64c324151ea0aee991c41b35f2d04f2736b7 100644 --- a/test/javax/xml/crypto/dsig/ValidationTests.java +++ b/test/javax/xml/crypto/dsig/ValidationTests.java @@ -35,6 +35,7 @@ import java.io.FileInputStream; import java.security.*; import javax.xml.crypto.Data; import javax.xml.crypto.KeySelector; +import javax.xml.crypto.MarshalException; import javax.xml.crypto.OctetStreamData; import javax.xml.crypto.URIDereferencer; import javax.xml.crypto.URIReference; @@ -60,9 +61,17 @@ public class ValidationTests { static class Test { String file; KeySelector ks; - Test(String file, KeySelector ks) { + Class exception; + + Test(String file, KeySelector ks, Class exception) { this.file = file; this.ks = ks; + this.exception = exception; + } + + // XMLSignatureException is expected by default + Test(String file, KeySelector ks) { + this(file, ks, XMLSignatureException.class); } } @@ -109,7 +118,17 @@ public class ValidationTests { private final static Test[] INVALID_TESTS = { new Test("signature-enveloping-hmac-sha1-40.xml", SKKS), new Test("signature-enveloping-hmac-sha1-trunclen-0-attack.xml", SKKS), - new Test("signature-enveloping-hmac-sha1-trunclen-8-attack.xml", SKKS) + new Test("signature-enveloping-hmac-sha1-trunclen-8-attack.xml", SKKS), + new Test("signature-extra-text-in-signed-info.xml", SKKS, + MarshalException.class), + new Test("signature-wrong-canonicalization-method-algorithm.xml", SKKS, + MarshalException.class), + new Test("signature-wrong-transform-algorithm.xml", SKKS, + MarshalException.class), + new Test("signature-no-reference-uri.xml", SKKS), + new Test("signature-wrong-signature-method-algorithm.xml", SKKS, + MarshalException.class), + new Test("signature-wrong-tag-names.xml", SKKS, MarshalException.class) }; public static void main(String args[]) throws Exception { @@ -142,9 +161,14 @@ public class ValidationTests { test_signature(test); System.out.println("FAILED"); atLeastOneFailed = true; - } catch (XMLSignatureException xse) { - System.out.println(xse.getMessage()); - System.out.println("PASSED"); + } catch (Exception e) { + System.out.println("Exception: " + e); + if (e.getClass() != test.exception) { + System.out.println("FAILED: unexpected exception"); + atLeastOneFailed = true; + } else { + System.out.println("PASSED"); + } } } diff --git a/test/javax/xml/crypto/dsig/data/signature-extra-text-in-signed-info.xml b/test/javax/xml/crypto/dsig/data/signature-extra-text-in-signed-info.xml new file mode 100644 index 0000000000000000000000000000000000000000..578e7bb16e9071081e8583b91b39e903fd77bc8e --- /dev/null +++ b/test/javax/xml/crypto/dsig/data/signature-extra-text-in-signed-info.xml @@ -0,0 +1,3 @@ +test1Bq8FsjajUBYPD7stQeJSc66GlM=extra textiTrgJERmYeD5hFwY8/MwJpkF+nd++AAOgf/Kxt9SwdE6BIYq2Vyxq4CQPhD+t2971BGTgvF6ejZd ++/Ko4Zs5Dqf4Lt65Vck0q43rM0PdP1e8gJov0IPYnZ1zeqFpah+N/OjmqTbshaZWRIjf3eqS6en5 +ZKjn+TkCQ1kOX/YUNDc= \ No newline at end of file diff --git a/test/javax/xml/crypto/dsig/data/signature-no-reference-uri.xml b/test/javax/xml/crypto/dsig/data/signature-no-reference-uri.xml new file mode 100644 index 0000000000000000000000000000000000000000..eb199f79df237134948d5583707a8b2f69dfe4e4 --- /dev/null +++ b/test/javax/xml/crypto/dsig/data/signature-no-reference-uri.xml @@ -0,0 +1,3 @@ +test1Bq8FsjajUBYPD7stQeJSc66GlM=BNPSYlNcyXcO/Tc1tr9mQ/KAZ40eFybLTDyB/HH1EHHMpc972A+nOX2EWBaLsVgG8apl0Isp1ZqV +gmoDHNF6xrcJJQVydVJzU08GVV4GiXHMqRYQbted7STQLhlhssvNNdMEoVApsX5ByL66wxKZQXrT +z1kZtOHAi88DOrmIJu0= \ No newline at end of file diff --git a/test/javax/xml/crypto/dsig/data/signature-wrong-canonicalization-method-algorithm.xml b/test/javax/xml/crypto/dsig/data/signature-wrong-canonicalization-method-algorithm.xml new file mode 100644 index 0000000000000000000000000000000000000000..2ce430e1de91d2d61c362757bb79fecf49f610c9 --- /dev/null +++ b/test/javax/xml/crypto/dsig/data/signature-wrong-canonicalization-method-algorithm.xml @@ -0,0 +1,3 @@ +test1Bq8FsjajUBYPD7stQeJSc66GlM=EBbyEV7e+1CTUsyCTyxiN8p+U3/za1oTjK7q+kF8Q87r8e/7C1z4ndGWbk6zyI3w6leT+I2suW9U +KkdvkrDXX2OyLw0GfgJfLkNn+1pGK6kyWpL95NoWJZhHkUAKKBZ0ikfZ4j33gYxrYK+IYCLeZYzr +hlZjdXXXCiSH0Sq+weQ= \ No newline at end of file diff --git a/test/javax/xml/crypto/dsig/data/signature-wrong-signature-method-algorithm.xml b/test/javax/xml/crypto/dsig/data/signature-wrong-signature-method-algorithm.xml new file mode 100644 index 0000000000000000000000000000000000000000..a2709caec76a8396ca0fbda9e9c24b6b4d7516f7 --- /dev/null +++ b/test/javax/xml/crypto/dsig/data/signature-wrong-signature-method-algorithm.xml @@ -0,0 +1,3 @@ +test1Bq8FsjajUBYPD7stQeJSc66GlM=RjL9nfQg9u6+KEFfAlBBH7E7ilFgB7YEQ5MxOIJN/fOdQmc5iDD+YuhiHzNGXGi/UOyo6t8LxTxl +X4oFE1RNlPVkSAZK4LcTWhVa757WwgW1/EZo8PQYWp5NScLq6PumYaujoovSYBKW2N6+jQpnD/L6 +4cuEVNnwEFqvOLrjogY= \ No newline at end of file diff --git a/test/javax/xml/crypto/dsig/data/signature-wrong-tag-names.xml b/test/javax/xml/crypto/dsig/data/signature-wrong-tag-names.xml new file mode 100644 index 0000000000000000000000000000000000000000..152eb791985cb1bd07c0b0415259fdb3039e648d --- /dev/null +++ b/test/javax/xml/crypto/dsig/data/signature-wrong-tag-names.xml @@ -0,0 +1,3 @@ +test1Bq8FsjajUBYPD7stQeJSc66GlM=cbNpPGavhM0BGUtrvLxvy2SCIt+I27BPpVEt0Q9mXrdPYurMqWF/67AdY9m5RqS7+ZZlwUtem083 +MczRYbKoOIq7sMbCqKKdzbSE/U6rfmky/ACQ5wgemZl8jtipwu5LhAUzjhzT8hhTjVqOYpHdkVJz +l9dnd9eWbLmEr3BI0VA= \ No newline at end of file diff --git a/test/javax/xml/crypto/dsig/data/signature-wrong-transform-algorithm.xml b/test/javax/xml/crypto/dsig/data/signature-wrong-transform-algorithm.xml new file mode 100644 index 0000000000000000000000000000000000000000..a64abc75c4630fb59474c88ff306f24508d6ea68 --- /dev/null +++ b/test/javax/xml/crypto/dsig/data/signature-wrong-transform-algorithm.xml @@ -0,0 +1,4 @@ + +test1Bq8FsjajUBYPD7stQeJSc66GlM=Wzyx3jgEKGwY+pBXBmqWLWhASHQYCCGZVii5sKKKeZUBKxNBthjiSVfzKANuLgX6zAt16XRycrSL +zFKTPuvGeWVPDvd+KTNKCJxN9ccrG7v23EM7RY2eMJGu2r5DLfKwV7H6YuJPsOuWifVkKAhvq7gd +6akJshxyAj9Ud+mjo48= \ No newline at end of file diff --git a/test/javax/xml/jaxp/common/8144593/TestSAXDriver.java b/test/javax/xml/jaxp/common/8144593/TestSAXDriver.java new file mode 100644 index 0000000000000000000000000000000000000000..627fe1a41b3a3a66a80e369d19667a07eb806868 --- /dev/null +++ b/test/javax/xml/jaxp/common/8144593/TestSAXDriver.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016, 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. + * + * 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. + */ + +import com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl; +import javax.xml.XMLConstants; +import org.xml.sax.SAXNotRecognizedException; +import org.xml.sax.SAXNotSupportedException; + +/* + * Test implementation of SAXParser. It is extended from JDK parser and two methods + * are overriden to disable support of specific features and properties. + * This class is used in ValidationWarningsTest and TransformationWarningsTest + * to generate multiple warnings during xml validation and transformation processes. +*/ +public class TestSAXDriver extends SAXParserImpl.JAXPSAXParser { + + @Override + public synchronized void setFeature(String name, boolean value) throws SAXNotRecognizedException, SAXNotSupportedException { + if (XMLConstants.FEATURE_SECURE_PROCESSING.equals(name)) { + throw new SAXNotRecognizedException(name+" feature is not recognised by test SAX parser intentionally."); + } else { + super.setFeature(name, value); + } + } + + @Override + public synchronized void setProperty(String name, Object value) throws SAXNotRecognizedException, SAXNotSupportedException { + if (XMLConstants.ACCESS_EXTERNAL_DTD.equals(name) || ENT_EXP_LIMIT_PROP.equals(name)) { + throw new SAXNotRecognizedException(name+" property is not recognised by test SAX parser intentionally."); + } else { + super.setProperty(name, value); + } + } + + private static final String ENT_EXP_LIMIT_PROP = "http://www.oracle.com/xml/jaxp/properties/entityExpansionLimit"; +} diff --git a/test/javax/xml/jaxp/common/8144593/TransformationWarningsTest.java b/test/javax/xml/jaxp/common/8144593/TransformationWarningsTest.java new file mode 100644 index 0000000000000000000000000000000000000000..71c3ed1f1edfc17ba49fcefd9b43457452fd8713 --- /dev/null +++ b/test/javax/xml/jaxp/common/8144593/TransformationWarningsTest.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2016, 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. + * + * 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. + */ + +import java.io.StringReader; +import java.io.StringWriter; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; +import org.testng.annotations.Test; +import org.testng.annotations.BeforeClass; + +/* + * @test + * @bug 8144593 + * @summary Check that warnings about unsupported properties from parsers + * are suppressed during the transformation process. + * @compile -XDignore.symbol.file TestSAXDriver.java + * @run testng/othervm TransformationWarningsTest + */ +public class TransformationWarningsTest extends WarningsTestBase { + + @BeforeClass + public void setup() { + //Set test SAX driver implementation. + System.setProperty("org.xml.sax.driver", "TestSAXDriver"); + } + + @Test + public void testTransformation() throws Exception { + startTest(); + } + + //One iteration of xml transformation test case. It will be called from each + //TestWorker task defined in WarningsTestBase class. + void doOneTestIteration() throws Exception { + // Prepare output stream + StringWriter xmlResultString = new StringWriter(); + StreamResult xmlResultStream = new StreamResult(xmlResultString); + // Prepare xml source stream + Source src = new StreamSource(new StringReader(xml)); + Transformer t = createTransformer(); + //Transform the xml + t.transform(src, xmlResultStream); + } + + //Create transformer from xsl test string + Transformer createTransformer() throws Exception { + // Prepare sources for transormation + Source xslsrc = new StreamSource(new StringReader(xsl)); + + // Create factory and transformer + TransformerFactory tf = TransformerFactory.newInstance(); + Transformer t = tf.newTransformer(xslsrc); + + // Set URI Resolver to return the newly constructed xml + // stream source object from xml test string + t.setURIResolver((String href, String base) -> new StreamSource(new StringReader(xml))); + return t; + } + + //Xsl and Xml contents used in the transformation test + private static final String xsl = "" + + " " + + " " + + " Simple Transformation Result. No warnings should be printed to console" + + " " + + ""; + private static final String xml = ""; +} diff --git a/test/javax/xml/jaxp/common/8144593/ValidationWarningsTest.java b/test/javax/xml/jaxp/common/8144593/ValidationWarningsTest.java new file mode 100644 index 0000000000000000000000000000000000000000..28c003ce85738f70aeabf81b5f6ee485c0b0babc --- /dev/null +++ b/test/javax/xml/jaxp/common/8144593/ValidationWarningsTest.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2016, 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. + * + * 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. + */ + +import java.io.ByteArrayInputStream; +import java.io.StringReader; +import javax.xml.XMLConstants; +import javax.xml.transform.Source; +import javax.xml.transform.sax.SAXSource; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import javax.xml.validation.Validator; +import org.testng.annotations.Test; +import org.testng.annotations.BeforeClass; +import org.xml.sax.InputSource; + +/* + * @test + * @bug 8144593 + * @summary Check that warnings about unsupported properties from SAX + * parsers are suppressed during the xml validation process. + * @compile -XDignore.symbol.file TestSAXDriver.java + * @run testng/othervm ValidationWarningsTest + */ +public class ValidationWarningsTest extends WarningsTestBase { + + @BeforeClass + public void setup() { + //Set test SAX driver implementation. + System.setProperty("org.xml.sax.driver", "TestSAXDriver"); + } + + @Test + public void testValidation() throws Exception { + startTest(); + } + + //One iteration of xml validation test case. It will be called from each + //TestWorker task defined in WarningsTestBase class. + void doOneTestIteration() throws Exception { + Source src = new StreamSource(new StringReader(xml)); + SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + SAXSource xsdSource = new SAXSource(new InputSource(new ByteArrayInputStream(xsd.getBytes()))); + Schema schema = schemaFactory.newSchema(xsdSource); + Validator v = schema.newValidator(); + v.validate(src); + } + + //Xsd and Xml contents used in the validation test + private static final String xsd = "" + + " " + + " \n" + + " "; + private static final String xml = "Element"; + +} diff --git a/test/javax/xml/jaxp/common/8144593/WarningsTestBase.java b/test/javax/xml/jaxp/common/8144593/WarningsTestBase.java new file mode 100644 index 0000000000000000000000000000000000000000..7f31f62c53c7980268676e537384b48a10d4b610 --- /dev/null +++ b/test/javax/xml/jaxp/common/8144593/WarningsTestBase.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2016, 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. + * + * 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. + */ + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.xml.XMLConstants; +import org.testng.Assert; + +/* + * This class helps to test suppression of unsupported parser properties + * messages printed to standard error output. + * It launches THREADS_COUNT tasks. Each task does ITERATIONS_PER_THREAD + * sequential calls to doOneIteration method implemented by specific test class. + */ +public abstract class WarningsTestBase { + + /* + * Abstract method that should be implemented by test class. + * It is repeatedly called by each TestWorker task. + */ + abstract void doOneTestIteration() throws Exception; + + /* + * Launches parallel test tasks and check the output for the number of + * generated warning messages. There should be no more than one message of + * each type. + */ + void startTest() throws Exception { + //Save standard error stream + PrintStream defStdErr = System.err; + //Set new byte array stream as standard error stream + ByteArrayOutputStream byteStream = new ByteArrayOutputStream(5000); + System.setErr(new PrintStream(byteStream)); + //Execute multiple TestWorker tasks + for (int id = 0; id < THREADS_COUNT; id++) { + EXECUTOR.execute(new TestWorker(id)); + } + //Initiate shutdown of previously submitted task + EXECUTOR.shutdown(); + //Wait for termination of submitted tasks + if (!EXECUTOR.awaitTermination(THREADS_COUNT, TimeUnit.SECONDS)) { + //If not all tasks terminates during the time out force them to shutdown + EXECUTOR.shutdownNow(); + } + //Restore default standard error stream + System.setErr(defStdErr); + //Print tasks stderr output + String errContent = byteStream.toString(); + System.out.println("Standard error output content:"); + System.out.println(errContent); + //Check tasks stderr output for quatity of warning messages + Assert.assertTrue(warningPrintedOnce(XMLConstants.ACCESS_EXTERNAL_DTD, errContent)); + Assert.assertTrue(warningPrintedOnce(ENT_EXP_PROPERTY, errContent)); + Assert.assertTrue(warningPrintedOnce(XMLConstants.FEATURE_SECURE_PROCESSING, errContent)); + } + + // Count occurences of warning messages in standard error and check if warning is printed + // not more than once + private boolean warningPrintedOnce(String propertyName, String testOutput) { + //Count for property name in test output + Pattern p = Pattern.compile(propertyName); + Matcher m = p.matcher(testOutput); + int count = 0; + while (m.find()) { + count += 1; + } + System.out.println("'" + propertyName + "' print count: " + count); + //If count is more than 1 then consider test failed + return count <= 1; + } + + //TestWorker task that sequentially calls test method + private class TestWorker implements Runnable { + // Task id + private final int id; + + TestWorker(int id) { + this.id = id; + } + + @Override + public void run() { + try { + System.out.printf("%d: waiting for barrier%n", id); + //Synchronize startup of all tasks + BARRIER.await(); + System.out.printf("%d: starting iterations%n", id); + //Call test method multiple times + for (int i = 0; i < ITERATIONS_PER_THREAD; i++) { + doOneTestIteration(); + } + } catch (Exception ex) { + throw new RuntimeException("TestWorker id:" + id + " failed", ex); + } + } + } + + //Entity expansion limit property name + private static final String ENT_EXP_PROPERTY = "http://www.oracle.com/xml/jaxp/properties/entityExpansionLimit"; + //Number of simultaneous test threads + private static final int THREADS_COUNT = 10; + //Number of iterations per one thread + private static final int ITERATIONS_PER_THREAD = 4; + //Test thread pool + private static final ExecutorService EXECUTOR = Executors.newCachedThreadPool(); + //Cyclic barrier for threads startup synchronisation + private static final CyclicBarrier BARRIER = new CyclicBarrier(THREADS_COUNT); +} diff --git a/test/javax/xml/jaxp/parsers/8072081/SupplementaryChars.java b/test/javax/xml/jaxp/parsers/8072081/SupplementaryChars.java new file mode 100644 index 0000000000000000000000000000000000000000..288a96b4ed6536ed722f2e02049b10ea6cb9585a --- /dev/null +++ b/test/javax/xml/jaxp/parsers/8072081/SupplementaryChars.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +import java.io.ByteArrayInputStream; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import org.xml.sax.SAXParseException; +import org.xml.sax.helpers.DefaultHandler; + +/** + * @test + * @bug 8072081 + * @summary verifies that supplementary characters are supported as character + * data in xml 1.0, and also names in xml 1.1. + * @run testng/othervm SupplementaryChars + */ +/* + * Joe Wang (huizhe.wang@oracle.com) + */ + +public class SupplementaryChars { + + @Test(dataProvider = "supported") + public void test(String xml) throws Exception { + ByteArrayInputStream stream = new ByteArrayInputStream(xml.getBytes("UTF-8")); + getParser().parse(stream, new DefaultHandler()); + stream.close(); + } + + @Test(dataProvider = "unsupported", expectedExceptions = SAXParseException.class) + public void testInvalid(String xml) throws Exception { + ByteArrayInputStream stream = new ByteArrayInputStream(xml.getBytes("UTF-8")); + getParser().parse(stream, new DefaultHandler()); + stream.close(); + } + + @DataProvider(name = "supported") + private Object[][] supported() { + + return new Object[][] { + {"\uD840\uDC0B"}, + {""}, + {"in tag name"}, + {"in attribute name"}, + {"\uD840\uDC0B"}, + {""} + }; + } + + @DataProvider(name = "unsupported") + private Object[][] unsupported() { + return new Object[][] { + {"in tag name"}, + {"in attribute name"} + }; + } + + private SAXParser getParser() { + SAXParser parser = null; + try { + SAXParserFactory factory = SAXParserFactory.newInstance(); + parser = factory.newSAXParser(); + } catch (Exception e) { + throw new RuntimeException(e.getMessage()); + } + return parser; + } +} diff --git a/test/javax/xml/jaxp/stream/8145974/SurrogatesTest.java b/test/javax/xml/jaxp/stream/8145974/SurrogatesTest.java new file mode 100644 index 0000000000000000000000000000000000000000..9dcaa154238bac0781b3156ccad83fc22cdb395a --- /dev/null +++ b/test/javax/xml/jaxp/stream/8145974/SurrogatesTest.java @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2016, 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. + */ + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.OutputStreamWriter; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.testng.Assert; +import org.testng.annotations.Test; +import org.testng.annotations.DataProvider; + +/* + * @test + * @bug 8145974 + * @run testng/othervm SurrogatesTest + * @summary Check that XMLStreamWriter generates valid xml with surrogate pair + * used within element text + */ + +public class SurrogatesTest { + + // Test that valid surrogate characters can be written/readen by xml stream + // reader/writer + @Test(dataProvider = "validData") + public void xmlWithValidSurrogatesTest(String content) + throws Exception { + generateAndReadXml(content); + } + + // Test that unbalanced surrogate character will + @Test(dataProvider = "invalidData", + expectedExceptions = XMLStreamException.class) + public void xmlWithUnbalancedSurrogatesTest(String content) + throws Exception { + generateAndReadXml(content); + } + + // Generates xml content with XMLStreamWriter and read it to check + // for correctness of xml and generated data + void generateAndReadXml(String content) throws Exception { + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + XMLOutputFactory factory = XMLOutputFactory.newInstance(); + OutputStreamWriter streamWriter = new OutputStreamWriter(stream); + XMLStreamWriter writer = factory.createXMLStreamWriter(streamWriter); + + // Generate xml with selected stream writer type + generateXML(writer, content); + String output = stream.toString(); + System.out.println("Generated xml: " + output); + // Read generated xml with StAX parser + readXML(output.getBytes(), content); + } + + // Generates XML with provided xml stream writer. Provided string + // is inserted into xml twice: with usage of writeCharacters( String ) + // and writeCharacters( char [], int , int ) + private void generateXML(XMLStreamWriter writer, String sequence) + throws XMLStreamException { + char[] seqArr = sequence.toCharArray(); + writer.writeStartDocument(); + writer.writeStartElement("root"); + + // Use writeCharacters( String ) to write characters + writer.writeStartElement("writeCharactersWithString"); + writer.writeCharacters(sequence); + writer.writeEndElement(); + + // Use writeCharacters( char [], int , int ) to write characters + writer.writeStartElement("writeCharactersWithArray"); + writer.writeCharacters(seqArr, 0, seqArr.length); + writer.writeEndElement(); + + // Close root element and document + writer.writeEndElement(); + writer.writeEndDocument(); + writer.flush(); + writer.close(); + } + + // Reads generated XML data and check if it contains expected + // text in writeCharactersWithString and writeCharactersWithArray + // elements + private void readXML(byte[] xmlData, String expectedContent) + throws Exception { + InputStream stream = new ByteArrayInputStream(xmlData); + XMLInputFactory factory = XMLInputFactory.newInstance(); + XMLStreamReader xmlReader + = factory.createXMLStreamReader(stream); + boolean inTestElement = false; + StringBuilder sb = new StringBuilder(); + while (xmlReader.hasNext()) { + String ename; + switch (xmlReader.getEventType()) { + case XMLStreamConstants.START_ELEMENT: + ename = xmlReader.getLocalName(); + if (ename.equals("writeCharactersWithString") + || ename.equals("writeCharactersWithArray")) { + inTestElement = true; + } + break; + case XMLStreamConstants.END_ELEMENT: + ename = xmlReader.getLocalName(); + if (ename.equals("writeCharactersWithString") + || ename.equals("writeCharactersWithArray")) { + inTestElement = false; + String content = sb.toString(); + System.out.println(ename + " text:'" + content + "' expected:'" + expectedContent+"'"); + Assert.assertEquals(content, expectedContent); + sb.setLength(0); + } + break; + case XMLStreamConstants.CHARACTERS: + if (inTestElement) { + sb.append(xmlReader.getText()); + } + break; + } + xmlReader.next(); + } + } + + @DataProvider(name = "validData") + Object[][] getValidData() { + return new Object[][] { + {"Don't Worry Be \uD83D\uDE0A"}, + {"BMP characters \uE000\uFFFD"}, + {"Simple text"}, + }; + } + + @DataProvider(name = "invalidData") + Object[][] getInvalidData() { + return new Object[][] { + {"Unbalanced surrogate \uD83D"}, + {"Unbalanced surrogate \uD83Dis here"}, + {"Surrogate with followup BMP\uD83D\uFFF9"}, + }; + } +} diff --git a/test/javax/xml/jaxp/transform/8150704/Bug8150704-1.ref b/test/javax/xml/jaxp/transform/8150704/Bug8150704-1.ref new file mode 100644 index 0000000000000000000000000000000000000000..0af2588d8943ef359dc164c6b4e79a6493e4697b --- /dev/null +++ b/test/javax/xml/jaxp/transform/8150704/Bug8150704-1.ref @@ -0,0 +1 @@ +................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................ diff --git a/test/javax/xml/jaxp/transform/8150704/Bug8150704-1.xml b/test/javax/xml/jaxp/transform/8150704/Bug8150704-1.xml new file mode 100644 index 0000000000000000000000000000000000000000..382a25f08fb26322df1a7c7c0afc42f461bb41b9 --- /dev/null +++ b/test/javax/xml/jaxp/transform/8150704/Bug8150704-1.xml @@ -0,0 +1,5 @@ + + + + . + diff --git a/test/javax/xml/jaxp/transform/8150704/Bug8150704-1.xsl b/test/javax/xml/jaxp/transform/8150704/Bug8150704-1.xsl new file mode 100644 index 0000000000000000000000000000000000000000..f390323c2f9d44a8c7d2db19f4a875f95fe874e6 --- /dev/null +++ b/test/javax/xml/jaxp/transform/8150704/Bug8150704-1.xsl @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/javax/xml/jaxp/transform/8150704/Bug8150704-2.ref b/test/javax/xml/jaxp/transform/8150704/Bug8150704-2.ref new file mode 100644 index 0000000000000000000000000000000000000000..b012e31307cd742564b3657577d4dce9e3ab698a --- /dev/null +++ b/test/javax/xml/jaxp/transform/8150704/Bug8150704-2.ref @@ -0,0 +1,83 @@ +0fto-erech 200amos-batch 00000000X/ +1FB01 20150709 EWF 2016021207USD 0000,9302122026623 ////////91284422 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000007366,71//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////D8OOoOOooooOoooooO////15/07 P0480715 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40090597 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150630 EWF 2016021206USD 0000,9302122026624 ////////1500006837 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000003844,00//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////b3oooooooooooooooo////15/07 R1683315 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40127254 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150709 EWF 2016021207CHF 0001,0000022026625 ////////94043801 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000000438,50//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////0CooOooooooooooOOo////15/07 P0472115 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////30092874 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150702 EWF 2016021207EUR 0001,0468822026626 ////////TL152062 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000000661,30//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////3coooooooooooooooo////15/07 P0431815 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40099751 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150617 EWF 2016021206EUR 0001,0468822026627 ////////TKL100216 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000000699,92//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////55oooooOoOooooOoOo////15/07 L0032815 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////2014686 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150702 EWF 2016021207EUR 0001,0468822026628 ////////TL152063 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000001983,00//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////9boooooooooooooooo////15/07 P0431815 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40099751 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150713 EWF 2016021207EUR 0001,0468822026629 ////////000359084 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000002230,76//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////51oOoOoOoOoooooOOO////15/07 R1735915 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40128088 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150708 EWF 2016021207CHF 0001,0000022026630 ////////90864081 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000001893,20//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////acoooooooooooooooo////15/07 P0470615 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////30090668 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150708 EWF 2016021207USD 0000,9302122026631 ////////123939 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000007896,34//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////09oooooooooooooooo////15/07 P0400015 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40128846 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150707 EWF 2016021207USD 0000,9302122026633 ////////000358117 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000006810,00//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////f5oooooooooooooooo////15/07 P0462815 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40128088 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150713 EWF 2016021207CHF 0001,0000022026635 ////////M90257500 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000016300,50//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////C3oOOOooOoOooOOOoo////15/07 R1488615 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////30124373 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150713 EWF 2016021207USD 0000,9302122026637 ////////M90257457 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000000831,90//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////60ooooOooOOOoOoOoo////15/07 P0463815 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////30124373 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 40///////////////0000000000055,22//////////////////////////////////////////////// /////////////////////////////////////7000 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////P0463815 ////15/07 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////400158 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150713 EWF 2016021207USD 0000,9302122026638 ////////M90257509 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000002218,00//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////60OoooooOOooooOooo////15/07 P0491115 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////30124373 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 40///////////////0000000000055,22//////////////////////////////////////////////// /////////////////////////////////////7000 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////P0491115 ////15/07 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////400158 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150713 EWF 2016021207CHF 0001,0000022026639 ////////M90257515 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000005833,20//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////A6OOooOoOoOooOoooo////15/07 R1575215 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////30124373 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150701 EWF 2016021207USD 0000,9302122026642 ////////C/5 335835 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000000515,00//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////16OooooOooOOoOoooo////15/07 R1612715 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40126141 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150701 EWF 2016021207USD 0000,9302122026643 ////////C/5 335833 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000000835,00//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////58OOoOOooooOooOOoo////15/07 R1441715 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40126141 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150706 EWF 2016021207USD 0000,9302122026644 ////////C/5 336036 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000000515,00//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////6BooooOOoooOooOooo////15/07 R1659015 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40126141 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150701 EWF 2016021207USD 0000,9302122026645 ////////C/5 335836 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000000515,00//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////6DoOoooOooOOoOooOo////15/07 R1613415 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40126141 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150708 EWF 2016021207USD 0000,9302122026646 ////////C/5 336201 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000000515,00//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////74ooOoOooooooooOoO////15/07 R1728915 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40126141 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150706 EWF 2016021207USD 0000,9302122026647 ////////C/5 336035 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000000515,00//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////86OoooOOoooOoooOOo////15/07 R1612615 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40126141 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150706 EWF 2016021207USD 0000,9302122026648 ////////C/5 336034 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000000835,00//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////99OOooooooOooOoooo////15/07 R1445115 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40126141 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150701 EWF 2016021207USD 0000,9302122026649 ////////C/5 335834 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000000835,00//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////D8OOoooOOOooooOOoo////15/07 R1445315 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40126141 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150706 EWF 2016021207CHF 0001,0000022026650 ////////351732 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000000192,80//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////4BooOooooOOOoOOOOo////15/07 P0448015 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////30090682 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150706 EWF 2016021207CHF 0001,0000022026651 ////////351730 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000000057,25//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////69ooOoOooooooooooO////15/07 P0451715 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////30090682 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 40///////////////0000000000007,02//////////////////////////////////////////////// /////////////////////////////////////7000 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////P0451715 ////15/07 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////400122 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150706 EWF 2016021207CHF 0001,0000022026652 ////////351731 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000000100,05//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////A9oooooooOoOooOOOo////15/07 P0448015 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////30090682 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150707 EWF 2016021207EUR 0001,0468822026653 ////////05/91014407 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000000225,00//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////22oooOooooOooOooOO////15/07 R1727915 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40096899 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150707 EWF 2016021207EUR 0001,0468822026654 ////////05/91015508 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000000225,00//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////24OooooOOoOooOoOoO////15/07 R1728015 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40096899 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150701 EWF 2016021207EUR 0001,0468822026655 ////////05/91015531 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000000768,45//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////76oOOOOooOoOooooOO////15/07 W0054415 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40096899 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150708 EWF 2016021207USD 0000,9302122026656 ////////SI156008034 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000000261,79//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////96OooooOoOoooOOOoo////15/07 P0479215 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40126601 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150709 EWF 2016021207EUR 0001,0468822026657 ////////05/91015509 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000000705,35//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////99ooOoOOoooooOoooo////15/07 R1625015 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40096899 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150713 EWF 2016021207EUR 0001,0468822026662 ////////55941607 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000000725,60//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////4BOoooOOOoOoooooOo////15/07 P0486115 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40091085 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150708 EWF 2016021207CHF 0001,0000022026663 ////////100-120606 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000004229,50//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////0boooooooooooooooo////15/07 P0474115 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////30094003 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 40///////////////0000000000430,56//////////////////////////////////////////////// /////////////////////////////////////7000 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////P0474115 ////15/07 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////400158 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 40///////////////0000000000054,38//////////////////////////////////////////////// /////////////////////////////////////7000 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////P0474115 ////15/07 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////400122 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150707 EWF 2016021207CHF 0001,0000022026664 ////////13143106 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000000318,65//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////6eoooooooooooooooo////15/07 P0468115 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////30092269 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 40///////////////0000000000014,04//////////////////////////////////////////////// /////////////////////////////////////7000 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////P0468115 ////15/07 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////400122 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150709 EWF 2016021207EUR 0001,0468822026665 ////////TL152315 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000001983,90//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////74oooooooooooooooo////15/07 P0431815 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40099751 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150710 EWF 2016021207EUR 0001,0468822026667 ////////11321 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000000840,00//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////caoooooooooooooooo////15/07 P0471915 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40129316 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20150401 EWF 2016021204EUR 0001,0553176278995 ////////76278995 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000007833,33//////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////15/04 S0026415 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////566//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////VERB05001 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20110209 EWF 2016021202CHF 0001,0000090149059 ////////M90149059 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000001077,30//////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////11/03 S0080410 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////566//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////30124373 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +1FB01 20110209 EWF 2016021202USD 0000,9570290149062 ////////90149062 ///////////////////////////////////////////////////////////X/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +2BBSEG 31///////////////0000000002185,78//////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////11/03 S0125011 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////566//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////30124374 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/test/javax/xml/jaxp/transform/8150704/Bug8150704-2.xml b/test/javax/xml/jaxp/transform/8150704/Bug8150704-2.xml new file mode 100644 index 0000000000000000000000000000000000000000..19a8381e919fdf6c7dbb08389f435665d36573df --- /dev/null +++ b/test/javax/xml/jaxp/transform/8150704/Bug8150704-2.xml @@ -0,0 +1,2438 @@ + + + + 22026623 + + + CRX + CHF + + OPEN + I + V0409 + CAGE1 + 40090597 + + 91284422 + 2015-07-09 + + 2015-07-15 + 2015-07-15 + D8OOoOOooooOoooooOOOOooOoooOoOoo + + 7366.71 + 0.0 + 0.0 + 0.0 + + V0 + 0.0 + + + + P + P0480715 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-08-08 + 0 + Y + + + 07 + 2015 + + + USD + CHF + 0.93021 + + + + + 22026624 + + + CRX + CHF + + OPEN + I + V0307 + CAGE2 + 40127254 + + 1500006837 + 2015-06-30 + + 2015-07-16 + 2015-07-16 + b3oooooooooooooooooooooooooooooo + + 3844.0 + 0.0 + 0.0 + 0.0 + + V0 + 0.0 + + + + R + R1683315 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-07-30 + 0 + Y + + + 07 + 2015 + + + USD + CHF + 0.93021 + + + + + 22026625 + + + CRX + CHF + + CLOSED + I + V0568 + 30092874 + + 94043801 + 2015-07-09 + 2015-07-16 + 2015-07-16 + 2015-07-16 + 0CooOooooooooooOOoooOooOoOOoooOo + + 438.5 + 190.008 + 0.0 + 0.0 + + 4V + 32.48 + + + + P + P0472115 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-08-08 + 0 + Y + + + 07 + 2015 + + + CHF + CHF + 1.0 + + + + + 22026626 + + + CRX + CHF + + OPEN + I + V0316 + CAGE3 + 40099751 + + TL152062 + 2015-07-02 + + 2015-07-16 + 2015-07-16 + 3coooooooooooooooooooooooooooooo + + 661.3 + 0.0 + 0.0 + 0.0 + + V0 + 0.0 + + + + P + P0431815 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-08-01 + 0 + Y + + + 07 + 2015 + + + EUR + CHF + 1.04688 + + + + + 22026627 + + + CRX + CHF + + OPEN + I + V0440 + 2014686 + + TKL100216 + 2015-06-17 + + 2015-07-16 + 2015-07-16 + 55oooooOoOooooOoOoOOOoOOOoooOOoo + + 699.92 + 0.0 + 0.0 + 0.0 + + V0 + 0.0 + + + + L + L0032815 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-07-17 + 0 + Y + + + 07 + 2015 + + + EUR + CHF + 1.04688 + + + + + 22026628 + + + CRX + CHF + + OPEN + I + V0316 + CAGE4 + 40099751 + + TL152063 + 2015-07-02 + + 2015-07-16 + 2015-07-16 + 9boooooooooooooooooooooooooooooo + + 1983.0 + 0.0 + 0.0 + 0.0 + + V0 + 0.0 + + + + P + P0431815 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-08-01 + 0 + Y + + + 07 + 2015 + + + EUR + CHF + 1.04688 + + + + + 22026629 + + + CRX + CHF + + OPEN + I + V0506 + 40128088 + + 000359084 + 2015-07-13 + + 2015-07-16 + 2015-07-16 + 51oOoOoOoOoooooOOOoOooooOOoooOoO + + 2230.76 + 0.0 + 0.0 + 0.0 + + V0 + 0.0 + + + + R + R1735915 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-08-12 + 0 + Y + + + 07 + 2015 + + + EUR + CHF + 1.04688 + + + + + 22026630 + + + CRX + CHF + + OPEN + I + V0497 + 30090668 + + 90864081 + 2015-07-08 + + 2015-07-16 + 2015-07-16 + acoooooooooooooooooooooooooooooo + + 1893.2 + 0.0 + 0.0 + 0.0 + + 4V + 0.0 + + + + P + P0470615 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-08-07 + 0 + Y + + + 07 + 2015 + + + CHF + CHF + 1.0 + + + + + 22026631 + + + CRX + CHF + + OPEN + I + V0512 + 40128846 + + 123939 + 2015-07-08 + + 2015-07-16 + 2015-07-16 + 09oooooooooooooooooooooooooooooo + + 7896.34 + 0.0 + 0.0 + 0.0 + + TAX + 0.0 + + + + P + P0400015 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-08-07 + 0 + Y + + + 07 + 2015 + + + USD + CHF + 0.93021 + + + + + 22026633 + + + CRX + CHF + + CLOSED + I + V0202 + 40128088 + + 000358117 + 2015-07-07 + 2015-07-16 + 2015-07-16 + 2015-07-16 + f5oooooooooooooooooooooooooooooo + + 6810.0 + 3187.08 + 0.0 + 0.0 + + V0 + 0.0 + + + + P + P0462815 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-08-06 + 0 + Y + + + 07 + 2015 + + + USD + CHF + 0.93021 + + + + + 22026635 + + + CRX + CHF + + OPEN + I + V0011 + 30124373 + + M90257500 + 2015-07-13 + + 2015-07-16 + 2015-07-16 + C3oOOOooOoOooOOOoooOOOoOOoooOoOO + + 16300.5 + 0.0 + 0.0 + 0.0 + + V0 + 0.0 + + + + R + R1488615 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-08-12 + 0 + Y + + + 07 + 2015 + + + CHF + CHF + 1.0 + + + + + 22026637 + + + CRX + CHF + + CLOSED + I + V0139 + 30124373 + + M90257457 + 2015-07-13 + 2015-07-16 + 2015-07-16 + 2015-07-16 + 60ooooOooOOOoOoOoooooooOOOOoooOO + + 831.9 + 334.1052 + 118.0 + 0.0 + + V0 + 0.0 + + + + P + P0463815 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-08-12 + 0 + Y + + + 07 + 2015 + + + USD + CHF + 0.93021 + + + + + H + HANDLING CHARGE + N + N + + 400158 + + 7000 + 7000 + + + 55.224 + 55.224 + + V0 + V0 + 0.0 + + + D + + + + 22026638 + + + CRX + CHF + + CLOSED + I + V0139 + 30124373 + + M90257509 + 2015-07-13 + 2015-07-16 + 2015-07-16 + 2015-07-16 + 60OoooooOOooooOoooooooooOOooOOOO + + 2218.0 + 982.8 + 118.0 + 0.0 + + V0 + 0.0 + + + + P + P0491115 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-08-12 + 0 + Y + + + 07 + 2015 + + + USD + CHF + 0.93021 + + + + + H + HANDLING CHARGE + N + N + + 400158 + + 7000 + 7000 + + + 55.224 + 55.224 + + V0 + V0 + 0.0 + + + D + + + + 22026639 + + + CRX + CHF + + OPEN + I + V0162 + 30124373 + + M90257515 + 2015-07-13 + + 2015-07-16 + 2015-07-16 + A6OOooOoOoOooOoooooooooOooooOOoo + + 5833.2 + 0.0 + 0.0 + 0.0 + + V0 + 0.0 + + + + R + R1575215 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-08-12 + 0 + Y + + + 07 + 2015 + + + CHF + CHF + 1.0 + + + + + 22026642 + + + CRX + CHF + + OPEN + I + V0400 + CAGE5 + 40126141 + + C/5 335835 + 2015-07-01 + + 2015-07-16 + 2015-07-16 + 16OooooOooOOoOooooOoooooooooooOO + + 515.0 + 0.0 + 0.0 + 0.0 + + V0 + 0.0 + + + + R + R1612715 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-07-31 + 0 + Y + + + 07 + 2015 + + + USD + CHF + 0.93021 + + + + + 22026643 + + + CRX + CHF + + OPEN + I + V0400 + CAGE6 + 40126141 + + C/5 335833 + 2015-07-01 + + 2015-07-16 + 2015-07-16 + 58OOoOOooooOooOOooOoooOooooOOoOo + + 835.0 + 0.0 + 0.0 + 0.0 + + V0 + 0.0 + + + + R + R1441715 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-07-31 + 0 + Y + + + 07 + 2015 + + + USD + CHF + 0.93021 + + + + + 22026644 + + + CRX + CHF + + OPEN + I + V0400 + CAGE7 + 40126141 + + C/5 336036 + 2015-07-06 + + 2015-07-16 + 2015-07-16 + 6BooooOOoooOooOooooOooooOoOOoooo + + 515.0 + 0.0 + 0.0 + 0.0 + + V0 + 0.0 + + + + R + R1659015 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-08-05 + 0 + Y + + + 07 + 2015 + + + USD + CHF + 0.93021 + + + + + 22026645 + + + CRX + CHF + + OPEN + I + V0400 + CAGE8 + 40126141 + + C/5 335836 + 2015-07-01 + + 2015-07-16 + 2015-07-16 + 6DoOoooOooOOoOooOoOoOoOOOoOoOooo + + 515.0 + 0.0 + 0.0 + 0.0 + + V0 + 0.0 + + + + R + R1613415 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-07-31 + 0 + Y + + + 07 + 2015 + + + USD + CHF + 0.93021 + + + + + 22026646 + + + CRX + CHF + + OPEN + I + V0400 + CAGE9 + 40126141 + + C/5 336201 + 2015-07-08 + + 2015-07-16 + 2015-07-16 + 74ooOoOooooooooOoOOOoOoOooOoooOO + + 515.0 + 0.0 + 0.0 + 0.0 + + V0 + 0.0 + + + + R + R1728915 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-08-07 + 0 + Y + + + 07 + 2015 + + + USD + CHF + 0.93021 + + + + + 22026647 + + + CRX + CHF + + OPEN + I + V0400 + CAGEA + 40126141 + + C/5 336035 + 2015-07-06 + + 2015-07-16 + 2015-07-16 + 86OoooOOoooOoooOOoOooOoooOOoOoOo + + 515.0 + 0.0 + 0.0 + 0.0 + + V0 + 0.0 + + + + R + R1612615 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-08-05 + 0 + Y + + + 07 + 2015 + + + USD + CHF + 0.93021 + + + + + 22026648 + + + CRX + CHF + + OPEN + I + V0400 + CAGEB + 40126141 + + C/5 336034 + 2015-07-06 + + 2015-07-16 + 2015-07-16 + 99OOooooooOooOooooOooOooOoOOoOoo + + 835.0 + 0.0 + 0.0 + 0.0 + + V0 + 0.0 + + + + R + R1445115 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-08-05 + 0 + Y + + + 07 + 2015 + + + USD + CHF + 0.93021 + + + + + 22026649 + + + CRX + CHF + + OPEN + I + V0400 + CAGEC + 40126141 + + C/5 335834 + 2015-07-01 + + 2015-07-16 + 2015-07-16 + D8OOoooOOOooooOOoooOOoOoooOoOOOO + + 835.0 + 0.0 + 0.0 + 0.0 + + V0 + 0.0 + + + + R + R1445315 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-07-31 + 0 + Y + + + 07 + 2015 + + + USD + CHF + 0.93021 + + + + + 22026650 + + + CRX + CHF + + OPEN + I + V0429 + 30090682 + + 351732 + 2015-07-06 + + 2015-07-16 + 2015-07-16 + 4BooOooooOOOoOOOOooo + + 192.8 + 0.0 + 0.0 + 0.0 + + 4V + 0.0 + + + + P + P0448015 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-08-05 + 0 + Y + + + 07 + 2015 + + + CHF + CHF + 1.0 + + + + + 22026651 + + + CRX + CHF + + CLOSED + I + V0429 + 30090682 + + 351730 + 2015-07-06 + 2015-07-16 + 2015-07-16 + 2015-07-16 + 69ooOoOooooooooooOoOooOOOOoooOoO + + 57.25 + 17.784 + 15.0 + 0.0 + + 4V + 4.24 + + + + P + P0451715 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-08-05 + 0 + Y + + + 07 + 2015 + + + CHF + CHF + 1.0 + + + + + F + FREIGHT + N + N + + 400122 + + 7000 + 7000 + + + 7.02 + 7.02 + + 4V + 4V + 0.5616 + + + D + + + + 22026652 + + + CRX + CHF + + OPEN + I + V0429 + 30090682 + + 351731 + 2015-07-06 + + 2015-07-16 + 2015-07-16 + A9oooooooOoOooOOOoOO + + 100.05 + 0.0 + 0.0 + 0.0 + + 4V + 0.0 + + + + P + P0448015 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-08-05 + 0 + Y + + + 07 + 2015 + + + CHF + CHF + 1.0 + + + + + 22026653 + + + CRX + CHF + + OPEN + I + V0028 + CAGED + 40096899 + + 05/91014407 + 2015-07-07 + + 2015-07-16 + 2015-07-16 + 22oooOooooOooOooOOoOooOoooooOooO + + 225.0 + 0.0 + 0.0 + 0.0 + + V0 + 0.0 + + + + R + R1727915 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-08-06 + 0 + Y + + + 07 + 2015 + + + EUR + CHF + 1.04688 + + + + + 22026654 + + + CRX + CHF + + OPEN + I + V0028 + CAGEE + 40096899 + + 05/91015508 + 2015-07-07 + + 2015-07-16 + 2015-07-16 + 24OooooOOoOooOoOoOoOoooOOoOOooOo + + 225.0 + 0.0 + 0.0 + 0.0 + + V0 + 0.0 + + + + R + R1728015 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-08-06 + 0 + Y + + + 07 + 2015 + + + EUR + CHF + 1.04688 + + + + + 22026655 + + + CRX + CHF + + CLOSED + I + V0028 + CAGEF + 40096899 + + 05/91015531 + 2015-07-01 + 2015-07-16 + 2015-07-16 + 2015-07-16 + 76oOOOOooOoOooooOOoOoOOooOooOoOO + + 768.45 + 359.6346 + 0.0 + 0.0 + + V0 + 0.0 + + + + W + W0054415 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-07-31 + 0 + Y + + + 07 + 2015 + + + EUR + CHF + 1.04688 + + + + + 22026656 + + + CRX + CHF + + OPEN + I + V0651 + 40126601 + + SI156008034 + 2015-07-08 + + 2015-07-16 + 2015-07-16 + 96OooooOoOoooOOOoooOOoooOoOOOOoO + + 261.79 + 0.0 + 0.0 + 0.0 + + V0 + 0.0 + + + + P + P0479215 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-08-07 + 0 + Y + + + 07 + 2015 + + + USD + CHF + 0.93021 + + + + + 22026657 + + + CRX + CHF + + CLOSED + I + V0028 + CAGEG + 40096899 + + 05/91015509 + 2015-07-09 + 2015-07-16 + 2015-07-16 + 2015-07-16 + 99ooOoOOoooooOooooOOOOoooOOoOOoO + + 705.35 + 330.1038 + 0.0 + 0.0 + + V0 + 0.0 + + + + R + R1625015 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-08-08 + 0 + Y + + + 07 + 2015 + + + EUR + CHF + 1.04688 + + + + + 22026662 + + + CRX + CHF + + OPEN + I + V0495 + CAGEH + 40091085 + + 55941607 + 2015-07-13 + + 2015-07-16 + 2015-07-16 + 4BOoooOOOoOoooooOoOOooOooooOoOoo + + 725.6 + 0.0 + 0.0 + 0.0 + + V0 + 0.0 + + + + P + P0486115 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-08-12 + 0 + Y + + + 07 + 2015 + + + EUR + CHF + 1.04688 + + + + + 22026663 + + + CRX + CHF + + CLOSED + I + V0604 + 30094003 + + 100-120606 + 2015-07-08 + 2015-07-16 + 2015-07-16 + 2015-07-16 + 0boooooooooooooooooooooooooooooo + + 4229.5 + 1347.84 + 1036.2 + 0.0 + + TAX + 313.3 + + + + P + P0474115 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-08-07 + 0 + Y + + + 07 + 2015 + + + CHF + CHF + 1.0 + + + + + H + HANDLING CHARGE + N + N + + 400158 + + 7000 + 7000 + + + 430.56 + 430.56 + + 4V + 4V + 34.4448 + + + D + + + + F + FREIGHT + N + N + + 400122 + + 7000 + 7000 + + + 54.3816 + 54.3816 + + 4V + 4V + 4.3524 + + + D + + + + 22026664 + + + CRX + CHF + + CLOSED + I + V0634 + 30092269 + + 13143106 + 2015-07-07 + 2015-07-16 + 2015-07-16 + 2015-07-16 + 6eoooooooooooooooooooooooooooooo + + 318.65 + 124.0434 + 30.0 + 0.0 + + 4V + 23.599999999999998 + + + + P + P0468115 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-08-06 + 0 + Y + + + 07 + 2015 + + + CHF + CHF + 1.0 + + + + + F + FREIGHT + N + N + + 400122 + + 7000 + 7000 + + + 14.04 + 14.04 + + 4V + 4V + 1.1232 + + + D + + + + 22026665 + + + CRX + CHF + + OPEN + I + V0316 + CAGEI + 40099751 + + TL152315 + 2015-07-09 + + 2015-07-16 + 2015-07-16 + 74oooooooooooooooooooooooooooooo + + 1983.9 + 0.0 + 0.0 + 0.0 + + V0 + 0.0 + + + + P + P0431815 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-08-08 + 0 + Y + + + 07 + 2015 + + + EUR + CHF + 1.04688 + + + + + 22026667 + + + CRX + CHF + + OPEN + I + V0642 + 40129316 + + 11321 + 2015-07-10 + + 2015-07-16 + 2015-07-16 + caoooooooooooooooooooooooooooooo + + 840.0 + 0.0 + 0.0 + 0.0 + + V0 + 0.0 + + + + P + P0471915 + + + 2016-02-12 + + Y + + + + 30D + + + + + + 2015-08-09 + 0 + Y + + + 07 + 2015 + + + EUR + CHF + 1.04688 + + + + + 76278995 + + + CRX + CHF + + CLOSED + I + V0166 + CAGEJ + VERB05001 + + 76278995 + 2015-04-01 + 2015-04-17 + 2015-04-17 + 2015-04-17 + + 7833.33 + 3394.4414 + 0.0 + 0.0 + + V0 + 580.25 + + + + S + S0026415 + + + 2016-02-12 + + Y + + + + + + + + + + 2015-04-01 + 0 + Y + + + 04 + 2015 + + + EUR + CHF + 1.05531 + + + + + 90149059 + + + CRX + CHF + + CLOSED + I + V0016 + 30124373 + + M90149059 + 2011-02-09 + 2011-02-18 + 2011-02-18 + 2011-02-18 + + 1077.3 + 504.1764 + 0.0 + 0.0 + + TAX + 0.0 + + + + S + S0080410 + + + 2016-02-12 + + N + + + + 5 + + + + + + 2011-02-09 + 0 + N + + + 03 + 2011 + + + CHF + CHF + 1.0 + + + + + 90149062 + + + CRX + CHF + + CLOSED + I + V0016 + 30124374 + + 90149062 + 2011-02-09 + 2011-02-21 + 2011-02-21 + 2011-02-21 + + 2185.78 + 1022.945 + 0.0 + 0.0 + + TAX + 0.0 + + + + S + S0125011 + + + 2016-02-12 + + N + + + + 6 + + + + + + 2011-02-09 + 0 + N + + + 03 + 2011 + + + USD + CHF + 0.95702 + + + + + diff --git a/test/javax/xml/jaxp/transform/8150704/Bug8150704-2.xsl b/test/javax/xml/jaxp/transform/8150704/Bug8150704-2.xsl new file mode 100644 index 0000000000000000000000000000000000000000..03040b70137dcab330d5d8eef0dab8b221dec274 --- /dev/null +++ b/test/javax/xml/jaxp/transform/8150704/Bug8150704-2.xsl @@ -0,0 +1,1935 @@ + + + + + + + + + +0 +fto-erech +200 +amos-batch +00000000 +X + + +FB01 +TP +EWF + + +566 +950 + + +2w + +V0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +1 + + + + + + + + + + + + + + + + + + + + +KA +EA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +/ + + + +/ +/ +/ +/ +/ +X +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ + + + + + + +2 +BBSEG + +31 +21 + +/ +/ +/ + + + + +/ +/ +/ + + + +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ + + + + + + + + + + + +/ +/ + + + + + + + + + + + +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ + + + + + + + + + + +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ + + + +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ + + +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ + + +/ +/ +/ +/ + + +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ + + + + + + + +2 +BBSEG + +40 +50 + +/ +/ +/ + + + + +/ +/ +/ + + + +/ +/ +/ +/ + + + + + + + + + + +/ + + + + + + + + + + +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ + + + +/ +/ + + + + + + + + +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ + + + + + + + + + + +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ + + + +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ + + +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ + + +/ +/ +/ +/ + + +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ + + + + + + + +2 +BBSEG + +40 +50 + +/ +/ +/ + + + +/ +/ +/ + + + +/ +/ +/ +/ + + + + + + + + + + +/ + + + + + + + + + + +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ + + + + + +/ +/ + + + + + + + + +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ + + + + + + + + + + +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ + + + + + +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ + + +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ + + +/ +/ +/ +/ + + +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ + + + + + + + +2 +BBSEG + +40 +50 + +/ +/ +/ + + + + +/ +/ +/ + + + +/ +/ +/ +/ + + + + + + + + + + +/ + + + + + + + + + + +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ + + + + + +/ +/ + + + + + + + + +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ + + + + + + + + + + +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ + + + + + +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ + + +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ + + +/ +/ +/ +/ + + +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ +/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +INVALID ALIGN + + + + diff --git a/test/javax/xml/jaxp/transform/8150704/TransformerTest.java b/test/javax/xml/jaxp/transform/8150704/TransformerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..62ade1147833dd0d40383b2666c3481e72af0b0f --- /dev/null +++ b/test/javax/xml/jaxp/transform/8150704/TransformerTest.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2016, 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. + * + * 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. + */ + +/* @test + * @bug 8150704 + * @summary Test that XSL transformation with lots of temporary result trees will not run out of DTM IDs. + * @run testng/othervm TransformerTest + */ + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.StringWriter; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + + +public class TransformerTest { + + @Test(dataProvider = "bug8150704") + public final void testBug8150704(String xsl, String xml, String ref) throws Exception { + System.out.println("Testing transformation of "+xml); + Transformer transformer = createTransformerFromResource(xsl); + StringWriter result = transformResourceToStringWriter(transformer, xml); + String resultstring = result.toString().replaceAll("\\r\\n", "\n").replaceAll("\\r", "\n"); + String reference = getFileContentAsString(new File(getClass().getResource(ref).getPath())); + Assert.assertEquals(resultstring, reference, "Output of transformation of "+xml+" does not match reference"); + } + + @DataProvider(name = "bug8150704") + private Object[][] dataBug8150704() { + return new Object[][] { + //xsl file, xml file, reference file + {"Bug8150704-1.xsl", "Bug8150704-1.xml", "Bug8150704-1.ref"}, + {"Bug8150704-2.xsl", "Bug8150704-2.xml", "Bug8150704-2.ref"}, + }; + } + + private Transformer createTransformerFromResource(String xslResource) throws TransformerException { + return TransformerFactory.newInstance().newTransformer(new StreamSource(getClass().getResource(xslResource).toString())); + } + + private StringWriter transformResourceToStringWriter(Transformer transformer, String xmlResource) throws TransformerException { + StringWriter sw = new StringWriter(); + transformer.transform(new StreamSource(getClass().getResource(xmlResource).toString()), new StreamResult(sw)); + return sw; + } + + /** + * Reads the contents of the given file into a string. + * WARNING: this method adds a final line feed even if the last line of the file doesn't contain one. + * + * @param f + * The file to read + * @return The content of the file as a string, with line terminators as \"n" + * for all platforms + * @throws IOException + * If there was an error reading + */ + private String getFileContentAsString(File f) throws IOException { + try (BufferedReader reader = new BufferedReader(new FileReader(f))) { + String line; + StringBuilder sb = new StringBuilder(); + while ((line = reader.readLine()) != null) { + sb.append(line).append("\n"); + } + return sb.toString(); + } + } +} diff --git a/test/javax/xml/jaxp/validation/8149915/Bug8149915.xsd b/test/javax/xml/jaxp/validation/8149915/Bug8149915.xsd new file mode 100644 index 0000000000000000000000000000000000000000..872033f5d1a7959003ee0c02595a0900751c2c05 --- /dev/null +++ b/test/javax/xml/jaxp/validation/8149915/Bug8149915.xsd @@ -0,0 +1,7 @@ + + + + Testapp for XSD annotation issue + This is an XSD annotation, just for the sake of it. + + diff --git a/test/javax/xml/jaxp/validation/8149915/SchemaTest.java b/test/javax/xml/jaxp/validation/8149915/SchemaTest.java new file mode 100644 index 0000000000000000000000000000000000000000..c58d842429bec131dc53d931cb19f38c35cf4e49 --- /dev/null +++ b/test/javax/xml/jaxp/validation/8149915/SchemaTest.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2016, 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. + * + * 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. + */ + + +/* @test + * @summary Test Schema creation + * @bug 8149915 + * @run testng/othervm SchemaTest + */ + +import java.io.File; +import javax.xml.XMLConstants; +import javax.xml.validation.SchemaFactory; +import org.testng.annotations.Test; + +public class SchemaTest { + + /* + * @bug 8149915 + * Verifies that the annotation validator is initialized with the security manager for schema + * creation with http://apache.org/xml/features/validate-annotations=true. + */ + @Test + public void testValidation() throws Exception { + SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + factory.setFeature("http://apache.org/xml/features/validate-annotations", true); + factory.newSchema(new File(getClass().getResource("Bug8149915.xsd").getFile())); + } +} diff --git a/test/lib/testlibrary/JavaToolUtils.java b/test/lib/testlibrary/JavaToolUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..c9736bcf9a043945b540031866d0a2c9ce9e9db1 --- /dev/null +++ b/test/lib/testlibrary/JavaToolUtils.java @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2014, 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. + */ + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.file.Files; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.TimeUnit; +import java.util.jar.Attributes; +import java.util.jar.JarEntry; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.ToolProvider; + +/** + * Utils class for compiling , creating jar file and executing a java command + * + * @author Raghu Nair + */ + +public class JavaToolUtils { + + public static final long DEFAULT_WAIT_TIME = 10000; + + private JavaToolUtils() { + } + + /** + * Takes a list of files and compile these files into the working directory. + * + * @param files + * @throws IOException + */ + public static void compileFiles(List files) throws IOException { + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + try (StandardJavaFileManager fileManager = compiler. + getStandardFileManager(null, null, null)) { + Iterable compilationUnit + = fileManager.getJavaFileObjectsFromFiles(files); + compiler.getTask(null, fileManager, null, null, null, + compilationUnit).call(); + } + } + + /** + * Create a jar file using the list of files provided. + * + * @param jar + * @param files + * @throws IOException + */ + public static void createJar(File jar, List files) + throws IOException { + Manifest manifest = new Manifest(); + manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, + "1.0"); + try (JarOutputStream target = new JarOutputStream( + new FileOutputStream(jar), manifest)) { + for (File file : files) { + add(file, target); + } + } + } + + private static void add(File source, JarOutputStream target) + throws IOException { + Objects.requireNonNull(source, "source cannot be null"); + Objects.requireNonNull(target, "target cannot be null"); + // not tested against directories and from different path. + String name = source.getName(); + if (source.isDirectory()) { + if (!name.isEmpty()) { + if (!name.endsWith("/")) { + name += "/"; + } + JarEntry entry = new JarEntry(name); + entry.setTime(source.lastModified()); + target.putNextEntry(entry); + target.closeEntry(); + } + for (File nestedFile : source.listFiles()) { + add(nestedFile, target); + } + return; + } + System.out.println("Adding entry " + name); + JarEntry entry = new JarEntry(name); + entry.setTime(source.lastModified()); + target.putNextEntry(entry); + Files.copy(source.toPath(), target); + target.closeEntry(); + } + + /** + * Runs java command with provided arguments. Caller should not pass java + * command in the argument list. + * + * @param commands + * @param waitTime time to wait for the command to exit in milli seconds + * @return + * @throws Exception + */ + public static int runJava(List commands,long waitTime) + throws Exception { + String java = System.getProperty("java.home") + "/bin/java"; + commands.add(0, java); + String command = commands.toString().replace(",", " "); + System.out.println("Executing the following command \n" + command); + ProcessBuilder processBuilder = new ProcessBuilder(commands); + final Process process = processBuilder.start(); + BufferedReader errorStream = new BufferedReader( + new InputStreamReader(process.getErrorStream())); + BufferedReader outStream = new BufferedReader( + new InputStreamReader(process.getInputStream())); + String errorLine; + StringBuilder errors = new StringBuilder(); + String outLines; + while ((errorLine = errorStream.readLine()) != null) { + errors.append(errorLine).append("\n"); + } + while ((outLines = outStream.readLine()) != null) { + System.out.println(outLines); + } + errorLine = errors.toString(); + System.err.println(errorLine); + process.waitFor(waitTime, TimeUnit.MILLISECONDS); + int exitStatus = process.exitValue(); + if (exitStatus != 0 && errorLine != null && errorLine.isEmpty()) { + throw new RuntimeException(errorLine); + } + return exitStatus; + } + + /** + * Runs java command with provided arguments. Caller should not pass java + * command in the argument list. + * + * @param commands + * @return + * @throws Exception + */ + public static int runJava(List commands) throws Exception { + return runJava(commands, DEFAULT_WAIT_TIME); + } + + /** + * Run any command + * @param commands + * @return + * @throws Exception + */ + public static int runCommand(List commands) throws Exception { + String command = commands.toString().replace(",", " "); + System.out.println("Executing the following command \n" + command); + ProcessBuilder processBuilder = new ProcessBuilder(commands); + final Process process = processBuilder.start(); + BufferedReader errorStream = new BufferedReader( + new InputStreamReader(process.getErrorStream())); + BufferedReader outStream = new BufferedReader( + new InputStreamReader(process.getInputStream())); + String errorLine; + StringBuilder errors = new StringBuilder(); + String outLines; + while ((errorLine = errorStream.readLine()) != null) { + errors.append(errorLine).append("\n"); + } + while ((outLines = outStream.readLine()) != null) { + System.out.println(outLines); + } + errorLine = errors.toString(); + System.err.println(errorLine); + int exitStatus = process.exitValue(); + if (exitStatus != 0 && errorLine != null && errorLine.isEmpty()) { + throw new RuntimeException(errorLine); + } + return exitStatus; + } + + +} diff --git a/test/lib/testlibrary/jdk/testlibrary/JcmdBase.java b/test/lib/testlibrary/jdk/testlibrary/JcmdBase.java index 14599c998bd51e46f35168772e93bbd7e69fe297..1837ceae1738b94354d5439df50f2fc5f41959ae 100644 --- a/test/lib/testlibrary/jdk/testlibrary/JcmdBase.java +++ b/test/lib/testlibrary/jdk/testlibrary/JcmdBase.java @@ -26,34 +26,91 @@ package jdk.testlibrary; import java.util.Arrays; /** - * Super class for tests which need to attach jcmd to the current process. + * Helper class for starting jcmd process. + *

+ * - jcmd will send diagnostic requests to the current java process:
+ *      jcmd pid_to_current_process PerfCounter.print
+ * - jcmd will be run without sending request to any JVM
+ *      jcmd -h
+ * 
*/ -public class JcmdBase { +public final class JcmdBase { private static ProcessBuilder processBuilder = new ProcessBuilder(); + private JcmdBase() { + // Private constructor to prevent class instantiation + } + /** - * Attach jcmd to the current process + * Sends the diagnostic command request to the current process * - * @param toolArgs - * jcmd command line parameters, e.g. VM.flags - * @return jcmd output - * @throws Exception + * @see #jcmd(boolean, String[], String[]) */ - public final static OutputAnalyzer jcmd(String... toolArgs) + public final static OutputAnalyzer jcmd(String... jcmdArgs) throws Exception { + return jcmd(true, null, jcmdArgs); + } + + /** + * Sends the diagnostic command request to the current process. + * jcmd will be run with specified {@code vmArgs}. + * + * @see #jcmd(boolean, String[], String[]) + */ + public final static OutputAnalyzer jcmd(String[] vmArgs, + String[] jcmdArgs) throws Exception { + return jcmd(true, vmArgs, jcmdArgs); + } + + /** + * Runs jcmd without sending request to any JVM + * + * @see #jcmd(boolean, String[], String[]) + */ + public final static OutputAnalyzer jcmdNoPid(String[] vmArgs, + String[] jcmdArgs) throws Exception { + return jcmd(false, vmArgs, jcmdArgs); + } + + /** + * If {@code requestToCurrentProcess} is {@code true} + * sends a diagnostic command request to the current process. + * If {@code requestToCurrentProcess} is {@code false} + * runs jcmd without sending request to any JVM. + * + * @param requestToCurrentProcess + * Defines if jcmd will send request to the current process + * @param vmArgs + * jcmd will be run with VM arguments specified, + * e.g. -XX:+UsePerfData + * @param jcmdArgs + * jcmd will be run with option or command and its arguments + * specified, e.g. VM.flags + * @return The output from {@link OutputAnalyzer} object + * @throws Exception + */ + private static final OutputAnalyzer jcmd(boolean requestToCurrentProcess, + String[] vmArgs, String[] jcmdArgs) throws Exception { JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jcmd"); - launcher.addToolArg(Integer.toString(ProcessTools.getProcessId())); - for (String toolArg : toolArgs) { - launcher.addToolArg(toolArg); + if (vmArgs != null) { + for (String vmArg : vmArgs) { + launcher.addVMArg(vmArg); + } + } + if (requestToCurrentProcess) { + launcher.addToolArg(Long.toString(ProcessTools.getProcessId())); + } + if (jcmdArgs != null) { + for (String toolArg : jcmdArgs) { + launcher.addToolArg(toolArg); + } } processBuilder.command(launcher.getCommand()); System.out.println(Arrays.toString(processBuilder.command().toArray()).replace(",", "")); OutputAnalyzer output = new OutputAnalyzer(processBuilder.start()); System.out.println(output.getOutput()); - output.shouldHaveExitValue(0); - return output; } diff --git a/test/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java b/test/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java index d39c0ab2ce2102a64e6cf35a935ba7aea00b5862..7c0d36400ba2b13d6e0fb74c3403a4b4c8a57923 100644 --- a/test/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java +++ b/test/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java @@ -23,11 +23,14 @@ package jdk.testlibrary; +import static jdk.testlibrary.Asserts.*; + import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.Scanner; /** * Utility class for verifying output and exit value from a {@code Process}. @@ -397,22 +400,105 @@ public final class OutputAnalyzer { return exitValue; } + /** * Get the contents of the output buffer (stdout and stderr) as list of strings. * Output will be split by system property 'line.separator'. * * @return Contents of the output buffer as list of strings */ - public List asLines() { - return asLines(getOutput()); - } + public List asLines() { + return asLines(getOutput()); + } - private List asLines(String buffer) { + public List asLines(String buffer) { List l = new ArrayList<>(); + String[] a = buffer.split(Utils.NEW_LINE); + for (String string : a) { l.add(string); } return l; } + + /** + * Check if there is a line matching {@code pattern} and return its index + * + * @param pattern Matching pattern + * @return Index of first matching line + */ + private int indexOf(List lines, String pattern) { + for (int i = 0; i < lines.size(); i++) { + if (lines.get(i).matches (pattern)) { + return i; + } + } + return -1; + } + + /** + * @see #shouldMatchByLine(String, String, String) + */ + public int shouldMatchByLine(String pattern) { + return shouldMatchByLine(null, null, pattern); + } + + /** + * @see #shouldMatchByLine(String, String, String) + */ + public int shouldMatchByLineFrom(String from, String pattern) { + return shouldMatchByLine(from, null, pattern); + } + + /** + * @see #shouldMatchByLine(String, String, String) + */ + public int shouldMatchByLineTo(String to, String pattern) { + return shouldMatchByLine(null, to, pattern); + } + + /** + * Verify that the stdout and stderr contents of output buffer match the + * {@code pattern} line by line. The whole output could be matched or + * just a subset of it. + * + * @param from + * The line from where output will be matched. + * Set {@code from} to null for matching from the first line. + * @param to + * The line until where output will be matched. + * Set {@code to} to null for matching until the last line. + * @param pattern + * Matching pattern + * @return Count of lines which match the {@code pattern} + */ + public int shouldMatchByLine(String from, String to, String pattern) { + List lines = asLines(); + + int fromIndex = 0; + if (from != null) { + fromIndex = indexOf(lines, from); + assertGreaterThan(fromIndex, -1, + "The line/pattern '" + from + "' from where the output should match can not be found"); + } + + int toIndex = lines.size(); + if (to != null) { + toIndex = indexOf(lines, to); + assertGreaterThan(toIndex, -1, + "The line/pattern '" + to + "' until where the output should match can not be found"); + } + + List subList = lines.subList(fromIndex, toIndex); + int matchedCount = 0; + for (String line : subList) { + assertTrue(line.matches(pattern), + "The line '" + line + "' does not match pattern '" + pattern + "'"); + matchedCount++; + } + + return matchedCount; + } + } diff --git a/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java b/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java index a5b956fea2bc5e7f3dab0cf65476eb691426d5f5..5050e15dff5207cf762f33b5d7db9a631d814811 100644 --- a/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java +++ b/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java @@ -269,16 +269,46 @@ public final class ProcessTools { } /** - * Create ProcessBuilder using the java launcher from the jdk to be tested - * and with any platform specific arguments prepended + * Create ProcessBuilder using the java launcher from the jdk to be tested, + * and with any platform specific arguments prepended. + * + * @param command Arguments to pass to the java command. + * @return The ProcessBuilder instance representing the java command. */ public static ProcessBuilder createJavaProcessBuilder(String... command) throws Exception { + return createJavaProcessBuilder(false, command); + } + + /** + * Create ProcessBuilder using the java launcher from the jdk to be tested, + * and with any platform specific arguments prepended. + * + * @param addTestVmAndJavaOptions If true, adds test.vm.opts and test.java.opts + * to the java arguments. + * @param command Arguments to pass to the java command. + * @return The ProcessBuilder instance representing the java command. + */ + public static ProcessBuilder createJavaProcessBuilder(boolean addTestVmAndJavaOptions, String... command) throws Exception { String javapath = JDKToolFinder.getJDKTool("java"); ArrayList args = new ArrayList<>(); args.add(javapath); Collections.addAll(args, getPlatformSpecificVMArgs()); + + if (addTestVmAndJavaOptions) { + // -cp is needed to make sure the same classpath is used whether the test is + // run in AgentVM mode or OtherVM mode. It was added to the hotspot version + // of this API as part of 8077608. However, for the jdk version it is only + // added when addTestVmAndJavaOptions is true in order to minimize + // disruption to existing JDK tests, which have yet to be tested with -cp + // being added. At some point -cp should always be added to be consistent + // with what the hotspot version does. + args.add("-cp"); + args.add(System.getProperty("java.class.path")); + Collections.addAll(args, Utils.getTestJavaOpts()); + } + Collections.addAll(args, command); // Reporting diff --git a/test/lib/testlibrary/jdk/testlibrary/Utils.java b/test/lib/testlibrary/jdk/testlibrary/Utils.java index 67af0cddc9a7e21cc3fbd20624d5471fdb0610f4..c21923460b614577009990b3722a49e00ddfffbc 100644 --- a/test/lib/testlibrary/jdk/testlibrary/Utils.java +++ b/test/lib/testlibrary/jdk/testlibrary/Utils.java @@ -25,6 +25,9 @@ package jdk.testlibrary; import static jdk.testlibrary.Asserts.assertTrue; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; import java.io.IOException; import java.net.InetAddress; import java.net.ServerSocket; @@ -241,7 +244,6 @@ public final class Utils { * @throws Exception If multiple matching jvms are found. */ public static int tryFindJvmPid(String key) throws Throwable { - ProcessBuilder pb = null; OutputAnalyzer output = null; try { JDKToolLauncher jcmdLauncher = JDKToolLauncher.create("jcmd"); @@ -268,6 +270,25 @@ public final class Utils { } } + /** + * Returns file content as a list of strings + * + * @param file File to operate on + * @return List of strings + * @throws IOException + */ + public static List fileAsList(File file) throws IOException { + assertTrue(file.exists() && file.isFile(), + file.getAbsolutePath() + " does not exist or not a file"); + List output = new ArrayList<>(); + try (BufferedReader reader = new BufferedReader(new FileReader(file.getAbsolutePath()))) { + while (reader.ready()) { + output.add(reader.readLine().replace(NEW_LINE, "")); + } + } + return output; + } + /** * Adjusts the provided timeout value for the TIMEOUT_FACTOR * @param tOut the timeout value to be adjusted diff --git a/test/sample/TEST.properties b/test/sample/TEST.properties new file mode 100644 index 0000000000000000000000000000000000000000..8e5f78afde3d4e7b741ea954878801dc26e9b334 --- /dev/null +++ b/test/sample/TEST.properties @@ -0,0 +1 @@ +external.lib.roots = ../../ diff --git a/test/sample/chatserver/ChatTest.java b/test/sample/chatserver/ChatTest.java index 05d6f44e8608ad7eb84ce25945e919e03f5cab8d..9cb2daa70c57d1dc1081f6e8a6560b674b9f622d 100644 --- a/test/sample/chatserver/ChatTest.java +++ b/test/sample/chatserver/ChatTest.java @@ -25,9 +25,9 @@ /* @test * @summary Test chat server chatserver test * - * @library ../../../src/share/sample/nio/chatserver + * @library /src/share/sample/nio/chatserver * @build ChatTest ChatServer Client ClientReader DataReader MessageReader NameReader - * @run main ChatTest + * @run testng ChatTest */ import java.io.*; @@ -38,10 +38,13 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.CyclicBarrier; +import org.testng.annotations.Test; + public class ChatTest { public static int listeningPort = 0; - public static void main(String[] args) throws Throwable { + @Test + public static void doTest() throws Throwable { testStartStop(); testPortOpen(); testAsksForName(); diff --git a/test/sample/mergesort/MergeSortTest.java b/test/sample/mergesort/MergeSortTest.java index 001e4f0a17061825c68263ea5b05e838f3c9d06b..53b5252eb9000ce109ef88d187374165807039c7 100644 --- a/test/sample/mergesort/MergeSortTest.java +++ b/test/sample/mergesort/MergeSortTest.java @@ -25,14 +25,16 @@ /* @test * @summary Test MergeSort * - * @library ../../../src/share/sample/forkjoin/mergesort + * @library /src/share/sample/forkjoin/mergesort * @build MergeSortTest MergeDemo MergeSort - * @run main MergeSortTest + * @run testng MergeSortTest */ import java.util.Arrays; import java.util.Random; +import org.testng.annotations.Test; + public class MergeSortTest { private Random random; private MergeSort target; @@ -42,7 +44,8 @@ public class MergeSortTest { this.target = target; } - public static void main(String[] args) { + @Test + public static void doTest() { MergeSortTest test = new MergeSortTest(new Random(), new MergeSort(Runtime.getRuntime().availableProcessors() * 4)); test.run(); } diff --git a/test/sun/awt/datatransfer/DataFlavorComparatorTest1.java b/test/sun/awt/datatransfer/DataFlavorComparatorTest1.java index cc926c807580db34add6ab041fd877968d7ab769..d9af913dc56c5d2a789fa9abe957968ab8b3bff1 100644 --- a/test/sun/awt/datatransfer/DataFlavorComparatorTest1.java +++ b/test/sun/awt/datatransfer/DataFlavorComparatorTest1.java @@ -37,42 +37,61 @@ public class DataFlavorComparatorTest1 { public static void main(String[] args) throws Exception { String[] mimes = new String[] { + "text/plain;class=java.nio.ByteBuffer;charset=UTF-8", + "text/uri-list;class=java.nio.ByteBuffer;charset=UTF-8", + "text/plain;class=java.nio.ByteBuffer;charset=UTF-16LE", + "text/uri-list;class=java.nio.ByteBuffer;charset=UTF-16LE", + "application/x-java-text-encoding", + "application/x-java-serialized-object;class=java.lang.String", + "text/plain;class=java.io.InputStream;charset=UTF-8", + "text/uri-list;class=java.io.InputStream;charset=UTF-8", + "text/plain;class=java.io.InputStream;charset=windows-1252", + "text/uri-list;class=java.io.InputStream;charset=windows-1252", + "application/x-java-url;class=java.net.URL", + "text/plain;class=java.io.Reader", + "text/plain;charset=windows-1252", + "text/uri-list;class=java.io.Reader", + "text/uri-list;charset=windows-1252", + "text/plain;charset=UTF-8", + "text/uri-list;charset=UTF-8", + "text/plain;class=java.io.InputStream;charset=US-ASCII", + "text/uri-list;class=java.io.InputStream;charset=US-ASCII", + "text/plain;class=java.io.InputStream;charset=UTF-16LE", + "text/plain;charset=US-ASCII", + "text/uri-list;class=java.io.InputStream;charset=UTF-16LE", + "text/uri-list;charset=US-ASCII", + "text/plain;charset=UTF-16LE", + "text/uri-list;charset=UTF-16LE", + "text/plain;class=java.nio.ByteBuffer;charset=UTF-16BE", + "text/uri-list;class=java.nio.ByteBuffer;charset=UTF-16BE", + "text/plain;class=java.nio.ByteBuffer;charset=ISO-8859-1", + "text/uri-list;class=java.nio.ByteBuffer;charset=ISO-8859-1", "text/plain", - "text/plain; charset=unicode", - "text/plain; charset=cp1251", - "text/plain; charset=unicode; class=java.io.InputStream", - "text/plain; charset=unicode; class=java.io.Serializable", - "text/plain; charset=unicode; class=java.lang.Object", - "text/plain; class=java.lang.String", - "text/plain; class=java.io.Reader", - "text/plain; class=java.lang.Object", - "text/html", - "text/html; charset=unicode", - "text/html; charset=cp1251", - "text/html; charset=unicode; class=java.io.InputStream", - "text/html; charset=unicode; class=java.io.Serializable", - "text/html; charset=unicode; class=java.lang.Object", - "text/html; class=java.lang.String", - "text/html; class=java.io.Reader", - "text/html; class=java.lang.Object", - "text/unknown", - "text/unknown; charset=unicode", - "text/unknown; charset=cp1251", - "text/unknown; charset=unicode; class=java.io.InputStream", - "text/unknown; charset=unicode; class=java.io.Serializable", - "text/unknown; charset=unicode; class=java.lang.Object", - "text/unknown; class=java.lang.String", - "text/unknown; class=java.io.Reader", - "text/unknown; class=java.lang.Object", - "application/unknown; class=java.io.InputStream", - "application/unknown; class=java.lang.Object", - "application/unknown", - "application/x-java-jvm-local-objectref; class=java.io.InputStream", - "application/x-java-jvm-local-objectref; class=java.lang.Object", - "application/x-java-jvm-local-objectref", - "unknown/flavor", - "unknown/flavor; class=java.io.InputStream", - "unknown/flavor; class=java.lang.Object", + "text/uri-list", + "text/plain;class=java.nio.ByteBuffer;charset=UTF-16", + "text/uri-list;class=java.nio.ByteBuffer;charset=UTF-16", + "text/plain;class=java.io.InputStream;charset=unicode", + "text/uri-list;class=java.io.InputStream;charset=UTF-16", + "text/plain;class=java.nio.CharBuffer", + "text/uri-list;class=java.nio.CharBuffer", + "text/plain;class=java.lang.String", + "text/plain;charset=UTF-16BE", + "text/uri-list;class=java.lang.String", + "text/uri-list;charset=UTF-16BE", + "text/plain;charset=ISO-8859-1", + "text/uri-list;charset=ISO-8859-1", + "text/plain;class=java.io.InputStream;charset=UTF-16BE", + "text/uri-list;class=java.io.InputStream;charset=UTF-16BE", + "text/plain;class=java.nio.ByteBuffer;charset=US-ASCII", + "text/uri-list;class=java.nio.ByteBuffer;charset=US-ASCII", + "text/plain;class=java.io.InputStream;charset=ISO-8859-1", + "text/uri-list;class=java.io.InputStream;charset=ISO-8859-1", + "text/plain;charset=UTF-16", + "text/plain;class=java.nio.ByteBuffer;charset=windows-1252", + "text/uri-list;charset=UTF-16", + "text/uri-list;class=java.nio.ByteBuffer;charset=windows-1252", + "text/plain;class=java.io.InputStream;charset=windows-1252", + "text/uri-list;class=java.io.InputStream;charset=windows-1252", }; DataFlavor[] flavors = new DataFlavor[mimes.length]; diff --git a/test/sun/management/jmxremote/bootstrap/JMXAgentInterfaceBinding.java b/test/sun/management/jmxremote/bootstrap/JMXAgentInterfaceBinding.java new file mode 100644 index 0000000000000000000000000000000000000000..4647f280fef13e3064b7b51b03b6da80551494b6 --- /dev/null +++ b/test/sun/management/jmxremote/bootstrap/JMXAgentInterfaceBinding.java @@ -0,0 +1,306 @@ +/* + * Copyright (c) 2015, Red Hat Inc + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.MalformedURLException; +import java.net.Socket; +import java.net.SocketAddress; +import java.net.UnknownHostException; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXServiceURL; +import javax.management.remote.rmi.RMIConnectorServer; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; +import javax.rmi.ssl.SslRMIClientSocketFactory; + +/** + * Tests client connections to the JDK's built-in JMX agent server on the given + * ports/interface combinations. + * + * @see JMXInterfaceBindingTest + * + * @author Severin Gehwolf + * + * Usage: + * + * SSL: + * java -Dcom.sun.management.jmxremote.ssl.need.client.auth=true \ + * -Dcom.sun.management.jmxremote.host=127.0.0.1 \ + * -Dcom.sun.management.jmxremote.port=9111 \ + * -Dcom.sun.management.jmxremote.rmi.port=9112 \ + * -Dcom.sun.management.jmxremote.authenticate=false \ + * -Dcom.sun.management.jmxremote.ssl=true \ + * -Dcom.sun.management.jmxremote.registry.ssl=true + * -Djavax.net.ssl.keyStore=... \ + * -Djavax.net.ssl.keyStorePassword=... \ + * JMXAgentInterfaceBinding 127.0.0.1 9111 9112 true + * + * Non-SSL: + * java -Dcom.sun.management.jmxremote.host=127.0.0.1 \ + * -Dcom.sun.management.jmxremote.port=9111 \ + * -Dcom.sun.management.jmxremote.rmi.port=9112 \ + * -Dcom.sun.management.jmxremote.authenticate=false \ + * -Dcom.sun.management.jmxremote.ssl=false \ + * JMXAgentInterfaceBinding 127.0.0.1 9111 9112 false + * + */ +public class JMXAgentInterfaceBinding { + + private final MainThread mainThread; + + public JMXAgentInterfaceBinding(InetAddress bindAddress, + int jmxPort, + int rmiPort, + boolean useSSL) { + this.mainThread = new MainThread(bindAddress, jmxPort, rmiPort, useSSL); + } + + public void startEndpoint() { + mainThread.start(); + try { + mainThread.join(); + } catch (InterruptedException e) { + throw new RuntimeException("Test failed", e); + } + if (mainThread.isFailed()) { + mainThread.rethrowException(); + } + } + + public static void main(String[] args) { + if (args.length != 4) { + throw new RuntimeException( + "Test failed. usage: java JMXInterfaceBindingTest {true|false}"); + } + int jmxPort = parsePortFromString(args[1]); + int rmiPort = parsePortFromString(args[2]); + boolean useSSL = Boolean.parseBoolean(args[3]); + String strBindAddr = args[0]; + System.out.println( + "DEBUG: Running test for triplet (hostname,jmxPort,rmiPort) = (" + + strBindAddr + "," + jmxPort + "," + rmiPort + "), useSSL = " + useSSL); + InetAddress bindAddress; + try { + bindAddress = InetAddress.getByName(args[0]); + } catch (UnknownHostException e) { + throw new RuntimeException("Test failed. Unknown ip: " + args[0]); + } + JMXAgentInterfaceBinding test = new JMXAgentInterfaceBinding(bindAddress, + jmxPort, rmiPort, useSSL); + test.startEndpoint(); // Expect for main test to terminate process + } + + private static int parsePortFromString(String port) { + try { + return Integer.parseInt(port); + } catch (NumberFormatException e) { + throw new RuntimeException( + "Invalid port specified. Not an integer! Value was: " + + port); + } + } + + private static class JMXConnectorThread extends Thread { + + private final String addr; + private final int jmxPort; + private final int rmiPort; + private final boolean useSSL; + private final CountDownLatch latch; + private boolean failed; + private boolean jmxConnectWorked; + private boolean rmiConnectWorked; + + private JMXConnectorThread(String addr, + int jmxPort, + int rmiPort, + boolean useSSL, + CountDownLatch latch) { + this.addr = addr; + this.jmxPort = jmxPort; + this.rmiPort = rmiPort; + this.latch = latch; + this.useSSL = useSSL; + } + + @Override + public void run() { + try { + connect(); + } catch (IOException e) { + failed = true; + } + } + + private void connect() throws IOException { + System.out.println( + "JMXConnectorThread: Attempting JMX connection on: " + + addr + " on port " + jmxPort); + JMXServiceURL url; + try { + url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + + addr + ":" + jmxPort + "/jmxrmi"); + } catch (MalformedURLException e) { + throw new RuntimeException("Test failed.", e); + } + Map env = new HashMap<>(); + if (useSSL) { + SslRMIClientSocketFactory csf = new SslRMIClientSocketFactory(); + env.put("com.sun.jndi.rmi.factory.socket", csf); + env.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, csf); + } + // connect and immediately close + JMXConnector c = JMXConnectorFactory.connect(url, env); + c.close(); + System.out.println("JMXConnectorThread: connection to JMX worked"); + jmxConnectWorked = true; + checkRmiSocket(); + latch.countDown(); // signal we are done. + } + + private void checkRmiSocket() throws IOException { + Socket rmiConnection; + if (useSSL) { + rmiConnection = SSLSocketFactory.getDefault().createSocket(); + } else { + rmiConnection = new Socket(); + } + SocketAddress target = new InetSocketAddress(addr, rmiPort); + rmiConnection.connect(target); + if (useSSL) { + ((SSLSocket)rmiConnection).startHandshake(); + } + System.out.println( + "JMXConnectorThread: connection to rmi socket worked host/port = " + + addr + "/" + rmiPort); + rmiConnectWorked = true; + // Closing the channel without sending any data will cause an + // java.io.EOFException on the server endpoint. We don't care about this + // though, since we only want to test if we can connect. + rmiConnection.close(); + } + + public boolean isFailed() { + return failed; + } + + public boolean jmxConnectionWorked() { + return jmxConnectWorked; + } + + public boolean rmiConnectionWorked() { + return rmiConnectWorked; + } + } + + private static class MainThread extends Thread { + + private static final int WAIT_FOR_JMX_AGENT_TIMEOUT_MS = 500; + private final String addr; + private final int jmxPort; + private final int rmiPort; + private final boolean useSSL; + private boolean terminated = false; + private boolean jmxAgentStarted = false; + private Exception excptn; + + private MainThread(InetAddress bindAddress, int jmxPort, int rmiPort, boolean useSSL) { + this.addr = wrapAddress(bindAddress.getHostAddress()); + this.jmxPort = jmxPort; + this.rmiPort = rmiPort; + this.useSSL = useSSL; + } + + @Override + public void run() { + try { + waitUntilReadyForConnections(); + // Do nothing, but wait for termination. + try { + while (!terminated) { + Thread.sleep(100); + } + } catch (InterruptedException e) { // ignore + } + System.out.println("MainThread: Thread stopped."); + } catch (Exception e) { + this.excptn = e; + } + } + + private void waitUntilReadyForConnections() { + CountDownLatch latch = new CountDownLatch(1); + JMXConnectorThread connectionTester = new JMXConnectorThread( + addr, jmxPort, rmiPort, useSSL, latch); + connectionTester.start(); + boolean expired = false; + try { + expired = !latch.await(WAIT_FOR_JMX_AGENT_TIMEOUT_MS, TimeUnit.MILLISECONDS); + System.out.println( + "MainThread: Finished waiting for JMX agent to become available: expired == " + + expired); + jmxAgentStarted = !expired; + } catch (InterruptedException e) { + throw new RuntimeException("Test failed", e); + } + if (!jmxAgentStarted) { + throw new RuntimeException( + "Test failed. JMX server agents not becoming available."); + } + if (connectionTester.isFailed() + || !connectionTester.jmxConnectionWorked() + || !connectionTester.rmiConnectionWorked()) { + throw new RuntimeException( + "Test failed. JMX agent does not seem ready. See log output for details."); + } + // The main test expects this exact message being printed + System.out.println("MainThread: Ready for connections"); + } + + private boolean isFailed() { + return excptn != null; + } + + private void rethrowException() throws RuntimeException { + throw new RuntimeException(excptn); + } + } + + /** + * Will wrap IPv6 address in '[]' + */ + static String wrapAddress(String address) { + if (address.contains(":")) { + return "[" + address + "]"; + } + return address; + } +} diff --git a/test/sun/management/jmxremote/bootstrap/JMXInterfaceBindingTest.java b/test/sun/management/jmxremote/bootstrap/JMXInterfaceBindingTest.java new file mode 100644 index 0000000000000000000000000000000000000000..4a48278af1299ef77c1457bd3499a85029a95051 --- /dev/null +++ b/test/sun/management/jmxremote/bootstrap/JMXInterfaceBindingTest.java @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2015, Red Hat Inc + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.File; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.function.Predicate; + +import jdk.testlibrary.ProcessTools; + +/** + * NOTE: + * This test requires at least a setup similar to the following in + * /etc/hosts file (or the windows equivalent). I.e. it expects it to + * be multi-homed and not both being the loop-back interface. + * For example: + * ----->8-------- /etc/hosts ----------->8--- + * 127.0.0.1 localhost + * 192.168.0.1 localhost + * ----->8-------- /etc/hosts ----------->8--- + * + * @test + * @bug 6425769 + * @summary Test JMX agent host address binding. Same ports but different + * interfaces to bind to (using plain sockets and SSL sockets). + * + * @modules java.management/sun.management + * java.management/sun.management.jmxremote + * @library /lib/testlibrary + * @build jdk.testlibrary.* JMXAgentInterfaceBinding + * @run main/timeout=5 JMXInterfaceBindingTest + */ +public class JMXInterfaceBindingTest { + + public static final int COMMUNICATION_ERROR_EXIT_VAL = 1; + public static final int STOP_PROCESS_EXIT_VAL = 137; + public static final int JMX_PORT = 9111; + public static final int RMI_PORT = 9112; + public static final String READY_MSG = "MainThread: Ready for connections"; + public static final String TEST_CLASS = JMXAgentInterfaceBinding.class.getSimpleName(); + public static final String KEYSTORE_LOC = System.getProperty("test.src", ".") + + File.separator + + "ssl" + + File.separator + + "keystore"; + public static final String TRUSTSTORE_LOC = System.getProperty("test.src", ".") + + File.separator + + "ssl" + + File.separator + + "truststore"; + public static final String TEST_CLASSPATH = System.getProperty("test.classes", "."); + + public void run(List addrs) { + System.out.println("DEBUG: Running tests with plain sockets."); + runTests(addrs, false); + System.out.println("DEBUG: Running tests with SSL sockets."); + runTests(addrs, true); + } + + private void runTests(List addrs, boolean useSSL) { + TestProcessThread[] jvms = new TestProcessThread[addrs.size()]; + for (int i = 0; i < addrs.size(); i++) { + String addr = JMXAgentInterfaceBinding.wrapAddress(addrs.get(i).getHostAddress()); + System.out.println(); + String msg = String.format("DEBUG: Launching java tester for triplet (HOSTNAME,JMX_PORT,RMI_PORT) == (%s,%d,%d)", + addr, + JMX_PORT, + RMI_PORT); + System.out.println(msg); + jvms[i] = runJMXBindingTest(addr, useSSL); + jvms[i].start(); + System.out.println("DEBUG: Started " + (i + 1) + " Process(es)."); + } + int failedProcesses = 0; + for (TestProcessThread pt: jvms) { + try { + pt.stopProcess(); + pt.join(); + } catch (InterruptedException e) { + System.err.println("Failed to stop process: " + pt.getName()); + throw new RuntimeException("Test failed", e); + } + int exitValue = pt.getExitValue(); + // If there is a communication error (the case we care about) + // we get a exit code of 1 + if (exitValue == COMMUNICATION_ERROR_EXIT_VAL) { + // Failure case since the java processes should still be + // running. + System.err.println("Test FAILURE on " + pt.getName()); + failedProcesses++; + } else if (exitValue == STOP_PROCESS_EXIT_VAL) { + System.out.println("DEBUG: OK. Spawned java process terminated with expected exit code of " + STOP_PROCESS_EXIT_VAL); + } else { + System.err.println("Test FAILURE on " + pt.getName() + " reason: Unexpected exit code => " + exitValue); + failedProcesses++; + } + } + if (failedProcesses > 0) { + throw new RuntimeException("Test FAILED. " + failedProcesses + " out of " + addrs.size() + " process(es) failed to start the JMX agent."); + } + } + + private TestProcessThread runJMXBindingTest(String address, boolean useSSL) { + List args = new ArrayList<>(); + args.add("-classpath"); + args.add(TEST_CLASSPATH); + args.add("-Dcom.sun.management.jmxremote.host=" + address); + args.add("-Dcom.sun.management.jmxremote.port=" + JMX_PORT); + args.add("-Dcom.sun.management.jmxremote.rmi.port=" + RMI_PORT); + args.add("-Dcom.sun.management.jmxremote.authenticate=false"); + args.add("-Dcom.sun.management.jmxremote.ssl=" + Boolean.toString(useSSL)); + if (useSSL) { + args.add("-Dcom.sun.management.jmxremote.registry.ssl=true"); + args.add("-Djavax.net.ssl.keyStore=" + KEYSTORE_LOC); + args.add("-Djavax.net.ssl.trustStore=" + TRUSTSTORE_LOC); + args.add("-Djavax.net.ssl.keyStorePassword=password"); + args.add("-Djavax.net.ssl.trustStorePassword=trustword"); + } + args.add(TEST_CLASS); + args.add(address); + args.add(Integer.toString(JMX_PORT)); + args.add(Integer.toString(RMI_PORT)); + args.add(Boolean.toString(useSSL)); + try { + ProcessBuilder builder = ProcessTools.createJavaProcessBuilder(args.toArray(new String[] {})); + System.out.println(ProcessTools.getCommandLine(builder)); + TestProcessThread jvm = new TestProcessThread("JMX-Tester-" + address, JMXInterfaceBindingTest::isJMXAgentResponseAvailable, builder); + return jvm; + } catch (Exception e) { + throw new RuntimeException("Test failed", e); + } + + } + + private static boolean isJMXAgentResponseAvailable(String line) { + if (line.equals(READY_MSG)) { + System.out.println("DEBUG: Found expected READY_MSG."); + return true; + } else if (line.startsWith("Error:")) { + // Allow for a JVM process that exits with + // "Error: JMX connector server communication error: ..." + // to continue as well since we handle that case elsewhere. + // This has the effect that the test does not timeout and + // fails with an exception in the test. + System.err.println("PROBLEM: JMX agent of target JVM did not start as it should."); + return true; + } else { + return false; + } + } + + public static void main(String[] args) { + List addrs = getAddressesForLocalHost(); + if (addrs.size() < 2) { + System.out.println("Ignoring manual test since no more than one IPs are configured for 'localhost'"); + return; + } + JMXInterfaceBindingTest test = new JMXInterfaceBindingTest(); + test.run(addrs); + System.out.println("All tests PASSED."); + } + + private static List getAddressesForLocalHost() { + try { + List filtered = new ArrayList<>(); + for (NetworkInterface iface: Collections.list(NetworkInterface.getNetworkInterfaces())) { + for (InetAddress addr: Collections.list(iface.getInetAddresses())) { + if (isNonloopbackLocalhost(addr)) { + filtered.add(addr); + } + } + } + return filtered; + } catch (SocketException e) { + throw new RuntimeException("Test failed", e); + } + } + + // we need 'real' localhost addresses only (eg. not loopback ones) + // so we can bind the remote JMX connector to them + private static boolean isNonloopbackLocalhost(InetAddress i) { + if (!i.isLoopbackAddress()) { + return i.getHostName().toLowerCase().equals("localhost"); + } + return false; + } + + private static class TestProcessThread extends Thread { + + private final Predicate predicate; + private final ProcessBuilder pb; + private final CountDownLatch latch; + private Process process; + + public TestProcessThread(String threadName, Predicate predicate, ProcessBuilder pb) { + super(threadName); + this.predicate = predicate; + this.pb = pb; + this.latch = new CountDownLatch(1); + } + + @Override + public void run() { + try { + process = ProcessTools.startProcess(getName(), pb, predicate, 10, TimeUnit.SECONDS); + latch.countDown(); + process.waitFor(); + } catch (Exception e) { + throw new RuntimeException("Test failed", e); + } + } + + public void stopProcess() { + try { + latch.await(); + } catch (InterruptedException e1) { + throw new RuntimeException("Test failed", e1); + } + if (process != null) { + process.destroyForcibly(); + try { + process.waitFor(); + } catch (InterruptedException e) { + throw new RuntimeException("Test failed", e); + } + } + } + + public int getExitValue() { + return process.exitValue(); + } + } +} diff --git a/test/sun/nio/ch/TestMaxCachedBufferSize.java b/test/sun/nio/ch/TestMaxCachedBufferSize.java new file mode 100644 index 0000000000000000000000000000000000000000..8c8049bdf5c7df444131e82fefd6eeedde07efb2 --- /dev/null +++ b/test/sun/nio/ch/TestMaxCachedBufferSize.java @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2016, 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. + * + * 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. + */ + +import java.io.IOException; + +import java.lang.management.BufferPoolMXBean; +import java.lang.management.ManagementFactory; + +import java.nio.ByteBuffer; + +import java.nio.channels.FileChannel; + +import java.nio.file.Path; +import java.nio.file.Paths; + +import static java.nio.file.StandardOpenOption.CREATE; +import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING; +import static java.nio.file.StandardOpenOption.WRITE; + +import java.util.List; +import java.util.Random; + +/* + * @test + * @requires sun.arch.data.model == "64" + * @build TestMaxCachedBufferSize + * @run main/othervm TestMaxCachedBufferSize + * @run main/othervm -Djdk.nio.maxCachedBufferSize=0 TestMaxCachedBufferSize + * @run main/othervm -Djdk.nio.maxCachedBufferSize=2000 TestMaxCachedBufferSize + * @run main/othervm -Djdk.nio.maxCachedBufferSize=100000 TestMaxCachedBufferSize + * @run main/othervm -Djdk.nio.maxCachedBufferSize=10000000 TestMaxCachedBufferSize + * @summary Test the implementation of the jdk.nio.maxCachedBufferSize property. + */ +public class TestMaxCachedBufferSize { + private static final int DEFAULT_ITERS = 10 * 1000; + private static final int DEFAULT_THREAD_NUM = 4; + + private static final int SMALL_BUFFER_MIN_SIZE = 4 * 1024; + private static final int SMALL_BUFFER_MAX_SIZE = 64 * 1024; + private static final int SMALL_BUFFER_DIFF_SIZE = + SMALL_BUFFER_MAX_SIZE - SMALL_BUFFER_MIN_SIZE; + + private static final int LARGE_BUFFER_MIN_SIZE = 512 * 1024; + private static final int LARGE_BUFFER_MAX_SIZE = 4 * 1024 * 1024; + private static final int LARGE_BUFFER_DIFF_SIZE = + LARGE_BUFFER_MAX_SIZE - LARGE_BUFFER_MIN_SIZE; + + private static final int LARGE_BUFFER_FREQUENCY = 100; + + private static final String FILE_NAME_PREFIX = "nio-out-file-"; + private static final int VERBOSE_PERIOD = 5 * 1000; + + private static int iters = DEFAULT_ITERS; + private static int threadNum = DEFAULT_THREAD_NUM; + + private static BufferPoolMXBean getDirectPool() { + final List pools = + ManagementFactory.getPlatformMXBeans(BufferPoolMXBean.class); + for (BufferPoolMXBean pool : pools) { + if (pool.getName().equals("direct")) { + return pool; + } + } + throw new Error("could not find direct pool"); + } + private static final BufferPoolMXBean directPool = getDirectPool(); + + // Each worker will do write operations on a file channel using + // buffers of various sizes. The buffer size is randomly chosen to + // be within a small or a large range. This way we can control + // which buffers can be cached (all, only the small ones, or none) + // by setting the jdk.nio.maxCachedBufferSize property. + private static class Worker implements Runnable { + private final int id; + private final Random random = new Random(); + private long smallBufferCount = 0; + private long largeBufferCount = 0; + + private int getWriteSize() { + int minSize = 0; + int diff = 0; + if (random.nextInt() % LARGE_BUFFER_FREQUENCY != 0) { + // small buffer + minSize = SMALL_BUFFER_MIN_SIZE; + diff = SMALL_BUFFER_DIFF_SIZE; + smallBufferCount += 1; + } else { + // large buffer + minSize = LARGE_BUFFER_MIN_SIZE; + diff = LARGE_BUFFER_DIFF_SIZE; + largeBufferCount += 1; + } + return minSize + random.nextInt(diff); + } + + private void loop() { + final String fileName = String.format("%s%d", FILE_NAME_PREFIX, id); + + try { + for (int i = 0; i < iters; i += 1) { + final int writeSize = getWriteSize(); + + // This will allocate a HeapByteBuffer. It should not + // be a direct buffer, otherwise the write() method on + // the channel below will not create a temporary + // direct buffer for the write. + final ByteBuffer buffer = ByteBuffer.allocate(writeSize); + + // Put some random data on it. + while (buffer.hasRemaining()) { + buffer.put((byte) random.nextInt()); + } + buffer.rewind(); + + final Path file = Paths.get(fileName); + try (FileChannel outChannel = FileChannel.open(file, CREATE, TRUNCATE_EXISTING, WRITE)) { + // The write() method will create a temporary + // direct buffer for the write and attempt to cache + // it. It's important that buffer is not a + // direct buffer, otherwise the temporary buffer + // will not be created. + long res = outChannel.write(buffer); + } + + if ((i + 1) % VERBOSE_PERIOD == 0) { + System.out.printf( + " Worker %3d | %8d Iters | Small %8d Large %8d | Direct %4d / %7dK\n", + id, i + 1, smallBufferCount, largeBufferCount, + directPool.getCount(), directPool.getTotalCapacity() / 1024); + } + } + } catch (IOException e) { + throw new Error("I/O error", e); + } + } + + @Override + public void run() { + loop(); + } + + public Worker(int id) { + this.id = id; + } + } + + public static void checkDirectBuffers(long expectedCount, long expectedMax) { + final long directCount = directPool.getCount(); + final long directTotalCapacity = directPool.getTotalCapacity(); + System.out.printf("Direct %d / %dK\n", + directCount, directTotalCapacity / 1024); + + // Note that directCount could be < expectedCount. This can + // happen if a GC occurs after one of the worker threads exits + // since its thread-local DirectByteBuffer could be cleaned up + // before we reach here. + if (directCount > expectedCount) { + throw new Error(String.format( + "inconsistent direct buffer total count, expected = %d, found = %d", + expectedCount, directCount)); + } + + if (directTotalCapacity > expectedMax) { + throw new Error(String.format( + "inconsistent direct buffer total capacity, expectex max = %d, found = %d", + expectedMax, directTotalCapacity)); + } + } + + public static void main(String[] args) { + final String maxBufferSizeStr = System.getProperty("jdk.nio.maxCachedBufferSize"); + final long maxBufferSize = + (maxBufferSizeStr != null) ? Long.valueOf(maxBufferSizeStr) : Long.MAX_VALUE; + + // We assume that the max cannot be equal to a size of a + // buffer that can be allocated (makes sanity checking at the + // end easier). + if ((SMALL_BUFFER_MIN_SIZE <= maxBufferSize && + maxBufferSize <= SMALL_BUFFER_MAX_SIZE) || + (LARGE_BUFFER_MIN_SIZE <= maxBufferSize && + maxBufferSize <= LARGE_BUFFER_MAX_SIZE)) { + throw new Error(String.format("max buffer size = %d not allowed", + maxBufferSize)); + } + + System.out.printf("Threads %d | Iterations %d | MaxBufferSize %d\n", + threadNum, iters, maxBufferSize); + System.out.println(); + + final Thread[] threads = new Thread[threadNum]; + for (int i = 0; i < threadNum; i += 1) { + threads[i] = new Thread(new Worker(i)); + threads[i].start(); + } + + try { + for (int i = 0; i < threadNum; i += 1) { + threads[i].join(); + } + } catch (InterruptedException e) { + throw new Error("join() interrupted!", e); + } + + // There is an assumption here that, at this point, only the + // cached DirectByteBuffers should be active. Given we + // haven't used any other DirectByteBuffers in this test, this + // should hold. + // + // Also note that we can only do the sanity checking at the + // end and not during the run given that, at any time, there + // could be buffers currently in use by some of the workers + // that will not be cached. + + System.out.println(); + if (maxBufferSize < SMALL_BUFFER_MAX_SIZE) { + // The max buffer size is smaller than all buffers that + // were allocated. No buffers should have been cached. + checkDirectBuffers(0, 0); + } else if (maxBufferSize < LARGE_BUFFER_MIN_SIZE) { + // The max buffer size is larger than all small buffers + // but smaller than all large buffers that were + // allocated. Only small buffers could have been cached. + checkDirectBuffers(threadNum, + (long) threadNum * (long) SMALL_BUFFER_MAX_SIZE); + } else { + // The max buffer size is larger than all buffers that + // were allocated. All buffers could have been cached. + checkDirectBuffers(threadNum, + (long) threadNum * (long) LARGE_BUFFER_MAX_SIZE); + } + } +} diff --git a/test/sun/security/TestSignatureOidHelper.java b/test/sun/security/TestSignatureOidHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..be135992bf7427b19d9cb1848d16c0a2a1602944 --- /dev/null +++ b/test/sun/security/TestSignatureOidHelper.java @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +import java.security.InvalidKeyException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.Signature; +import java.security.SignatureException; +import java.util.List; + +/* + * Utilities for testing the signature algorithm OIDs. + */ +public class TestSignatureOidHelper { + + private static final byte[] INPUT = "1234567890".getBytes(); + + private final String algorithm; + + private final String provider; + + private final int keySize; + + private final List data; + + public TestSignatureOidHelper(String algorithm, String provider, + int keySize, List data) { + this.algorithm = algorithm; + this.provider = provider; + this.keySize = keySize; + this.data = data; + } + + public void execute() throws Exception { + KeyPair keyPair = createKeyPair(); + for (OidAlgorithmPair oidAlgorithmPair : data) { + runTest(oidAlgorithmPair, keyPair); + System.out.println("passed"); + } + System.out.println("All tests passed"); + } + + private KeyPair createKeyPair() + throws NoSuchAlgorithmException, NoSuchProviderException { + KeyPairGenerator keyGen = KeyPairGenerator.getInstance(algorithm, + provider); + keyGen.initialize(keySize); + return keyGen.generateKeyPair(); + } + + private void runTest(OidAlgorithmPair oidAlgorithmPair, KeyPair keyPair) + throws NoSuchAlgorithmException, NoSuchProviderException, + InvalidKeyException, SignatureException { + Signature sgAlgorithm = + Signature.getInstance(oidAlgorithmPair.algorithm, provider); + Signature sgOid = Signature.getInstance(oidAlgorithmPair.oid, provider); + + if (sgAlgorithm == null) { + throw new RuntimeException(String.format( + "Test failed: algorithm string %s getInstance failed.%n", + oidAlgorithmPair.algorithm)); + } + + if (sgOid == null) { + throw new RuntimeException( + String.format("Test failed: OID %s getInstance failed.%n", + oidAlgorithmPair.oid)); + } + + if (!sgAlgorithm.getAlgorithm().equals(oidAlgorithmPair.algorithm)) { + throw new RuntimeException(String.format( + "Test failed: algorithm string %s getInstance " + + "doesn't generate expected algorithm.%n", + oidAlgorithmPair.algorithm)); + } + + sgAlgorithm.initSign(keyPair.getPrivate()); + sgAlgorithm.update(INPUT); + sgOid.initVerify(keyPair.getPublic()); + sgOid.update(INPUT); + if (!sgOid.verify(sgAlgorithm.sign())) { + throw new RuntimeException( + "Signature verification failed unexpectedly"); + } + } +} + +class OidAlgorithmPair { + + public final String oid; + public final String algorithm; + + public OidAlgorithmPair(String oid, String algorithm) { + this.oid = oid; + this.algorithm = algorithm; + } + + @Override + public String toString() { + return "[oid=" + oid + ", algorithm=" + algorithm + "]"; + } +} diff --git a/test/sun/security/ec/NSASuiteB/TestSHAwithECDSASignatureOids.java b/test/sun/security/ec/NSASuiteB/TestSHAwithECDSASignatureOids.java new file mode 100644 index 0000000000000000000000000000000000000000..58a8106574666664277bb187d37638249ad52eee --- /dev/null +++ b/test/sun/security/ec/NSASuiteB/TestSHAwithECDSASignatureOids.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +import java.util.Arrays; +import java.util.List; + +/* + * @test + * @bug 8075286 + * @summary Test the SHAwithECDSA signature algorithm OIDs in JDK. + * OID and algorithm transformation string should match. + * Both could be able to be used to generate the algorithm instance. + * @compile ../../TestSignatureOidHelper.java + * @run main TestSHAwithECDSASignatureOids + */ +public class TestSHAwithECDSASignatureOids { + + private static final List DATA = Arrays.asList( + new OidAlgorithmPair("1.2.840.10045.4.1", "SHA1withECDSA"), + new OidAlgorithmPair("1.2.840.10045.4.3.1", "SHA224withECDSA"), + new OidAlgorithmPair("1.2.840.10045.4.3.2", "SHA256withECDSA"), + new OidAlgorithmPair("1.2.840.10045.4.3.3", "SHA384withECDSA"), + new OidAlgorithmPair("1.2.840.10045.4.3.4", "SHA512withECDSA")); + + public static void main(String[] args) throws Exception { + TestSignatureOidHelper helper = new TestSignatureOidHelper("EC", + "SunEC", 256, DATA); + helper.execute(); + } +} diff --git a/test/sun/security/ec/SignatureOffsets.java b/test/sun/security/ec/SignatureOffsets.java new file mode 100644 index 0000000000000000000000000000000000000000..948923e78bad3ec6cbd4d6400ae4ebf7463bee79 --- /dev/null +++ b/test/sun/security/ec/SignatureOffsets.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.SignatureException; + +/* + * @test + * @bug 8050374 + * @key randomness + * @summary This test validates signature verification + * Signature.verify(byte[], int, int). The test uses RandomFactory to + * get random set of clear text data to sign. After the signature + * generation, the test tries to verify signature with the above API + * and passing in different signature offset (0, 33, 66, 99). + * @library /lib/testlibrary + * @compile ../../../java/security/Signature/Offsets.java + * @run main SignatureOffsets SunEC NONEwithECDSA + * @run main SignatureOffsets SunEC SHA1withECDSA + * @run main SignatureOffsets SunEC SHA256withECDSA + * @run main SignatureOffsets SunEC SHA224withECDSA + * @run main SignatureOffsets SunEC SHA384withECDSA + * @run main SignatureOffsets SunEC SHA512withECDSA + */ +public class SignatureOffsets { + + public static void main(String[] args) throws NoSuchAlgorithmException, + InvalidKeyException, SignatureException { + Offsets.main(args); + } +} \ No newline at end of file diff --git a/test/sun/security/ec/SignedObjectChain.java b/test/sun/security/ec/SignedObjectChain.java new file mode 100644 index 0000000000000000000000000000000000000000..6e93053a776860630818eb2f5fb8f459eafeeb76 --- /dev/null +++ b/test/sun/security/ec/SignedObjectChain.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +/* + * @test + * @bug 8050374 + * @compile ../../../java/security/SignedObject/Chain.java + * @summary Verify a chain of signed objects + */ +public class SignedObjectChain { + + private static class Test extends Chain.Test { + + public Test(Chain.SigAlg sigAlg) { + super(sigAlg, Chain.KeyAlg.EC, Chain.Provider.SunEC); + } + } + + private static final Test[] tests = { + new Test(Chain.SigAlg.SHA1withECDSA), + new Test(Chain.SigAlg.SHA256withECDSA), + new Test(Chain.SigAlg.SHA224withECDSA), + new Test(Chain.SigAlg.SHA384withECDSA), + new Test(Chain.SigAlg.SHA512withECDSA), + }; + + public static void main(String argv[]) { + boolean resutl = java.util.Arrays.stream(tests).allMatch( + (test) -> Chain.runTest(test)); + + if(resutl) { + System.out.println("All tests passed"); + } else { + throw new RuntimeException("Some tests failed"); + } + } +} diff --git a/test/sun/security/mscapi/SignatureOffsets.java b/test/sun/security/mscapi/SignatureOffsets.java new file mode 100644 index 0000000000000000000000000000000000000000..34f91fbf9be91e2b0f11e1503486684577753811 --- /dev/null +++ b/test/sun/security/mscapi/SignatureOffsets.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.SignatureException; + +/* + * @test + * @bug 8050374 + * @key randomness + * @summary This test validates signature verification + * Signature.verify(byte[], int, int). The test uses RandomFactory to + * get random set of clear text data to sign. After the signature + * generation, the test tries to verify signature with the above API + * and passing in different signature offset (0, 33, 66, 99). + * @library /lib/testlibrary + * @compile ../../../java/security/Signature/Offsets.java + * @run main SignatureOffsets SunMSCAPI NONEwithRSA + * @run main SignatureOffsets SunMSCAPI MD2withRSA + * @run main SignatureOffsets SunMSCAPI MD5withRSA + * @run main SignatureOffsets SunMSCAPI SHA1withRSA + * @run main SignatureOffsets SunMSCAPI SHA256withRSA + * @run main SignatureOffsets SunMSCAPI SHA384withRSA + * @run main SignatureOffsets SunMSCAPI SHA512withRSA + */ +public class SignatureOffsets { + + public static void main(String[] args) throws NoSuchAlgorithmException, + InvalidKeyException, SignatureException { + Offsets.main(args); + } +} \ No newline at end of file diff --git a/test/sun/security/mscapi/SignedObjectChain.java b/test/sun/security/mscapi/SignedObjectChain.java new file mode 100644 index 0000000000000000000000000000000000000000..9790daa919bc23ff7efe9c8130a00418791fe909 --- /dev/null +++ b/test/sun/security/mscapi/SignedObjectChain.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +/* + * @test + * @bug 8050374 + * @compile ../../../java/security/SignedObject/Chain.java + * @summary Verify a chain of signed objects + */ +public class SignedObjectChain { + + private static class Test extends Chain.Test { + + public Test(Chain.SigAlg sigAlg) { + super(sigAlg, Chain.KeyAlg.RSA, Chain.Provider.SunMSCAPI); + } + } + + private static final Test[] tests = { + new Test(Chain.SigAlg.MD2withRSA), + new Test(Chain.SigAlg.MD5withRSA), + new Test(Chain.SigAlg.SHA1withRSA), + new Test(Chain.SigAlg.SHA256withRSA), + new Test(Chain.SigAlg.SHA384withRSA), + new Test(Chain.SigAlg.SHA512withRSA), + }; + + public static void main(String argv[]) { + boolean resutl = java.util.Arrays.stream(tests).allMatch( + (test) -> Chain.runTest(test)); + + if(resutl) { + System.out.println("All tests passed"); + } else { + throw new RuntimeException("Some tests failed"); + } + } +} diff --git a/test/sun/security/pkcs/pkcs10/PKCS10AttrEncoding.java b/test/sun/security/pkcs/pkcs10/PKCS10AttrEncoding.java new file mode 100644 index 0000000000000000000000000000000000000000..efca1b0d2e4e6376b4f09006203a86e487c5f55a --- /dev/null +++ b/test/sun/security/pkcs/pkcs10/PKCS10AttrEncoding.java @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2015, 2016, 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. + * + * 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. + */ + +/* + * @test + * @bug 8048357 + * @summary test DER encoding of PKCS10 attributes + * @compile -XDignore.symbol.file PKCS10AttrEncoding.java + * @run main PKCS10AttrEncoding + */ +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PrivateKey; +import java.security.Signature; +import java.util.Enumeration; +import java.util.GregorianCalendar; +import java.util.HashMap; +import sun.security.pkcs.PKCS9Attribute; +import sun.security.pkcs10.PKCS10; +import sun.security.pkcs10.PKCS10Attribute; +import sun.security.pkcs10.PKCS10Attributes; +import sun.security.util.ObjectIdentifier; +import sun.security.x509.X500Name; +import sun.security.x509.X509Key; + +public class PKCS10AttrEncoding { + + static final ObjectIdentifier[] ids = { + PKCS9Attribute.CONTENT_TYPE_OID, // ContentType + PKCS9Attribute.SIGNING_TIME_OID, // SigningTime + PKCS9Attribute.CHALLENGE_PASSWORD_OID // ChallengePassword + }; + static int failedCount = 0; + static HashMap constructedMap = new HashMap<>(); + + public static void main(String[] args) throws Exception { + + // initializations + int len = ids.length; + Object[] values = { + new ObjectIdentifier("1.2.3.4"), + new GregorianCalendar(1970, 1, 25, 8, 56, 7).getTime(), + "challenging" + }; + for (int j = 0; j < len; j++) { + constructedMap.put(ids[j], values[j]); + } + + X500Name subject = new X500Name("cn=Test"); + KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA"); + String sigAlg = "DSA"; + + keyGen.initialize(512); + + KeyPair pair = keyGen.generateKeyPair(); + X509Key publicKey = (X509Key) pair.getPublic(); + PrivateKey privateKey = pair.getPrivate(); + + Signature signature = Signature.getInstance(sigAlg); + signature.initSign(privateKey); + + // Create the PKCS10 request + PKCS10Attribute[] attrs = new PKCS10Attribute[len]; + for (int j = 0; j < len; j++) { + attrs[j] = new PKCS10Attribute(ids[j], values[j]); + } + PKCS10 req = new PKCS10(publicKey, new PKCS10Attributes(attrs)); + System.out.println("List of attributes in constructed PKCS10 " + + "request: "); + checkAttributes(req.getAttributes().getElements()); + + // Encode the PKCS10 request and generate another PKCS10 request from + // the encoded byte array + req.encodeAndSign(subject, signature); + PKCS10 resp = new PKCS10(req.getEncoded()); + System.out.println("List of attributes in DER encoded PKCS10 Request:"); + checkAttributes(resp.getAttributes().getElements()); + + if (failedCount > 0) { + throw new RuntimeException("Attributes Compared : Failed"); + } + System.out.println("Attributes Compared : Pass"); + } + + static void checkAttributes(Enumeration attrs) { + int numOfAttrs = 0; + while (attrs.hasMoreElements()) { + numOfAttrs ++; + PKCS10Attribute attr = (PKCS10Attribute) attrs.nextElement(); + + if (constructedMap.containsKey(attr.getAttributeId())) { + if (constructedMap.get(attr.getAttributeId()). + equals(attr.getAttributeValue())) { + System.out.print("AttributeId: " + attr.getAttributeId()); + System.out.println(" AttributeValue: " + + attr.getAttributeValue()); + } else { + failedCount++; + System.out.print("< AttributeId: " + attr.getAttributeId()); + System.out.println(" AttributeValue: " + constructedMap. + get(attr.getAttributeId())); + System.out.print("< AttributeId: " + attr.getAttributeId()); + System.out.println(" AttributeValue: " + + attr.getAttributeValue()); + } + } else { + failedCount++; + System.out.println("No " + attr.getAttributeId() + + " in DER encoded PKCS10 Request"); + } + } + if(numOfAttrs != constructedMap.size()){ + failedCount++; + System.out.println("Incorrect number of attributes."); + + } + System.out.println(); + } + +} diff --git a/test/sun/security/pkcs/pkcs10/PKCS10AttributeReader.java b/test/sun/security/pkcs/pkcs10/PKCS10AttributeReader.java new file mode 100644 index 0000000000000000000000000000000000000000..d5bde6d63aae03ffe9196f6b81592416a0db7890 --- /dev/null +++ b/test/sun/security/pkcs/pkcs10/PKCS10AttributeReader.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2015, 2016, 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. + * + * 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. + */ + +/* + * @test + * @bug 8048357 + * @summary Read in a file containing a DER encoded PKCS10 certificate request, + * flanked with "begin" and "end" lines. + * @compile -XDignore.symbol.file PKCS10AttributeReader.java + * @run main PKCS10AttributeReader + */ +import java.util.Base64; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Date; +import sun.security.pkcs.PKCS9Attribute; +import sun.security.pkcs10.PKCS10Attribute; +import sun.security.pkcs10.PKCS10Attributes; +import sun.security.util.DerInputStream; +import sun.security.util.ObjectIdentifier; + +/* + Tests only reads DER encoding files, contents of corresponding asn.1 files + are copied below for reference. + + # An attribute set for testing with PKCS10. + + {A0 # implicit tag + {SEQ # Content Type + {OID 1.2.840.113549.1.9.3} + {SET + {OID "1234"} + } + } + {SEQ # Challenge Password + {OID 1.2.840.113549.1.9.7} + {SET + {T61String "GuessWhoAmI"} + } + } + {SEQ # Signing Time + {OID 1.2.840.113549.1.9.5} + {SET + {UTCTime "970422145010Z"} + } + } + } + */ +public class PKCS10AttributeReader { + // DER encoded files are binary files, to avoid attaching binary files, + // DER files were encoded in base64 + static final String ATTRIBS = "oE8wEwYJKoZIhvcNAQkDMQYGBDEyMzQwGgYJKoZIhv" + + "cNAQkHMQ0UC0d1ZXNzV2hv\nQW1JMBwGCSqGSIb3DQEJBTEPFw05NzA0MjIxND" + + "UwMTBa"; + + public static void main(String[] args) throws Exception { + + // Decode base64 encoded DER file + byte[] pkcs10Bytes = Base64.getMimeDecoder().decode(ATTRIBS.getBytes()); + + HashMap RequestStander = new HashMap() { + { + put(PKCS9Attribute.CHALLENGE_PASSWORD_OID, "GuessWhoAmI"); + put(PKCS9Attribute.SIGNING_TIME_OID, new Date(861720610000L)); + put(PKCS9Attribute.CONTENT_TYPE_OID, + new ObjectIdentifier("1.9.50.51.52")); + } + }; + + int invalidNum = 0; + PKCS10Attributes resp = new PKCS10Attributes( + new DerInputStream(pkcs10Bytes)); + Enumeration eReq = resp.getElements(); + int numOfAttrs = 0; + while (eReq.hasMoreElements()) { + numOfAttrs++; + PKCS10Attribute attr = (PKCS10Attribute) eReq.nextElement(); + if (RequestStander.containsKey(attr.getAttributeId())) { + if (RequestStander.get(attr.getAttributeId()) + .equals(attr.getAttributeValue())) { + System.out.println(attr.getAttributeId() + " " + + attr.getAttributeValue()); + } else { + invalidNum++; + System.out.println("< " + attr.getAttributeId() + " " + + attr.getAttributeValue()); + System.out.println("< " + attr.getAttributeId() + " " + + RequestStander.get(attr.getAttributeId())); + } + } else { + invalidNum++; + System.out.println("No" + attr.getAttributeId() + + "in Certificate Request list"); + } + } + if (numOfAttrs != RequestStander.size()) { + invalidNum++; + System.out.println("Incorrect number of attributes."); + } + System.out.println(); + if (invalidNum > 0) { + throw new RuntimeException( + "Attributes Compared with Stander :" + " Failed"); + } + System.out.println("Attributes Compared with Stander: Pass"); + } + +} diff --git a/test/sun/security/pkcs/pkcs7/PKCS7VerifyTest.java b/test/sun/security/pkcs/pkcs7/PKCS7VerifyTest.java new file mode 100644 index 0000000000000000000000000000000000000000..24cc111befa08831b0fe411dc58773a4d702e4e7 --- /dev/null +++ b/test/sun/security/pkcs/pkcs7/PKCS7VerifyTest.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2015, 2016, 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. + * + * 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. + */ + +/* + * @test + * @bug 8048357 + * @summary Read signed data in one or more PKCS7 objects from individual files, + * verify SignerInfos and certificate chain. + * @run main PKCS7VerifyTest PKCS7TEST.DSA.base64 + * @run main PKCS7VerifyTest PKCS7TEST.DSA.base64 PKCS7TEST.SF + */ +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.cert.X509Certificate; +import java.util.Base64; +import java.util.HashMap; +import java.util.Map; +import sun.security.pkcs.PKCS7; +import sun.security.pkcs.SignerInfo; + +public class PKCS7VerifyTest { + + static final String TESTSRC = System.getProperty("test.src", "."); + static final String FS = File.separator; + static final String FILEPATH = TESTSRC + FS + "jarsigner" + FS + "META-INF" + + FS; + + public static void main(String[] args) throws Exception { + if (args.length == 0) { + throw new RuntimeException("usage: java JarVerify "); + } + + // The command " java PKCS7VerifyTest file1 [file2] " + // treats file1 as containing the DER encoding of a PKCS7 signed data + // object. If file2 is absent, the program verifies that some signature + // (SignerInfo) file1 correctly signs the data contained in the + // ContentInfo component of the PKCS7 object encoded by file1. If file2 + // is present, the program verifies file1 contains a correct signature + // for the contents of file2. + + PKCS7 pkcs7; + byte[] data; + + // to avoid attaching binary DSA file, the DSA file was encoded + // in Base64, decode encoded Base64 DSA file below + byte[] base64Bytes = Files.readAllBytes(Paths.get(FILEPATH + args[0])); + pkcs7 = new PKCS7(new ByteArrayInputStream( + Base64.getMimeDecoder().decode(base64Bytes))); + if (args.length < 2) { + data = null; + } else { + data = Files.readAllBytes(Paths.get(FILEPATH + args[1])); + + } + + SignerInfo[] signerInfos = pkcs7.verify(data); + + if (signerInfos == null) { + throw new RuntimeException("no signers verify"); + } + System.out.println("Verifying SignerInfos:"); + for (SignerInfo signerInfo : signerInfos) { + System.out.println(signerInfo.toString()); + } + + X509Certificate certs[] = pkcs7.getCertificates(); + + HashMap certTable = new HashMap(certs.length); + for (X509Certificate cert : certs) { + certTable.put(cert.getSubjectDN().toString(), cert); + } + + // try to verify all the certs + for (Map.Entry entry : certTable.entrySet()) { + + X509Certificate cert = entry.getValue(); + X509Certificate issuerCert = certTable + .get(cert.getIssuerDN().toString()); + + System.out.println("Subject: " + cert.getSubjectDN()); + if (issuerCert == null) { + System.out.println("Issuer certificate not found"); + } else { + System.out.println("Issuer: " + cert.getIssuerDN()); + cert.verify(issuerCert.getPublicKey()); + System.out.println("Cert verifies."); + } + System.out.println(); + } + } + +} diff --git a/test/sun/security/pkcs/pkcs7/SignerOrder.java b/test/sun/security/pkcs/pkcs7/SignerOrder.java new file mode 100644 index 0000000000000000000000000000000000000000..1848b4374dd09802fa0ab9a78b51cbb0e187188e --- /dev/null +++ b/test/sun/security/pkcs/pkcs7/SignerOrder.java @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2015, 2016, 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. + * + * 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. + */ + +/* + * @test + * @bug 8048357 + * @summary test PKCS7 data signing, encoding and verification + * @run main SignerOrder + */ +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PrivateKey; +import java.security.Signature; +import java.security.SignatureException; +import java.security.cert.X509Certificate; +import java.util.Date; +import sun.misc.HexDumpEncoder; +import sun.security.pkcs.ContentInfo; +import sun.security.pkcs.PKCS7; +import sun.security.pkcs.SignerInfo; +import sun.security.util.DerOutputStream; +import sun.security.x509.AlgorithmId; +import sun.security.x509.CertificateAlgorithmId; +import sun.security.x509.CertificateSerialNumber; +import sun.security.x509.CertificateValidity; +import sun.security.x509.CertificateVersion; +import sun.security.x509.CertificateX509Key; +import sun.security.x509.X500Name; +import sun.security.x509.X509CertImpl; +import sun.security.x509.X509CertInfo; +import sun.security.x509.X509Key; + +public class SignerOrder { + + static final HexDumpEncoder hexDump = new HexDumpEncoder(); + + //signer infos + static final byte[] data1 = "12345".getBytes(); + static final byte[] data2 = "abcde".getBytes(); + + public static void main(String[] argv) throws Exception { + + SignerInfo[] signerInfos = new SignerInfo[9]; + SimpleSigner signer1 = new SimpleSigner(null, null, null, null); + signerInfos[8] = signer1.genSignerInfo(data1); + signerInfos[7] = signer1.genSignerInfo(new byte[]{}); + signerInfos[6] = signer1.genSignerInfo(data2); + + SimpleSigner signer2 = new SimpleSigner(null, null, null, null); + signerInfos[5] = signer2.genSignerInfo(data1); + signerInfos[4] = signer2.genSignerInfo(new byte[]{}); + signerInfos[3] = signer2.genSignerInfo(data2); + + SimpleSigner signer3 = new SimpleSigner(null, null, null, null); + signerInfos[2] = signer3.genSignerInfo(data1); + signerInfos[1] = signer3.genSignerInfo(new byte[]{}); + signerInfos[0] = signer3.genSignerInfo(data2); + + ContentInfo contentInfo = new ContentInfo(data1); + + AlgorithmId[] algIds = {new AlgorithmId(AlgorithmId.SHA256_oid)}; + + X509Certificate[] certs = {signer3.getCert(), signer2.getCert(), + signer1.getCert()}; + + PKCS7 pkcs71 = new PKCS7(algIds, contentInfo, + certs, + signerInfos); + + System.out.println("SignerInfos in original."); + printSignerInfos(pkcs71.getSignerInfos()); + + DerOutputStream out = new DerOutputStream(); + pkcs71.encodeSignedData(out); + + PKCS7 pkcs72 = new PKCS7(out.toByteArray()); + System.out.println("\nSignerInfos read back in:"); + printSignerInfos(pkcs72.getSignerInfos()); + + System.out.println("Verified signers of original:"); + SignerInfo[] verifs1 = pkcs71.verify(); + + System.out.println("Verified signers of after read-in:"); + SignerInfo[] verifs2 = pkcs72.verify(); + + if (verifs1.length != verifs2.length) { + throw new RuntimeException("Length or Original vs read-in " + + "should be same"); + } + } + + static void printSignerInfos(SignerInfo signerInfo) throws IOException { + ByteArrayOutputStream strm = new ByteArrayOutputStream(); + signerInfo.derEncode(strm); + System.out.println("SignerInfo, length: " + + strm.toByteArray().length); + System.out.println(hexDump.encode(strm.toByteArray())); + System.out.println("\n"); + strm.reset(); + } + + static void printSignerInfos(SignerInfo[] signerInfos) throws IOException { + ByteArrayOutputStream strm = new ByteArrayOutputStream(); + for (int i = 0; i < signerInfos.length; i++) { + signerInfos[i].derEncode(strm); + System.out.println("SignerInfo[" + i + "], length: " + + strm.toByteArray().length); + System.out.println(hexDump.encode(strm.toByteArray())); + System.out.println("\n"); + strm.reset(); + } + } + +} + +/** + * A simple extension of sun.security.x509.X500Signer that adds a no-fuss + * signing algorithm. + */ +class SimpleSigner { + + private final Signature sig; + private final X500Name agent; + private final AlgorithmId digestAlgId; + private final AlgorithmId encryptionAlgId; + private final AlgorithmId algId; // signature algid; + //combines digest + encryption + private final X509Key publicKey; + private final PrivateKey privateKey; + private final X509Certificate cert; + + public SimpleSigner(String digestAlg, + String encryptionAlg, + KeyPair keyPair, + X500Name agent) throws Exception { + + if (agent == null) { + agent = new X500Name("cn=test"); + } + if (digestAlg == null) { + digestAlg = "SHA"; + } + if (encryptionAlg == null) { + encryptionAlg = "DSA"; + } + if (keyPair == null) { + KeyPairGenerator keyGen = + KeyPairGenerator.getInstance(encryptionAlg); + keyGen.initialize(1024); + keyPair = keyGen.generateKeyPair(); + } + publicKey = (X509Key) keyPair.getPublic(); + privateKey = keyPair.getPrivate(); + + if ("DSA".equals(encryptionAlg)) { + this.sig = Signature.getInstance(encryptionAlg); + } else { // RSA + this.sig = Signature.getInstance(digestAlg + "/" + encryptionAlg); + } + this.sig.initSign(privateKey); + + this.agent = agent; + this.digestAlgId = AlgorithmId.get(digestAlg); + this.encryptionAlgId = AlgorithmId.get(encryptionAlg); + this.algId = AlgorithmId.get(this.sig.getAlgorithm()); + + this.cert = getSelfCert(); + } + + /** + * Take the data and sign it. + * + * @param buf buffer holding the next chunk of the data to be signed + * @param offset starting point of to-be-signed data + * @param len how many bytes of data are to be signed + * @return the signature for the input data. + * @exception SignatureException on errors. + */ + public byte[] simpleSign(byte[] buf, int offset, int len) + throws SignatureException { + sig.update(buf, offset, len); + return sig.sign(); + } + + /** + * Returns the digest algorithm used to sign. + */ + public AlgorithmId getDigestAlgId() { + return digestAlgId; + } + + /** + * Returns the encryption algorithm used to sign. + */ + public AlgorithmId getEncryptionAlgId() { + return encryptionAlgId; + } + + /** + * Returns the name of the signing agent. + */ + public X500Name getSigner() { + return agent; + } + + public X509Certificate getCert() { + return cert; + } + + private X509Certificate getSelfCert() throws Exception { + long validity = 1000; + X509CertImpl certLocal; + Date firstDate, lastDate; + + firstDate = new Date(); + lastDate = new Date(); + lastDate.setTime(lastDate.getTime() + validity + 1000); + + CertificateValidity interval = new CertificateValidity(firstDate, + lastDate); + + X509CertInfo info = new X509CertInfo(); + // Add all mandatory attributes + info.set(X509CertInfo.VERSION, + new CertificateVersion(CertificateVersion.V1)); + info.set(X509CertInfo.SERIAL_NUMBER, + new CertificateSerialNumber( + (int) (firstDate.getTime() / 1000))); + info.set(X509CertInfo.ALGORITHM_ID, + new CertificateAlgorithmId(algId)); + info.set(X509CertInfo.SUBJECT, agent); + info.set(X509CertInfo.KEY, new CertificateX509Key(publicKey)); + info.set(X509CertInfo.VALIDITY, interval); + info.set(X509CertInfo.ISSUER, agent); + + certLocal = new X509CertImpl(info); + certLocal.sign(privateKey, algId.getName()); + + return certLocal; + } + + public SignerInfo genSignerInfo(byte[] data) throws SignatureException { + return new SignerInfo((X500Name) cert.getIssuerDN(), + new BigInteger("" + cert.getSerialNumber()), + getDigestAlgId(), algId, + simpleSign(data, 0, data.length)); + } +} diff --git a/test/sun/security/pkcs/pkcs7/jarsigner/META-INF/MANIFEST.MF b/test/sun/security/pkcs/pkcs7/jarsigner/META-INF/MANIFEST.MF new file mode 100644 index 0000000000000000000000000000000000000000..6be546d4daf36ee6bb5146cf09e3cc10583c69d7 --- /dev/null +++ b/test/sun/security/pkcs/pkcs7/jarsigner/META-INF/MANIFEST.MF @@ -0,0 +1,82 @@ +Manifest-Version: 1.0 + +Name: CheckCerts.class +Digest-Algorithms: SHA +SHA-Digest: xLygljhRro6990piIVEilVI8szQ= + +Name: ContentInfoTest.class +Digest-Algorithms: SHA +SHA-Digest: TSVdEMQW2gdFi6qeba+UixdHSdo= + +Name: JarVerify.class +Digest-Algorithms: SHA +SHA-Digest: Wg+PiDzunNGH4KrWAp00/okp39s= + +Name: JarVerify2.class +Digest-Algorithms: SHA +SHA-Digest: 5uYBQxwGWgYmNBwhnWRbymeXmWM= + +Name: PKCS7Read.class +Digest-Algorithms: SHA +SHA-Digest: JPIxttHBfRpQaFyiQJ2Wfkvj/ls= + +Name: PKCS7Test.class +Digest-Algorithms: SHA +SHA-Digest: R64SXXgZrOvGiO/eMsfG/T1Vn30= + +Name: PKCS7Test10.class +Digest-Algorithms: SHA +SHA-Digest: 2R0yxuxRHTPqdAzJJcrvqkpbQgo= + +Name: PKCS7Test11.class +Digest-Algorithms: SHA +SHA-Digest: /0HcwnpQi0hwJsJtvt5peWFGvtc= + +Name: PKCS7Test12.class +Digest-Algorithms: SHA +SHA-Digest: s5CcqimfRqR9CW25tFBY0JK3RVU= + +Name: PKCS7Test2.class +Digest-Algorithms: SHA +SHA-Digest: 71VkFEMUle5sjXNFbSW31F1ZJ58= + +Name: PKCS7Test3.class +Digest-Algorithms: SHA +SHA-Digest: mU/D5C6SgPRmwoLQzwF5VnN3aqM= + +Name: PKCS7Test4.class +Digest-Algorithms: SHA +SHA-Digest: ss9NFvxF8emaEjdKdvtzWXfs0/E= + +Name: PKCS7Test5.class +Digest-Algorithms: SHA +SHA-Digest: DHvQ20UAXoYgfCPAOeCOrglsJwU= + +Name: PKCS7Test6.class +Digest-Algorithms: SHA +SHA-Digest: aiCb8chroH7XDaNfAz6wr57lXsA= + +Name: PKCS7Test7.class +Digest-Algorithms: SHA +SHA-Digest: UoieXLC68alFgfD/Q1NW9/r2kaY= + +Name: PKCS7Test8.class +Digest-Algorithms: SHA +SHA-Digest: eMW7mq5b/KVB1M5L76wcV1+uFQs= + +Name: PKCS7Test9.class +Digest-Algorithms: SHA +SHA-Digest: EEWCZG1creWjqVZVIEgr0on3y6A= + +Name: SignerInfoTest.class +Digest-Algorithms: SHA +SHA-Digest: l6SNfpnFipGg8gy4XqY3HhA0RrY= + +Name: SignerInfoTest2.class +Digest-Algorithms: SHA +SHA-Digest: 5jbzlkZqXKNmmmE+pcjQka8D6WE= + +Name: SimpleSigner.class +Digest-Algorithms: SHA +SHA-Digest: l9ODQHY4wxhIvLw4/B0qe9NjwxQ= + diff --git a/test/sun/security/pkcs/pkcs7/jarsigner/META-INF/PKCS7TEST.DSA.base64 b/test/sun/security/pkcs/pkcs7/jarsigner/META-INF/PKCS7TEST.DSA.base64 new file mode 100644 index 0000000000000000000000000000000000000000..f084beb89b674a30516f6693cc927dea9140bb1c --- /dev/null +++ b/test/sun/security/pkcs/pkcs7/jarsigner/META-INF/PKCS7TEST.DSA.base64 @@ -0,0 +1,60 @@ +MIILKAYJKoZIhvcNAQcCoIILGTCCCxUCAQExCzAJBgUrDgMCGgUAMIIHbQYJKoZI +hvcNAQcBoIIHXgSCB1pTaWduYXR1cmUtVmVyc2lvbjogMS4wDQoNCk5hbWU6IENo +ZWNrQ2VydHMuY2xhc3MNCkRpZ2VzdC1BbGdvcml0aG1zOiBTSEENClNIQS1EaWdl +c3Q6IHlhMXh3dnNRTytEUnBRYnczRmgyblJCMkpRYz0NCg0KTmFtZTogQ29udGVu +dEluZm9UZXN0LmNsYXNzDQpEaWdlc3QtQWxnb3JpdGhtczogU0hBDQpTSEEtRGln +ZXN0OiBDYStFSmFrVTZ6dzRLQWhvcWNuQ3BOcWsyTEk9DQoNCk5hbWU6IEphclZl +cmlmeS5jbGFzcw0KRGlnZXN0LUFsZ29yaXRobXM6IFNIQQ0KU0hBLURpZ2VzdDog +K0RHYVdXa25md2U0Wk9wc29NVEZ6ZldSdmhRPQ0KDQpOYW1lOiBKYXJWZXJpZnky +LmNsYXNzDQpEaWdlc3QtQWxnb3JpdGhtczogU0hBDQpTSEEtRGlnZXN0OiBHcUR6 +WXlZNFAvV0g1SEt2aVdxWHR0UGc1ckU9DQoNCk5hbWU6IFBLQ1M3UmVhZC5jbGFz +cw0KRGlnZXN0LUFsZ29yaXRobXM6IFNIQQ0KU0hBLURpZ2VzdDogUW1mOEs5aFhW +bHdJZFBZNm52MmpGUGZHcWtBPQ0KDQpOYW1lOiBQS0NTN1Rlc3QuY2xhc3MNCkRp +Z2VzdC1BbGdvcml0aG1zOiBTSEENClNIQS1EaWdlc3Q6IEdiZS9nenl2MkY1OGY2 +RUVoU1oxQnFHWHRsbz0NCg0KTmFtZTogUEtDUzdUZXN0MTAuY2xhc3MNCkRpZ2Vz +dC1BbGdvcml0aG1zOiBTSEENClNIQS1EaWdlc3Q6IDh3QnFXLy9lVzJzTlJJOTFi +TFlFT29kY2dhRT0NCg0KTmFtZTogUEtDUzdUZXN0MTEuY2xhc3MNCkRpZ2VzdC1B +bGdvcml0aG1zOiBTSEENClNIQS1EaWdlc3Q6IGJYaExLRXNsY3VFWGk0dS9haGdU +MnE2dGNFVT0NCg0KTmFtZTogUEtDUzdUZXN0MTIuY2xhc3MNCkRpZ2VzdC1BbGdv +cml0aG1zOiBTSEENClNIQS1EaWdlc3Q6IDlLRVkxYjUyUUxtTjBxei81ejB3QkZy +T216MD0NCg0KTmFtZTogUEtDUzdUZXN0Mi5jbGFzcw0KRGlnZXN0LUFsZ29yaXRo +bXM6IFNIQQ0KU0hBLURpZ2VzdDogK1VhMzIvMlE4RjJiclFRbVNYWCtYUytNL2g0 +PQ0KDQpOYW1lOiBQS0NTN1Rlc3QzLmNsYXNzDQpEaWdlc3QtQWxnb3JpdGhtczog +U0hBDQpTSEEtRGlnZXN0OiAwSFhVWnlhU2ZkZUtlZThuWnpFalJTeXJldTQ9DQoN +Ck5hbWU6IFBLQ1M3VGVzdDQuY2xhc3MNCkRpZ2VzdC1BbGdvcml0aG1zOiBTSEEN +ClNIQS1EaWdlc3Q6IEo3eXJTMjRvS3VTZ2F1dHZkemhxQmo3ZGJjUT0NCg0KTmFt +ZTogUEtDUzdUZXN0NS5jbGFzcw0KRGlnZXN0LUFsZ29yaXRobXM6IFNIQQ0KU0hB +LURpZ2VzdDogSlR2OVdTb3gxTEVTUjJMcTdzMFVxU2x0RFNRPQ0KDQpOYW1lOiBQ +S0NTN1Rlc3Q2LmNsYXNzDQpEaWdlc3QtQWxnb3JpdGhtczogU0hBDQpTSEEtRGln +ZXN0OiBnR3Yra05oK3UzSFExdHp4bGNBVzdTcEZUS2s9DQoNCk5hbWU6IFBLQ1M3 +VGVzdDcuY2xhc3MNCkRpZ2VzdC1BbGdvcml0aG1zOiBTSEENClNIQS1EaWdlc3Q6 +IGZpSEYxYUExYWN6czFPd0V5OEc3VkMrcjdMST0NCg0KTmFtZTogUEtDUzdUZXN0 +OC5jbGFzcw0KRGlnZXN0LUFsZ29yaXRobXM6IFNIQQ0KU0hBLURpZ2VzdDogNzRU +VzdJOVZPdzVWZ0x2aFJtRGZxRVd2ZkFRPQ0KDQpOYW1lOiBQS0NTN1Rlc3Q5LmNs +YXNzDQpEaWdlc3QtQWxnb3JpdGhtczogU0hBDQpTSEEtRGlnZXN0OiAxY0JJbkdU +Y08xQVFaKy8wdmhGa2laV3dsQTA9DQoNCk5hbWU6IFNpZ25lckluZm9UZXN0LmNs +YXNzDQpEaWdlc3QtQWxnb3JpdGhtczogU0hBDQpTSEEtRGlnZXN0OiBjRlk0Q3RT +anphMUErV2pBS05TVnF1cGpSWUU9DQoNCk5hbWU6IFNpZ25lckluZm9UZXN0Mi5j +bGFzcw0KRGlnZXN0LUFsZ29yaXRobXM6IFNIQQ0KU0hBLURpZ2VzdDogYU5NMEZQ +MHpFelF6eGxYeDZxQ0J4dWtta0hRPQ0KDQpOYW1lOiBTaW1wbGVTaWduZXIuY2xh +c3MNCkRpZ2VzdC1BbGdvcml0aG1zOiBTSEENClNIQS1EaWdlc3Q6IC9MV0NzbkM3 +TVpNUjZHb3czeTJjdnA3STBTTT0NCg0KoIICvzCCArswggJ3AgUA59UzNDALBgcq +hkjOOAQDBQAwdTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRIwEAYDVQQHEwlD +dXBlcnRpbm8xGTAXBgNVBAoTEFN1biBNaWNyb3N5c3RlbXMxETAPBgNVBAsTCEph +dmFTb2Z0MRcwFQYDVQQDEw5Eb3VnbGFzIEhvb3ZlcjAeFw05NzEwMDIxODEyMDda +Fw05NzEyMzExNzEyMDdaMHUxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTESMBAG +A1UEBxMJQ3VwZXJ0aW5vMRkwFwYDVQQKExBTdW4gTWljcm9zeXN0ZW1zMREwDwYD +VQQLEwhKYXZhU29mdDEXMBUGA1UEAxMORG91Z2xhcyBIb292ZXIwggFRMIHoBgcq +hkjOOAQBMIHcAmEA6eZCWZ01XzfJf/01ZxILjiXJzUPpJ7OpZw++xdiQFBki0sOz +rSSACTeZhp0ehGqrSfqwrSbSzmoiIZ1HC859d31KIfvpwnC1f2BwAvPO+Dk2lM9F +7jaIwRqMVqsSej2vAhUAnNvYTJ8awvOND4D0KrlS5zOL9RECYDBHCtWgBfsUzi2d +zYfji8fRscX6y67L6V8ZCqejHSPE27y+BhdFREAaWywCCWXYwr0hcdNmhEV3H3S6 +CE0gKdg8HBWFR/Op8aJxW+I9Ua5NPlofanBk8xaTOjRtP1KSUgNkAAJhAMN5uB+B +ZJ0W2UjXMyKoFUFXRYiLpnaSw63kl9tKnR9R5rEreiyHQ5IelPxjwCHGgTbYK0y+ +xKTGHVWiQN/YJmHLbSrcSSM/d89aR/sVbGoAwQOyYraFGUNIOTQjjXcXCjALBgcq +hkjOOAQDBQADMQAwLgIVAJxmL029GLXDJVbk72d4cSPQ4/rvAhUAll9UPl8aOMEg +V4egANhwbynMGSgxgc4wgcsCAQEwfjB1MQswCQYDVQQGEwJVUzELMAkGA1UECBMC +Q0ExEjAQBgNVBAcTCUN1cGVydGlubzEZMBcGA1UEChMQU3VuIE1pY3Jvc3lzdGVt +czERMA8GA1UECxMISmF2YVNvZnQxFzAVBgNVBAMTDkRvdWdsYXMgSG9vdmVyAgUA +59UzNDAJBgUrDgMCGgUAMAsGByqGSM44BAMFAAQuMCwCFDmry17kzDD6Y5X1BqIS +lq6swckPAhRtiXvBHa5CRGjbwk8yqf9hGgZfFA== diff --git a/test/sun/security/pkcs/pkcs7/jarsigner/META-INF/PKCS7TEST.SF b/test/sun/security/pkcs/pkcs7/jarsigner/META-INF/PKCS7TEST.SF new file mode 100644 index 0000000000000000000000000000000000000000..05a793821897da6c23a8f8d3f68bf5f858190d00 --- /dev/null +++ b/test/sun/security/pkcs/pkcs7/jarsigner/META-INF/PKCS7TEST.SF @@ -0,0 +1,82 @@ +Signature-Version: 1.0 + +Name: CheckCerts.class +Digest-Algorithms: SHA +SHA-Digest: ya1xwvsQO+DRpQbw3Fh2nRB2JQc= + +Name: ContentInfoTest.class +Digest-Algorithms: SHA +SHA-Digest: Ca+EJakU6zw4KAhoqcnCpNqk2LI= + +Name: JarVerify.class +Digest-Algorithms: SHA +SHA-Digest: +DGaWWknfwe4ZOpsoMTFzfWRvhQ= + +Name: JarVerify2.class +Digest-Algorithms: SHA +SHA-Digest: GqDzYyY4P/WH5HKviWqXttPg5rE= + +Name: PKCS7Read.class +Digest-Algorithms: SHA +SHA-Digest: Qmf8K9hXVlwIdPY6nv2jFPfGqkA= + +Name: PKCS7Test.class +Digest-Algorithms: SHA +SHA-Digest: Gbe/gzyv2F58f6EEhSZ1BqGXtlo= + +Name: PKCS7Test10.class +Digest-Algorithms: SHA +SHA-Digest: 8wBqW//eW2sNRI91bLYEOodcgaE= + +Name: PKCS7Test11.class +Digest-Algorithms: SHA +SHA-Digest: bXhLKEslcuEXi4u/ahgT2q6tcEU= + +Name: PKCS7Test12.class +Digest-Algorithms: SHA +SHA-Digest: 9KEY1b52QLmN0qz/5z0wBFrOmz0= + +Name: PKCS7Test2.class +Digest-Algorithms: SHA +SHA-Digest: +Ua32/2Q8F2brQQmSXX+XS+M/h4= + +Name: PKCS7Test3.class +Digest-Algorithms: SHA +SHA-Digest: 0HXUZyaSfdeKee8nZzEjRSyreu4= + +Name: PKCS7Test4.class +Digest-Algorithms: SHA +SHA-Digest: J7yrS24oKuSgautvdzhqBj7dbcQ= + +Name: PKCS7Test5.class +Digest-Algorithms: SHA +SHA-Digest: JTv9WSox1LESR2Lq7s0UqSltDSQ= + +Name: PKCS7Test6.class +Digest-Algorithms: SHA +SHA-Digest: gGv+kNh+u3HQ1tzxlcAW7SpFTKk= + +Name: PKCS7Test7.class +Digest-Algorithms: SHA +SHA-Digest: fiHF1aA1aczs1OwEy8G7VC+r7LI= + +Name: PKCS7Test8.class +Digest-Algorithms: SHA +SHA-Digest: 74TW7I9VOw5VgLvhRmDfqEWvfAQ= + +Name: PKCS7Test9.class +Digest-Algorithms: SHA +SHA-Digest: 1cBInGTcO1AQZ+/0vhFkiZWwlA0= + +Name: SignerInfoTest.class +Digest-Algorithms: SHA +SHA-Digest: cFY4CtSjza1A+WjAKNSVqupjRYE= + +Name: SignerInfoTest2.class +Digest-Algorithms: SHA +SHA-Digest: aNM0FP0zEzQzxlXx6qCBxukmkHQ= + +Name: SimpleSigner.class +Digest-Algorithms: SHA +SHA-Digest: /LWCsnC7MZMR6Gow3y2cvp7I0SM= + diff --git a/test/sun/security/pkcs/pkcs8/PKCS8Test.java b/test/sun/security/pkcs/pkcs8/PKCS8Test.java new file mode 100644 index 0000000000000000000000000000000000000000..6bd3af5b96c98ce2ee39166000a7ceec96a6b49d --- /dev/null +++ b/test/sun/security/pkcs/pkcs8/PKCS8Test.java @@ -0,0 +1,282 @@ +/* + * Copyright (c) 2015, 2016, 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. + * + * 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. + */ + +/* + * @test + * @bug 8048357 + * @summary PKCS8 Standards Conformance Tests + * @requires (os.family != "solaris") + * @compile -XDignore.symbol.file PKCS8Test.java + * @run main PKCS8Test + */ + +/* + * Skip Solaris since the DSAPrivateKeys returned by + * SunPKCS11 Provider are not subclasses of PKCS8Key + */ +import java.io.IOException; +import java.math.BigInteger; +import java.security.InvalidKeyException; +import java.util.Arrays; +import sun.misc.HexDumpEncoder; +import sun.security.pkcs.PKCS8Key; +import sun.security.provider.DSAPrivateKey; +import sun.security.util.DerOutputStream; +import sun.security.util.DerValue; +import sun.security.x509.AlgorithmId; +import static java.lang.System.out; + +public class PKCS8Test { + + static final HexDumpEncoder hexDump = new HexDumpEncoder(); + + static final DerOutputStream derOutput = new DerOutputStream(); + + static final String FORMAT = "PKCS#8"; + static final String EXPECTED_ALG_ID_CHRS = "DSA\n\tp: 02\n\tq: 03\n" + + "\tg: 04\n"; + static final String ALGORITHM = "DSA"; + static final String EXCEPTION_MESSAGE = "version mismatch: (supported: " + + "00, parsed: 01"; + + // test second branch in byte[] encode() + // DER encoding,include (empty) set of attributes + static final int[] NEW_ENCODED_KEY_INTS = { 0x30, + // length 30 = 0x1e + 0x1e, + // first element + // version Version (= INTEGER) + 0x02, + // length 1 + 0x01, + // value 0 + 0x00, + // second element + // privateKeyAlgorithmIdentifier PrivateKeyAlgorithmIdentifier + // (sequence) + // (an object identifier?) + 0x30, + // length 18 + 0x12, + // contents + // object identifier, 5 bytes + 0x06, 0x05, + // { 1 3 14 3 2 12 } + 0x2b, 0x0e, 0x03, 0x02, 0x0c, + // sequence, 9 bytes + 0x30, 0x09, + // integer 2 + 0x02, 0x01, 0x02, + // integer 3 + 0x02, 0x01, 0x03, + // integer 4 + 0x02, 0x01, 0x04, + // third element + // privateKey PrivateKey (= OCTET STRING) + 0x04, + // length + 0x03, + // privateKey contents + 0x02, 0x01, 0x01, + // 4th (optional) element -- attributes [0] IMPLICIT Attributes + // OPTIONAL + // (Attributes = SET OF Attribute) Here, it will be empty. + 0xA0, + // length + 0x00 }; + + // encoding originally created, but with the version changed + static final int[] NEW_ENCODED_KEY_INTS_2 = { + // sequence + 0x30, + // length 28 = 0x1c + 0x1c, + // first element + // version Version (= INTEGER) + 0x02, + // length 1 + 0x01, + // value 1 (illegal) + 0x01, + // second element + // privateKeyAlgorithmIdentifier PrivateKeyAlgorithmIdentifier + // (sequence) + // (an object identifier?) + 0x30, + // length 18 + 0x12, + // contents + // object identifier, 5 bytes + 0x06, 0x05, + // { 1 3 14 3 2 12 } + 0x2b, 0x0e, 0x03, 0x02, 0x0c, + // sequence, 9 bytes + 0x30, 0x09, + // integer 2 + 0x02, 0x01, 0x02, + // integer 3 + 0x02, 0x01, 0x03, + // integer 4 + 0x02, 0x01, 0x04, + // third element + // privateKey PrivateKey (= OCTET STRING) + 0x04, + // length + 0x03, + // privateKey contents + 0x02, 0x01, 0x01 }; + + // 0000: 30 1E 02 01 00 30 14 06 07 2A 86 48 CE 38 04 01 0....0...*.H.8.. + // 0010: 30 09 02 01 02 02 01 03 02 01 04 04 03 02 01 01 0............... + static final int[] EXPECTED = { 0x30, + // length 30 = 0x1e + 0x1e, + // first element + // version Version (= INTEGER) + 0x02, + // length 1 + 0x01, + // value 0 + 0x00, + // second element + // privateKeyAlgorithmIdentifier PrivateKeyAlgorithmIdentifier + // (sequence) + // (an object identifier?) + 0x30, 0x14, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, 0x01, + // integer 2 + 0x30, 0x09, 0x02, + // integer 3 + 0x01, 0x02, 0x02, + // integer 4 + 0x01, 0x03, 0x02, + // third element + // privateKey PrivateKey (= OCTET STRING) + 0x01, + // length + 0x04, + // privateKey contents + 0x04, 0x03, 0x02, + // 4th (optional) element -- attributes [0] IMPLICIT Attributes + // OPTIONAL + // (Attributes = SET OF Attribute) Here, it will be empty. + 0x01, + // length + 0x01 }; + + static void raiseException(String expected, String received) { + throw new RuntimeException( + "Expected " + expected + "; Received " + received); + } + + public static void main(String[] args) + throws IOException, InvalidKeyException { + + BigInteger p = BigInteger.valueOf(1); + BigInteger q = BigInteger.valueOf(2); + BigInteger g = BigInteger.valueOf(3); + BigInteger x = BigInteger.valueOf(4); + + DSAPrivateKey priv = new DSAPrivateKey(p, q, g, x); + + byte[] encodedKey = priv.getEncoded(); + byte[] expectedBytes = new byte[EXPECTED.length]; + for (int i = 0; i < EXPECTED.length; i++) { + expectedBytes[i] = (byte) EXPECTED[i]; + } + + dumpByteArray("encodedKey :", encodedKey); + if (!Arrays.equals(encodedKey, expectedBytes)) { + raiseException(new String(expectedBytes), new String(encodedKey)); + } + + PKCS8Key decodedKey = PKCS8Key.parse(new DerValue(encodedKey)); + + String alg = decodedKey.getAlgorithm(); + AlgorithmId algId = decodedKey.getAlgorithmId(); + out.println("Algorithm :" + alg); + out.println("AlgorithmId: " + algId); + + if (!ALGORITHM.equals(alg)) { + raiseException(ALGORITHM, alg); + } + if (!EXPECTED_ALG_ID_CHRS.equalsIgnoreCase(algId.toString())) { + raiseException(EXPECTED_ALG_ID_CHRS, algId.toString()); + } + + decodedKey.encode(derOutput); + dumpByteArray("Stream encode: ", derOutput.toByteArray()); + if (!Arrays.equals(derOutput.toByteArray(), expectedBytes)) { + raiseException(new String(expectedBytes), derOutput.toString()); + } + + dumpByteArray("byte[] encoding: ", decodedKey.getEncoded()); + if (!Arrays.equals(decodedKey.getEncoded(), expectedBytes)) { + raiseException(new String(expectedBytes), + new String(decodedKey.getEncoded())); + } + + if (!FORMAT.equals(decodedKey.getFormat())) { + raiseException(FORMAT, decodedKey.getFormat()); + } + + try { + byte[] newEncodedKey = new byte[NEW_ENCODED_KEY_INTS.length]; + for (int i = 0; i < newEncodedKey.length; i++) { + newEncodedKey[i] = (byte) NEW_ENCODED_KEY_INTS[i]; + } + PKCS8Key newDecodedKey = PKCS8Key + .parse(new DerValue(newEncodedKey)); + + throw new RuntimeException( + "key1: Expected an IOException during " + "parsing"); + } catch (IOException e) { + System.out.println("newEncodedKey: should have excess data due to " + + "attributes, which are not supported"); + } + + try { + byte[] newEncodedKey2 = new byte[NEW_ENCODED_KEY_INTS_2.length]; + for (int i = 0; i < newEncodedKey2.length; i++) { + newEncodedKey2[i] = (byte) NEW_ENCODED_KEY_INTS_2[i]; + } + + PKCS8Key newDecodedKey2 = PKCS8Key + .parse(new DerValue(newEncodedKey2)); + + throw new RuntimeException( + "key2: Expected an IOException during " + "parsing"); + } catch (IOException e) { + out.println("Key 2: should be illegal version"); + out.println(e.getMessage()); + if (!EXCEPTION_MESSAGE.equals(e.getMessage())) { + throw new RuntimeException("Key2: expected: " + + EXCEPTION_MESSAGE + " get: " + e.getMessage()); + } + } + } + + static void dumpByteArray(String nm, byte[] bytes) throws IOException { + out.println(nm + " length: " + bytes.length); + hexDump.encodeBuffer(bytes, out); + } +} diff --git a/test/sun/security/pkcs11/Mac/MacKAT.java b/test/sun/security/pkcs11/Mac/MacKAT.java new file mode 100644 index 0000000000000000000000000000000000000000..c7da92971591301d1e295a3608ecc9c0317466c8 --- /dev/null +++ b/test/sun/security/pkcs11/Mac/MacKAT.java @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2003, 2014, 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. + * + * 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. + */ + +import java.io.UnsupportedEncodingException; +import java.security.Provider; +import java.util.Arrays; +import java.util.List; +import java.util.Random; +import javax.crypto.Mac; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + +/** + * @test + * @bug 4846410 6313661 4963723 + * @summary Basic known-answer-test for Hmac algorithms + * @author Andreas Sterbenz + * @library .. + * @run main MacKAT + */ +public class MacKAT extends PKCS11Test { + + private final static byte[] ALONG, BLONG, BKEY, BKEY_20, DDDATA_50, + AAKEY_20, CDDATA_50, AAKEY_131; + + static { + ALONG = new byte[1024 * 128]; + Arrays.fill(ALONG, (byte)'a'); + BLONG = new byte[1024 * 128]; + Random random = new Random(12345678); + random.nextBytes(BLONG); + BKEY = new byte[128]; + random.nextBytes(BKEY); + BKEY_20 = new byte[20]; + Arrays.fill(BKEY_20, (byte) 0x0b); + DDDATA_50 = new byte[50]; + Arrays.fill(DDDATA_50, (byte) 0xdd); + AAKEY_20 = new byte[20]; + Arrays.fill(AAKEY_20, (byte) 0xaa); + CDDATA_50 = new byte[50]; + Arrays.fill(CDDATA_50, (byte) 0xcd); + AAKEY_131 = new byte[131]; + Arrays.fill(AAKEY_131, (byte) 0xaa); + } + + private final static Test[] tests = { + newMacTest("SslMacMD5", + ALONG, + "f4:ad:01:71:51:f6:89:56:72:a3:32:bf:d9:2a:f2:a5", + "1b:34:61:29:05:0d:73:db:25:d0:dd:64:06:29:f6:8a"), + newMacTest("SslMacMD5", + BLONG, + "34:1c:ad:a0:95:57:32:f8:8e:80:8f:ee:b2:d8:23:e5", + "76:00:4a:72:98:9b:65:ec:2e:f1:43:c4:65:4a:13:71"), + newMacTest("SslMacSHA1", + ALONG, + "11:c1:71:2e:61:be:4b:cf:bc:6d:e2:4c:58:ae:27:30:0b:24:a4:87", + "23:ae:dd:61:87:6c:7a:45:47:2f:2c:8f:ea:64:99:3e:27:5f:97:a5"), + newMacTest("SslMacSHA1", + BLONG, + "84:af:57:0a:af:ef:16:93:90:50:da:88:f8:ad:1a:c5:66:6c:94:d0", + "9b:bb:e2:aa:9b:28:1c:95:0e:ea:30:21:98:a5:7e:31:9e:bf:5f:51"), + newMacTest("HmacMD5", + ALONG, + "76:00:4a:72:98:9b:65:ec:2e:f1:43:c4:65:4a:13:71", + "1b:34:61:29:05:0d:73:db:25:d0:dd:64:06:29:f6:8a"), + newMacTest("HmacMD5", + BLONG, + "6c:22:79:bb:34:9e:da:f4:f5:cf:df:0c:62:3d:59:e0", + "76:00:4a:72:98:9b:65:ec:2e:f1:43:c4:65:4a:13:71"), + newMacTest("HmacMD5", + BLONG, + "e6:ad:00:c9:49:6b:98:fe:53:a2:b9:2d:7d:41:a2:03", + BKEY), + newMacTest("HmacSHA1", + ALONG, + "9e:b3:6e:35:fa:fb:17:2e:2b:f3:b0:4a:9d:38:83:c4:5f:6d:d9:00", + "1b:34:61:29:05:0d:73:db:25:d0:dd:64:06:29:f6:8a"), + newMacTest("HmacSHA1", + BLONG, + "80:2d:5b:ea:08:df:a4:1f:e5:3e:1c:fa:fc:ad:dd:31:da:15:60:2c", + "76:00:4a:72:98:9b:65:ec:2e:f1:43:c4:65:4a:13:71"), + newMacTest("HmacSHA1", + BLONG, + "a2:fa:2a:85:18:0e:94:b2:a5:e2:17:8b:2a:29:7a:95:cd:e8:aa:82", + BKEY), + newMacTest("HmacSHA256", + ALONG, + "3f:6d:08:df:0c:90:b0:e9:ed:13:4a:2e:c3:48:1d:3d:3e:61:2e:f1:" + + "30:c2:63:c4:58:57:03:c2:cb:87:15:07", + "1b:34:61:29:05:0d:73:db:25:d0:dd:64:06:29:f6:8a"), + newMacTest("HmacSHA256", + BLONG, + "e2:4e:a3:b9:0b:b8:99:e4:71:cf:ca:9f:f8:4e:f0:34:8b:19:9f:33:" + + "4b:1a:b7:13:f7:c8:57:92:e3:03:74:78", + BKEY), + newMacTest("HmacSHA384", + ALONG, + "d0:f0:d4:54:1c:0a:6d:81:ed:15:20:d7:0c:96:06:61:a0:ff:c9:ff:" + + "91:e9:a0:cd:e2:45:64:9d:93:4c:a9:fa:89:ae:c0:90:e6:" + + "0b:a1:a0:56:80:57:3b:ed:4b:b0:71", + "1b:34:61:29:05:0d:73:db:25:d0:dd:64:06:29:f6:8a"), + newMacTest("HmacSHA384", + BLONG, + "75:c4:ca:c7:f7:58:9d:d3:23:b1:1b:5c:93:2d:ec:7a:03:dc:8c:eb:" + + "8d:fe:79:46:4f:30:e7:99:62:de:44:e2:38:95:0e:79:91:" + + "78:2f:a4:05:0a:f0:17:10:38:a1:8e", + BKEY), + newMacTest("HmacSHA512", + ALONG, + "41:ea:4c:e5:31:3f:7c:18:0e:5e:95:a9:25:0a:10:58:e6:40:53:88:" + + "82:4f:5a:da:6f:29:de:04:7b:8e:d7:ed:7c:4d:b8:2a:48:" + + "2d:17:2a:2d:59:bb:81:9c:bf:33:40:04:77:44:fb:45:25:" + + "1f:fd:b9:29:f4:a6:69:a3:43:6f", + "1b:34:61:29:05:0d:73:db:25:d0:dd:64:06:29:f6:8a"), + newMacTest("HmacSHA512", + BLONG, + "fb:cf:4b:c6:d5:49:5a:5b:0b:d9:2a:32:f5:fa:68:d2:68:a4:0f:ae:" + + "53:fc:49:12:e6:1d:53:cf:b2:cb:c5:c5:f2:2d:86:bd:14:" + + "61:30:c3:a6:6f:44:1f:77:9b:aa:a1:22:48:a9:dd:d0:45:" + + "86:d1:a1:82:53:13:c4:03:06:a3", + BKEY), + + // Test vectors From RFC 4231 + newMacTest("HmacSHA224", + bytes("Hi There"), + "89:6f:b1:12:8a:bb:df:19:68:32:10:7c:d4:9d:f3:3f:47:b4:b1:16:" + + "99:12:ba:4f:53:68:4b:22", + BKEY_20), + newMacTest("HmacSHA224", + bytes("what do ya want for nothing?"), + "a3:0e:01:09:8b:c6:db:bf:45:69:0f:3a:7e:9e:6d:0f:8b:be:a2:a3:" + + "9e:61:48:00:8f:d0:5e:44", + bytes("Jefe")), + newMacTest("HmacSHA224", + DDDATA_50, + "7f:b3:cb:35:88:c6:c1:f6:ff:a9:69:4d:7d:6a:d2:64:93:65:b0:c1:" + + "f6:5d:69:d1:ec:83:33:ea", + AAKEY_20), + newMacTest("HmacSHA224", + CDDATA_50, + "6c:11:50:68:74:01:3c:ac:6a:2a:bc:1b:b3:82:62:7c:ec:6a:90:d8:" + + "6e:fc:01:2d:e7:af:ec:5a", + "01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f:10:11:12:13:14:" + + "15:16:17:18:19"), + newMacTest("HmacSHA224", + bytes("Test Using Larger Than Block-Size Key - Hash Key First"), + "95:e9:a0:db:96:20:95:ad:ae:be:9b:2d:6f:0d:bc:e2:d4:99:f1:12:" + + "f2:d2:b7:27:3f:a6:87:0e", + AAKEY_131), + newMacTest("HmacSHA224", + bytes("This is a test using a larger than block-size key and " + + "a larger than block-size data. The key needs to be " + + "hashed before being used by the HMAC algorithm."), + "3a:85:41:66:ac:5d:9f:02:3f:54:d5:17:d0:b3:9d:bd:94:67:70:db:" + + "9c:2b:95:c9:f6:f5:65:d1", + AAKEY_131), + }; + + public static void main(String[] args) throws Exception { + main(new MacKAT()); + } + + @Override + public void main(Provider p) throws Exception { + long start = System.currentTimeMillis(); + + List algorithms = getSupportedAlgorithms("Mac", "", p); + for (Test test : tests) { + if(!algorithms.contains(test.getAlg())) { + continue; + } + test.run(p); + } + + System.out.println("All tests passed"); + long stop = System.currentTimeMillis(); + System.out.println("Done (" + (stop - start) + " ms)."); + } + + private static byte[] bytes(String s) { + try { + return s.getBytes("UTF8"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + private static Test newMacTest(String alg, byte[] input, String macvalue, + String key) { + return new MacTest(alg, input, parse(macvalue), parse(key)); + } + + private static Test newMacTest(String alg, byte[] input, String macvalue, + byte[] key) { + return new MacTest(alg, input, parse(macvalue), key); + } + + interface Test { + void run(Provider p) throws Exception; + String getAlg(); + } + + static class MacTest implements Test { + private final String alg; + private final byte[] input; + private final byte[] macvalue; + private final byte[] key; + + MacTest(String alg, byte[] input, byte[] macvalue, byte[] key) { + this.alg = alg; + this.input = input; + this.macvalue = macvalue; + this.key = key; + } + + @Override + public String getAlg() { + return alg; + } + + @Override + public void run(Provider p) throws Exception { + Mac mac = Mac.getInstance(alg, p); + SecretKey keySpec = new SecretKeySpec(key, alg); + mac.init(keySpec); + mac.update(input); + byte[] macv = mac.doFinal(); + if (Arrays.equals(macvalue, macv) == false) { + System.out.println("Mac test for " + alg + " failed:"); + if (input.length < 256) { + System.out.println("input: " + + PKCS11Test.toString(input)); + } + System.out.println("key: " + PKCS11Test.toString(key)); + System.out.println("macvalue: " + + PKCS11Test.toString(macvalue)); + System.out.println("calculated: " + PKCS11Test.toString(macv)); + throw new Exception("Mac test for " + alg + " failed"); + } + System.out.println("passed: " + alg); + } + } + +} diff --git a/test/sun/security/pkcs11/Mac/MacSameTest.java b/test/sun/security/pkcs11/Mac/MacSameTest.java new file mode 100644 index 0000000000000000000000000000000000000000..f5e2787e609e78387911c47f4d9ddc4d983c899b --- /dev/null +++ b/test/sun/security/pkcs11/Mac/MacSameTest.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 1998, 2014, 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. + * + * 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. + */ + +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.Provider; +import java.security.SecureRandom; +import java.util.List; +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; + +/** + * @test + * @bug 8048603 + * @summary Check if doFinal and update operation result in same Mac + * @author Yu-Ching Valerie Peng, Bill Situ, Alexander Fomin + * @library .. + * @run main MacSameTest + */ +public class MacSameTest extends PKCS11Test { + + private static final int MESSAGE_SIZE = 25; + private static final int OFFSET = 5; + private static final int KEY_SIZE = 70; + + /** + * Initialize a message, instantiate a Mac object, + * initialize the object with a SecretKey, + * feed the message into the Mac object + * all at once and get the output MAC as result1. + * Reset the Mac object, chop the message into three pieces, + * feed into the Mac object sequentially, and get the output MAC as result2. + * Finally, compare result1 and result2 and see if they are the same. + * + * @param args the command line arguments + */ + public static void main(String[] args) throws Exception { + main(new MacSameTest()); + } + + @Override + public void main(Provider p) { + List algorithms = getSupportedAlgorithms("Mac", "Hmac", p); + boolean success = true; + for (String alg : algorithms) { + try { + doTest(alg, p); + } catch (Exception e) { + System.out.println("Unexpected exception: " + e); + e.printStackTrace(); + success = false; + } + } + + if (!success) { + throw new RuntimeException("Test failed"); + } + } + + private void doTest(String algo, Provider provider) + throws NoSuchAlgorithmException, NoSuchProviderException, + InvalidKeyException { + System.out.println("Test " + algo); + Mac mac; + try { + mac = Mac.getInstance(algo, provider); + } catch (NoSuchAlgorithmException nsae) { + if ("SunPKCS11-Solaris".equals(provider.getName())) { + // depending on Solaris configuration, + // it can support HMAC or not with Mac + System.out.println("Expected NoSuchAlgorithmException thrown: " + + nsae); + return; + } + throw nsae; + } + + byte[] plain = new byte[MESSAGE_SIZE]; + for (int i = 0; i < MESSAGE_SIZE; i++) { + plain[i] = (byte) (i % 256); + } + + byte[] tail = new byte[plain.length - OFFSET]; + System.arraycopy(plain, OFFSET, tail, 0, tail.length); + + SecureRandom srdm = new SecureRandom(); + byte[] keyVal = new byte[KEY_SIZE]; + srdm.nextBytes(keyVal); + SecretKeySpec keySpec = new SecretKeySpec(keyVal, "HMAC"); + + mac.init(keySpec); + byte[] result1 = mac.doFinal(plain); + + mac.reset(); + mac.update(plain[0]); + mac.update(plain, 1, OFFSET - 1); + byte[] result2 = mac.doFinal(tail); + + if (!java.util.Arrays.equals(result1, result2)) { + throw new RuntimeException("result1 and result2 are not the same"); + } + } + +} diff --git a/test/sun/security/pkcs11/PKCS11Test.java b/test/sun/security/pkcs11/PKCS11Test.java index ca836f032b2b8239342721fa9c65f559155a3eb1..c8a147af5c025b8ccb155ee6fcd3d009a5f03c0e 100644 --- a/test/sun/security/pkcs11/PKCS11Test.java +++ b/test/sun/security/pkcs11/PKCS11Test.java @@ -578,4 +578,21 @@ public abstract class PKCS11Test { return r; } + /** + * Returns supported algorithms of specified type. + */ + static List getSupportedAlgorithms(String type, String alg, + Provider p) { + // prepare a list of supported algorithms + List algorithms = new ArrayList<>(); + Set services = p.getServices(); + for (Provider.Service service : services) { + if (service.getType().equals(type) + && service.getAlgorithm().startsWith(alg)) { + algorithms.add(service.getAlgorithm()); + } + } + return algorithms; + } + } diff --git a/test/sun/security/pkcs12/P12SecretKey.java b/test/sun/security/pkcs12/P12SecretKey.java new file mode 100644 index 0000000000000000000000000000000000000000..39f95d5e0b1304f9e72437ab0b904d7b9b8c1b87 --- /dev/null +++ b/test/sun/security/pkcs12/P12SecretKey.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2016, 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. + * + * 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. + */ + +/* + * @test + * @bug 8149411 + * @summary Get AES key from keystore (uses SecretKeySpec not SecretKeyFactory) + */ + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.security.KeyStore; +import java.security.cert.CertificateException; +import java.util.Arrays; + +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; + +public class P12SecretKey { + + private static final String ALIAS = "alias"; + + public static void main(String[] args) throws Exception { + P12SecretKey testp12 = new P12SecretKey(); + String keystoreType = "pkcs12"; + if (args != null && args.length > 0) { + keystoreType = args[0]; + } + testp12.run(keystoreType); + } + + private void run(String keystoreType) throws Exception { + char[] pw = "password".toCharArray(); + KeyStore ks = KeyStore.getInstance(keystoreType); + ks.load(null, pw); + + KeyGenerator kg = KeyGenerator.getInstance("AES"); + kg.init(128); + SecretKey key = kg.generateKey(); + + KeyStore.SecretKeyEntry ske = new KeyStore.SecretKeyEntry(key); + KeyStore.ProtectionParameter kspp = new KeyStore.PasswordProtection(pw); + ks.setEntry(ALIAS, ske, kspp); + + File ksFile = File.createTempFile("test", ".test"); + try (FileOutputStream fos = new FileOutputStream(ksFile)) { + ks.store(fos, pw); + fos.flush(); + } + + // now see if we can get it back + try (FileInputStream fis = new FileInputStream(ksFile)) { + KeyStore ks2 = KeyStore.getInstance(keystoreType); + ks2.load(fis, pw); + KeyStore.Entry entry = ks2.getEntry(ALIAS, kspp); + SecretKey keyIn = ((KeyStore.SecretKeyEntry)entry).getSecretKey(); + if (Arrays.equals(key.getEncoded(), keyIn.getEncoded())) { + System.err.println("OK: worked just fine with " + keystoreType + + " keystore"); + } else { + System.err.println("ERROR: keys are NOT equal after storing in " + + keystoreType + " keystore"); + } + } + } +} diff --git a/test/sun/security/pkcs12/StoreSecretKeyTest.java b/test/sun/security/pkcs12/StoreSecretKeyTest.java index 97bc3758d62366b030d4e1858d1f50f0e45cf152..15889334baed277db2c807d1bf8cffe5c1a342da 100644 --- a/test/sun/security/pkcs12/StoreSecretKeyTest.java +++ b/test/sun/security/pkcs12/StoreSecretKeyTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2015 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, 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 @@ -23,8 +23,9 @@ /* * @test - * @bug 8005408 8079129 + * @bug 8005408 8079129 8048830 * @summary KeyStore API enhancements + * @run main StoreSecretKeyTest */ import java.io.*; @@ -44,9 +45,20 @@ public class StoreSecretKeyTest { private static final String CERT = DIR + "/trusted.pem"; private static final String ALIAS = "my trusted cert"; private static final String ALIAS2 = "my secret key"; - + private enum ALGORITHM { + DES(56), + DESede(168), + AES(128); + final int len; + ALGORITHM(int l) { + len = l; + } + final int getLength() { + return len; + } + } public static void main(String[] args) throws Exception { - + boolean isSecretkeyAlgSupported = false; // Skip test if AES is unavailable try { SecretKeyFactory.getInstance("AES"); @@ -55,57 +67,69 @@ public class StoreSecretKeyTest { return; } - new File(KEYSTORE).delete(); + for (ALGORITHM alg : ALGORITHM.values()) { + isSecretkeyAlgSupported |= testSecretKeyAlgorithm(alg); + } + if (!isSecretkeyAlgSupported) { + throw new Exception("None of the SecretKey algorithms is " + + "supported"); + } + } - KeyStore keystore = KeyStore.getInstance("PKCS12"); - keystore.load(null, null); + private static boolean testSecretKeyAlgorithm(ALGORITHM algorithm) throws + Exception { - // Set trusted certificate entry - Certificate cert = loadCertificate(CERT); - keystore.setEntry(ALIAS, - new KeyStore.TrustedCertificateEntry(cert), null); + System.out.println("Testing algorithm : " + algorithm.name()); + new File(KEYSTORE).delete(); + try { + KeyStore keystore = KeyStore.getInstance("PKCS12"); + keystore.load(null, null); - // Set secret key entry - keystore.setEntry(ALIAS2, - new KeyStore.SecretKeyEntry(generateSecretKey("AES", 128)), + // Set trusted certificate entry + Certificate cert = loadCertificate(CERT); + keystore.setEntry(ALIAS, + new KeyStore.TrustedCertificateEntry(cert), null); + // Set secret key entry + SecretKey secretKey = generateSecretKey(algorithm.name(), + algorithm.len); + if(secretKey == null) { + return false; + } + keystore.setEntry(ALIAS2, + new KeyStore.SecretKeyEntry(secretKey), new KeyStore.PasswordProtection(PASSWORD)); - try (FileOutputStream outStream = new FileOutputStream(KEYSTORE)) { - System.out.println("Storing keystore to: " + KEYSTORE); - keystore.store(outStream, PASSWORD); - } - - try (FileInputStream inStream = new FileInputStream(KEYSTORE)) { - System.out.println("Loading keystore from: " + KEYSTORE); - keystore.load(inStream, PASSWORD); - System.out.println("Loaded keystore with " + keystore.size() + - " entries"); - } + try (FileOutputStream outStream = new FileOutputStream(KEYSTORE)) { + System.out.println("Storing keystore to: " + KEYSTORE); + keystore.store(outStream, PASSWORD); + } - KeyStore.Entry entry = keystore.getEntry(ALIAS2, - new KeyStore.PasswordProtection(PASSWORD)); - System.out.println("Retrieved entry: " + entry); + try (FileInputStream inStream = new FileInputStream(KEYSTORE)) { + System.out.println("Loading keystore from: " + KEYSTORE); + keystore.load(inStream, PASSWORD); + System.out.println("Loaded keystore with " + keystore.size() + + " entries"); + } - if (entry instanceof KeyStore.SecretKeyEntry) { - System.out.println("Retrieved secret key entry: " + entry); - } else { - throw new Exception("Not a secret key entry"); + KeyStore.Entry entry = keystore.getEntry(ALIAS2, + new KeyStore.PasswordProtection(PASSWORD)); + System.out.println("Retrieved entry: " + entry); + + if (entry instanceof KeyStore.SecretKeyEntry) { + System.out.println("Retrieved secret key entry: " + entry); + } else { + throw new Exception("Not a secret key entry"); + } + } catch (KeyStoreException | UnrecoverableKeyException ex) { + System.out.println("Unable to check SecretKey algorithm due to " + + "exception: " + ex.getMessage()); + return false; } + return true; } private static SecretKey generateSecretKey(String algorithm, int size) throws NoSuchAlgorithmException { - - // Failover to DES if the requested secret key factory is unavailable - SecretKeyFactory keyFactory; - try { - keyFactory = SecretKeyFactory.getInstance(algorithm); - } catch (NoSuchAlgorithmException nsae) { - keyFactory = SecretKeyFactory.getInstance("DES"); - algorithm = "DES"; - size = 56; - } - KeyGenerator generator = KeyGenerator.getInstance(algorithm); generator.init(size); return generator.generateKey(); diff --git a/test/sun/security/provider/NSASuiteB/TestDSAGenParameterSpec.java b/test/sun/security/provider/NSASuiteB/TestDSAGenParameterSpec.java new file mode 100644 index 0000000000000000000000000000000000000000..43a857f0c266c6c595f21e98f526d84e8ce04c08 --- /dev/null +++ b/test/sun/security/provider/NSASuiteB/TestDSAGenParameterSpec.java @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +import java.security.AlgorithmParameterGenerator; +import java.security.AlgorithmParameters; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidParameterException; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.spec.DSAGenParameterSpec; +import java.security.spec.DSAParameterSpec; +import java.security.spec.InvalidParameterSpecException; +import java.util.Arrays; +import java.util.List; + +/* + * @test + * @bug 8075286 + * @summary Verify that DSAGenParameterSpec can and can only be used to generate + * DSA within some certain range of key sizes as described in the class + * specification (L, N) as (1024, 160), (2048, 224), (2048, 256) and + * (3072, 256) should be OK for DSAGenParameterSpec. But the real + * implementation SUN doesn't support (3072, 256). + * @run main TestDSAGenParameterSpec + */ +public class TestDSAGenParameterSpec { + + private static final String ALGORITHM_NAME = "DSA"; + private static final String PROVIDER_NAME = "SUN"; + + private static final List DATA = Arrays.asList( + new DataTuple(1024, 160, true, true), + new DataTuple(2048, 224, true, true), + new DataTuple(2048, 256, true, true), + new DataTuple(3072, 256, true, false), + new DataTuple(1024, 224), + new DataTuple(2048, 160), + new DataTuple(4096, 256), + new DataTuple(512, 160), + new DataTuple(3072, 224)); + + private static void testDSAGenParameterSpec(DataTuple dataTuple) + throws NoSuchAlgorithmException, NoSuchProviderException, + InvalidParameterSpecException, InvalidAlgorithmParameterException { + System.out.printf("Test case: primePLen=%d, " + "subprimeQLen=%d%n", + dataTuple.primePLen, dataTuple.subprimeQLen); + + AlgorithmParameterGenerator apg = + AlgorithmParameterGenerator.getInstance(ALGORITHM_NAME, + PROVIDER_NAME); + + DSAGenParameterSpec genParamSpec = createGenParameterSpec(dataTuple); + // genParamSpec will be null if IllegalAE is thrown when expected. + if (genParamSpec == null) { + return; + } + + try { + apg.init(genParamSpec, null); + AlgorithmParameters param = apg.generateParameters(); + + checkParam(param, genParamSpec); + System.out.println("Test case passed"); + } catch (InvalidParameterException ipe) { + // The DSAGenParameterSpec API support this, but the real + // implementation in SUN doesn't + if (!dataTuple.isSunProviderSupported) { + System.out.println("Test case passed: expected " + + "InvalidParameterException is caught"); + } else { + throw new RuntimeException("Test case failed.", ipe); + } + } + } + + private static void checkParam(AlgorithmParameters param, + DSAGenParameterSpec genParam) throws InvalidParameterSpecException, + NoSuchAlgorithmException, NoSuchProviderException, + InvalidAlgorithmParameterException { + String algorithm = param.getAlgorithm(); + if (!algorithm.equalsIgnoreCase(ALGORITHM_NAME)) { + throw new RuntimeException( + "Unexpected type of parameters: " + algorithm); + } + + DSAParameterSpec spec = param.getParameterSpec(DSAParameterSpec.class); + int valueL = spec.getP().bitLength(); + int strengthP = genParam.getPrimePLength(); + if (strengthP != valueL) { + System.out.printf("P: Expected %d but actual %d%n", strengthP, + valueL); + throw new RuntimeException("Wrong P strength"); + } + + int valueN = spec.getQ().bitLength(); + int strengthQ = genParam.getSubprimeQLength(); + if (strengthQ != valueN) { + System.out.printf("Q: Expected %d but actual %d%n", strengthQ, + valueN); + throw new RuntimeException("Wrong Q strength"); + } + + if (genParam.getSubprimeQLength() != genParam.getSeedLength()) { + System.out.println("Defaut seed length should be the same as Q."); + throw new RuntimeException("Wrong seed length"); + } + + // use the parameters to generate real DSA keys + KeyPairGenerator keyGen = KeyPairGenerator.getInstance(ALGORITHM_NAME, + PROVIDER_NAME); + keyGen.initialize(spec); + keyGen.generateKeyPair(); + } + + private static DSAGenParameterSpec createGenParameterSpec( + DataTuple dataTuple) { + DSAGenParameterSpec genParamSpec = null; + try { + genParamSpec = new DSAGenParameterSpec(dataTuple.primePLen, + dataTuple.subprimeQLen); + if (!dataTuple.isDSASpecSupported) { + throw new RuntimeException( + "Test case failed: the key length must not supported"); + } + } catch (IllegalArgumentException e) { + if (!dataTuple.isDSASpecSupported) { + System.out.println("Test case passed: expected " + + "IllegalArgumentException is caught"); + } else { + throw new RuntimeException("Test case failed: unexpected " + + "IllegalArgumentException is thrown", e); + } + } + + return genParamSpec; + } + + public static void main(String[] args) throws Exception { + for (DataTuple dataTuple : DATA) { + testDSAGenParameterSpec(dataTuple); + } + System.out.println("All tests passed"); + } + + private static class DataTuple { + + private int primePLen; + private int subprimeQLen; + private boolean isDSASpecSupported; + private boolean isSunProviderSupported; + + private DataTuple(int primePLen, int subprimeQLen, + boolean isDSASpecSupported, boolean isSunProviderSupported) { + this.primePLen = primePLen; + this.subprimeQLen = subprimeQLen; + this.isDSASpecSupported = isDSASpecSupported; + this.isSunProviderSupported = isSunProviderSupported; + } + + private DataTuple(int primePLen, int subprimeQLen) { + this(primePLen, subprimeQLen, false, false); + } + } +} diff --git a/test/sun/security/provider/NSASuiteB/TestSHAOids.java b/test/sun/security/provider/NSASuiteB/TestSHAOids.java new file mode 100644 index 0000000000000000000000000000000000000000..66d72b6d84e78062368adf2e71d4199a91e30020 --- /dev/null +++ b/test/sun/security/provider/NSASuiteB/TestSHAOids.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.util.Arrays; +import java.util.List; + +/* + * @test + * @bug 8075286 + * @summary Test the SHA algorithm OIDs in JDK. + * OID and algorithm transformation string should match. + * Both could be able to be used to generate the algorithm instance. + * @run main TestSHAOids + */ +public class TestSHAOids { + + private static final String PROVIDER_NAME = "SUN"; + private static final byte[] INPUT = "1234567890".getBytes(); + + private static final List DATA = Arrays.asList( + new DataTuple("2.16.840.1.101.3.4.2.1", "SHA-256"), + new DataTuple("2.16.840.1.101.3.4.2.2", "SHA-384"), + new DataTuple("2.16.840.1.101.3.4.2.3", "SHA-512"), + new DataTuple("2.16.840.1.101.3.4.2.4", "SHA-224")); + + public static void main(String[] args) throws Exception { + for (DataTuple dataTuple : DATA) { + runTest(dataTuple); + System.out.println("passed"); + } + System.out.println("All tests passed"); + } + + private static void runTest(DataTuple dataTuple) + throws NoSuchAlgorithmException, NoSuchProviderException { + MessageDigest mdAlgorithm = MessageDigest.getInstance( + dataTuple.algorithm, PROVIDER_NAME); + MessageDigest mdOid = MessageDigest.getInstance(dataTuple.oid, + PROVIDER_NAME); + + if (mdAlgorithm == null) { + throw new RuntimeException(String.format( + "Test failed: algorithm string %s getInstance failed.%n", + dataTuple.algorithm)); + } + + if (mdOid == null) { + throw new RuntimeException( + String.format("Test failed: OID %s getInstance failed.%n", + dataTuple.oid)); + } + + if (!mdAlgorithm.getAlgorithm().equals(dataTuple.algorithm)) { + throw new RuntimeException(String.format( + "Test failed: algorithm string %s getInstance doesn't " + + "generate expected algorithm.%n", + dataTuple.algorithm)); + } + + mdAlgorithm.update(INPUT); + mdOid.update(INPUT); + + // Comparison + if (!Arrays.equals(mdAlgorithm.digest(), mdOid.digest())) { + throw new RuntimeException("Digest comparison failed: " + + "the two digests are not the same"); + } + } + + private static class DataTuple { + + private final String oid; + private final String algorithm; + + private DataTuple(String oid, String algorithm) { + this.oid = oid; + this.algorithm = algorithm; + } + } +} diff --git a/test/sun/security/provider/NSASuiteB/TestSHAwithDSASignatureOids.java b/test/sun/security/provider/NSASuiteB/TestSHAwithDSASignatureOids.java new file mode 100644 index 0000000000000000000000000000000000000000..dad84ccfd7eb1237e86f6eae23766ae566b096ed --- /dev/null +++ b/test/sun/security/provider/NSASuiteB/TestSHAwithDSASignatureOids.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +import java.util.Arrays; +import java.util.List; + +/* + * @test + * @bug 8075286 + * @summary Test the SHAwithDSA signature algorithm OIDs in JDK. + * OID and algorithm transformation string should match. + * Both could be able to be used to generate the algorithm instance. + * @compile ../../TestSignatureOidHelper.java + * @run main TestSHAwithDSASignatureOids + */ +public class TestSHAwithDSASignatureOids { + + private static final List DATA = Arrays.asList( + new OidAlgorithmPair("2.16.840.1.101.3.4.3.1", "SHA224withDSA"), + new OidAlgorithmPair("2.16.840.1.101.3.4.3.2", "SHA256withDSA")); + + public static void main(String[] args) throws Exception { + TestSignatureOidHelper helper = new TestSignatureOidHelper("DSA", + "SUN", 1024, DATA); + helper.execute(); + } +} diff --git a/test/sun/security/rsa/KeySizeTest.java b/test/sun/security/rsa/KeySizeTest.java new file mode 100644 index 0000000000000000000000000000000000000000..35f9902b8c3d5696f0fb995992ed02bcea6ce646 --- /dev/null +++ b/test/sun/security/rsa/KeySizeTest.java @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.interfaces.RSAKey; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.RSAPrivateKeySpec; +import java.security.spec.RSAPublicKeySpec; + +/** + * @test + * @bug 8044199 + * @summary test if the private and public key size are the same as what is set + * through KeyPairGenerator. + * @run main KeySizeTest 512 10 + * @run main KeySizeTest 768 10 + * @run main KeySizeTest 1024 10 + * @run main KeySizeTest 2048 5 + * @run main KeySizeTest 4096 1 + */ +public class KeySizeTest { + + /** + * ALGORITHM name, fixed as RSA. + */ + private static final String KEYALG = "RSA"; + + /** + * JDK default RSA Provider. + */ + private static final String PROVIDER_NAME = "SunRsaSign"; + + public static void main(String[] args) throws Exception { + int iKeyPairSize = Integer.parseInt(args[0]); + int maxLoopCnt = Integer.parseInt(args[1]); + + int failCount = 0; + KeyPairGenerator keyPairGen + = KeyPairGenerator.getInstance(KEYALG, PROVIDER_NAME); + keyPairGen.initialize(iKeyPairSize); + // Generate RSA keypair + KeyPair keyPair = keyPairGen.generateKeyPair(); + + // Get priavte and public keys + PrivateKey privateKey = keyPair.getPrivate(); + PublicKey publicKey = keyPair.getPublic(); + try { + if (!sizeTest(keyPair)) { + failCount++; + } + } catch (Exception ex) { + ex.printStackTrace(System.err); + failCount++; + } + + for (int iCnt = 0; iCnt < maxLoopCnt; iCnt++) { + + // Get keysize (modulus) of keys + KeyFactory keyFact = KeyFactory.getInstance(KEYALG, PROVIDER_NAME); + + // Comparing binary length. + RSAPrivateKeySpec privateKeySpec + = (RSAPrivateKeySpec) keyFact.getKeySpec(privateKey, + RSAPrivateKeySpec.class); + int iPrivateKeySize = privateKeySpec.getModulus().bitLength(); + + RSAPublicKeySpec publicKeySpec + = (RSAPublicKeySpec) keyFact.getKeySpec(publicKey, + RSAPublicKeySpec.class); + int iPublicKeySize = publicKeySpec.getModulus().bitLength(); + + if ((iKeyPairSize != iPublicKeySize) || (iKeyPairSize != iPrivateKeySize)) { + System.err.println("iKeyPairSize : " + iKeyPairSize); + System.err.println("Generated a " + iPrivateKeySize + + " bit RSA private key"); + System.err.println("Generated a " + iPublicKeySize + + " bit RSA public key"); + failCount++; + } + } + + if (failCount > 0) { + throw new RuntimeException("There are " + failCount + " tests failed."); + } + } + + /** + * @param kpair test key pair. + * @return true if test passed. false if test failed. + */ + private static boolean sizeTest(KeyPair kpair) { + RSAPrivateKey priv = (RSAPrivateKey) kpair.getPrivate(); + RSAPublicKey pub = (RSAPublicKey) kpair.getPublic(); + + // test the getModulus method + if ((priv instanceof RSAKey) && (pub instanceof RSAKey)) { + if (!priv.getModulus().equals(pub.getModulus())) { + System.err.println("priv.getModulus() = " + priv.getModulus()); + System.err.println("pub.getModulus() = " + pub.getModulus()); + return false; + } + } + return true; + } +} diff --git a/test/sun/security/rsa/PrivateKeyEqualityTest.java b/test/sun/security/rsa/PrivateKeyEqualityTest.java new file mode 100644 index 0000000000000000000000000000000000000000..1a3a6df756a1e241dc8f9d484302507a2a64b294 --- /dev/null +++ b/test/sun/security/rsa/PrivateKeyEqualityTest.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ +import java.security.KeyFactory; +import java.security.KeyPairGenerator; +import java.security.KeyPair; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.interfaces.RSAPrivateCrtKey; +import java.security.interfaces.RSAPrivateKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.RSAPrivateKeySpec; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.RSAPrivateCrtKeySpec; + +/** + * @test + * @bug 8044199 4666485 + * @summary Equality checking for RSAPrivateKey by SunRsaSign provider. + */ +public class PrivateKeyEqualityTest { + /** + * ALGORITHM name, fixed as RSA. + */ + private static final String KEYALG = "RSA"; + + /** + * JDK default RSA Provider. + */ + private static final String PROVIDER_NAME = "SunRsaSign"; + + public static void main(String[] args) throws NoSuchAlgorithmException, + NoSuchProviderException, InvalidKeySpecException { + // Generate the first key. + KeyPairGenerator generator + = KeyPairGenerator.getInstance(KEYALG, PROVIDER_NAME); + KeyPair keyPair = generator.generateKeyPair(); + RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate(); + if (!(rsaPrivateKey instanceof RSAPrivateCrtKey)) { + System.err.println("rsaPrivateKey class : " + rsaPrivateKey.getClass().getName()); + throw new RuntimeException("rsaPrivateKey is not a RSAPrivateCrtKey instance"); + } + + // Generate the second key. + KeyFactory factory = KeyFactory.getInstance(KEYALG, PROVIDER_NAME); + RSAPrivateKeySpec rsaPrivateKeySpec = new RSAPrivateKeySpec( + rsaPrivateKey.getModulus(), rsaPrivateKey.getPrivateExponent()); + RSAPrivateKey rsaPrivateKey2 = (RSAPrivateKey) factory.generatePrivate( + rsaPrivateKeySpec); + + // Generate the third key. + PKCS8EncodedKeySpec encodedKeySpec = new PKCS8EncodedKeySpec( + rsaPrivateKey.getEncoded()); + RSAPrivateKey rsaPrivateKey3 = (RSAPrivateKey) factory.generatePrivate( + encodedKeySpec); + + // Check for equality. + if (rsaPrivateKey.equals(rsaPrivateKey2)) { + throw new RuntimeException("rsaPrivateKey should not equal to rsaPrivateKey2"); + } + if (!rsaPrivateKey3.equals(rsaPrivateKey)) { + throw new RuntimeException("rsaPrivateKey3 should equal to rsaPrivateKey"); + } + if (rsaPrivateKey3.equals(rsaPrivateKey2)) { + throw new RuntimeException("rsaPrivateKey3 should not equal to rsaPrivateKey2"); + } + if (rsaPrivateKey2.equals(rsaPrivateKey3)) { + throw new RuntimeException("rsaPrivateKey2 should not equal to rsaPrivateKey3"); + } + + // Generate the fourth key. + RSAPrivateCrtKey rsaPrivateCrtKey = (RSAPrivateCrtKey)rsaPrivateKey; + RSAPrivateCrtKeySpec rsaPrivateCrtKeySpec = new RSAPrivateCrtKeySpec( + rsaPrivateCrtKey.getModulus(), + rsaPrivateCrtKey.getPublicExponent(), + rsaPrivateCrtKey.getPrivateExponent(), + rsaPrivateCrtKey.getPrimeP(), + rsaPrivateCrtKey.getPrimeQ(), + rsaPrivateCrtKey.getPrimeExponentP(), + rsaPrivateCrtKey.getPrimeExponentQ(), + rsaPrivateCrtKey.getCrtCoefficient() + ); + RSAPrivateCrtKey rsaPrivateKey4 = (RSAPrivateCrtKey) factory.generatePrivate( + rsaPrivateCrtKeySpec); + if (!rsaPrivateKey.equals(rsaPrivateKey4)) { + throw new RuntimeException("rsaPrivateKey should equal to rsaPrivateKey4"); + } + } +} diff --git a/test/sun/security/rsa/SignatureOffsets.java b/test/sun/security/rsa/SignatureOffsets.java new file mode 100644 index 0000000000000000000000000000000000000000..b813b26d4a511fef75de53d3d99262d4f4d1c3c1 --- /dev/null +++ b/test/sun/security/rsa/SignatureOffsets.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.SignatureException; + +/* + * @test + * @bug 8050374 + * @key randomness + * @summary This test validates signature verification + * Signature.verify(byte[], int, int). The test uses RandomFactory to + * get random set of clear text data to sign. After the signature + * generation, the test tries to verify signature with the above API + * and passing in different signature offset (0, 33, 66, 99). + * @library /lib/testlibrary + * @compile ../../../java/security/Signature/Offsets.java + * @run main SignatureOffsets SunRsaSign MD2withRSA + * @run main SignatureOffsets SunRsaSign MD5withRSA + * @run main SignatureOffsets SunRsaSign SHA1withRSA + * @run main SignatureOffsets SunRsaSign SHA224withRSA + * @run main SignatureOffsets SunRsaSign SHA256withRSA + * @run main SignatureOffsets SunRsaSign SHA384withRSA + * @run main SignatureOffsets SunRsaSign SHA512withRSA + */ +public class SignatureOffsets { + + public static void main(String[] args) throws NoSuchAlgorithmException, + InvalidKeyException, SignatureException { + Offsets.main(args); + } +} \ No newline at end of file diff --git a/test/sun/security/rsa/SignatureTest.java b/test/sun/security/rsa/SignatureTest.java new file mode 100644 index 0000000000000000000000000000000000000000..0eed4ec1e5f8a876d543bec641630316f218c0bb --- /dev/null +++ b/test/sun/security/rsa/SignatureTest.java @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.Signature; +import java.security.SignatureException; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.RSAPrivateKeySpec; +import java.security.spec.RSAPublicKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.Arrays; +import static javax.crypto.Cipher.PRIVATE_KEY; +import static javax.crypto.Cipher.PUBLIC_KEY; +import jdk.testlibrary.RandomFactory; + +/** + * @test + * @bug 8044199 + * @summary Create a signature for RSA and get its signed data. re-initiate + * the signature with the public key. The signature can be verified + * by acquired signed data. + * @key randomness + * @library ../../../lib/testlibrary + * @run main SignatureTest MD2withRSA 512 + * @run main SignatureTest MD5withRSA 512 + * @run main SignatureTest SHA1withRSA 512 + * @run main SignatureTest SHA256withRSA 512 + * @run main SignatureTest MD2withRSA 768 + * @run main SignatureTest MD5withRSA 768 + * @run main SignatureTest SHA1withRSA 768 + * @run main SignatureTest SHA256withRSA 768 + * @run main SignatureTest MD2withRSA 1024 + * @run main SignatureTest MD5withRSA 1024 + * @run main SignatureTest SHA1withRSA 1024 + * @run main SignatureTest SHA256withRSA 1024 + * @run main SignatureTest MD2withRSA 2048 + * @run main SignatureTest MD5withRSA 2048 + * @run main SignatureTest SHA1withRSA 2048 + * @run main SignatureTest SHA256withRSA 2048 + * @run main/timeout=240 SignatureTest MD2withRSA 4096 + * @run main/timeout=240 SignatureTest MD5withRSA 4096 + * @run main/timeout=240 SignatureTest SHA1withRSA 4096 + * @run main/timeout=240 SignatureTest SHA256withRSA 4096 + * @run main/timeout=240 SignatureTest MD2withRSA 5120 + * @run main/timeout=240 SignatureTest MD5withRSA 5120 + * @run main/timeout=240 SignatureTest SHA1withRSA 5120 + * @run main/timeout=240 SignatureTest SHA256withRSA 5120 + * @run main/timeout=240 SignatureTest MD2withRSA 6144 + * @run main/timeout=240 SignatureTest MD5withRSA 6144 + * @run main/timeout=240 SignatureTest SHA1withRSA 6144 + * @run main/timeout=240 SignatureTest SHA256withRSA 6144 + */ +public class SignatureTest { + /** + * ALGORITHM name, fixed as RSA. + */ + private static final String KEYALG = "RSA"; + + /** + * JDK default RSA Provider. + */ + private static final String PROVIDER = "SunRsaSign"; + + /** + * How much times signature updated. + */ + private static final int UPDATE_TIMES_FIFTY = 50; + + /** + * How much times signature initial updated. + */ + private static final int UPDATE_TIMES_HUNDRED = 100; + + public static void main(String[] args) throws Exception { + String testAlg = args[0]; + int testSize = Integer.parseInt(args[1]); + + byte[] data = new byte[100]; + RandomFactory.getRandom().nextBytes(data); + + // create a key pair + KeyPair kpair = generateKeys(KEYALG, testSize); + Key[] privs = manipulateKey(PRIVATE_KEY, kpair.getPrivate()); + Key[] pubs = manipulateKey(PUBLIC_KEY, kpair.getPublic()); + // For signature algorithm, create and verify a signature + + Arrays.stream(privs).forEach(priv + -> Arrays.stream(pubs).forEach(pub -> { + try { + checkSignature(data, (PublicKey) pub, (PrivateKey) priv, + testAlg); + } catch (NoSuchAlgorithmException | InvalidKeyException + | SignatureException | NoSuchProviderException ex) { + throw new RuntimeException(ex); + } + } + )); + + } + + private static KeyPair generateKeys(String keyalg, int size) + throws NoSuchAlgorithmException { + KeyPairGenerator kpg = KeyPairGenerator.getInstance(keyalg); + kpg.initialize(size); + return kpg.generateKeyPair(); + } + + private static Key[] manipulateKey(int type, Key key) + throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException { + KeyFactory kf = KeyFactory.getInstance(KEYALG, PROVIDER); + + switch (type) { + case PUBLIC_KEY: + try { + kf.getKeySpec(key, RSAPrivateKeySpec.class); + throw new RuntimeException("Expected InvalidKeySpecException " + + "not thrown"); + } catch (InvalidKeySpecException expected) { + } + + return new Key[]{ + kf.generatePublic(kf.getKeySpec(key, RSAPublicKeySpec.class)), + kf.generatePublic(new X509EncodedKeySpec(key.getEncoded())), + kf.generatePublic(new RSAPublicKeySpec( + ((RSAPublicKey) key).getModulus(), + ((RSAPublicKey) key).getPublicExponent())) + }; + case PRIVATE_KEY: + try { + kf.getKeySpec(key, RSAPublicKeySpec.class); + throw new RuntimeException("Expected InvalidKeySpecException" + + " not thrown"); + } catch (InvalidKeySpecException expected) { + } + return new Key[]{ + kf.generatePrivate(kf.getKeySpec(key, + RSAPrivateKeySpec.class)), + kf.generatePrivate(new PKCS8EncodedKeySpec( + key.getEncoded())), + kf.generatePrivate(new RSAPrivateKeySpec(((RSAPrivateKey) key).getModulus(), + ((RSAPrivateKey) key).getPrivateExponent())) + }; + } + throw new RuntimeException("We shouldn't reach here"); + } + + private static void checkSignature(byte[] data, PublicKey pub, + PrivateKey priv, String sigalg) throws NoSuchAlgorithmException, + InvalidKeyException, SignatureException, NoSuchProviderException { + Signature sig = Signature.getInstance(sigalg, PROVIDER); + sig.initSign(priv); + for (int i = 0; i < UPDATE_TIMES_HUNDRED; i++) { + sig.update(data); + } + byte[] signedData = sig.sign(); + + // Make sure signature verifies with original data + sig.initVerify(pub); + for (int i = 0; i < UPDATE_TIMES_HUNDRED; i++) { + sig.update(data); + } + if (!sig.verify(signedData)) { + throw new RuntimeException("Failed to verify " + sigalg + + " signature"); + } + + // Make sure signature does NOT verify when the original data + // has changed + sig.initVerify(pub); + for (int i = 0; i < UPDATE_TIMES_FIFTY; i++) { + sig.update(data); + } + + if (sig.verify(signedData)) { + throw new RuntimeException("Failed to detect bad " + sigalg + + " signature"); + } + } +} diff --git a/test/sun/security/rsa/SignedObjectChain.java b/test/sun/security/rsa/SignedObjectChain.java new file mode 100644 index 0000000000000000000000000000000000000000..7bda7cd4df62d7cf33e0c819717557831a1a7bde --- /dev/null +++ b/test/sun/security/rsa/SignedObjectChain.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +/* + * @test + * @bug 8050374 + * @compile ../../../java/security/SignedObject/Chain.java + * @summary Verify a chain of signed objects + */ +public class SignedObjectChain { + + private static class Test extends Chain.Test { + + public Test(Chain.SigAlg sigAlg) { + super(sigAlg, Chain.KeyAlg.RSA, Chain.Provider.SunRsaSign); + } + } + + private static final Test[] tests = { + new Test(Chain.SigAlg.MD2withRSA), + new Test(Chain.SigAlg.MD5withRSA), + new Test(Chain.SigAlg.SHA1withRSA), + new Test(Chain.SigAlg.SHA224withRSA), + new Test(Chain.SigAlg.SHA256withRSA), + new Test(Chain.SigAlg.SHA384withRSA), + new Test(Chain.SigAlg.SHA512withRSA), + }; + + public static void main(String argv[]) { + boolean resutl = java.util.Arrays.stream(tests).allMatch( + (test) -> Chain.runTest(test)); + + if(resutl) { + System.out.println("All tests passed"); + } else { + throw new RuntimeException("Some tests failed"); + } + } +} diff --git a/test/sun/security/rsa/SpecTest.java b/test/sun/security/rsa/SpecTest.java new file mode 100644 index 0000000000000000000000000000000000000000..d2ab0a8e79fd80846eac899c8c40d30da4d9782f --- /dev/null +++ b/test/sun/security/rsa/SpecTest.java @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ +import java.math.BigInteger; +import java.security.InvalidAlgorithmParameterException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.interfaces.RSAKey; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.RSAKeyGenParameterSpec; + +/** + * @test + * @bug 8044199 + * @summary Check same KeyPair's private key and public key have same modulus. + * also check public key's public exponent equals to given spec's public + * exponent. + * @run main SpecTest 512 + * @run main SpecTest 768 + * @run main SpecTest 1024 + * @run main SpecTest 2048 + * @run main/timeout=240 SpecTest 4096 + * @run main/timeout=240 SpecTest 5120 + */ +public class SpecTest { + /** + * ALGORITHM name, fixed as RSA. + */ + private static final String KEYALG = "RSA"; + + /** + * JDK default RSA Provider. + */ + private static final String PROVIDER = "SunRsaSign"; + + /** + * + * @param kpair test key pair + * @param pubExponent expected public exponent. + * @return true if test passed. false if test failed. + */ + private static boolean specTest(KeyPair kpair, BigInteger pubExponent) { + boolean passed = true; + RSAPrivateKey priv = (RSAPrivateKey) kpair.getPrivate(); + RSAPublicKey pub = (RSAPublicKey) kpair.getPublic(); + + // test the getModulus method + if ((priv instanceof RSAKey) && (pub instanceof RSAKey)) { + if (!priv.getModulus().equals(pub.getModulus())) { + System.err.println("priv.getModulus() = " + priv.getModulus()); + System.err.println("pub.getModulus() = " + pub.getModulus()); + passed = false; + } + + if (!pubExponent.equals(pub.getPublicExponent())) { + System.err.println("pubExponent = " + pubExponent); + System.err.println("pub.getPublicExponent() = " + + pub.getPublicExponent()); + passed = false; + } + } + return passed; + } + + public static void main(String[] args) { + int failCount = 0; + + // Test key size. + int size = Integer.parseInt(args[0]); + + try { + KeyPairGenerator kpg1 = KeyPairGenerator.getInstance(KEYALG, PROVIDER); + kpg1.initialize(new RSAKeyGenParameterSpec(size, + RSAKeyGenParameterSpec.F4)); + if (!specTest(kpg1.generateKeyPair(), + RSAKeyGenParameterSpec.F4)) { + failCount++; + } + + KeyPairGenerator kpg2 = KeyPairGenerator.getInstance(KEYALG, PROVIDER); + kpg2.initialize(new RSAKeyGenParameterSpec(size, + RSAKeyGenParameterSpec.F0)); + if (!specTest(kpg2.generateKeyPair(), RSAKeyGenParameterSpec.F0)) { + failCount++; + } + } catch (NoSuchAlgorithmException | NoSuchProviderException + | InvalidAlgorithmParameterException ex) { + ex.printStackTrace(System.err); + failCount++; + } + + if (failCount != 0) { + throw new RuntimeException("There are " + failCount + + " tests failed."); + } + } +} diff --git a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLCtxAccessToSessCtx.java b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLCtxAccessToSessCtx.java index 41fddc46ed01d3943c865568eb895988a9cdb10b..c23951f3526b582a1314d3ad1bb87a2ef0f0ea06 100644 --- a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLCtxAccessToSessCtx.java +++ b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLCtxAccessToSessCtx.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2016, 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 @@ -35,6 +35,7 @@ import java.io.*; import java.net.*; import javax.net.ssl.*; import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; import java.security.KeyStore; public class SSLCtxAccessToSessCtx { @@ -63,7 +64,7 @@ public class SSLCtxAccessToSessCtx { /* * Is the server ready to serve? */ - volatile static boolean serverReady = false; + AtomicInteger serverReady = new AtomicInteger(1); // only one port now /* * Turn on SSL debugging? @@ -89,12 +90,13 @@ public class SSLCtxAccessToSessCtx { SSLServerSocket sslServerSocket = (SSLServerSocket) sslssf.createServerSocket(serverPort); - serverPorts[createdPorts++] = sslServerSocket.getLocalPort(); + int slot = createdPorts.getAndIncrement(); + serverPorts[slot] = sslServerSocket.getLocalPort(); /* * Signal Client, we're ready for his connect. */ - serverReady = true; + serverReady.getAndDecrement(); int read = 0; SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept(); InputStream sslIS = sslSocket.getInputStream(); @@ -121,7 +123,7 @@ public class SSLCtxAccessToSessCtx { /* * Wait for server to get started. */ - while (!serverReady) { + while (serverReady.get() > 0) { Thread.sleep(50); } /* @@ -151,8 +153,8 @@ public class SSLCtxAccessToSessCtx { * The remainder is just support stuff */ - volatile int serverPorts[] = new int[]{0}; - volatile int createdPorts = 0; + int serverPorts[] = new int[]{0}; // only one port at present + AtomicInteger createdPorts = new AtomicInteger(0); static SSLServerSocketFactory sslssf; static SSLSocketFactory sslsf; static SSLContext sslctx; @@ -255,14 +257,20 @@ public class SSLCtxAccessToSessCtx { */ System.err.println("Server died..."); e.printStackTrace(); - serverReady = true; + serverReady.set(0); serverException = e; } } }; serverThread.start(); } else { - doServerSide(port); + try { + doServerSide(port); + } catch (Exception e) { + serverException = e; + } finally { + serverReady.set(0); + } } } @@ -284,7 +292,11 @@ public class SSLCtxAccessToSessCtx { }; clientThread.start(); } else { - doClientSide(); + try { + doClientSide(); + } catch (Exception e) { + clientException = e; + } } } } diff --git a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionCacheSizeTests.java b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionCacheSizeTests.java index d4e00855dc6db51c733faef873d93342fc777575..72faf5952d99cd9b0d588c12369773fcb9b08d27 100644 --- a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionCacheSizeTests.java +++ b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionCacheSizeTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2016, 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 @@ -28,7 +28,7 @@ /* * @test - * @bug 4366807 + * @bug 4366807 * @summary Need new APIs to get/set session timeout and session cache size. * @run main/othervm SessionCacheSizeTests */ @@ -108,36 +108,47 @@ public class SessionCacheSizeTests { void doServerSide(int serverPort, int serverConns) throws Exception { - SSLServerSocket sslServerSocket = - (SSLServerSocket) sslssf.createServerSocket(serverPort); - serverPorts[createdPorts++] = sslServerSocket.getLocalPort(); + try (SSLServerSocket sslServerSocket = + (SSLServerSocket) sslssf.createServerSocket(serverPort)) { - /* - * Signal Client, we're ready for his connect. - */ - if (createdPorts == serverPorts.length) { - serverReady = true; - } - int read = 0; - int nConnections = 0; - /* - * Divide the max connections among the available server ports. - * The use of more than one server port ensures creation of more - * than one session. - */ - SSLSession sessions [] = new SSLSession [serverConns]; - SSLSessionContext sessCtx = sslctx.getServerSessionContext(); - - while (nConnections < serverConns) { - SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept(); - InputStream sslIS = sslSocket.getInputStream(); - OutputStream sslOS = sslSocket.getOutputStream(); - read = sslIS.read(); - sessions[nConnections] = sslSocket.getSession(); - sslOS.write(85); - sslOS.flush(); - sslSocket.close(); - nConnections++; + // timeout to accept a connection + sslServerSocket.setSoTimeout(45000); + + // make sure createdPorts++ is atomic + synchronized(serverPorts) { + serverPorts[createdPorts++] = sslServerSocket.getLocalPort(); + + /* + * Signal Client, we're ready for his connect. + */ + if (createdPorts == serverPorts.length) { + serverReady = true; + } + } + int read = 0; + int nConnections = 0; + + /* + * Divide the max connections among the available server ports. + * The use of more than one server port ensures creation of more + * than one session. + */ + SSLSession sessions [] = new SSLSession [serverConns]; + SSLSessionContext sessCtx = sslctx.getServerSessionContext(); + + while (nConnections < serverConns) { + try (SSLSocket sslSocket = + (SSLSocket)sslServerSocket.accept()) { + sslSocket.setSoTimeout(90000); // timeout to read + InputStream sslIS = sslSocket.getInputStream(); + OutputStream sslOS = sslSocket.getOutputStream(); + read = sslIS.read(); + sessions[nConnections] = sslSocket.getSession(); + sslOS.write(85); + sslOS.flush(); + nConnections++; + } + } } } @@ -263,8 +274,8 @@ public class SessionCacheSizeTests { * Using four ports (one per each connection), we are able to create * alteast four sessions. */ - volatile int serverPorts[] = new int[]{0, 0, 0, 0}; - volatile int createdPorts = 0; + int serverPorts[] = new int[]{0, 0, 0, 0}; // MAX_ACTIVE_CONNECTIONS: 4 + int createdPorts = 0; static SSLServerSocketFactory sslssf; static SSLSocketFactory sslsf; static SSLContext sslctx; diff --git a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionTimeOutTests.java b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionTimeOutTests.java index 9264cb08723c13f87995d84ef3f406b3ce56037d..0c887221995c76742847b416ec64a923c371b266 100644 --- a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionTimeOutTests.java +++ b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionTimeOutTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2016, 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 @@ -36,6 +36,7 @@ import java.net.*; import javax.net.ssl.*; import java.util.*; import java.security.*; +import java.util.concurrent.atomic.AtomicInteger; /** * Session reuse time-out tests cover the cases below: @@ -79,7 +80,7 @@ public class SessionTimeOutTests { /* * Is the server ready to serve? */ - volatile static int serverReady = PORTS; + AtomicInteger serverReady = new AtomicInteger(PORTS); /* * Turn on SSL debugging? @@ -98,7 +99,7 @@ public class SessionTimeOutTests { /* * Define the server side of the test. * - * If the server prematurely exits, serverReady will be set to true + * If the server prematurely exits, serverReady will be set to zero * to avoid infinite hangs. */ @@ -111,12 +112,13 @@ public class SessionTimeOutTests { SSLServerSocket sslServerSocket = (SSLServerSocket) sslssf.createServerSocket(serverPort); - serverPorts[createdPorts++] = sslServerSocket.getLocalPort(); + int slot = createdPorts.getAndIncrement(); + serverPorts[slot] = sslServerSocket.getLocalPort(); /* * Signal Client, we're ready for his connect. */ - serverReady--; + serverReady.getAndDecrement(); int read = 0; int nConnections = 0; SSLSession sessions [] = new SSLSession [serverConns]; @@ -137,7 +139,7 @@ public class SessionTimeOutTests { /* * Define the client side of the test. * - * If the server prematurely exits, serverReady will be set to true + * If the server prematurely exits, serverReady will be set to zero * to avoid infinite hangs. */ void doClientSide() throws Exception { @@ -145,7 +147,7 @@ public class SessionTimeOutTests { /* * Wait for server to get started. */ - while (serverReady > 0) { + while (serverReady.get() > 0) { Thread.sleep(50); } @@ -287,8 +289,8 @@ public class SessionTimeOutTests { * The remainder is just support stuff */ - volatile int serverPorts[] = new int[PORTS]; - volatile int createdPorts = 0; + int serverPorts[] = new int[PORTS]; + AtomicInteger createdPorts = new AtomicInteger(0); static SSLServerSocketFactory sslssf; static SSLSocketFactory sslsf; static SSLContext sslctx; @@ -447,7 +449,7 @@ public class SessionTimeOutTests { */ System.err.println("Server died..."); e.printStackTrace(); - serverReady = 0; + serverReady.set(0); serverException = e; } } @@ -459,7 +461,7 @@ public class SessionTimeOutTests { } catch (Exception e) { serverException = e; } finally { - serverReady = 0; + serverReady.set(0); } } } diff --git a/test/sun/security/ssl/rsa/SignatureOffsets.java b/test/sun/security/ssl/rsa/SignatureOffsets.java new file mode 100644 index 0000000000000000000000000000000000000000..618dde714d4e7e8fd6a5fc354441884a0e1abe6c --- /dev/null +++ b/test/sun/security/ssl/rsa/SignatureOffsets.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.SignatureException; + +/* + * @test + * @bug 8050374 + * @key randomness + * @summary This test validates signature verification + * Signature.verify(byte[], int, int). The test uses RandomFactory to + * get random set of clear text data to sign. After the signature + * generation, the test tries to verify signature with the above API + * and passing in different signature offset (0, 33, 66, 99). + * @library /lib/testlibrary + * @compile ../../../../java/security/Signature/Offsets.java + * @run main SignatureOffsets SunJSSE MD2withRSA + * @run main SignatureOffsets SunJSSE MD5withRSA + * @run main SignatureOffsets SunJSSE SHA1withRSA + * @run main SignatureOffsets SunJSSE MD5andSHA1withRSA + */ +public class SignatureOffsets { + + public static void main(String[] args) throws NoSuchAlgorithmException, + InvalidKeyException, SignatureException { + Offsets.main(args); + } +} \ No newline at end of file diff --git a/test/sun/security/ssl/rsa/SignedObjectChain.java b/test/sun/security/ssl/rsa/SignedObjectChain.java new file mode 100644 index 0000000000000000000000000000000000000000..ba4b00c56d8a0b2385e433b37d622b9808e43d31 --- /dev/null +++ b/test/sun/security/ssl/rsa/SignedObjectChain.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +/* + * @test + * @bug 8050374 + * @compile ../../../../java/security/SignedObject/Chain.java + * @summary Verify a chain of signed objects + */ +public class SignedObjectChain { + + private static class Test extends Chain.Test { + + public Test(Chain.SigAlg sigAlg) { + super(sigAlg, Chain.KeyAlg.RSA, Chain.Provider.SunJSSE); + } + } + + private static final Test[] tests = { + new Test(Chain.SigAlg.MD2withRSA), + new Test(Chain.SigAlg.MD5withRSA), + new Test(Chain.SigAlg.SHA1withRSA), + new Test(Chain.SigAlg.MD5andSHA1withRSA), + }; + + public static void main(String argv[]) { + boolean resutl = java.util.Arrays.stream(tests).allMatch( + (test) -> Chain.runTest(test)); + + if(resutl) { + System.out.println("All tests passed"); + } else { + throw new RuntimeException("Some tests failed"); + } + } +} diff --git a/test/sun/security/x509/X509CertImpl/V3Certificate.java b/test/sun/security/x509/X509CertImpl/V3Certificate.java new file mode 100644 index 0000000000000000000000000000000000000000..57e96de5a10c4aa933974af0561b77a8d7f957f2 --- /dev/null +++ b/test/sun/security/x509/X509CertImpl/V3Certificate.java @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2015, 2016, 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. + * + * 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. + */ + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintWriter; +import static java.lang.System.out; +import java.security.InvalidKeyException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.Signature; +import java.security.SignatureException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; +import sun.misc.BASE64Encoder; +import sun.security.util.BitArray; +import sun.security.util.ObjectIdentifier; +import sun.security.x509.*; + +/** + * @test + * @bug 8049237 + * @summary This test generates V3 certificate with all the supported + * extensions. Writes back the generated certificate in to a file and checks for + * equality with the original certificate. + */ +public class V3Certificate { + + public static final String V3_FILE = "certV3"; + public static final String V3_B64_FILE = "certV3.b64"; + + public static void main(String[] args) throws IOException, + NoSuchAlgorithmException, InvalidKeyException, CertificateException, + NoSuchProviderException, SignatureException { + + boolean success = true; + + success &= test("RSA", "SHA256withRSA", 2048); + success &= test("DSA", "SHA256withDSA", 2048); + success &= test("EC", "SHA256withECDSA", 384); + + if (!success) { + throw new RuntimeException("At least one test case failed"); + } + } + + public static boolean test(String algorithm, String sigAlg, int keyLength) + throws IOException, + NoSuchAlgorithmException, + InvalidKeyException, + CertificateException, + NoSuchProviderException, + SignatureException { + + byte[] issuerId = {1, 2, 3, 4, 5}; + byte[] subjectId = {6, 7, 8, 9, 10}; + boolean testResult = true; + + // Subject and Issuer + X500Name subject = new X500Name("test", "Oracle", "Santa Clara", + "US"); + X500Name issuer = subject; + + // Generate keys and sign + KeyPairGenerator keyGen = KeyPairGenerator.getInstance(algorithm); + keyGen.initialize(keyLength); + KeyPair pair = keyGen.generateKeyPair(); + PublicKey publicKey = pair.getPublic(); + PrivateKey privateKey = pair.getPrivate(); + MessageDigest md = MessageDigest.getInstance("SHA"); + byte[] keyId = md.digest(publicKey.getEncoded()); + + Signature signature = Signature.getInstance(sigAlg); + signature.initSign(privateKey); + + // Validity interval + Date firstDate = new Date(); + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("PST")); + cal.set(2014, 03, 10, 12, 30, 30); + Date lastDate = cal.getTime(); + CertificateValidity interval = new CertificateValidity(firstDate, + lastDate); + + // Certificate Info + X509CertInfo cert = new X509CertInfo(); + + cert.set(X509CertInfo.VERSION, + new CertificateVersion(CertificateVersion.V3)); + cert.set(X509CertInfo.SERIAL_NUMBER, + new CertificateSerialNumber((int) (firstDate.getTime() / 1000))); + cert.set(X509CertInfo.ALGORITHM_ID, + new CertificateAlgorithmId(AlgorithmId.get(sigAlg))); + cert.set(X509CertInfo.SUBJECT, subject); + cert.set(X509CertInfo.KEY, new CertificateX509Key(publicKey)); + cert.set(X509CertInfo.VALIDITY, interval); + cert.set(X509CertInfo.ISSUER, issuer); + + cert.set(X509CertInfo.ISSUER_ID, + new UniqueIdentity( + new BitArray(issuerId.length * 8 - 2, issuerId))); + cert.set(X509CertInfo.SUBJECT_ID, new UniqueIdentity(subjectId)); + + // Create Extensions + CertificateExtensions exts = new CertificateExtensions(); + + GeneralNameInterface mailInf = new RFC822Name("test@Oracle.com"); + GeneralName mail = new GeneralName(mailInf); + GeneralNameInterface dnsInf = new DNSName("Oracle.com"); + GeneralName dns = new GeneralName(dnsInf); + GeneralNameInterface uriInf = new URIName("http://www.Oracle.com"); + GeneralName uri = new GeneralName(uriInf); + + // localhost + byte[] address = new byte[]{127, 0, 0, 1}; + + GeneralNameInterface ipInf = new IPAddressName(address); + GeneralName ip = new GeneralName(ipInf); + int[] oidData = new int[]{1, 2, 3, 4}; + + GeneralNameInterface oidInf = new OIDName(new ObjectIdentifier(oidData)); + GeneralName oid = new GeneralName(oidInf); + + SubjectAlternativeNameExtension subjectName + = new SubjectAlternativeNameExtension(); + IssuerAlternativeNameExtension issuerName + = new IssuerAlternativeNameExtension(); + + GeneralNames subjectNames + = (GeneralNames) subjectName. + get(SubjectAlternativeNameExtension.SUBJECT_NAME); + + GeneralNames issuerNames + = (GeneralNames) issuerName. + get(IssuerAlternativeNameExtension.ISSUER_NAME); + + subjectNames.add(mail); + subjectNames.add(dns); + subjectNames.add(uri); + + issuerNames.add(ip); + issuerNames.add(oid); + + cal.set(2000, 11, 15, 12, 30, 30); + lastDate = cal.getTime(); + PrivateKeyUsageExtension pkusage + = new PrivateKeyUsageExtension(firstDate, lastDate); + + KeyUsageExtension usage = new KeyUsageExtension(); + usage.set(KeyUsageExtension.CRL_SIGN, true); + usage.set(KeyUsageExtension.DIGITAL_SIGNATURE, true); + usage.set(KeyUsageExtension.NON_REPUDIATION, true); + + KeyIdentifier kid = new KeyIdentifier(keyId); + SerialNumber sn = new SerialNumber(42); + AuthorityKeyIdentifierExtension aki + = new AuthorityKeyIdentifierExtension(kid, subjectNames, sn); + + SubjectKeyIdentifierExtension ski + = new SubjectKeyIdentifierExtension(keyId); + + BasicConstraintsExtension cons + = new BasicConstraintsExtension(true, 10); + + PolicyConstraintsExtension pce = new PolicyConstraintsExtension(2, 4); + + exts.set(SubjectAlternativeNameExtension.NAME, subjectName); + exts.set(IssuerAlternativeNameExtension.NAME, issuerName); + exts.set(PrivateKeyUsageExtension.NAME, pkusage); + exts.set(KeyUsageExtension.NAME, usage); + exts.set(AuthorityKeyIdentifierExtension.NAME, aki); + exts.set(SubjectKeyIdentifierExtension.NAME, ski); + exts.set(BasicConstraintsExtension.NAME, cons); + exts.set(PolicyConstraintsExtension.NAME, pce); + cert.set(X509CertInfo.EXTENSIONS, exts); + + // Generate and sign X509CertImpl + X509CertImpl crt = new X509CertImpl(cert); + crt.sign(privateKey, sigAlg); + crt.verify(publicKey); + + try (FileOutputStream fos = new FileOutputStream(new File(V3_FILE)); + FileOutputStream fos_b64 + = new FileOutputStream(new File(V3_B64_FILE)); + PrintWriter pw = new PrintWriter(fos_b64)) { + crt.encode((OutputStream) fos); + fos.flush(); + + // Certificate boundaries/ + pw.println("-----BEGIN CERTIFICATE-----"); + pw.flush(); + new BASE64Encoder().encodeBuffer(crt.getEncoded(), fos_b64); + fos_b64.flush(); + pw.println("-----END CERTIFICATE-----"); + } + + out.println("*** Certificate ***"); + out.println(crt); + out.println("*** End Certificate ***"); + + X509Certificate x2 = generateCertificate(V3_FILE); + if (!x2.equals(crt)) { + out.println("*** Certificate mismatch ***"); + testResult = false; + } + + X509Certificate x3 = generateCertificate(V3_B64_FILE); + if (!x3.equals(crt)) { + out.println("*** Certificate mismatch ***"); + testResult = false; + } + + return testResult; + } + + static X509Certificate generateCertificate(String certFile) { + try (InputStream inStrm = new FileInputStream(certFile)) { + CertificateFactory cf = CertificateFactory.getInstance("X509"); + X509Certificate x2 + = (X509Certificate) cf.generateCertificate(inStrm); + return x2; + } catch (CertificateException | IOException e) { + throw new RuntimeException("Exception while " + + "genrating certificate for " + certFile, e); + } + } +} diff --git a/test/sun/tools/jcmd/TestJcmdDefaults.java b/test/sun/tools/jcmd/TestJcmdDefaults.java new file mode 100644 index 0000000000000000000000000000000000000000..a5310862859fc14cbe853d2d9e69a4f5b19d1c6a --- /dev/null +++ b/test/sun/tools/jcmd/TestJcmdDefaults.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2011, 2014, 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. + * + * 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. + */ + +import static jdk.testlibrary.Asserts.*; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +import jdk.testlibrary.JcmdBase; +import jdk.testlibrary.OutputAnalyzer; +import jdk.testlibrary.Utils; + +/** + * Unit test for jcmd utility. Tests jcmd options which do not send + * requests to a specific JVM process. + */ +/* + * @test + * @bug 7104647 + * @library /lib/testlibrary + * @run main TestJcmdDefaults + */ +public class TestJcmdDefaults { + + private static final String TEST_SRC = System.getProperty("test.src").trim(); + private static final String[] VM_ARGS = new String[] { "-XX:+UsePerfData" }; + private static final String JCMD_LIST_REGEX = "^\\d+\\s*.*"; + + public static void main(String[] args) throws Exception { + testJcmdUsage("-h"); + testJcmdUsage("-help"); + testJcmdDefaults(); + testJcmdDefaults("-l"); + } + + /** + * jcmd -J-XX:+UsePerfData -h + * jcmd -J-XX:+UsePerfData -help + */ + private static void testJcmdUsage(String... jcmdArgs) throws Exception { + OutputAnalyzer output = JcmdBase.jcmdNoPid(VM_ARGS, jcmdArgs); + + assertNotEquals(output.getExitValue(), 0); + verifyOutputAgainstFile(output); + } + + /** + * jcmd -J-XX:+UsePerfData + * jcmd -J-XX:+UsePerfData -l + */ + private static void testJcmdDefaults(String... jcmdArgs) throws Exception { + OutputAnalyzer output = JcmdBase.jcmdNoPid(VM_ARGS, jcmdArgs); + + output.shouldHaveExitValue(0); + output.shouldContain("sun.tools.jcmd.JCmd"); + matchListedProcesses(output); + } + + /** + * Verifies the listed processes match a certain pattern. + * + * The output should look like: + * 12246 sun.tools.jcmd.JCmd + * 24428 com.sun.javatest.regtest.MainWrapper /tmp/jtreg/jtreg-workdir/classes/sun/tools/jcmd/TestJcmdDefaults.jta + * + * @param output The generated output from the jcmd. + * @throws Exception + */ + private static void matchListedProcesses(OutputAnalyzer output) throws Exception { + int matchedCount = output.shouldMatchByLine(JCMD_LIST_REGEX); + assertGreaterThan(matchedCount , 0, + "Found no lines matching pattern: " + JCMD_LIST_REGEX); + } + + private static void verifyOutputAgainstFile(OutputAnalyzer output) throws IOException { + File file = new File(TEST_SRC, "usage.out"); + List fileOutput = Utils.fileAsList(file); + List outputAsLines = output.asLines(); + assertTrue(outputAsLines.containsAll(fileOutput), + "The ouput should contain all content of " + file.getAbsolutePath()); + } + +} diff --git a/test/sun/tools/jcmd/TestJcmdSanity.java b/test/sun/tools/jcmd/TestJcmdSanity.java new file mode 100644 index 0000000000000000000000000000000000000000..b25c4c54786b1fe7dbb8d5ad0cf5ae0ade27b878 --- /dev/null +++ b/test/sun/tools/jcmd/TestJcmdSanity.java @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2011, 2014, 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. + * + * 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. + */ + +import static jdk.testlibrary.Asserts.*; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +import jdk.testlibrary.JcmdBase; +import jdk.testlibrary.OutputAnalyzer; +import jdk.testlibrary.ProcessTools; +import jdk.testlibrary.Utils; + +/** + * Unit test for jcmd utility. The test will send different diagnostic command + * requests to the current java process. + */ +/* + * @test + * @bug 7104647 7154822 + * @library /lib/testlibrary + * @run main TestJcmdSanity + */ +public class TestJcmdSanity { + + private static final String TEST_SRC = System.getProperty("test.src").trim(); + private static final String[] VM_ARGS = new String[] { "-XX:+UsePerfData" }; + private static final String JCMD_COMMAND_REGEX = "(\\w|\\.)*"; + private static final String PERF_COUNTER_REGEX = "(\\w|\\.)*\\=.*"; + + public static void main(String[] args) throws Exception { + testJcmdPidHelp(); + testJcmdPidHelpHelp(); + testJcmdPid_f(); + testJcmdPidPerfCounterPrint(); + testJcmdPidBigScript(); + } + + /** + * jcmd -J-XX:+UsePerfData pid help + */ + private static void testJcmdPidHelp() throws Exception { + OutputAnalyzer output = JcmdBase.jcmd(VM_ARGS, + new String[] {"help"}); + output.shouldHaveExitValue(0); + output.shouldNotContain("Exception"); + output.shouldContain(Integer.toString(ProcessTools.getProcessId()) + ":"); + matchJcmdCommands(output); + output.shouldContain("For more information about a specific command use 'help '."); + } + + /** + * jcmd -J-XX:+UsePerfData pid help help + */ + private static void testJcmdPidHelpHelp() throws Exception { + OutputAnalyzer output = JcmdBase.jcmd(VM_ARGS, + new String[] {"help", "help"}); + + output.shouldHaveExitValue(0); + verifyOutputAgainstFile(output); + } + + /** + * jcmd -J-XX:+UsePerfData pid PerfCounter.print + */ + private static void testJcmdPidPerfCounterPrint() throws Exception { + OutputAnalyzer output = JcmdBase.jcmd(VM_ARGS, + new String[] {"PerfCounter.print"}); + + output.shouldHaveExitValue(0); + matchPerfCounters(output); + } + + /** + * jcmd -J-XX:+UsePerfData pid -f dcmd-script.txt + */ + private static void testJcmdPid_f() throws Exception { + File scrpitFile = new File(TEST_SRC, "dcmd-script.txt"); + OutputAnalyzer output = JcmdBase.jcmd(VM_ARGS, + new String[] {"-f", scrpitFile.getAbsolutePath()}); + + output.shouldHaveExitValue(0); + verifyOutputAgainstFile(output); + } + + /** + * Tests that it possible send a file over 1024 bytes large via jcmd -f. + * + * jcmd -J-XX:+UsePerfData pid -f dcmd-big-script.txt + */ + private static void testJcmdPidBigScript() throws Exception { + File scrpitFile = new File(TEST_SRC, "dcmd-big-script.txt"); + OutputAnalyzer output = JcmdBase.jcmd(VM_ARGS, + new String[] {"-f", scrpitFile.getAbsolutePath()}); + + output.shouldHaveExitValue(0); + output.shouldNotContain("Exception"); + output.shouldContain(System.getProperty("java.vm.name").trim()); + } + + /** + * Verifies the listed jcmd commands match a certain pattern. + * + * The output of the jcmd commands should look like: + * VM.uptime + * VM.flags + * VM.system_properties + * + * @param output The generated output from the jcmd. + * @throws Exception + */ + private static void matchJcmdCommands(OutputAnalyzer output) throws Exception { + int matchedCount = output.shouldMatchByLine(JCMD_COMMAND_REGEX, + "help", + JCMD_COMMAND_REGEX); + assertGreaterThan(matchedCount , 0, + "Found no lines matching pattern: " + JCMD_COMMAND_REGEX); + } + + /** + * Verifies the generated output from the PerfCounter.print command + * matches a certain pattern. + * + * The output of perf counters should look like: + * java.property.java.vm.name="Java HotSpot(TM) 64-Bit Server VM" + * java.threads.daemon=7 + * sun.rt.javaCommand="com.sun.javatest.regtest.MainWrapper /tmp/jtreg/jtreg-workdir/classes/sun/tools/jcmd/TestJcmdSanity.jta" + * + * @param output The generated output from the PerfCounter.print command. + * @throws Exception + */ + private static void matchPerfCounters(OutputAnalyzer output) throws Exception { + int matchedCount = output.shouldMatchByLineFrom(PERF_COUNTER_REGEX, + PERF_COUNTER_REGEX); + assertGreaterThan(matchedCount , 0, + "Found no lines matching pattern: " + PERF_COUNTER_REGEX); + } + + private static void verifyOutputAgainstFile(OutputAnalyzer output) throws IOException { + File file = new File(TEST_SRC, "help_help.out"); + List fileOutput = Utils.fileAsList(file); + List outputAsLines = output.asLines(); + assertTrue(outputAsLines.containsAll(fileOutput), + "The ouput should contain all content of " + file.getAbsolutePath()); + } + +} diff --git a/test/sun/tools/jcmd/help_help.out b/test/sun/tools/jcmd/help_help.out index beaf0f35b94581516e25f0755ea0798db1102281..3f151b92acd6d9999a13cd31e03083ca68583473 100644 --- a/test/sun/tools/jcmd/help_help.out +++ b/test/sun/tools/jcmd/help_help.out @@ -1,7 +1,7 @@ help For more information about a specific command use 'help '. With no argument this will show a list of available commands. 'help all' will show help for all commands. -Impact: Low +Impact: Low Syntax : help [options] [] diff --git a/test/sun/tools/jcmd/jcmd-Defaults.sh b/test/sun/tools/jcmd/jcmd-Defaults.sh deleted file mode 100644 index 2d6aa2ebe893a05bcf064e98baa1bd3aed9ec3e0..0000000000000000000000000000000000000000 --- a/test/sun/tools/jcmd/jcmd-Defaults.sh +++ /dev/null @@ -1,33 +0,0 @@ -# -# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# 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. -# - -# @test -# @bug 7104647 -# @run shell jcmd-Defaults.sh -# @summary Test that output of 'jcmd' and 'jcmd -l' match a specific pattern - -JCMD="${TESTJAVA}/bin/jcmd" - -${JCMD} -J-XX:+UsePerfData 2>&1 | awk -f ${TESTSRC}/jcmd_Output1.awk - -${JCMD} -J-XX:+UsePerfData -l 2>&1 | awk -f ${TESTSRC}/jcmd_Output1.awk diff --git a/test/sun/tools/jcmd/jcmd-big-script.sh b/test/sun/tools/jcmd/jcmd-big-script.sh deleted file mode 100644 index a101c8cf2a8fe8db3c646b4b2869554f18779023..0000000000000000000000000000000000000000 --- a/test/sun/tools/jcmd/jcmd-big-script.sh +++ /dev/null @@ -1,70 +0,0 @@ -#!/bin/sh - -# -# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# 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. -# - - -# @test -# @bug 7154822 -# @summary test if we can send a file over 1024 bytes large via jcmd -f -# @author David Buck -# -# @library ../common -# @build SimpleApplication ShutdownSimpleApplication -# @run shell jcmd-big-script.sh - -. ${TESTSRC}/../common/CommonSetup.sh -. ${TESTSRC}/../common/ApplicationSetup.sh - -# Start application and use PORTFILE for coordination -PORTFILE="${TESTCLASSES}"/shutdown.port -startApplication SimpleApplication "${PORTFILE}" - -failed=0; - -# -f