8186057: TLS interoperability testing between different Java versions
An interop test for checking the compatibility among different Java versions. Reviewed-by: asmotrak
This commit is contained in:
parent
6912165887
commit
f8aaf97179
265
test/jdk/javax/net/ssl/compatibility/Cert.java
Normal file
265
test/jdk/javax/net/ssl/compatibility/Cert.java
Normal file
@ -0,0 +1,265 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The certificates and corresponding private keys used by the test.
|
||||
* All of certificates uses relative weak key size and hash algorithm, then
|
||||
* all JDK releases can load them. Accordingly, a custom java.security file is
|
||||
* provided to make sure such weak key sizes and algorithms are not blocked by
|
||||
* any JDK build.
|
||||
*/
|
||||
public enum Cert {
|
||||
|
||||
// This certificate is generated by the below command:
|
||||
// openssl req -x509 -newkey rsa:1024 -days 7300 \
|
||||
// -subj "/CN=RSA_SHA1_1024" -sha1 \
|
||||
// -keyout key.pem -out cert.pem
|
||||
RSA_SHA1_1024(
|
||||
SignatureAlgorithm.RSA,
|
||||
"-----BEGIN CERTIFICATE-----\n" +
|
||||
"MIIB/jCCAWegAwIBAgIJANPuKkD7/jxkMA0GCSqGSIb3DQEBBQUAMBgxFjAUBgNV\n" +
|
||||
"BAMMDVJTQV9TSEExXzEwMjQwHhcNMTcwOTA3MDIwNTM0WhcNMzcwOTAyMDIwNTM0\n" +
|
||||
"WjAYMRYwFAYDVQQDDA1SU0FfU0hBMV8xMDI0MIGfMA0GCSqGSIb3DQEBAQUAA4GN\n" +
|
||||
"ADCBiQKBgQC3v7UeIxD5bdv4mqwcpah7sNxpI3IxUFzI2ao1g1jVzDPZt9Zawa3K\n" +
|
||||
"H+m9al1Fg2X1dyNeRlbiXavcIZOQwZqNj08zJEwAdICP8iOnXQ2HUv5cpzArOPTu\n" +
|
||||
"GY3flhf39xgiWsSdfb+cP0QsWNagNU8EtebbHndv8W+2K5JEdlpwQQIDAQABo1Aw\n" +
|
||||
"TjAdBgNVHQ4EFgQU32KqdiGyzg39chNt/OwQzGOlUyAwHwYDVR0jBBgwFoAU32Kq\n" +
|
||||
"diGyzg39chNt/OwQzGOlUyAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOB\n" +
|
||||
"gQAWx8y45IIWWhy44cuQs0qcSDQihIvhXB3pvlpCNdfsSrVoaaH8lrOVjTC718ip\n" +
|
||||
"fE1sF8I9niLHUg8WrAzdQRDsKyUhDUhEEJ7w1ffxwf8bcI9+NgWwEix0Dazzkub8\n" +
|
||||
"2IRXuZ3dGwzoI54XtxvKMFH86nJEj4M/XQGrc9bnlhcn4g==\n" +
|
||||
"-----END CERTIFICATE-----",
|
||||
"30820278020100300d06092a864886f70d0101010500048202623082025e0201" +
|
||||
"0002818100b7bfb51e2310f96ddbf89aac1ca5a87bb0dc69237231505cc8d9aa" +
|
||||
"358358d5cc33d9b7d65ac1adca1fe9bd6a5d458365f577235e4656e25dabdc21" +
|
||||
"9390c19a8d8f4f33244c0074808ff223a75d0d8752fe5ca7302b38f4ee198ddf" +
|
||||
"9617f7f718225ac49d7dbf9c3f442c58d6a0354f04b5e6db1e776ff16fb62b92" +
|
||||
"44765a7041020301000102818100b2c5afdf5c5a9d72c73b7eb0c9465b3fcc79" +
|
||||
"0549d946255bc0861555ef2eb503f1c67757f400cfa7019996123020fb906d5b" +
|
||||
"b66b789ffba90b16270cbd1fbfcf285a821dcdc78fd8f17f399eb231ce9724db" +
|
||||
"af60f9dd20f3e57bb4c0f9fdc9069589b82d442dd868d48c031eb782e27f9e70" +
|
||||
"8469f9b3d5b1b23cee5bf1b41781024100dec184ea77c2126c6bc0c01ba727b4" +
|
||||
"642587d63811240932334dc80c7976e0f715f156e52b352a25e5c52542af2b5f" +
|
||||
"68a29a9b68858f313c4375cc78ec03d859024100d32be8375f52cbe904002321" +
|
||||
"6977aee83fa88bf536d4052d2ed578727d7b7e5aeef91fc52b34c1b6638c00f0" +
|
||||
"4c6985fdaaa2d6e72adbcc7d10ed8bafff69da29024100ae8210acd6f13519b7" +
|
||||
"38a3c7862636ce1610daa3c5d9e3526e9acad3eafc54b57d7d3a44029b7dcf7e" +
|
||||
"b7f9beca1842806892929949b8aa2bb9f5b9202a55c0d1024100887dc0c2c9a2" +
|
||||
"429a823374818c2207b3a631d304d443867505e884c9bbc1ae9228146e2c8b18" +
|
||||
"b67ca52b411010d3c3ff89e366f454076dcd08bc01a5e8790ac102402321988a" +
|
||||
"2003e19c878791d402a7c0acdd1b6dd27203ed88f86a0e3a390ee57c0cd277f3" +
|
||||
"ea5df6440dbc8bdb4c8b3c28fc77e6991bc4ed3f4dc0619a5b953e8e"),
|
||||
|
||||
// This certificate is generated by the below command:
|
||||
// openssl req -x509 -newkey rsa:1024 -days 7300 \
|
||||
// -subj "/CN=www.example.com" -sha1 \
|
||||
// -keyout key.pem -out cert.pem
|
||||
RSA_EXAMPLE_SHA1_1024(
|
||||
SignatureAlgorithm.RSA,
|
||||
"-----BEGIN CERTIFICATE-----\n" +
|
||||
"MIICAjCCAWugAwIBAgIJAK6TC9eDtZg4MA0GCSqGSIb3DQEBBQUAMBoxGDAWBgNV\n" +
|
||||
"BAMMD3d3dy5leGFtcGxlLmNvbTAeFw0xNzExMDIwNTA5NDRaFw0zNzEwMjgwNTA5\n" +
|
||||
"NDRaMBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTCBnzANBgkqhkiG9w0BAQEF\n" +
|
||||
"AAOBjQAwgYkCgYEAtt5kxFTzJuoxJR2UgeXUxCw7TfL3FeK3lCrU3vruBe3XKKvF\n" +
|
||||
"oyCxf/B5ucm22gzMfOvJBWRg6KrNTrXGI1LtlmAYNDM5J0lK2N/neKOm3Qxe0d1W\n" +
|
||||
"AZ1lwgrMNirsWu+r4UPNMq5UohL5nqVU9WwVa12t0GF3er3k32tMTBqSclcCAwEA\n" +
|
||||
"AaNQME4wHQYDVR0OBBYEFNc8tKGfZdFyaY0ZslwGLt1kpRYAMB8GA1UdIwQYMBaA\n" +
|
||||
"FNc8tKGfZdFyaY0ZslwGLt1kpRYAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEF\n" +
|
||||
"BQADgYEAc71ZO83YEw9WvhxDEng9tMYUhJnNZJss6+gfWjZ487aiEGnS+VgKsHWz\n" +
|
||||
"DBLBrYe9Ag5L9f1HtPNheUbnhhBbQ607jOG/wfmpi4VoU3myB5uxOfeAZdXDOB5x\n" +
|
||||
"bv3t7KcEhgmPjB/e123jrBK8qnAYmDlQVlkZScctB3I1OuA2Po4=\n" +
|
||||
"-----END CERTIFICATE-----",
|
||||
"30820277020100300d06092a864886f70d0101010500048202613082025d0201" +
|
||||
"0002818100b6de64c454f326ea31251d9481e5d4c42c3b4df2f715e2b7942ad4" +
|
||||
"defaee05edd728abc5a320b17ff079b9c9b6da0ccc7cebc9056460e8aacd4eb5" +
|
||||
"c62352ed96601834333927494ad8dfe778a3a6dd0c5ed1dd56019d65c20acc36" +
|
||||
"2aec5aefabe143cd32ae54a212f99ea554f56c156b5dadd061777abde4df6b4c" +
|
||||
"4c1a927257020301000102818048af52bc1acbdededd13d4930fa28b9441c47c" +
|
||||
"b222f5c6fc92df07676db3a815a61c9b51de0a03a347b10a609bd6459a0dd926" +
|
||||
"38877261686a5c6bb1ca9e8ea2373870af7685e7d6cebd66faba65af2ef04bd9" +
|
||||
"1244ae56900fcd6ce11207d8c4040176e4ba9fef3d563741a1027b229134cfe1" +
|
||||
"c0a90d9c8eba9ce6349835e769024100e82494b6f777c784ffc29298d033e11d" +
|
||||
"af46f0d464c4dbd950d46bcd697d0f0b49a77699f0111d408e8748f2b461ab8f" +
|
||||
"210071c9c20d8ecee3ae229cb9c3954b024100c9a976f0011fcdc0ca7fb2f679" +
|
||||
"974fa85d420c604ca7ff64fe4667a44f73088eef290d22195474039760e99325" +
|
||||
"3ca45ee444588b150467d14451d3c45dab0ba5024019df39d3ca70c703c39d63" +
|
||||
"c9342b1403c2ed1d1a0ec101df8e6a9e391e7099a4a068d187068261c8381a4b" +
|
||||
"bf00eb81bb49ea4ac439a4592e25a1daa9acea67510241008c4640007497bdd4" +
|
||||
"94473da26b33d06a29ecae9531dd4e2edf1cf42cfc42e53a1fac2b8183a3164c" +
|
||||
"053999600c6fe15a4c682a3b1cb482ceb33a4416fc9ce52d024100e4f08cd10a" +
|
||||
"5c8face0b20db86443d0a42e34dfdde236dae4f042a06dd3aff7ca159f8aa3b7" +
|
||||
"854df41d510148096155204f2bf46c4a96e271747a4126a66ade6c"),
|
||||
|
||||
// This certificate is generated by the below commands:
|
||||
// openssl dsaparam -genkey 1024 -out key.pem
|
||||
// openssl req -x509 -new -key key.pem -days 7300 \
|
||||
// -subj "/CN=DSA_SHA1_1024" -sha1 -out cert.pem
|
||||
DSA_SHA1_1024(
|
||||
SignatureAlgorithm.DSA,
|
||||
"-----BEGIN CERTIFICATE-----\n" +
|
||||
"MIICuzCCAnugAwIBAgIJAMAMLRrhQWQFMAkGByqGSM44BAMwGDEWMBQGA1UEAwwN\n" +
|
||||
"RFNBX1NIQTFfMTAyNDAeFw0xNzExMDIwNjA4MDRaFw0zNzEwMjgwNjA4MDRaMBgx\n" +
|
||||
"FjAUBgNVBAMMDURTQV9TSEExXzEwMjQwggG2MIIBKwYHKoZIzjgEATCCAR4CgYEA\n" +
|
||||
"8CspE1sE84pJ4YxzVHFEDNJvBaIxsbax03pDwNHr/ogP9PVwF9z1jT6hpC5WluHG\n" +
|
||||
"g5n5gqpF2XpBhX2fKm1qqZWRxNvHKo0+zzAhUqMrvRJqcjlL4ijXndHldt67/VKS\n" +
|
||||
"0eTKi9m64c+yJx80YYphCO5b93d2sTM29z8QZOlrbD8CFQCmttKnPAOk4uz8Z8cV\n" +
|
||||
"uPGeGOMB9wKBgCItgPpAjW0srIwCaDysDNpydX6hB+1NTy1gFYl24n8edLGbR0mZ\n" +
|
||||
"isteBd6LjMtgicRmtKZzKxW7igxoVvR3WHpTucFjms5NRNjPaj5wt3DxoXn4hyWk\n" +
|
||||
"LzMvDeBvi+jKJiO0jnQ3+1NDOlAQy6ukeH59/gxZ3UmcNxDlAQ/IYHcpA4GEAAKB\n" +
|
||||
"gEgvi72gL+zax7Y2hg4PL1PqZx2jFp0XlTIugiTrcsGytrAnn+/s2+3xVyVyvVMn\n" +
|
||||
"0z5yL5eP9cdGA7qV1+7n6KJ8jNAhLCBSiC6x5ekd88aTlqnmt5lstk4w0Q0zSa58\n" +
|
||||
"Hp6dCFg2Irk6Z9ERKaXJJBBS6reaFeATVROhN/LEEzzvo1AwTjAdBgNVHQ4EFgQU\n" +
|
||||
"jb+HHABclGNR4lpf19nHFZpfwPQwHwYDVR0jBBgwFoAUjb+HHABclGNR4lpf19nH\n" +
|
||||
"FZpfwPQwDAYDVR0TBAUwAwEB/zAJBgcqhkjOOAQDAy8AMCwCFDB3F/m6jsZdHaoy\n" +
|
||||
"1xTp2U8uHBO+AhQYzeJuJd8/qRSDVLs8mesE8TQg2g==\n" +
|
||||
"-----END CERTIFICATE-----",
|
||||
"3082014a0201003082012b06072a8648ce3804013082011e02818100f02b2913" +
|
||||
"5b04f38a49e18c735471440cd26f05a231b1b6b1d37a43c0d1ebfe880ff4f570" +
|
||||
"17dcf58d3ea1a42e5696e1c68399f982aa45d97a41857d9f2a6d6aa99591c4db" +
|
||||
"c72a8d3ecf302152a32bbd126a72394be228d79dd1e576debbfd5292d1e4ca8b" +
|
||||
"d9bae1cfb2271f34618a6108ee5bf77776b13336f73f1064e96b6c3f021500a6" +
|
||||
"b6d2a73c03a4e2ecfc67c715b8f19e18e301f7028180222d80fa408d6d2cac8c" +
|
||||
"02683cac0cda72757ea107ed4d4f2d60158976e27f1e74b19b4749998acb5e05" +
|
||||
"de8b8ccb6089c466b4a6732b15bb8a0c6856f477587a53b9c1639ace4d44d8cf" +
|
||||
"6a3e70b770f1a179f88725a42f332f0de06f8be8ca2623b48e7437fb53433a50" +
|
||||
"10cbaba4787e7dfe0c59dd499c3710e5010fc8607729041602146ef9db36045f" +
|
||||
"bcd8c7fd82ba29c5c5057ed11c7f"),
|
||||
|
||||
// This certificate is generated by the below commands:
|
||||
// openssl dsaparam -genkey 1024 -out key.pem
|
||||
// openssl req -x509 -new -key key.pem -days 7300 \
|
||||
// -subj "/CN=www.example.com" -sha1 -out cert.pem
|
||||
DSA_EXAMPLE_SHA1_1024(
|
||||
SignatureAlgorithm.DSA,
|
||||
"-----BEGIN CERTIFICATE-----\n" +
|
||||
"MIICwDCCAoCgAwIBAgIJAI5mKbdK5ZqyMAkGByqGSM44BAMwGjEYMBYGA1UEAwwP\n" +
|
||||
"d3d3LmV4YW1wbGUuY29tMB4XDTE3MTEwMjA1NDczOVoXDTM3MTAyODA1NDczOVow\n" +
|
||||
"GjEYMBYGA1UEAwwPd3d3LmV4YW1wbGUuY29tMIIBtzCCASwGByqGSM44BAEwggEf\n" +
|
||||
"AoGBANVGWRSlxVZQKlVrTDcU/6Mr8QFlR3kGKmkvdbTHH1EhcP7YlZ7CJ30VBDbN\n" +
|
||||
"LS2HvN3HHNooJ7hHBheL5Yz8EZIUa95TzPukZ1TmCo9fufR5i9HWj9Z8jLhyqx3l\n" +
|
||||
"iUZOYN9H0MSn4ftK6dr5oTz2ZGYDblXDCq6R8qZfuw1URFqrAhUArx0nmGEI/1S/\n" +
|
||||
"qyxnV4I6ItOntxMCgYEAxZKIZ/7aOGfzaQG2wRFdD/viHBZkkcxCsgmPUroQVUIw\n" +
|
||||
"dqmUnfYk8cb02LCevhhSwcjfocQsA3y1jufIUdWaHuIB9W3EsFJQNd/Byh9j/pRD\n" +
|
||||
"7zH/8lnBzJh2S7y10Vg840STVo5+ekZb4E+W7KK5gUaEQ6kAtUIIB0xjNz7RWs4D\n" +
|
||||
"gYQAAoGAPVQKWqJSlMrbU4XEsx50Ur8P84CwMnS7WcQNLnih1ScaK2BijgVj5Fny\n" +
|
||||
"9JZxITwj7XD7FWriq3kTjbydi3iAvrgVWij79x5Z7fTRCuoBVmtnAFkVGalwbGr2\n" +
|
||||
"ghz70y6hep2Evb1pRCrHjRkMaJFE5Y2CA7VbpKoat+j47/LkXJ2jUDBOMB0GA1Ud\n" +
|
||||
"DgQWBBSVjWy3SpaDfnFo+37mZJqX2aybzTAfBgNVHSMEGDAWgBSVjWy3SpaDfnFo\n" +
|
||||
"+37mZJqX2aybzTAMBgNVHRMEBTADAQH/MAkGByqGSM44BAMDLwAwLAIUd5NOlcfX\n" +
|
||||
"5rakT9H8UzlFcFQLr0MCFGrEYvlFUf/HJOH4FwXS2jEholBB\n" +
|
||||
"-----END CERTIFICATE-----",
|
||||
"3082014c0201003082012c06072a8648ce3804013082011f02818100d5465914" +
|
||||
"a5c556502a556b4c3714ffa32bf101654779062a692f75b4c71f512170fed895" +
|
||||
"9ec2277d150436cd2d2d87bcddc71cda2827b84706178be58cfc1192146bde53" +
|
||||
"ccfba46754e60a8f5fb9f4798bd1d68fd67c8cb872ab1de589464e60df47d0c4" +
|
||||
"a7e1fb4ae9daf9a13cf66466036e55c30aae91f2a65fbb0d54445aab021500af" +
|
||||
"1d27986108ff54bfab2c6757823a22d3a7b71302818100c5928867feda3867f3" +
|
||||
"6901b6c1115d0ffbe21c166491cc42b2098f52ba1055423076a9949df624f1c6" +
|
||||
"f4d8b09ebe1852c1c8dfa1c42c037cb58ee7c851d59a1ee201f56dc4b0525035" +
|
||||
"dfc1ca1f63fe9443ef31fff259c1cc98764bbcb5d1583ce34493568e7e7a465b" +
|
||||
"e04f96eca2b981468443a900b54208074c63373ed15ace0417021500abf47692" +
|
||||
"88c6ac41e2802e7eb7addba367339318"),
|
||||
|
||||
// This certificate is generated by the below commands:
|
||||
// openssl ecparam -name prime256v1 -genkey -out key.pem
|
||||
// openssl req -new -key key.pem -x509 -nodes -days 7300 \
|
||||
// -subj "/CN=ECDSA_SHA1_prime256v1" -sha1 -out cert.pem
|
||||
ECDSA_SHA1_PRIME256V1(
|
||||
SignatureAlgorithm.ECDSA,
|
||||
"-----BEGIN CERTIFICATE-----\n" +
|
||||
"MIIBhDCCASygAwIBAgIJAKW4wuujp9JbMAkGByqGSM49BAEwIDEeMBwGA1UEAwwV\n" +
|
||||
"RUNEU0FfU0hBMV9wcmltZTI1NnYxMB4XDTE3MDkwNzAyMTA0MVoXDTM3MDkwMjAy\n" +
|
||||
"MTA0MVowIDEeMBwGA1UEAwwVRUNEU0FfU0hBMV9wcmltZTI1NnYxMFkwEwYHKoZI\n" +
|
||||
"zj0CAQYIKoZIzj0DAQcDQgAEdbE+AMwsFBf73YXRVwsvsx2dMt1xgDxj/4pN+BfY\n" +
|
||||
"LWnO94beeZcrCJ1/N8CHmDOce7KRDR6/9kpi20wFAVXZ3KNQME4wHQYDVR0OBBYE\n" +
|
||||
"FA/hB2ODDNdz1JF08u2uhknhlsVoMB8GA1UdIwQYMBaAFA/hB2ODDNdz1JF08u2u\n" +
|
||||
"hknhlsVoMAwGA1UdEwQFMAMBAf8wCQYHKoZIzj0EAQNHADBEAiBNxv2L2FW+6+w/\n" +
|
||||
"QtDe+YSUNRj3F8QrpLkfGk7rVaOiHQIgVF2pWJ5ytg0pbCuO8Bh+UZ7zfZUD03s8\n" +
|
||||
"ZuIYW7RtMe0=\n" +
|
||||
"-----END CERTIFICATE-----",
|
||||
"308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02" +
|
||||
"010104204d901d5efd0e3def78d5307788a4c760115effce4b9e2c31ae5860b6" +
|
||||
"c11915aca1440342000475b13e00cc2c1417fbdd85d1570b2fb31d9d32dd7180" +
|
||||
"3c63ff8a4df817d82d69cef786de79972b089d7f37c08798339c7bb2910d1ebf" +
|
||||
"f64a62db4c050155d9dc"),
|
||||
|
||||
// This certificate is generated by the below commands:
|
||||
// openssl ecparam -name prime256v1 -genkey -out key.pem
|
||||
// openssl req -new -key key.pem -x509 -nodes -days 7300 \
|
||||
// -subj "/CN=www.example.com" -sha1 -out cert.pem
|
||||
ECDSA_EXAMPLE_SHA1_PRIME256V1(
|
||||
SignatureAlgorithm.ECDSA,
|
||||
"-----BEGIN CERTIFICATE-----\n" +
|
||||
"MIIBeDCCASCgAwIBAgIJAMxOXBpiJ5mDMAkGByqGSM49BAEwGjEYMBYGA1UEAwwP\n" +
|
||||
"d3d3LmV4YW1wbGUuY29tMB4XDTE3MTEwMjA1MTg0MVoXDTM3MTAyODA1MTg0MVow\n" +
|
||||
"GjEYMBYGA1UEAwwPd3d3LmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0D\n" +
|
||||
"AQcDQgAER9IyuwyrJ7X9DmIqGC3YNTlWBt4Fo/Y3RnlcxhTVxb/ZAYVNhqe4MbSM\n" +
|
||||
"2nsVnYMjjXXDav1plNKvmgGDf9s/saNQME4wHQYDVR0OBBYEFHNUTaIIEA89uNKH\n" +
|
||||
"OOUgJ981Qj5HMB8GA1UdIwQYMBaAFHNUTaIIEA89uNKHOOUgJ981Qj5HMAwGA1Ud\n" +
|
||||
"EwQFMAMBAf8wCQYHKoZIzj0EAQNHADBEAiBCW59S1nE15j8euO6/q9bM6J9Ci5xJ\n" +
|
||||
"WWAVznGGxnS/HgIgFaFKC31uxTXoBN7QN0yW/umQgJ0nsjwj7Pnxc0wNyw8=\n" +
|
||||
"-----END CERTIFICATE-----",
|
||||
"308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02" +
|
||||
"010104209aa3784cd0c1fe0553e59b3c7b8f08c8fdaffd94f34e2c1683243a79" +
|
||||
"7b64b673a1440342000447d232bb0cab27b5fd0e622a182dd835395606de05a3" +
|
||||
"f63746795cc614d5c5bfd901854d86a7b831b48cda7b159d83238d75c36afd69" +
|
||||
"94d2af9a01837fdb3fb1");
|
||||
|
||||
public final SignatureAlgorithm signatureAlgorithm;
|
||||
public final String certMaterials;
|
||||
public final String privKeyMaterials;
|
||||
|
||||
private Cert(
|
||||
SignatureAlgorithm signatureAlgorithm,
|
||||
String certMaterials,
|
||||
String privKeyMaterials) {
|
||||
this.signatureAlgorithm = signatureAlgorithm;
|
||||
this.certMaterials = certMaterials;
|
||||
this.privKeyMaterials = privKeyMaterials;
|
||||
}
|
||||
|
||||
// Two certificates (mainCert and exampleCert) are selected to respect the
|
||||
// specified cipher suite. SNI-associated cases specify exampleCert as desired.
|
||||
public static Cert[] getCerts(String cipherSuite) {
|
||||
Cert mainCert = Cert.DSA_SHA1_1024;
|
||||
Cert exampleCert = Cert.DSA_EXAMPLE_SHA1_1024;
|
||||
if (cipherSuite.contains("_ECDHE_RSA_")) {
|
||||
mainCert = Cert.RSA_SHA1_1024;
|
||||
exampleCert = Cert.RSA_EXAMPLE_SHA1_1024;
|
||||
} else if (cipherSuite.contains("_EC")) {
|
||||
mainCert = Cert.ECDSA_SHA1_PRIME256V1;
|
||||
exampleCert = Cert.ECDSA_EXAMPLE_SHA1_PRIME256V1;
|
||||
} else if (cipherSuite.contains("_RSA")) {
|
||||
mainCert = Cert.RSA_SHA1_1024;
|
||||
exampleCert = Cert.RSA_EXAMPLE_SHA1_1024;
|
||||
}
|
||||
System.out.printf("mainCert=%s, exampleCert=%s%n",
|
||||
mainCert, exampleCert);
|
||||
return new Cert[] { mainCert, exampleCert };
|
||||
}
|
||||
}
|
||||
|
||||
enum SignatureAlgorithm {
|
||||
|
||||
RSA, DSA, ECDSA;
|
||||
}
|
206
test/jdk/javax/net/ssl/compatibility/Client.java
Normal file
206
test/jdk/javax/net/ssl/compatibility/Client.java
Normal file
@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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 java.net.InetSocketAddress;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLParameters;
|
||||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
|
||||
/*
|
||||
* A simple SSL socket client.
|
||||
*/
|
||||
public class Client {
|
||||
|
||||
private final SSLSocket socket;
|
||||
|
||||
public Client(SSLContext context) throws Exception {
|
||||
SSLSocketFactory socketFactory = context.getSocketFactory();
|
||||
socket = (SSLSocket) socketFactory.createSocket();
|
||||
socket.setSoTimeout(Utils.TIMEOUT);
|
||||
}
|
||||
|
||||
public Client(Cert... certs) throws Exception {
|
||||
this(Utils.createSSLContext(certs));
|
||||
}
|
||||
|
||||
private SSLSession getSession() {
|
||||
return socket.getSession();
|
||||
}
|
||||
|
||||
private void setEnabledCipherSuites(String... cipherSuites) {
|
||||
socket.setEnabledCipherSuites(cipherSuites);
|
||||
}
|
||||
|
||||
private void setEnabledProtocols(String... protocols) {
|
||||
socket.setEnabledProtocols(protocols);
|
||||
}
|
||||
|
||||
@SuppressWarnings(value = { "unchecked", "rawtypes" })
|
||||
private void setServerName(String hostname) {
|
||||
List serverNames = new ArrayList();
|
||||
serverNames.add(createSNIHostName(hostname));
|
||||
SSLParameters params = socket.getSSLParameters();
|
||||
params.setServerNames(serverNames);
|
||||
socket.setSSLParameters(params);
|
||||
}
|
||||
|
||||
// Create SNIHostName via reflection due to pre-8 JDK builds don't support
|
||||
// SNI. Those JDK builds cannot find classes SNIServerName and SNIHostName.
|
||||
private Object createSNIHostName(String hostname) {
|
||||
try {
|
||||
Class<?> clazz = Class.forName("javax.net.ssl.SNIHostName");
|
||||
return clazz.getConstructor(String.class).newInstance(hostname);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Creates SNIHostName failed!", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void setApplicationProtocols(String... protocols) {
|
||||
SSLParameters params = socket.getSSLParameters();
|
||||
params.setApplicationProtocols(protocols);
|
||||
socket.setSSLParameters(params);
|
||||
}
|
||||
|
||||
private String getNegotiatedApplicationProtocol() {
|
||||
return socket.getApplicationProtocol();
|
||||
}
|
||||
|
||||
private void oneTimeConnect(String host, int port) throws IOException {
|
||||
socket.connect(new InetSocketAddress(host, port));
|
||||
|
||||
OutputStream out = socket.getOutputStream();
|
||||
out.write('C');
|
||||
out.flush();
|
||||
|
||||
InputStream in = socket.getInputStream();
|
||||
in.read();
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
socket.close();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
System.out.println("----- Client start -----");
|
||||
int port = Integer.valueOf(System.getProperty(Utils.PROP_PORT));
|
||||
|
||||
String protocol = System.getProperty(Utils.PROP_PROTOCOL);
|
||||
String cipherSuite = System.getProperty(Utils.PROP_CIPHER_SUITE);
|
||||
String serverName = System.getProperty(Utils.PROP_SERVER_NAME);
|
||||
String appProtocols = System.getProperty(Utils.PROP_APP_PROTOCOLS);
|
||||
boolean supportsSNIOnServer
|
||||
= Utils.getBoolProperty(Utils.PROP_SUPPORTS_SNI_ON_SERVER);
|
||||
boolean supportsSNIOnClient
|
||||
= Utils.getBoolProperty(Utils.PROP_SUPPORTS_SNI_ON_CLIENT);
|
||||
boolean supportsALPNOnServer
|
||||
= Utils.getBoolProperty(Utils.PROP_SUPPORTS_ALPN_ON_SERVER);
|
||||
boolean supportsALPNOnClient
|
||||
= Utils.getBoolProperty(Utils.PROP_SUPPORTS_ALPN_ON_CLIENT);
|
||||
boolean negativeCase
|
||||
= Utils.getBoolProperty(Utils.PROP_NEGATIVE_CASE_ON_CLIENT);
|
||||
System.out.println(Utils.join(Utils.PARAM_DELIMITER,
|
||||
"ClientJDK=" + System.getProperty(Utils.PROP_CLIENT_JDK),
|
||||
"Protocol=" + protocol,
|
||||
"CipherSuite=" + cipherSuite,
|
||||
"ServerName=" + serverName,
|
||||
"AppProtocols=" + appProtocols));
|
||||
|
||||
Status status = Status.SUCCESS;
|
||||
Client client = null;
|
||||
try {
|
||||
client = new Client(Cert.getCerts(cipherSuite));
|
||||
client.setEnabledProtocols(protocol);
|
||||
client.setEnabledCipherSuites(cipherSuite);
|
||||
|
||||
if (serverName != null) {
|
||||
if (supportsSNIOnClient) {
|
||||
client.setServerName(serverName);
|
||||
} else {
|
||||
System.out.println(
|
||||
"Ignored due to client doesn't support SNI.");
|
||||
}
|
||||
}
|
||||
|
||||
if (appProtocols != null) {
|
||||
if (supportsALPNOnClient) {
|
||||
client.setApplicationProtocols(
|
||||
Utils.split(appProtocols, Utils.VALUE_DELIMITER));
|
||||
} else {
|
||||
System.out.println(
|
||||
"Ignored due to client doesn't support ALPN.");
|
||||
}
|
||||
}
|
||||
|
||||
client.oneTimeConnect("localhost", port);
|
||||
|
||||
if (serverName != null && supportsSNIOnServer
|
||||
&& supportsSNIOnClient) {
|
||||
X509Certificate cert
|
||||
= (X509Certificate) client.getSession().getPeerCertificates()[0];
|
||||
String subject
|
||||
= cert.getSubjectX500Principal().getName();
|
||||
if (!subject.contains(serverName)) {
|
||||
System.out.println("Unexpected server: " + subject);
|
||||
status = Status.FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
if (appProtocols != null && supportsALPNOnServer
|
||||
&& supportsALPNOnClient) {
|
||||
String negoAppProtocol
|
||||
= client.getNegotiatedApplicationProtocol();
|
||||
String expectedNegoAppProtocol
|
||||
= System.getProperty(Utils.PROP_NEGO_APP_PROTOCOL);
|
||||
if (!expectedNegoAppProtocol.equals(negoAppProtocol)) {
|
||||
System.out.println("Unexpected negotiated app protocol: "
|
||||
+ negoAppProtocol);
|
||||
status = Status.FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
if (status != Status.FAIL) {
|
||||
status = negativeCase
|
||||
? Status.UNEXPECTED_SUCCESS
|
||||
: Status.SUCCESS;
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
status = Utils.handleException(exception, negativeCase);
|
||||
} finally {
|
||||
if (client != null) {
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("STATUS: " + status);
|
||||
System.out.println("----- Client end -----");
|
||||
}
|
||||
}
|
338
test/jdk/javax/net/ssl/compatibility/Compatibility.java
Normal file
338
test/jdk/javax/net/ssl/compatibility/Compatibility.java
Normal file
@ -0,0 +1,338 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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 This test is used to check the interop compatibility on JSSE among
|
||||
* different JDK releases.
|
||||
* Note that, this is a manual test. For more details about the test and
|
||||
* its usages, please look through README.
|
||||
*
|
||||
* @library /test/lib
|
||||
* @compile -source 1.6 -target 1.6 JdkUtils.java Parameter.java Server.java Client.java
|
||||
* @run main/manual Compatibility
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
|
||||
public class Compatibility {
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
String javaSecurityFile
|
||||
= System.getProperty("test.src") + "/java.security";
|
||||
boolean debug = Utils.getBoolProperty("debug");
|
||||
|
||||
Set<JdkInfo> jdkInfos = jdkInfoList();
|
||||
|
||||
System.out.println("Test start");
|
||||
|
||||
List<TestCase> testCases = new ArrayList<>();
|
||||
ExecutorService executor = Executors.newCachedThreadPool();
|
||||
PrintStream origStdOut = System.out;
|
||||
PrintStream origStdErr = System.err;
|
||||
|
||||
try (PrintStream printStream = new PrintStream(
|
||||
new FileOutputStream(Utils.TEST_LOG, true))) {
|
||||
System.setOut(printStream);
|
||||
System.setErr(printStream);
|
||||
|
||||
System.out.println(Utils.startHtml());
|
||||
System.out.println(Utils.startPre());
|
||||
|
||||
for (UseCase useCase : UseCase.getAllUseCases()) {
|
||||
for (JdkInfo serverJdk : jdkInfos) {
|
||||
if (useCase.ignoredByJdk(serverJdk)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Map<String, String> props = new LinkedHashMap<>();
|
||||
if (debug) {
|
||||
props.put("javax.net.debug", "ssl");
|
||||
}
|
||||
props.put("java.security.properties", javaSecurityFile);
|
||||
|
||||
props.put(Utils.PROP_PROTOCOL, useCase.protocol.version);
|
||||
props.put(Utils.PROP_CIPHER_SUITE, useCase.cipherSuite.name());
|
||||
props.put(Utils.PROP_CLIENT_AUTH, useCase.clientAuth.name());
|
||||
if (useCase.appProtocol != AppProtocol.NONE) {
|
||||
props.put(Utils.PROP_APP_PROTOCOLS,
|
||||
Utils.join(Utils.VALUE_DELIMITER,
|
||||
useCase.appProtocol.appProtocols));
|
||||
props.put(Utils.PROP_NEGO_APP_PROTOCOL,
|
||||
useCase.appProtocol.negoAppProtocol);
|
||||
}
|
||||
props.put(Utils.PROP_SERVER_JDK, serverJdk.version);
|
||||
|
||||
props.put(Utils.PROP_SUPPORTS_SNI_ON_SERVER,
|
||||
serverJdk.supportsSNI + "");
|
||||
props.put(Utils.PROP_SUPPORTS_ALPN_ON_SERVER,
|
||||
serverJdk.supportsALPN + "");
|
||||
|
||||
for (JdkInfo clientJdk : jdkInfos) {
|
||||
if (useCase.ignoredByJdk(clientJdk)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
TestCase testCase = new TestCase(serverJdk, clientJdk,
|
||||
useCase);
|
||||
System.out.println(Utils.anchorName(testCase.toString(),
|
||||
"----- Case start -----"));
|
||||
System.out.println(testCase.toString());
|
||||
|
||||
props.put(Utils.PROP_NEGATIVE_CASE_ON_SERVER,
|
||||
testCase.negativeCaseOnServer + "");
|
||||
props.put(Utils.PROP_NEGATIVE_CASE_ON_CLIENT,
|
||||
testCase.negativeCaseOnClient + "");
|
||||
|
||||
Future<OutputAnalyzer> serverFuture = executor.submit(() -> {
|
||||
return runServer(serverJdk.jdkPath, props);
|
||||
});
|
||||
int port = waitForServerStarted();
|
||||
System.out.println("port=" + port);
|
||||
|
||||
props.put(Utils.PROP_PORT, port + "");
|
||||
|
||||
props.put(Utils.PROP_CLIENT_JDK, clientJdk.version);
|
||||
|
||||
props.put(Utils.PROP_SUPPORTS_SNI_ON_CLIENT,
|
||||
clientJdk.supportsSNI + "");
|
||||
props.put(Utils.PROP_SUPPORTS_ALPN_ON_CLIENT,
|
||||
clientJdk.supportsALPN + "");
|
||||
if (useCase.serverName != ServerName.NONE) {
|
||||
props.put(Utils.PROP_SERVER_NAME,
|
||||
useCase.serverName.name);
|
||||
}
|
||||
|
||||
Status clientStatus = null;
|
||||
if (port != -1) {
|
||||
String clientOutput = runClient(clientJdk.jdkPath,
|
||||
props).getOutput();
|
||||
clientStatus = getStatus(clientOutput);
|
||||
}
|
||||
|
||||
String serverOutput = serverFuture.get().getOutput();
|
||||
Status serverStatus = getStatus(serverOutput);
|
||||
testCase.setStatus(caseStatus(serverStatus, clientStatus));
|
||||
testCases.add(testCase);
|
||||
System.out.printf(
|
||||
"ServerStatus=%s, ClientStatus=%s, CaseStatus=%s%n",
|
||||
serverStatus, clientStatus, testCase.getStatus());
|
||||
|
||||
// Confirm the server has stopped.
|
||||
if(new File(Utils.PORT_LOG).exists()) {
|
||||
throw new RuntimeException("Server doesn't stop.");
|
||||
}
|
||||
System.out.println("----- Case end -----");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println(Utils.endPre());
|
||||
System.out.println(Utils.endHtml());
|
||||
}
|
||||
System.setOut(origStdOut);
|
||||
System.setErr(origStdErr);
|
||||
executor.shutdown();
|
||||
|
||||
System.out.println("Test end");
|
||||
System.out.println("Report is being generated...");
|
||||
boolean failed = generateReport(testCases);
|
||||
System.out.println("Report is generated.");
|
||||
if (failed) {
|
||||
throw new RuntimeException("At least one case failed. "
|
||||
+ "Please check logs for more details.");
|
||||
}
|
||||
}
|
||||
|
||||
private static Status getStatus(String log) {
|
||||
if (log.contains(Status.UNEXPECTED_SUCCESS.name())) {
|
||||
return Status.UNEXPECTED_SUCCESS;
|
||||
} else if (log.contains(Status.SUCCESS.name())) {
|
||||
return Status.SUCCESS;
|
||||
} else if (log.contains(Status.EXPECTED_FAIL.name())) {
|
||||
return Status.EXPECTED_FAIL;
|
||||
} else if (log.contains(Status.TIMEOUT.name())) {
|
||||
return Status.TIMEOUT;
|
||||
} else {
|
||||
return Status.FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
private static Status caseStatus(Status serverStatus, Status clientStatus) {
|
||||
if (clientStatus == null || clientStatus == Status.TIMEOUT) {
|
||||
return serverStatus == Status.EXPECTED_FAIL
|
||||
? Status.EXPECTED_FAIL
|
||||
: Status.FAIL;
|
||||
} else if (serverStatus == Status.TIMEOUT) {
|
||||
return clientStatus == Status.EXPECTED_FAIL
|
||||
? Status.EXPECTED_FAIL
|
||||
: Status.FAIL;
|
||||
} else {
|
||||
return serverStatus == clientStatus
|
||||
? serverStatus
|
||||
: Status.FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieves JDK info from the file which is specified by jdkListFile.
|
||||
// If no such file or no JDK is specified by the file, the current testing
|
||||
// JDK will be used.
|
||||
private static Set<JdkInfo> jdkInfoList() throws Throwable {
|
||||
List<String> jdkList = jdkList("jdkListFile");
|
||||
if (jdkList.size() == 0) {
|
||||
jdkList.add(System.getProperty("test.jdk"));
|
||||
}
|
||||
|
||||
Set<JdkInfo> jdkInfoList = new LinkedHashSet<>();
|
||||
for (String jdkPath : jdkList) {
|
||||
JdkInfo jdkInfo = new JdkInfo(jdkPath);
|
||||
// JDK version must be unique.
|
||||
if (!jdkInfoList.add(jdkInfo)) {
|
||||
System.out.println("The JDK version is duplicate: " + jdkPath);
|
||||
}
|
||||
}
|
||||
return jdkInfoList;
|
||||
}
|
||||
|
||||
private static List<String> jdkList(String listFileProp) throws IOException {
|
||||
String listFile = System.getProperty(listFileProp);
|
||||
System.out.println(listFileProp + "=" + listFile);
|
||||
if (listFile != null && new File(listFile).exists()) {
|
||||
return Files.lines(Paths.get(listFile))
|
||||
.filter(line -> { return !line.trim().isEmpty(); })
|
||||
.collect(Collectors.toList());
|
||||
} else {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
// Checks if server is already launched, and returns server port.
|
||||
private static int waitForServerStarted()
|
||||
throws IOException, InterruptedException {
|
||||
System.out.print("Waiting for server");
|
||||
long deadline = System.currentTimeMillis() + Utils.TIMEOUT;
|
||||
int port;
|
||||
while ((port = getServerPort()) == -1
|
||||
&& System.currentTimeMillis() < deadline) {
|
||||
System.out.print(".");
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
return port;
|
||||
}
|
||||
|
||||
// Retrieves the latest server port from port.log.
|
||||
private static int getServerPort() throws IOException {
|
||||
if (!new File(Utils.PORT_LOG).exists()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return Integer.valueOf(
|
||||
Files.lines(Paths.get(Utils.PORT_LOG)).findFirst().get());
|
||||
}
|
||||
|
||||
private static OutputAnalyzer runServer(String jdkPath,
|
||||
Map<String, String> props) {
|
||||
return ProcessUtils.java(jdkPath, props, Server.class);
|
||||
}
|
||||
|
||||
private static OutputAnalyzer runClient(String jdkPath,
|
||||
Map<String, String> props) {
|
||||
return ProcessUtils.java(jdkPath, props, Client.class);
|
||||
}
|
||||
|
||||
// Generates the test result report.
|
||||
private static boolean generateReport(List<TestCase> testCases)
|
||||
throws IOException {
|
||||
boolean failed = false;
|
||||
StringBuilder report = new StringBuilder();
|
||||
report.append(Utils.startHtml());
|
||||
report.append(Utils.tableStyle());
|
||||
report.append(Utils.startTable());
|
||||
report.append(Utils.row(
|
||||
"No.",
|
||||
"ServerJDK",
|
||||
"ClientJDK",
|
||||
"Protocol",
|
||||
"CipherSuite",
|
||||
"ClientAuth",
|
||||
"SNI",
|
||||
"ALPN",
|
||||
"Status"));
|
||||
for (int i = 0, size = testCases.size(); i < size; i++) {
|
||||
TestCase testCase = testCases.get(i);
|
||||
|
||||
report.append(Utils.row(
|
||||
Utils.anchorLink(
|
||||
Utils.TEST_LOG,
|
||||
testCase.toString(),
|
||||
i + ""),
|
||||
testCase.serverJdk.version,
|
||||
testCase.clientJdk.version,
|
||||
testCase.useCase.protocol.version,
|
||||
testCase.useCase.cipherSuite,
|
||||
Utils.boolToStr(
|
||||
testCase.useCase.clientAuth == ClientAuth.TRUE),
|
||||
Utils.boolToStr(
|
||||
testCase.useCase.serverName == ServerName.EXAMPLE),
|
||||
Utils.boolToStr(
|
||||
testCase.useCase.appProtocol == AppProtocol.EXAMPLE),
|
||||
testCase.getStatus()));
|
||||
failed = failed
|
||||
|| testCase.getStatus() == Status.FAIL
|
||||
|| testCase.getStatus() == Status.UNEXPECTED_SUCCESS;
|
||||
}
|
||||
report.append(Utils.endTable());
|
||||
report.append(Utils.endHtml());
|
||||
|
||||
generateFile("report.html", report.toString());
|
||||
return failed;
|
||||
}
|
||||
|
||||
private static void generateFile(String path, String content)
|
||||
throws IOException {
|
||||
try(FileWriter writer = new FileWriter(new File(path))) {
|
||||
writer.write(content);
|
||||
}
|
||||
}
|
||||
}
|
92
test/jdk/javax/net/ssl/compatibility/JdkInfo.java
Normal file
92
test/jdk/javax/net/ssl/compatibility/JdkInfo.java
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* It represents a JDK with some specific attributes.
|
||||
* If two JdkInfo instances have the same version value, the instances are
|
||||
* regarded as equivalent.
|
||||
*/
|
||||
public class JdkInfo {
|
||||
|
||||
public final String jdkPath;
|
||||
|
||||
public final String version;
|
||||
public final boolean supportsECKey;
|
||||
public final boolean supportsSNI;
|
||||
public final boolean supportsALPN;
|
||||
|
||||
public JdkInfo(String jdkPath) throws Throwable {
|
||||
this.jdkPath = jdkPath;
|
||||
|
||||
String output = jdkAttributes(jdkPath);
|
||||
if (output == null || output.trim().isEmpty()) {
|
||||
throw new RuntimeException(
|
||||
"Cannot determine the JDK attributes: " + jdkPath);
|
||||
}
|
||||
|
||||
String[] attributes = Utils.split(output, Utils.PARAM_DELIMITER);
|
||||
version = attributes[0].replaceAll(".*=", "");
|
||||
supportsECKey = Boolean.valueOf(attributes[1].replaceAll(".*=", ""));
|
||||
supportsSNI = Boolean.valueOf(attributes[2].replaceAll(".*=", ""));
|
||||
supportsALPN = Boolean.valueOf(attributes[3].replaceAll(".*=", ""));
|
||||
}
|
||||
|
||||
// Determines the specific attributes for the specified JDK.
|
||||
private static String jdkAttributes(String jdkPath) throws Throwable {
|
||||
return ProcessUtils.java(jdkPath, null, JdkUtils.class).getOutput();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return version == null ? 0 : version.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
JdkInfo other = (JdkInfo) obj;
|
||||
if (version == null) {
|
||||
if (other.version != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!version.equals(other.version)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean supportsCipherSuite(CipherSuite cipherSuite) {
|
||||
JdkRelease jdkRelease = JdkRelease.getRelease(version);
|
||||
return cipherSuite.startJdk.sequence <= jdkRelease.sequence
|
||||
&& (cipherSuite.endJdk == null
|
||||
|| cipherSuite.endJdk.sequence >= jdkRelease.sequence);
|
||||
}
|
||||
}
|
58
test/jdk/javax/net/ssl/compatibility/JdkRelease.java
Normal file
58
test/jdk/javax/net/ssl/compatibility/JdkRelease.java
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* JDK major versions.
|
||||
*/
|
||||
public enum JdkRelease {
|
||||
|
||||
JDK6(6, "1.6"),
|
||||
JDK7(7, "1.7"),
|
||||
JDK8(8, "1.8"),
|
||||
JDK9(9, "9"),
|
||||
JDK10(10, "10");
|
||||
|
||||
public final int sequence;
|
||||
public final String release;
|
||||
|
||||
private JdkRelease(int sequence, String release) {
|
||||
this.sequence = sequence;
|
||||
this.release = release;
|
||||
}
|
||||
|
||||
public static JdkRelease getRelease(String jdkVersion) {
|
||||
if (jdkVersion.startsWith(JDK6.release)) {
|
||||
return JDK6;
|
||||
} else if (jdkVersion.startsWith(JDK7.release)) {
|
||||
return JDK7;
|
||||
} else if (jdkVersion.startsWith(JDK8.release)) {
|
||||
return JDK8;
|
||||
} else if (jdkVersion.startsWith(JDK9.release)) {
|
||||
return JDK9;
|
||||
} else if (jdkVersion.startsWith(JDK10.release)) {
|
||||
return JDK10;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
88
test/jdk/javax/net/ssl/compatibility/JdkUtils.java
Normal file
88
test/jdk/javax/net/ssl/compatibility/JdkUtils.java
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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.NoSuchAlgorithmException;
|
||||
|
||||
import javax.net.ssl.SSLParameters;
|
||||
|
||||
/*
|
||||
* This class is used for returning some specific JDK information.
|
||||
*/
|
||||
public class JdkUtils {
|
||||
|
||||
public static final String JAVA_RUNTIME_VERSION = "javaRuntimeVersion";
|
||||
public static final String SUPPORTS_EC_KEY = "supportsECKey";
|
||||
public static final String SUPPORTS_SNI = "supportsSNI";
|
||||
public static final String SUPPORTS_ALPN = "supportsALPN";
|
||||
|
||||
// Returns the JDK build version.
|
||||
public static String javaRuntimeVersion() {
|
||||
return System.getProperty("java.runtime.version");
|
||||
}
|
||||
|
||||
// Checks if EC key algorithm is supported by the JDK build.
|
||||
private static boolean supportsECKey() {
|
||||
boolean isSupported = true;
|
||||
try {
|
||||
KeyFactory.getInstance("EC");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
isSupported = false;
|
||||
}
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
// Checks if SNI is supported by the JDK build.
|
||||
private static boolean supportsSNI() {
|
||||
boolean isSupported = true;
|
||||
try {
|
||||
SSLParameters.class.getMethod("getServerNames");
|
||||
} catch (NoSuchMethodException e) {
|
||||
isSupported = false;
|
||||
}
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
// Checks if ALPN is supported by the JDK build.
|
||||
private static boolean supportsALPN() {
|
||||
boolean isSupported = true;
|
||||
try {
|
||||
SSLParameters.class.getMethod("getApplicationProtocols");
|
||||
} catch (NoSuchMethodException e) {
|
||||
isSupported = false;
|
||||
}
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.print(Utils.join(Utils.PARAM_DELIMITER,
|
||||
attr(JAVA_RUNTIME_VERSION, javaRuntimeVersion()),
|
||||
attr(SUPPORTS_EC_KEY, supportsECKey()),
|
||||
attr(SUPPORTS_SNI, supportsSNI()),
|
||||
attr(SUPPORTS_ALPN, supportsALPN())));
|
||||
}
|
||||
|
||||
private static String attr(String name, Object value) {
|
||||
return name + "=" + String.valueOf(value);
|
||||
}
|
||||
}
|
252
test/jdk/javax/net/ssl/compatibility/Parameter.java
Normal file
252
test/jdk/javax/net/ssl/compatibility/Parameter.java
Normal file
@ -0,0 +1,252 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* A tagging interface that all TLS communication parameters must implement.
|
||||
*/
|
||||
public interface Parameter { }
|
||||
|
||||
/* The followings are TLS communication parameters. */
|
||||
|
||||
enum Protocol implements Parameter {
|
||||
|
||||
SSLV3_0(3, "SSLv3"),
|
||||
TLSV1_0(4, "TLSv1"),
|
||||
TLSV1_1(5, "TLSv1.1"),
|
||||
TLSV1_2(6, "TLSv1.2");
|
||||
|
||||
public final int sequence;
|
||||
public final String version;
|
||||
|
||||
private Protocol(int sequence, String version) {
|
||||
this.sequence = sequence;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
static Protocol getProtocol(String version) {
|
||||
for (Protocol protocol : values()) {
|
||||
if (protocol.version.equals(version)) {
|
||||
return protocol;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static Protocol[] getMandatoryValues() {
|
||||
return new Protocol[] { TLSV1_0, TLSV1_1, TLSV1_2 };
|
||||
}
|
||||
}
|
||||
|
||||
enum CipherSuite implements Parameter {
|
||||
|
||||
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384(
|
||||
Protocol.TLSV1_2, JdkRelease.JDK7),
|
||||
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384(
|
||||
Protocol.TLSV1_2, JdkRelease.JDK7),
|
||||
TLS_RSA_WITH_AES_256_CBC_SHA256(
|
||||
Protocol.TLSV1_2, JdkRelease.JDK7),
|
||||
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384(
|
||||
Protocol.TLSV1_2, JdkRelease.JDK7),
|
||||
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384(
|
||||
Protocol.TLSV1_2, JdkRelease.JDK7),
|
||||
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256(
|
||||
Protocol.TLSV1_2, JdkRelease.JDK7),
|
||||
TLS_DHE_DSS_WITH_AES_256_CBC_SHA256(
|
||||
Protocol.TLSV1_2, JdkRelease.JDK7),
|
||||
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA(),
|
||||
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA(),
|
||||
TLS_RSA_WITH_AES_256_CBC_SHA(),
|
||||
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA(),
|
||||
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA(),
|
||||
TLS_DHE_RSA_WITH_AES_256_CBC_SHA(),
|
||||
TLS_DHE_DSS_WITH_AES_256_CBC_SHA(),
|
||||
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256(
|
||||
Protocol.TLSV1_2, JdkRelease.JDK7),
|
||||
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256(
|
||||
Protocol.TLSV1_2, JdkRelease.JDK7),
|
||||
TLS_RSA_WITH_AES_128_CBC_SHA256(
|
||||
Protocol.TLSV1_2, JdkRelease.JDK7),
|
||||
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256(
|
||||
Protocol.TLSV1_2, JdkRelease.JDK7),
|
||||
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256(
|
||||
Protocol.TLSV1_2, JdkRelease.JDK7),
|
||||
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256(
|
||||
Protocol.TLSV1_2, JdkRelease.JDK7),
|
||||
TLS_DHE_DSS_WITH_AES_128_CBC_SHA256(
|
||||
Protocol.TLSV1_2, JdkRelease.JDK7),
|
||||
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA(),
|
||||
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA(),
|
||||
TLS_RSA_WITH_AES_128_CBC_SHA(),
|
||||
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA(),
|
||||
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA(
|
||||
Protocol.SSLV3_0, JdkRelease.JDK7),
|
||||
TLS_DHE_RSA_WITH_AES_128_CBC_SHA(),
|
||||
TLS_DHE_DSS_WITH_AES_128_CBC_SHA(),
|
||||
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384(
|
||||
Protocol.TLSV1_2, JdkRelease.JDK8),
|
||||
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256(
|
||||
Protocol.TLSV1_2, JdkRelease.JDK8),
|
||||
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384(
|
||||
Protocol.TLSV1_2, JdkRelease.JDK8),
|
||||
TLS_RSA_WITH_AES_256_GCM_SHA384(
|
||||
Protocol.TLSV1_2, JdkRelease.JDK8),
|
||||
TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384(
|
||||
Protocol.TLSV1_2, JdkRelease.JDK8),
|
||||
TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384(
|
||||
Protocol.TLSV1_2, JdkRelease.JDK8),
|
||||
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384(
|
||||
Protocol.TLSV1_2, JdkRelease.JDK8),
|
||||
TLS_DHE_DSS_WITH_AES_256_GCM_SHA384(
|
||||
Protocol.TLSV1_2, JdkRelease.JDK8),
|
||||
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256(
|
||||
Protocol.TLSV1_2, JdkRelease.JDK8),
|
||||
TLS_RSA_WITH_AES_128_GCM_SHA256(
|
||||
Protocol.TLSV1_2, JdkRelease.JDK8),
|
||||
TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256(
|
||||
Protocol.TLSV1_2, JdkRelease.JDK8),
|
||||
TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256(
|
||||
Protocol.TLSV1_2, JdkRelease.JDK8),
|
||||
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256(
|
||||
Protocol.TLSV1_2, JdkRelease.JDK8),
|
||||
TLS_DHE_DSS_WITH_AES_128_GCM_SHA256(
|
||||
Protocol.TLSV1_2, JdkRelease.JDK8),
|
||||
TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA(),
|
||||
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA(),
|
||||
TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA(),
|
||||
TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA(),
|
||||
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA(),
|
||||
TLS_ECDHE_RSA_WITH_RC4_128_SHA(),
|
||||
TLS_ECDH_ECDSA_WITH_RC4_128_SHA(),
|
||||
TLS_ECDH_RSA_WITH_RC4_128_SHA(),
|
||||
SSL_RSA_WITH_RC4_128_SHA(),
|
||||
SSL_RSA_WITH_3DES_EDE_CBC_SHA(),
|
||||
SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA(
|
||||
Protocol.SSLV3_0, JdkRelease.JDK6),
|
||||
SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA(
|
||||
Protocol.SSLV3_0, JdkRelease.JDK6),
|
||||
SSL_RSA_WITH_RC4_128_MD5(
|
||||
Protocol.SSLV3_0, JdkRelease.JDK6);
|
||||
|
||||
private static final boolean FULL_CIPHER_SUITES
|
||||
= Utils.getBoolProperty("fullCipherSuites");
|
||||
|
||||
final Protocol startProtocol;
|
||||
final Protocol endProtocol;
|
||||
|
||||
final JdkRelease startJdk;
|
||||
final JdkRelease endJdk;
|
||||
|
||||
private CipherSuite(
|
||||
Protocol startProtocol, Protocol endProtocol,
|
||||
JdkRelease startJdk, JdkRelease endJdk) {
|
||||
this.startProtocol = startProtocol;
|
||||
this.endProtocol = endProtocol;
|
||||
|
||||
this.startJdk = startJdk;
|
||||
this.endJdk = endJdk;
|
||||
}
|
||||
|
||||
private CipherSuite(Protocol startProtocol, JdkRelease startJdk) {
|
||||
this(startProtocol, null, startJdk, null);
|
||||
}
|
||||
|
||||
private CipherSuite() {
|
||||
this(Protocol.TLSV1_0, null, JdkRelease.JDK6, null);
|
||||
}
|
||||
|
||||
boolean supportedByProtocol(Protocol protocol) {
|
||||
return startProtocol.sequence <= protocol.sequence
|
||||
&& (endProtocol == null || endProtocol.sequence >= protocol.sequence);
|
||||
}
|
||||
|
||||
static CipherSuite[] getMandatoryValues() {
|
||||
return FULL_CIPHER_SUITES
|
||||
? values()
|
||||
: new CipherSuite[] {
|
||||
TLS_RSA_WITH_AES_128_CBC_SHA,
|
||||
TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
|
||||
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
|
||||
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
|
||||
TLS_RSA_WITH_AES_256_CBC_SHA256,
|
||||
TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,
|
||||
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
|
||||
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 };
|
||||
}
|
||||
|
||||
static CipherSuite getCipherSuite(String name) {
|
||||
for (CipherSuite cipherSuite : values()) {
|
||||
if (cipherSuite.name().equals(name)) {
|
||||
return cipherSuite;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
enum ClientAuth implements Parameter {
|
||||
|
||||
FALSE,
|
||||
TRUE;
|
||||
|
||||
static ClientAuth[] getMandatoryValues() {
|
||||
return new ClientAuth[] { TRUE };
|
||||
}
|
||||
}
|
||||
|
||||
enum ServerName implements Parameter {
|
||||
|
||||
NONE(null),
|
||||
EXAMPLE("www.example.com");
|
||||
|
||||
final String name;
|
||||
|
||||
private ServerName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
static ServerName[] getMandatoryValues() {
|
||||
return new ServerName[] { EXAMPLE };
|
||||
}
|
||||
}
|
||||
|
||||
enum AppProtocol implements Parameter {
|
||||
|
||||
NONE(null, null),
|
||||
EXAMPLE(new String[] { Utils.HTTP_2, Utils.HTTP_1_1 }, Utils.HTTP_2);
|
||||
|
||||
final String[] appProtocols;
|
||||
|
||||
// Expected negotiated application protocol
|
||||
final String negoAppProtocol;
|
||||
|
||||
private AppProtocol(String[] appProtocols, String negoAppProtocol) {
|
||||
this.appProtocols = appProtocols;
|
||||
this.negoAppProtocol = negoAppProtocol;
|
||||
}
|
||||
|
||||
static AppProtocol[] getMandatoryValues() {
|
||||
return new AppProtocol[] { EXAMPLE };
|
||||
}
|
||||
}
|
59
test/jdk/javax/net/ssl/compatibility/ProcessUtils.java
Normal file
59
test/jdk/javax/net/ssl/compatibility/ProcessUtils.java
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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 java.util.Map;
|
||||
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
|
||||
/*
|
||||
* Utilities for executing java process.
|
||||
*/
|
||||
public class ProcessUtils {
|
||||
|
||||
private static final String TEST_CLASSES = System.getProperty("test.classes");
|
||||
|
||||
public static OutputAnalyzer java(String jdkPath, Map<String, String> props,
|
||||
Class<?> clazz) {
|
||||
List<String> cmds = new ArrayList<>();
|
||||
cmds.add(jdkPath + "/bin/java");
|
||||
|
||||
if (props != null) {
|
||||
for (Map.Entry<String, String> prop : props.entrySet()) {
|
||||
cmds.add("-D" + prop.getKey() + "=" + prop.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
cmds.add("-cp");
|
||||
cmds.add(TEST_CLASSES);
|
||||
cmds.add(clazz.getName());
|
||||
try {
|
||||
return ProcessTools.executeCommand(
|
||||
cmds.toArray(new String[cmds.size()]));
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException("Execute command failed: " + cmds, e);
|
||||
}
|
||||
}
|
||||
}
|
130
test/jdk/javax/net/ssl/compatibility/README
Normal file
130
test/jdk/javax/net/ssl/compatibility/README
Normal file
@ -0,0 +1,130 @@
|
||||
# Copyright (c) 2017, 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.
|
||||
|
||||
##### Summary #####
|
||||
This test is used to check the interop compatibility on JSSE among different
|
||||
JDK releases. The oldest version supported by the test is JDK 6. Some of Java
|
||||
source files, JdkUtils.java, Parameter.java, Server.java, and Client.java, use
|
||||
only JDK 6-compliant language features and APIs, in order to allowing different
|
||||
JDK releases can load and run associated classes.
|
||||
|
||||
##### Output #####
|
||||
The test can generate a report at $JTREG_WORKDIR/scratch/report.html to display
|
||||
the key information for each case. It also outputs all of details on both of
|
||||
server and client sides to a separated file at $JTREG_WORKDIR/scratch/test.html.
|
||||
|
||||
##### Report Columns #####
|
||||
No.
|
||||
A sequence number. It contains a hyper link to the corresponding details
|
||||
in $JTREG_WORKDIR/scratch/test.html.
|
||||
|
||||
ServerJDK
|
||||
The version of the JDK that acts as server.
|
||||
|
||||
ClientJDK
|
||||
The version of the JDK that acts as client.
|
||||
|
||||
Protocol
|
||||
The TLS protocol version.
|
||||
|
||||
CipherSuite
|
||||
The only enabled cipher suite on both of server and client.
|
||||
|
||||
ClientAuth
|
||||
If the client authentication is checked, the value is "Y"; otherwise, "N".
|
||||
|
||||
SNI
|
||||
If the SNI is checked, the value is "Y"; otherwise, "N".
|
||||
|
||||
ALPN
|
||||
If the ALPN is checked, the value is "Y"; otherwise, "N".
|
||||
|
||||
Status
|
||||
It indicates the communication status for a test case.
|
||||
There are three status:
|
||||
SUCCESS: Communication succeed as expected.
|
||||
UNEXPECTED_SUCCESS: Communication succeed as unexpected.
|
||||
FAIL: Communication fails with unexpected failure.
|
||||
EXPECTED_FAIL: Communication fails with expected failure.
|
||||
Please note that, if a case finishes as status UNEXPECTED_SUCCESS or FAIL,
|
||||
that means the case fails. Any failed case results in the test goes to fail.
|
||||
|
||||
##### Usage #####
|
||||
jtreg [-options] \
|
||||
[-Ddebug=<true|false>] \
|
||||
[-DfullCases=<true|false>] \
|
||||
[-DfullCipherSuites=<true|false>] \
|
||||
[-DjdkListFile=</path/to/jdkListFile>] \
|
||||
$JDK_WORKSPACE/test/jdk/javax/net/ssl/compatibility/Compatibility.java
|
||||
|
||||
Besides the common jtreg options, like -jdk, this test introduces some more
|
||||
properties:
|
||||
debug
|
||||
It indicates if the test enable -Djavax.net.ssl=debug. This is a boolean
|
||||
property, and the default value is false.
|
||||
It is not mandatory.
|
||||
|
||||
fullCases
|
||||
It indicates if testing the full or mandatory set of parameter values.
|
||||
Every parameter provides a mandatory value set that must be covered.
|
||||
For more details about the parameter value sets, please see Parameter.java.
|
||||
This is a boolean property, and the default value is false.
|
||||
It is not mandatory.
|
||||
|
||||
fullCipherSuites
|
||||
It indicates if testing the full or mandatory set of cipher suites.
|
||||
For more details about the specific cipher suite sets, see CipherSuite in
|
||||
Parameter.java.
|
||||
This is a boolean property, and the default value is false.
|
||||
It is not mandatory.
|
||||
|
||||
jdkListFile
|
||||
It indicate the path of a file, which lists the absolute paths of different
|
||||
JDK builds. If no this property, the current testing JDK, specified by JTREG
|
||||
option -jdk, is used as the testing JDK.
|
||||
It is not mandatory.
|
||||
|
||||
##### Usage Examples #####
|
||||
Example 1
|
||||
$ jtreg -jdk:/path/to/latest/jdk \
|
||||
$JDK_WS/jdk/test/javax/net/ssl/compatibility/Compatibility.java
|
||||
This example doesn't specify any property introduced by the test. That means
|
||||
it uses the current testing JDK, namely /path/to/latest/jdk, as server and
|
||||
client. It doesn't output any debug log, and tests only mandatory parameter
|
||||
value sets.
|
||||
|
||||
Example 2
|
||||
$ cat /path/to/jdkList
|
||||
/path/to/jdk6
|
||||
/path/to/jdk7
|
||||
/path/to/jdk8
|
||||
/path/to/jdk9
|
||||
/path/to/jdk10
|
||||
|
||||
$ jtreg -jdk:/path/to/latest/jdk \
|
||||
-Ddebug=true \
|
||||
-DfullCipherSuites=true \
|
||||
-DjdkListFile=/path/to/jdkList \
|
||||
$JDK_WS/jdk/test/javax/net/ssl/compatibility/Compatibility.java
|
||||
The above example uses a file "/path/to/jdkList" to contain the paths of local
|
||||
different JDK builds through 6 to 10. The execution uses each of JDK builds as
|
||||
server and client respectively. And it enables SSL debug flag, and tests the
|
||||
full parameter value set.
|
171
test/jdk/javax/net/ssl/compatibility/Server.java
Normal file
171
test/jdk/javax/net/ssl/compatibility/Server.java
Normal file
@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLParameters;
|
||||
import javax.net.ssl.SSLServerSocket;
|
||||
import javax.net.ssl.SSLServerSocketFactory;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
|
||||
/*
|
||||
* A simple SSL socket server.
|
||||
*/
|
||||
public class Server {
|
||||
|
||||
private final SSLServerSocket serverSocket;
|
||||
|
||||
public Server(SSLContext context, int port) throws Exception {
|
||||
SSLServerSocketFactory serverFactory = context.getServerSocketFactory();
|
||||
serverSocket = (SSLServerSocket) serverFactory.createServerSocket(port);
|
||||
serverSocket.setSoTimeout(Utils.TIMEOUT);
|
||||
}
|
||||
|
||||
public Server(Cert[] certs, int port) throws Exception {
|
||||
this(Utils.createSSLContext(certs), port);
|
||||
}
|
||||
|
||||
public Server(Cert[] certs) throws Exception {
|
||||
this(certs, 0);
|
||||
}
|
||||
|
||||
private void setEnabledCipherSuites(String... cipherSuites) {
|
||||
serverSocket.setEnabledCipherSuites(cipherSuites);
|
||||
}
|
||||
|
||||
private void setEnabledProtocols(String... protocols) {
|
||||
serverSocket.setEnabledProtocols(protocols);
|
||||
}
|
||||
|
||||
private void setNeedClientAuth(boolean needClientAuth) {
|
||||
serverSocket.setNeedClientAuth(needClientAuth);
|
||||
}
|
||||
|
||||
private void setApplicationProtocols(String... protocols) {
|
||||
SSLParameters params = serverSocket.getSSLParameters();
|
||||
params.setApplicationProtocols(protocols);
|
||||
serverSocket.setSSLParameters(params);
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return serverSocket.getLocalPort();
|
||||
}
|
||||
|
||||
private void accept() throws IOException {
|
||||
SSLSocket socket = null;
|
||||
try {
|
||||
socket = (SSLSocket) serverSocket.accept();
|
||||
|
||||
InputStream in = socket.getInputStream();
|
||||
in.read();
|
||||
|
||||
OutputStream out = socket.getOutputStream();
|
||||
out.write('S');
|
||||
out.flush();
|
||||
} finally {
|
||||
if (socket != null) {
|
||||
socket.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
serverSocket.close();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
System.out.println("----- Server start -----");
|
||||
String protocol = System.getProperty(Utils.PROP_PROTOCOL);
|
||||
String cipherSuite = System.getProperty(Utils.PROP_CIPHER_SUITE);
|
||||
boolean clientAuth
|
||||
= Utils.getBoolProperty(Utils.PROP_CLIENT_AUTH);
|
||||
String appProtocols = System.getProperty(Utils.PROP_APP_PROTOCOLS);
|
||||
boolean supportsALPN
|
||||
= Utils.getBoolProperty(Utils.PROP_SUPPORTS_ALPN_ON_SERVER);
|
||||
boolean negativeCase
|
||||
= Utils.getBoolProperty(Utils.PROP_NEGATIVE_CASE_ON_SERVER);
|
||||
|
||||
System.out.println(Utils.join(Utils.PARAM_DELIMITER,
|
||||
"ServerJDK=" + System.getProperty(Utils.PROP_SERVER_JDK),
|
||||
"Protocol=" + protocol,
|
||||
"CipherSuite=" + cipherSuite,
|
||||
"ClientAuth=" + clientAuth,
|
||||
"AppProtocols=" + appProtocols));
|
||||
|
||||
Status status = Status.SUCCESS;
|
||||
Server server = null;
|
||||
try {
|
||||
server = new Server(Cert.getCerts(cipherSuite));
|
||||
System.out.println("port=" + server.getPort());
|
||||
server.setNeedClientAuth(clientAuth);
|
||||
server.setEnabledProtocols(protocol);
|
||||
server.setEnabledCipherSuites(cipherSuite);
|
||||
if (appProtocols != null) {
|
||||
if (supportsALPN) {
|
||||
server.setApplicationProtocols(
|
||||
Utils.split(appProtocols, Utils.VALUE_DELIMITER));
|
||||
} else {
|
||||
System.out.println(
|
||||
"Ignored due to server doesn't support ALPN.");
|
||||
}
|
||||
}
|
||||
|
||||
savePort(server.getPort());
|
||||
server.accept();
|
||||
|
||||
status = negativeCase ? Status.UNEXPECTED_SUCCESS : Status.SUCCESS;
|
||||
} catch (Exception exception) {
|
||||
status = Utils.handleException(exception, negativeCase);
|
||||
} finally {
|
||||
if (server != null) {
|
||||
server.close();
|
||||
}
|
||||
|
||||
// Cleanups port.log.
|
||||
File file = new File(Utils.PORT_LOG);
|
||||
if (file.exists()) {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("STATUS: " + status);
|
||||
System.out.println("----- Server end -----");
|
||||
}
|
||||
|
||||
private static void savePort(int port) throws IOException {
|
||||
FileWriter writer = null;
|
||||
try {
|
||||
writer = new FileWriter(new File(Utils.PORT_LOG));
|
||||
writer.write(port + "");
|
||||
} finally {
|
||||
if (writer != null) {
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
30
test/jdk/javax/net/ssl/compatibility/Status.java
Normal file
30
test/jdk/javax/net/ssl/compatibility/Status.java
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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 case result status.
|
||||
*/
|
||||
public enum Status {
|
||||
|
||||
SUCCESS, UNEXPECTED_SUCCESS, FAIL, EXPECTED_FAIL, TIMEOUT;
|
||||
}
|
64
test/jdk/javax/net/ssl/compatibility/TestCase.java
Normal file
64
test/jdk/javax/net/ssl/compatibility/TestCase.java
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* A test case for a specific TLS communication use case between two JDKs.
|
||||
*/
|
||||
public class TestCase {
|
||||
|
||||
public final JdkInfo serverJdk;
|
||||
public final JdkInfo clientJdk;
|
||||
public final UseCase useCase;
|
||||
|
||||
public final boolean negativeCaseOnServer;
|
||||
public final boolean negativeCaseOnClient;
|
||||
|
||||
private Status status;
|
||||
|
||||
public TestCase(JdkInfo serverJdk, JdkInfo clientJdk, UseCase useCase) {
|
||||
this.serverJdk = serverJdk;
|
||||
this.clientJdk = clientJdk;
|
||||
this.useCase = useCase;
|
||||
|
||||
negativeCaseOnServer = useCase.negativeCase
|
||||
|| !serverJdk.supportsCipherSuite(useCase.cipherSuite);
|
||||
negativeCaseOnClient = useCase.negativeCase
|
||||
|| !clientJdk.supportsCipherSuite(useCase.cipherSuite);
|
||||
}
|
||||
|
||||
public Status getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Status status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Utils.join(Utils.PARAM_DELIMITER,
|
||||
"ServerJDK=" + serverJdk.version,
|
||||
"ClientJDK=" + clientJdk.version,
|
||||
useCase.toString());
|
||||
}
|
||||
}
|
107
test/jdk/javax/net/ssl/compatibility/UseCase.java
Normal file
107
test/jdk/javax/net/ssl/compatibility/UseCase.java
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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;
|
||||
|
||||
/*
|
||||
* The TLS communication use case.
|
||||
*/
|
||||
public class UseCase {
|
||||
|
||||
private static final boolean FULL_CASES
|
||||
= Utils.getBoolProperty("fullCases");
|
||||
|
||||
private static final Parameter[][] PARAMS = new Parameter[][] {
|
||||
FULL_CASES ? Protocol.values() : Protocol.getMandatoryValues(),
|
||||
FULL_CASES ? CipherSuite.values() : CipherSuite.getMandatoryValues(),
|
||||
FULL_CASES ? ClientAuth.values() : ClientAuth.getMandatoryValues(),
|
||||
FULL_CASES ? ServerName.values() : ServerName.getMandatoryValues(),
|
||||
FULL_CASES ? AppProtocol.values() : AppProtocol.getMandatoryValues() };
|
||||
|
||||
public final Protocol protocol;
|
||||
public final CipherSuite cipherSuite;
|
||||
public final ClientAuth clientAuth;
|
||||
public final ServerName serverName;
|
||||
public final AppProtocol appProtocol;
|
||||
|
||||
public final boolean negativeCase;
|
||||
|
||||
public UseCase(
|
||||
Protocol protocol,
|
||||
CipherSuite cipherSuite,
|
||||
ClientAuth clientAuth,
|
||||
ServerName serverName,
|
||||
AppProtocol appProtocol) {
|
||||
this.protocol = protocol;
|
||||
this.cipherSuite = cipherSuite;
|
||||
this.clientAuth = clientAuth;
|
||||
this.serverName = serverName;
|
||||
this.appProtocol = appProtocol;
|
||||
|
||||
negativeCase = !cipherSuite.supportedByProtocol(protocol);
|
||||
}
|
||||
|
||||
// JDK 6 doesn't support EC key algorithm.
|
||||
public boolean ignoredByJdk(JdkInfo jdkInfo) {
|
||||
return cipherSuite.name().contains("_EC") && !jdkInfo.supportsECKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Utils.join(Utils.PARAM_DELIMITER,
|
||||
"Protocol=" + protocol.version,
|
||||
"CipherSuite=" + cipherSuite,
|
||||
"ClientAuth=" + clientAuth,
|
||||
"ServerName=" + serverName,
|
||||
"AppProtocols=" + appProtocol);
|
||||
}
|
||||
|
||||
public static List<UseCase> getAllUseCases() {
|
||||
List<UseCase> useCases = new ArrayList<>();
|
||||
getUseCases(PARAMS, 0, new Parameter[PARAMS.length], useCases);
|
||||
return useCases;
|
||||
}
|
||||
|
||||
private static void getUseCases(Parameter[][] params, int index,
|
||||
Parameter[] currentValues, List<UseCase> useCases) {
|
||||
if (index == params.length) {
|
||||
Protocol protocol = (Protocol) currentValues[0];
|
||||
CipherSuite cipherSuite = (CipherSuite) currentValues[1];
|
||||
|
||||
UseCase useCase = new UseCase(
|
||||
protocol,
|
||||
cipherSuite,
|
||||
(ClientAuth) currentValues[2],
|
||||
(ServerName) currentValues[3],
|
||||
(AppProtocol) currentValues[4]);
|
||||
useCases.add(useCase);
|
||||
} else {
|
||||
Parameter[] values = params[index];
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
currentValues[index] = values[i];
|
||||
getUseCases(params, index + 1, currentValues, useCases);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
282
test/jdk/javax/net/ssl/compatibility/Utils.java
Normal file
282
test/jdk/javax/net/ssl/compatibility/Utils.java
Normal file
@ -0,0 +1,282 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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.net.SocketTimeoutException;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.KeyStore;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLHandshakeException;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
|
||||
/*
|
||||
* Utilities for testing.
|
||||
*/
|
||||
public class Utils {
|
||||
|
||||
/* ***** Properties ***** */
|
||||
public static final String PROP_PORT = "test.port";
|
||||
public static final String PROP_PROTOCOL = "test.protocol";
|
||||
public static final String PROP_CIPHER_SUITE = "test.cipher.suite";
|
||||
public static final String PROP_CLIENT_AUTH = "test.client.auth";
|
||||
public static final String PROP_SERVER_JDK = "test.server.jdk";
|
||||
public static final String PROP_CLIENT_JDK = "test.client.jdk";
|
||||
public static final String PROP_SERVER_NAME = "test.server.name";
|
||||
public static final String PROP_APP_PROTOCOLS
|
||||
= "test.app.protocols";
|
||||
public static final String PROP_NEGO_APP_PROTOCOL
|
||||
= "test.negotiated.app.protocol";
|
||||
public static final String PROP_SUPPORTS_SNI_ON_SERVER
|
||||
= "test.supports.sni.on.server";
|
||||
public static final String PROP_SUPPORTS_SNI_ON_CLIENT
|
||||
= "test.supports.sni.on.client";
|
||||
public static final String PROP_SUPPORTS_ALPN_ON_SERVER
|
||||
= "test.supports.alpn.on.server";
|
||||
public static final String PROP_SUPPORTS_ALPN_ON_CLIENT
|
||||
= "test.supports.alpn.on.client";
|
||||
public static final String PROP_NEGATIVE_CASE_ON_SERVER
|
||||
= "test.negative.case.on.server";
|
||||
public static final String PROP_NEGATIVE_CASE_ON_CLIENT
|
||||
= "test.negative.case.on.client";
|
||||
|
||||
public static final int TIMEOUT = 10000;
|
||||
public static final char[] PASSWORD = "testpass".toCharArray();
|
||||
|
||||
public static final String TEST_LOG = "test.html";
|
||||
public static final String PORT_LOG = "port";
|
||||
|
||||
public static final String HTTP_2 = "h2";
|
||||
public static final String HTTP_1_1 = "http/1.1";
|
||||
|
||||
public static final String PARAM_DELIMITER = ";";
|
||||
public static final String VALUE_DELIMITER = ",";
|
||||
|
||||
/*
|
||||
* Creates SSL context with the specified certificate.
|
||||
*/
|
||||
public static SSLContext createSSLContext(Cert... certs) throws Exception {
|
||||
KeyStore trustStore = KeyStore.getInstance("JKS");
|
||||
trustStore.load(null, null);
|
||||
for (int i = 0; i < certs.length; i++) {
|
||||
trustStore.setCertificateEntry("trust-" + certs[i].name(),
|
||||
createCert(certs[i]));
|
||||
}
|
||||
TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
|
||||
tmf.init(trustStore);
|
||||
|
||||
KeyStore keyStore = KeyStore.getInstance("JKS");
|
||||
keyStore.load(null, null);
|
||||
for (int i = 0; i < certs.length; i++) {
|
||||
PrivateKey privKey = createKey(certs[i]);
|
||||
keyStore.setKeyEntry("cert-" + certs[i].name(), privKey, PASSWORD,
|
||||
new Certificate[] { createCert(certs[i]) });
|
||||
}
|
||||
KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509");
|
||||
kmf.init(keyStore, PASSWORD);
|
||||
|
||||
SSLContext context = SSLContext.getInstance("TLS");
|
||||
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
|
||||
return context;
|
||||
}
|
||||
|
||||
private static Certificate createCert(Cert cert) throws IOException {
|
||||
try {
|
||||
CertificateFactory certFactory
|
||||
= CertificateFactory.getInstance("X.509");
|
||||
return certFactory.generateCertificate(
|
||||
new ByteArrayInputStream(cert.certMaterials.getBytes()));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Create key failed: " + cert, e);
|
||||
}
|
||||
}
|
||||
|
||||
private static PrivateKey createKey(Cert cert)
|
||||
throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(
|
||||
hexToBytes(cert.privKeyMaterials));
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(
|
||||
getKeyAlgorithm(cert.signatureAlgorithm));
|
||||
PrivateKey privKey = keyFactory.generatePrivate(privKeySpec);
|
||||
return privKey;
|
||||
}
|
||||
|
||||
private static String getKeyAlgorithm(
|
||||
SignatureAlgorithm signatureAlgorithm) {
|
||||
String signatureAlogrithmName = signatureAlgorithm.name();
|
||||
return signatureAlogrithmName.equals(SignatureAlgorithm.ECDSA.name())
|
||||
? "EC"
|
||||
: signatureAlogrithmName;
|
||||
}
|
||||
|
||||
public static byte[] hexToBytes(String hex) {
|
||||
if (hex == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int length = hex.length();
|
||||
if (length % 2 != 0) {
|
||||
throw new IllegalArgumentException("Hex format is wrong.");
|
||||
}
|
||||
|
||||
byte[] bytes = new byte[length / 2];
|
||||
for (int i = 0; i < length; i += 2) {
|
||||
bytes[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
|
||||
+ Character.digit(hex.charAt(i + 1), 16));
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static String join(String delimiter, String... values) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
if (values != null && values.length > 0) {
|
||||
for (int i = 0; i < values.length - 1; i++) {
|
||||
result.append(values[i]).append(delimiter);
|
||||
}
|
||||
result.append(values[values.length - 1]);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public static String[] split(String str, String delimiter) {
|
||||
return str == null ? new String[0] : str.split(delimiter);
|
||||
}
|
||||
|
||||
public static String boolToStr(boolean bool) {
|
||||
return bool ? "Y" : "N";
|
||||
}
|
||||
|
||||
public static boolean getBoolProperty(String prop) {
|
||||
return Boolean.valueOf(System.getProperty(prop));
|
||||
}
|
||||
|
||||
public static Status handleException(Exception exception,
|
||||
boolean negativeCase) {
|
||||
Status status;
|
||||
if ((exception instanceof SSLHandshakeException
|
||||
|| exception instanceof IllegalArgumentException)
|
||||
&& negativeCase) {
|
||||
System.out.println("Expected exception: " + exception);
|
||||
status = Status.EXPECTED_FAIL;
|
||||
} else if (exception instanceof SocketTimeoutException) {
|
||||
status = Status.TIMEOUT;
|
||||
} else {
|
||||
exception.printStackTrace(System.out);
|
||||
status = Status.FAIL;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/* The HTML-related constants and methods. */
|
||||
|
||||
private static final String STYLE
|
||||
= "style=\"font-family: Courier New; "
|
||||
+ "font-size: 12px; "
|
||||
+ "white-space: pre-wrap\"";
|
||||
|
||||
private static final String TABLE_STYLE
|
||||
= "#test { font-family: \"Courier New\"; font-size: 12px; border-collapse: collapse; }\n"
|
||||
+ "#test td { border: 1px solid #ddd; padding: 4px; }\n"
|
||||
+ "#test tr:nth-child(odd) { background-color: #f2f2f2; }";
|
||||
|
||||
public static String row(Object... values) {
|
||||
StringBuilder row = new StringBuilder();
|
||||
row.append(startTr());
|
||||
for (Object value : values) {
|
||||
row.append(startTd());
|
||||
row.append(value);
|
||||
row.append(endTd());
|
||||
}
|
||||
row.append(endTr());
|
||||
return row.toString();
|
||||
}
|
||||
|
||||
public static String startHtml() {
|
||||
return startTag("html");
|
||||
}
|
||||
|
||||
public static String endHtml() {
|
||||
return endTag("html");
|
||||
}
|
||||
|
||||
public static String startPre() {
|
||||
return startTag("pre " + STYLE);
|
||||
}
|
||||
|
||||
public static String endPre() {
|
||||
return endTag("pre");
|
||||
}
|
||||
|
||||
public static String anchorName(String name, String text) {
|
||||
return "<a name=" + name + ">" + text + "</a>";
|
||||
}
|
||||
|
||||
public static String anchorLink(String file, String anchorName,
|
||||
String text) {
|
||||
return "<a href=" + file + "#" + anchorName + ">" + text + "</a>";
|
||||
}
|
||||
|
||||
public static String tableStyle() {
|
||||
return startTag("style") + TABLE_STYLE +endTag("style");
|
||||
}
|
||||
|
||||
public static String startTable() {
|
||||
return startTag("table id=\"test\"");
|
||||
}
|
||||
|
||||
public static String endTable() {
|
||||
return endTag("table");
|
||||
}
|
||||
|
||||
private static String startTr() {
|
||||
return startTag("tr");
|
||||
}
|
||||
|
||||
private static String endTr() {
|
||||
return endTag("tr");
|
||||
}
|
||||
|
||||
private static String startTd() {
|
||||
return startTag("td");
|
||||
}
|
||||
|
||||
private static String endTd() {
|
||||
return endTag("td");
|
||||
}
|
||||
|
||||
private static String startTag(String tag) {
|
||||
return "<" + tag + ">";
|
||||
}
|
||||
|
||||
private static String endTag(String tag) {
|
||||
return "</" + tag + ">";
|
||||
}
|
||||
}
|
2
test/jdk/javax/net/ssl/compatibility/java.security
Normal file
2
test/jdk/javax/net/ssl/compatibility/java.security
Normal file
@ -0,0 +1,2 @@
|
||||
jdk.certpath.disabledAlgorithms=
|
||||
jdk.tls.disabledAlgorithms=
|
Loading…
Reference in New Issue
Block a user