diff --git a/.github/workflows/build-cross-compile.yml b/.github/workflows/build-cross-compile.yml index 8df4fd4b196..d73bef53bb5 100644 --- a/.github/workflows/build-cross-compile.yml +++ b/.github/workflows/build-cross-compile.yml @@ -100,6 +100,10 @@ jobs: with: platform: linux-x64 + - name: 'Get GTest' + id: gtest + uses: ./.github/actions/get-gtest + # Upgrading apt to solve libc6 installation bugs, see JDK-8260460. - name: 'Install toolchain and dependencies' run: | @@ -155,6 +159,7 @@ jobs: --with-conf-name=linux-${{ matrix.target-cpu }} --with-version-opt=${GITHUB_ACTOR}-${GITHUB_SHA} --with-boot-jdk=${{ steps.bootjdk.outputs.path }} + --with-gtest=${{ steps.gtest.outputs.path }} --with-zlib=system --enable-debug --disable-precompiled-headers diff --git a/make/autoconf/libraries.m4 b/make/autoconf/libraries.m4 index 366682cf044..62db5b16c31 100644 --- a/make/autoconf/libraries.m4 +++ b/make/autoconf/libraries.m4 @@ -146,12 +146,6 @@ AC_DEFUN_ONCE([LIB_SETUP_LIBRARIES], fi fi - # Because RISC-V only has word-sized atomics, it requries libatomic where - # other common architectures do not. So link libatomic by default. - if test "x$OPENJDK_TARGET_OS" = xlinux && test "x$OPENJDK_TARGET_CPU" = xriscv64; then - BASIC_JVM_LIBS="$BASIC_JVM_LIBS -latomic" - fi - # perfstat lib if test "x$OPENJDK_TARGET_OS" = xaix; then BASIC_JVM_LIBS="$BASIC_JVM_LIBS -lperfstat" diff --git a/make/data/cacerts/digicertcseccrootg5 b/make/data/cacerts/digicertcseccrootg5 new file mode 100644 index 00000000000..04e1eb1be68 --- /dev/null +++ b/make/data/cacerts/digicertcseccrootg5 @@ -0,0 +1,21 @@ +Owner: CN=DigiCert CS ECC P384 Root G5, O="DigiCert, Inc.", C=US +Issuer: CN=DigiCert CS ECC P384 Root G5, O="DigiCert, Inc.", C=US +Serial number: 3698fe712d519f3ced0fdb7b1643011 +Valid from: Fri Jan 15 00:00:00 GMT 2021 until: Sun Jan 14 23:59:59 GMT 2046 +Signature algorithm name: SHA384withECDSA +Subject Public Key Algorithm: 384-bit EC (secp384r1) key +Version: 3 +-----BEGIN CERTIFICATE----- +MIICFjCCAZ2gAwIBAgIQA2mP5xLVGfPO0P23sWQwETAKBggqhkjOPQQDAzBNMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMTHERp +Z2lDZXJ0IENTIEVDQyBQMzg0IFJvb3QgRzUwHhcNMjEwMTE1MDAwMDAwWhcNNDYw +MTE0MjM1OTU5WjBNMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIElu +Yy4xJTAjBgNVBAMTHERpZ2lDZXJ0IENTIEVDQyBQMzg0IFJvb3QgRzUwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAAR/FK2Ftpf9AiE1TWDoOJOTmz0FEG2v0/7v+rv7c5nz +7DISjcdouIveiaKIVHeNuyF+M5VWlgno1YyhBLibbhkAYuhCKKZYN4QZVSZ7Mzdn +8ppyraGurgBCPBx+uHqeIZyjQjBAMB0GA1UdDgQWBBTwjJhxOThlwjobphdmHcjt +Zd6SNjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQD +AwNnADBkAjAjb+EAGSZQ5EYgZYs3p8/rBuHMMskqoewyDXOiHgIcNWEqTmmrOXft +l4jAfWvqid0CMEPx0VijdT6Gm7ZVEYsX9z3+CmnFf07GdRtalMvqERHGCCKI3tB6 +oqV56OMhp80Tsw== +-----END CERTIFICATE----- diff --git a/make/data/cacerts/digicertcsrsarootg5 b/make/data/cacerts/digicertcsrsarootg5 new file mode 100644 index 00000000000..fd570aeee8b --- /dev/null +++ b/make/data/cacerts/digicertcsrsarootg5 @@ -0,0 +1,38 @@ +Owner: CN=DigiCert CS RSA4096 Root G5, O="DigiCert, Inc.", C=US +Issuer: CN=DigiCert CS RSA4096 Root G5, O="DigiCert, Inc.", C=US +Serial number: 6cee131be6d55c807f7c0c7fb44e620 +Valid from: Fri Jan 15 00:00:00 GMT 2021 until: Sun Jan 14 23:59:59 GMT 2046 +Signature algorithm name: SHA384withRSA +Subject Public Key Algorithm: 4096-bit RSA key +Version: 3 +-----BEGIN CERTIFICATE----- +MIIFZDCCA0ygAwIBAgIQBs7hMb5tVcgH98DH+0TmIDANBgkqhkiG9w0BAQwFADBM +MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJDAiBgNVBAMT +G0RpZ2lDZXJ0IENTIFJTQTQwOTYgUm9vdCBHNTAeFw0yMTAxMTUwMDAwMDBaFw00 +NjAxMTQyMzU5NTlaMEwxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwg +SW5jLjEkMCIGA1UEAxMbRGlnaUNlcnQgQ1MgUlNBNDA5NiBSb290IEc1MIICIjAN +BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtjNzgNhiA3AULBEcOV58rnyDhh3+ +Ji9MJK2L6oNfqbw9W/wLmEwCRzDs4v7s6DRbZl6/O9cspiX/jFmz3+rafCnZRlBy +CB1u0RsK3R/NmYn6Dw9zxOGcHXUyzW+X2ipqlbJsyQnQ6gt7fRcGSZnv1t7gyFPU +rsZ38Ya7Ixy4wN9Z94590e+C5iaLWji1/3XVstlPCfM3iFDaEaSKFBTRUwQAffNq +RBj+UHAyBxyomg46HcUKH24LJmm3PKJXcCyG+kxulalYQ7msEtb/P+3XQxdrTM6e +xJCr//oQUJqjkFfW54wQrp8WGs81HX/Xdu2KnDWnKLinXSH8MDfd3ggZTxXG56ba +kEeO95RTTI5TAr79meXqhtCvAwLTm6qT8asojiAB/0z7zLcpQPWHpBITBR9DbtdR +UJ84tCDtFwkSj8y5Ga+fzb5pEdOvVRBtF4Z5llLGsgCd5a84sDX0iGuPDgQ9fO6v +zdNqEErGzYbKIj2hSlz7Dv+I31xip8C5HtmsbH44N/53kyXChYpPtTcGWgaBFPHO +lJ2ZkeoyWs5nPW4EZq0MTy2jLvee9Xid9wr9fo/jQopVlrzxnzct/J5flf6MGBv8 +jv1LkK/XA2gSY6zik6eiywTlT2TOA/rGFJ/Zi+jM1GKMa+QALBmfGgbGMYFU+1Mk +mq9Vmbqdda64wt0CAwEAAaNCMEAwHQYDVR0OBBYEFGgBk7HSSkBCaZRGLBxaiKkl +tEdPMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB +DAUAA4ICAQCS/O64AnkXAlF9IcVJZ6ek8agkOOsMaOpaQmuc9HPBaUotszcFUEKY +kp4GeSwuBpn2798roM2zkgGDtaDLJ7U8IxqYSaLsLZmlWUOs0rGT1lfXHLyT1sZA +4bNvGVW3E9flQzOktavL2sExZA101iztw41u67uvGUdhYS3A9AW5b3jcOvdCQGVT +kb2ZDZOSVKapN1krm8uZxrw99wSE8JQzHQ+CWjnLLkXDKBmjspuYyPwxa2CP9umG +KLzgPH10XRaJW2kkxxCLxEu7Nk/UWT/DsKSRmfgu0UoBnfWIEu+/WhFqWU9Za1pn +84+0Ew/A2C89KHKqGX8RfWpbn5XnX7eUT/E+oVr/Lcyd3yd3jzJzHGcKdvP6XLG/ +vB29DCibsscXZwszD8O9Ntz7ukILq+2Ew2LWhBapsQdrqW7uxs/msEQpwvCzYYAq +i2/SFFwlh1Rk86RMwaH4p2vq/uo6/HnbDo/cxvPJ1Gze6YOhjh0i7Mk6sgB73Dun +Qhp/3IupET2Op8Agb10JXUNE5o9mzKlbB/Hvm3oOs1ThlP0OLMaT11X9cZg1uAlK +/8YpKCz2Ui3bFBiSJ+IWfozK1GG+goeR65g3P79fXXc/NKwbOEOraHKZMh46Ghml +ozhMI9ej58zVKpIXkAtaS70WvfuGauKJmezkoFUYyaMIHxPgMghy0A== +-----END CERTIFICATE----- diff --git a/make/data/cacerts/digicerttlseccrootg5 b/make/data/cacerts/digicerttlseccrootg5 new file mode 100644 index 00000000000..9356292ef08 --- /dev/null +++ b/make/data/cacerts/digicerttlseccrootg5 @@ -0,0 +1,21 @@ +Owner: CN=DigiCert TLS ECC P384 Root G5, O="DigiCert, Inc.", C=US +Issuer: CN=DigiCert TLS ECC P384 Root G5, O="DigiCert, Inc.", C=US +Serial number: 9e09365acf7d9c8b93e1c0b042a2ef3 +Valid from: Fri Jan 15 00:00:00 GMT 2021 until: Sun Jan 14 23:59:59 GMT 2046 +Signature algorithm name: SHA384withECDSA +Subject Public Key Algorithm: 384-bit EC (secp384r1) key +Version: 3 +-----BEGIN CERTIFICATE----- +MIICGTCCAZ+gAwIBAgIQCeCTZaz32ci5PhwLBCou8zAKBggqhkjOPQQDAzBOMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJjAkBgNVBAMTHURp +Z2lDZXJ0IFRMUyBFQ0MgUDM4NCBSb290IEc1MB4XDTIxMDExNTAwMDAwMFoXDTQ2 +MDExNDIzNTk1OVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJ +bmMuMSYwJAYDVQQDEx1EaWdpQ2VydCBUTFMgRUNDIFAzODQgUm9vdCBHNTB2MBAG +ByqGSM49AgEGBSuBBAAiA2IABMFEoc8Rl1Ca3iOCNQfN0MsYndLxf3c1TzvdlHJS +7cI7+Oz6e2tYIOyZrsn8aLN1udsJ7MgT9U7GCh1mMEy7H0cKPGEQQil8pQgO4CLp +0zVozptjn4S1mU1YoI71VOeVyaNCMEAwHQYDVR0OBBYEFMFRRVBZqz7nLFr6ICIS +B4CIfBFqMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49 +BAMDA2gAMGUCMQCJao1H5+z8blUD2WdsJk6Dxv3J+ysTvLd6jLRl0mlpYxNjOyZQ +LgGheQaRnUi/wr4CMEfDFXuxoJGZSZOoPHzoRgaLLPIxAJSdYsiJvRmEFOml+wG4 +DXZDjC5Ty3zfDBeWUA== +-----END CERTIFICATE----- diff --git a/make/data/cacerts/digicerttlsrsarootg5 b/make/data/cacerts/digicerttlsrsarootg5 new file mode 100644 index 00000000000..ac66e174f06 --- /dev/null +++ b/make/data/cacerts/digicerttlsrsarootg5 @@ -0,0 +1,38 @@ +Owner: CN=DigiCert TLS RSA4096 Root G5, O="DigiCert, Inc.", C=US +Issuer: CN=DigiCert TLS RSA4096 Root G5, O="DigiCert, Inc.", C=US +Serial number: 8f9b478a8fa7eda6a333789de7ccf8a +Valid from: Fri Jan 15 00:00:00 GMT 2021 until: Sun Jan 14 23:59:59 GMT 2046 +Signature algorithm name: SHA384withRSA +Subject Public Key Algorithm: 4096-bit RSA key +Version: 3 +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCPm0eKj6ftpqMzeJ3nzPijANBgkqhkiG9w0BAQwFADBN +MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMT +HERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwHhcNMjEwMTE1MDAwMDAwWhcN +NDYwMTE0MjM1OTU5WjBNMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQs +IEluYy4xJTAjBgNVBAMTHERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCz0PTJeRGd/fxmgefM1eS87IE+ +ajWOLrfn3q/5B03PMJ3qCQuZvWxX2hhKuHisOjmopkisLnLlvevxGs3npAOpPxG0 +2C+JFvuUAT27L/gTBaF4HI4o4EXgg/RZG5Wzrn4DReW+wkL+7vI8toUTmDKdFqgp +wgscONyfMXdcvyej/Cestyu9dJsXLfKB2l2w4SMXPohKEiPQ6s+d3gMXsUJKoBZM +pG2T6T867jp8nVid9E6P/DsjyG244gXazOvswzH016cpVIDPRFtMbzCe88zdH5RD +nU1/cHAN1DrRN/BsnZvAFJNY781BOHW8EwOVfH/jXOnVDdXifBBiqmvwPXbzP6Po +sMH976pXTayGpxi0KcEsDr9kvimM2AItzVwv8n/vFfQMFawKsPHTDU9qTXeXAaDx +Zre3zu/O7Oyldcqs4+Fj97ihBMi8ez9dLRYiVu1ISf6nL3kwJZu6ay0/nTvEF+cd +Lvvyz6b84xQslpghjLSR6Rlgg/IwKwZzUNWYOwbpx4oMYIwo+FKbbuH2TbsGJJvX +KyY//SovcfXWJL5/MZ4PbeiPT02jP/816t9JXkGPhvnxd3lLG7SjXi/7RgLQZhNe +XoVPzthwiHvOAbWWl9fNff2C+MIkwcoBOU+NosEUQB+cZtUMCUbW8tDRSHZWOkPL +tgoRObqME2wGtZ7P6wIDAQABo0IwQDAdBgNVHQ4EFgQUUTMc7TZArxfTJc1paPKv +TiM+s0EwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN +AQEMBQADggIBAGCmr1tfV9qJ20tQqcQjNSH/0GEwhJG3PxDPJY7Jv0Y02cEhJhxw +GXIeo8mH/qlDZJY6yFMECrZBu8RHANmfGBg7sg7zNOok992vIGCukihfNudd5N7H +PNtQOa27PShNlnx2xlv0wdsUpasZYgcYQF+Xkdycx6u1UQ3maVNVzDl92sURVXLF +O4uJ+DQtpBflF+aZfTCIITfNMBc9uPK8qHWgQ9w+iUuQrm0D4ByjoJYJu32jtyoQ +REtGBzRj7TG5BO6jm5qu5jF49OokYTurWGT/u4cnYiWB39yhL/btp/96j1EuMPik +AdKFOV8BmZZvWltwGUb+hmA+rYAQCd05JS9Yf7vSdPD3Rh9GOUrYU9DzLjtxpdRv +/PNn5AeP3SYZ4Y1b+qOTEZvpyDrDVWiakuFSdjjo4bq9+0/V77PnSIMx8IIh47a+ +p6tv75/fTM8BuGJqIz3nCU2AG3swpMPdB380vqQmsvZB6Akd4yCYqjdP//fx4ilw +MUc/dNAUFvohigLVigmUdy7yWSiLfFCSCmZ4OIN1xLVaqBHG5cGdZlXPU8Sv13WF +qUITVuwhd4GTWgzqltlJyqEI8pc7bZsEGCREjnwB8twl2F6GmrE52/WRMmrRpnCK +ovfepEWFJqgejF0pW8hL2JpqA15w8oVPbEtoL8pU9ozaMv7Da4M/OMZ+ +-----END CERTIFICATE----- diff --git a/src/java.base/share/classes/sun/security/ssl/CertificateMessage.java b/src/java.base/share/classes/sun/security/ssl/CertificateMessage.java index d7fce6b1d5b..5921b7cfca5 100644 --- a/src/java.base/share/classes/sun/security/ssl/CertificateMessage.java +++ b/src/java.base/share/classes/sun/security/ssl/CertificateMessage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2021, 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 @@ -1043,6 +1043,7 @@ private static SSLPossession choosePossession( } Collection checkedKeyTypes = new HashSet<>(); + List supportedKeyTypes = new ArrayList<>(); for (SignatureScheme ss : hc.peerRequestedCertSignSchemes) { if (checkedKeyTypes.contains(ss.keyAlgorithm)) { if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { @@ -1051,6 +1052,7 @@ private static SSLPossession choosePossession( } continue; } + checkedKeyTypes.add(ss.keyAlgorithm); // Don't select a signature scheme unless we will be able to // produce a CertificateVerify message later @@ -1064,36 +1066,28 @@ private static SSLPossession choosePossession( "Unable to produce CertificateVerify for " + "signature scheme: " + ss.name); } - checkedKeyTypes.add(ss.keyAlgorithm); continue; } - SSLAuthentication ka = X509Authentication.valueOf(ss); + X509Authentication ka = X509Authentication.valueOf(ss); if (ka == null) { if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { SSLLogger.warning( "Unsupported authentication scheme: " + ss.name); } - checkedKeyTypes.add(ss.keyAlgorithm); continue; } - - SSLPossession pos = ka.createPossession(hc); - if (pos == null) { - if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { - SSLLogger.warning( - "Unavailable authentication scheme: " + ss.name); - } - continue; - } - - return pos; + supportedKeyTypes.add(ss.keyAlgorithm); } - if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { - SSLLogger.warning("No available authentication scheme"); + SSLPossession pos = X509Authentication + .createPossession(hc, supportedKeyTypes.toArray(String[]::new)); + if (pos == null) { + if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { + SSLLogger.warning("No available authentication scheme"); + } } - return null; + return pos; } private byte[] onProduceCertificate(ClientHandshakeContext chc, diff --git a/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java b/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java index 4def03c6785..e13fcd6b973 100644 --- a/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java +++ b/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java @@ -45,7 +45,6 @@ import sun.security.ssl.CipherSuite.KeyExchange; import sun.security.ssl.SSLHandshake.HandshakeMessage; import sun.security.ssl.X509Authentication.X509Possession; -import sun.security.ssl.X509Authentication.X509PossessionGenerator; /** * Pack of the CertificateRequest handshake message. @@ -726,10 +725,11 @@ public void consume(ConnectionContext context, chc.handshakeSession.setPeerSupportedSignatureAlgorithms(sss); chc.peerSupportedAuthorities = crm.getAuthorities(); - // For TLS 1.2, we need to use a combination of the CR message's - // allowed key types and the signature algorithms in order to - // find a certificate chain that has the right key and all certs - // using one or more of the allowed cert signature schemes. + // For TLS 1.2, we no longer use the certificate_types field + // from the CertificateRequest message to directly determine + // the SSLPossession. Instead, the choosePossession method + // will use the accepted signature schemes in the message to + // determine the set of acceptable certificate types to select from. SSLPossession pos = choosePossession(chc, crm); if (pos == null) { return; @@ -761,6 +761,7 @@ private static SSLPossession choosePossession(HandshakeContext hc, } Collection checkedKeyTypes = new HashSet<>(); + List supportedKeyTypes = new ArrayList<>(); for (SignatureScheme ss : hc.peerRequestedCertSignSchemes) { if (checkedKeyTypes.contains(ss.keyAlgorithm)) { if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { @@ -769,6 +770,7 @@ private static SSLPossession choosePossession(HandshakeContext hc, } continue; } + checkedKeyTypes.add(ss.keyAlgorithm); // Don't select a signature scheme unless we will be able to // produce a CertificateVerify message later @@ -782,7 +784,6 @@ private static SSLPossession choosePossession(HandshakeContext hc, "Unable to produce CertificateVerify for " + "signature scheme: " + ss.name); } - checkedKeyTypes.add(ss.keyAlgorithm); continue; } @@ -792,45 +793,32 @@ private static SSLPossession choosePossession(HandshakeContext hc, SSLLogger.warning( "Unsupported authentication scheme: " + ss.name); } - checkedKeyTypes.add(ss.keyAlgorithm); continue; } else { - // Any auth object will have a possession generator and - // we need to make sure the key types for that generator - // share at least one common algorithm with the CR's - // allowed key types. - if (ka.possessionGenerator instanceof - X509PossessionGenerator xpg) { - if (Collections.disjoint(crKeyTypes, - Arrays.asList(xpg.keyTypes))) { - if (SSLLogger.isOn && - SSLLogger.isOn("ssl,handshake")) { - SSLLogger.warning( - "Unsupported authentication scheme: " + - ss.name); - } - checkedKeyTypes.add(ss.keyAlgorithm); - continue; + // Any auth object will have a set of allowed key types. + // This set should share at least one common algorithm with + // the CR's allowed key types. + if (Collections.disjoint(crKeyTypes, + Arrays.asList(ka.keyTypes))) { + if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { + SSLLogger.warning( + "Unsupported authentication scheme: " + + ss.name); } + continue; } } - - SSLPossession pos = ka.createPossession(hc); - if (pos == null) { - if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { - SSLLogger.warning( - "Unavailable authentication scheme: " + ss.name); - } - continue; - } - - return pos; + supportedKeyTypes.add(ss.keyAlgorithm); } - if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { - SSLLogger.warning("No available authentication scheme"); + SSLPossession pos = X509Authentication + .createPossession(hc, supportedKeyTypes.toArray(String[]::new)); + if (pos == null) { + if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { + SSLLogger.warning("No available authentication scheme"); + } } - return null; + return pos; } } diff --git a/src/java.base/share/classes/sun/security/ssl/X509Authentication.java b/src/java.base/share/classes/sun/security/ssl/X509Authentication.java index cd41ab506fd..ba1396f017b 100644 --- a/src/java.base/share/classes/sun/security/ssl/X509Authentication.java +++ b/src/java.base/share/classes/sun/security/ssl/X509Authentication.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2021, 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,52 +35,46 @@ import java.security.spec.ECParameterSpec; import java.security.spec.NamedParameterSpec; import java.util.AbstractMap.SimpleImmutableEntry; +import java.util.Arrays; import java.util.Map; -import javax.net.ssl.SSLEngine; -import javax.net.ssl.SSLSocket; import javax.net.ssl.X509ExtendedKeyManager; + import sun.security.ssl.SupportedGroupsExtension.SupportedGroups; enum X509Authentication implements SSLAuthentication { // Require rsaEncryption public key - RSA ("RSA", new X509PossessionGenerator( - new String[]{"RSA"})), + RSA ("RSA", "RSA"), // Require RSASSA-PSS public key - RSASSA_PSS ("RSASSA-PSS", new X509PossessionGenerator( - new String[] {"RSASSA-PSS"})), + RSASSA_PSS ("RSASSA-PSS", "RSASSA-PSS"), // Require rsaEncryption or RSASSA-PSS public key // // Note that this is a specifical scheme for TLS 1.2. (EC)DHE_RSA cipher // suites of TLS 1.2 can use either rsaEncryption or RSASSA-PSS public // key for authentication and handshake. - RSA_OR_PSS ("RSA_OR_PSS", new X509PossessionGenerator( - new String[] {"RSA", "RSASSA-PSS"})), + RSA_OR_PSS ("RSA_OR_PSS", "RSA", "RSASSA-PSS"), // Require DSA public key - DSA ("DSA", new X509PossessionGenerator( - new String[] {"DSA"})), + DSA ("DSA", "DSA"), // Require EC public key - EC ("EC", new X509PossessionGenerator( - new String[] {"EC"})), + EC ("EC", "EC"), // Edwards-Curve key - EDDSA ("EdDSA", new X509PossessionGenerator( - new String[] {"EdDSA"})); + EDDSA ("EdDSA", "EdDSA"); - final String keyType; - final SSLPossessionGenerator possessionGenerator; + final String keyAlgorithm; + final String[] keyTypes; - private X509Authentication(String keyType, - SSLPossessionGenerator possessionGenerator) { - this.keyType = keyType; - this.possessionGenerator = possessionGenerator; + private X509Authentication(String keyAlgorithm, + String... keyTypes) { + this.keyAlgorithm = keyAlgorithm; + this.keyTypes = keyTypes; } static X509Authentication valueOf(SignatureScheme signatureScheme) { for (X509Authentication au : X509Authentication.values()) { - if (au.keyType.equals(signatureScheme.keyAlgorithm)) { + if (au.keyAlgorithm.equals(signatureScheme.keyAlgorithm)) { return au; } } @@ -90,7 +84,7 @@ static X509Authentication valueOf(SignatureScheme signatureScheme) { @Override public SSLPossession createPossession(HandshakeContext handshakeContext) { - return possessionGenerator.createPossession(handshakeContext); + return X509Authentication.createPossession(handshakeContext, keyTypes); } @Override @@ -194,116 +188,109 @@ static final class X509Credentials implements SSLCredentials { } } - static final class X509PossessionGenerator - implements SSLPossessionGenerator { - final String[] keyTypes; + public static SSLPossession createPossession( + HandshakeContext context, String[] keyTypes) { + if (context.sslConfig.isClientMode) { + return createClientPossession( + (ClientHandshakeContext) context, keyTypes); + } else { + return createServerPossession( + (ServerHandshakeContext) context, keyTypes); + } + } - private X509PossessionGenerator(String[] keyTypes) { - this.keyTypes = keyTypes; + // Used by TLS 1.2 and TLS 1.3. + private static SSLPossession createClientPossession( + ClientHandshakeContext chc, String[] keyTypes) { + X509ExtendedKeyManager km = chc.sslContext.getX509KeyManager(); + String clientAlias = null; + if (chc.conContext.transport instanceof SSLSocketImpl socket) { + clientAlias = km.chooseClientAlias( + keyTypes, + chc.peerSupportedAuthorities == null ? null : + chc.peerSupportedAuthorities.clone(), + socket); + } else if (chc.conContext.transport instanceof SSLEngineImpl engine) { + clientAlias = km.chooseEngineClientAlias( + keyTypes, + chc.peerSupportedAuthorities == null ? null : + chc.peerSupportedAuthorities.clone(), + engine); } - @Override - public SSLPossession createPossession(HandshakeContext context) { - if (context.sslConfig.isClientMode) { - for (String keyType : keyTypes) { - SSLPossession poss = createClientPossession( - (ClientHandshakeContext)context, keyType); - if (poss != null) { - return poss; - } - } - } else { - for (String keyType : keyTypes) { - SSLPossession poss = createServerPossession( - (ServerHandshakeContext)context, keyType); - if (poss != null) { - return poss; - } - } + if (clientAlias == null) { + if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { + SSLLogger.finest("No X.509 cert selected for " + + Arrays.toString(keyTypes)); } - return null; } - // Used by TLS 1.2 and TLS 1.3. - private SSLPossession createClientPossession( - ClientHandshakeContext chc, String keyType) { - X509ExtendedKeyManager km = chc.sslContext.getX509KeyManager(); - String clientAlias = null; - if (chc.conContext.transport instanceof SSLSocketImpl) { - clientAlias = km.chooseClientAlias( - new String[] { keyType }, - chc.peerSupportedAuthorities == null ? null : - chc.peerSupportedAuthorities.clone(), - (SSLSocket)chc.conContext.transport); - } else if (chc.conContext.transport instanceof SSLEngineImpl) { - clientAlias = km.chooseEngineClientAlias( - new String[] { keyType }, - chc.peerSupportedAuthorities == null ? null : - chc.peerSupportedAuthorities.clone(), - (SSLEngine)chc.conContext.transport); - } - - if (clientAlias == null) { - if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { - SSLLogger.finest("No X.509 cert selected for " + keyType); - } - return null; - } - - PrivateKey clientPrivateKey = km.getPrivateKey(clientAlias); - if (clientPrivateKey == null) { - if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { - SSLLogger.finest( - clientAlias + " is not a private key entry"); - } - return null; + PrivateKey clientPrivateKey = km.getPrivateKey(clientAlias); + if (clientPrivateKey == null) { + if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { + SSLLogger.finest( + clientAlias + " is not a private key entry"); } + return null; + } - X509Certificate[] clientCerts = km.getCertificateChain(clientAlias); - if ((clientCerts == null) || (clientCerts.length == 0)) { - if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { - SSLLogger.finest(clientAlias + + X509Certificate[] clientCerts = km.getCertificateChain(clientAlias); + if ((clientCerts == null) || (clientCerts.length == 0)) { + if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { + SSLLogger.finest(clientAlias + " is a private key entry with no cert chain stored"); - } - return null; } + return null; + } - PublicKey clientPublicKey = clientCerts[0].getPublicKey(); - if ((!clientPrivateKey.getAlgorithm().equals(keyType)) - || (!clientPublicKey.getAlgorithm().equals(keyType))) { - if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { - SSLLogger.fine( - clientAlias + " private or public key is not of " + - keyType + " algorithm"); - } - return null; + String privateKeyAlgorithm = clientPrivateKey.getAlgorithm(); + if (!Arrays.asList(keyTypes).contains(privateKeyAlgorithm)) { + if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { + SSLLogger.fine( + clientAlias + " private key algorithm " + + privateKeyAlgorithm + " not in request list"); } + return null; + } - return new X509Possession(clientPrivateKey, clientCerts); + String publicKeyAlgorithm = clientCerts[0].getPublicKey().getAlgorithm(); + if (!privateKeyAlgorithm.equals(publicKeyAlgorithm)) { + if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { + SSLLogger.fine( + clientAlias + " private or public key is not of " + + "same algorithm: " + + privateKeyAlgorithm + " vs " + + publicKeyAlgorithm); + } + return null; } - private SSLPossession createServerPossession( - ServerHandshakeContext shc, String keyType) { - X509ExtendedKeyManager km = shc.sslContext.getX509KeyManager(); - String serverAlias = null; - if (shc.conContext.transport instanceof SSLSocketImpl) { + return new X509Possession(clientPrivateKey, clientCerts); + } + + private static SSLPossession createServerPossession( + ServerHandshakeContext shc, String[] keyTypes) { + X509ExtendedKeyManager km = shc.sslContext.getX509KeyManager(); + String serverAlias = null; + for (String keyType : keyTypes) { + if (shc.conContext.transport instanceof SSLSocketImpl socket) { serverAlias = km.chooseServerAlias(keyType, shc.peerSupportedAuthorities == null ? null : shc.peerSupportedAuthorities.clone(), - (SSLSocket)shc.conContext.transport); - } else if (shc.conContext.transport instanceof SSLEngineImpl) { + socket); + } else if (shc.conContext.transport instanceof SSLEngineImpl engine) { serverAlias = km.chooseEngineServerAlias(keyType, shc.peerSupportedAuthorities == null ? null : shc.peerSupportedAuthorities.clone(), - (SSLEngine)shc.conContext.transport); + engine); } if (serverAlias == null) { if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { SSLLogger.finest("No X.509 cert selected for " + keyType); } - return null; + continue; } PrivateKey serverPrivateKey = km.getPrivateKey(serverAlias); @@ -312,7 +299,7 @@ private SSLPossession createServerPossession( SSLLogger.finest( serverAlias + " is not a private key entry"); } - return null; + continue; } X509Certificate[] serverCerts = km.getCertificateChain(serverAlias); @@ -321,7 +308,7 @@ private SSLPossession createServerPossession( SSLLogger.finest( serverAlias + " is not a certificate entry"); } - return null; + continue; } PublicKey serverPublicKey = serverCerts[0].getPublicKey(); @@ -330,9 +317,9 @@ private SSLPossession createServerPossession( if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { SSLLogger.fine( serverAlias + " private or public key is not of " + - keyType + " algorithm"); + keyType + " algorithm"); } - return null; + continue; } // For TLS 1.2 and prior versions, the public key of a EC cert @@ -344,9 +331,9 @@ private SSLPossession createServerPossession( if (!(serverPublicKey instanceof ECPublicKey)) { if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { SSLLogger.warning(serverAlias + - " public key is not an instance of ECPublicKey"); + " public key is not an instance of ECPublicKey"); } - return null; + continue; } // For ECC certs, check whether we support the EC domain @@ -354,24 +341,25 @@ private SSLPossession createServerPossession( // ClientHello extension, check against that too for // TLS 1.2 and prior versions. ECParameterSpec params = - ((ECPublicKey)serverPublicKey).getParams(); + ((ECPublicKey) serverPublicKey).getParams(); NamedGroup namedGroup = NamedGroup.valueOf(params); if ((namedGroup == null) || (!SupportedGroups.isSupported(namedGroup)) || ((shc.clientRequestedNamedGroups != null) && - !shc.clientRequestedNamedGroups.contains(namedGroup))) { + !shc.clientRequestedNamedGroups.contains(namedGroup))) { if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { SSLLogger.warning( - "Unsupported named group (" + namedGroup + - ") used in the " + serverAlias + " certificate"); + "Unsupported named group (" + namedGroup + + ") used in the " + serverAlias + " certificate"); } - return null; + continue; } } return new X509Possession(serverPrivateKey, serverCerts); } + return null; } } diff --git a/test/hotspot/jtreg/vmTestbase/nsk/sysdict/vm/stress/btree/btree002/btree002.java b/test/hotspot/jtreg/vmTestbase/nsk/sysdict/vm/stress/btree/btree002/btree002.java index 01f6d824411..5a4a9fae0d6 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/sysdict/vm/stress/btree/btree002/btree002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/sysdict/vm/stress/btree/btree002/btree002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, 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,7 +30,7 @@ * VM Testbase keywords: [stress, sysdict, stressopt, nonconcurrent] * VM Testbase readme: * DESCRIPTION - * Single thread loads a tree of classes with signle loader. + * Single thread loads a tree of classes with single loader. * The test is deemed failed if loading attempt fails. * The test repeats until the given number of iterations, * or until EndOfMemoryError. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/sysdict/vm/stress/btree/btree005/btree005.java b/test/hotspot/jtreg/vmTestbase/nsk/sysdict/vm/stress/btree/btree005/btree005.java index dff11c2e365..42041c94fcf 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/sysdict/vm/stress/btree/btree005/btree005.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/sysdict/vm/stress/btree/btree005/btree005.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, 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,7 +30,7 @@ * VM Testbase keywords: [stress, sysdict, stressopt, nonconcurrent] * VM Testbase readme: * DESCRIPTION - * Multiple threads load a tree of classes with signle loader. + * Multiple threads load a tree of classes with single loader. * The test is deemed failed if loading attempt fails. * The test repeats until the given number of iterations, * or until EndOfMemoryError. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/sysdict/vm/stress/btree/btree008/btree008.java b/test/hotspot/jtreg/vmTestbase/nsk/sysdict/vm/stress/btree/btree008/btree008.java index 20cc937cfb8..9861f3c051f 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/sysdict/vm/stress/btree/btree008/btree008.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/sysdict/vm/stress/btree/btree008/btree008.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, 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,7 +30,7 @@ * VM Testbase keywords: [stress, sysdict, stressopt, nonconcurrent] * VM Testbase readme: * DESCRIPTION - * Single thread loads a tree of classes with signle loader. + * Single thread loads a tree of classes with single loader. * Then, memory stress is induced to unload the classes. * The test is deemed failed if loading attempt fails; * or if the tested VM crashes. @@ -51,5 +51,6 @@ * -jarpath btree.jar${path.separator}fats.jar * -useSingleLoader * -stressHeap + * -t 1 */ diff --git a/test/hotspot/jtreg/vmTestbase/nsk/sysdict/vm/stress/btree/btree011/btree011.java b/test/hotspot/jtreg/vmTestbase/nsk/sysdict/vm/stress/btree/btree011/btree011.java index 8e1720831ec..507abcef278 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/sysdict/vm/stress/btree/btree011/btree011.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/sysdict/vm/stress/btree/btree011/btree011.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, 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,7 +30,7 @@ * VM Testbase keywords: [stress, sysdict, stressopt, nonconcurrent] * VM Testbase readme: * DESCRIPTION - * Multiple threads load a tree of classes with signle loader. + * Multiple threads load a tree of classes with single loader. * Then, memory stress is induced to unload the classes. * The test is deemed failed if loading attempt fails; * or if the tested VM crashes. diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index cd43a6473d1..05bf219cb54 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -650,7 +650,7 @@ com/sun/security/sasl/gsskerb/ConfSecurityLayer.java 8039280 generic- com/sun/security/sasl/gsskerb/NoSecurityLayer.java 8039280 generic-all javax/security/auth/kerberos/KerberosHashEqualsTest.java 8039280 generic-all javax/security/auth/kerberos/KerberosTixDateTest.java 8039280 generic-all -javax/security/auth/callback/PasswordCallback/CheckCleanerBound.java 8285785,8286045,8287596 generic-all +javax/security/auth/callback/PasswordCallback/CheckCleanerBound.java 8286045 generic-all sun/security/provider/PolicyFile/GrantAllPermToExtWhenNoPolicy.java 8039280 generic-all sun/security/provider/PolicyParser/ExtDirsChange.java 8039280 generic-all sun/security/provider/PolicyParser/PrincipalExpansionError.java 8039280 generic-all diff --git a/test/jdk/java/io/File/libGetXSpace.c b/test/jdk/java/io/File/libGetXSpace.c index 7a6cdf0d1dc..4eafb86bf36 100644 --- a/test/jdk/java/io/File/libGetXSpace.c +++ b/test/jdk/java/io/File/libGetXSpace.c @@ -23,7 +23,7 @@ #include #include "jni.h" #include "jni_util.h" -#ifdef _WIN64 +#ifdef WINDOWS #include #include #include @@ -42,7 +42,7 @@ extern "C" { #endif -#ifdef _WIN64 +#ifdef WINDOWS jboolean initialized = JNI_FALSE; BOOL(WINAPI * pfnGetDiskSpaceInformation)(LPCWSTR, LPVOID) = NULL; #endif @@ -67,7 +67,7 @@ Java_GetXSpace_getSpace0 return JNI_FALSE; } -#ifdef _WIN64 +#ifdef WINDOWS if (initialized == JNI_FALSE) { initialized = JNI_TRUE; HMODULE hmod = GetModuleHandleW(L"kernel32"); diff --git a/test/jdk/java/lang/Thread/IsAlive.java b/test/jdk/java/lang/Thread/IsAlive.java index ffb7ca6fea5..a95fe345cad 100644 --- a/test/jdk/java/lang/Thread/IsAlive.java +++ b/test/jdk/java/lang/Thread/IsAlive.java @@ -25,7 +25,7 @@ * @test * @bug 8305425 * @summary Check Thread.isAlive - * @run main/othervm/timeout=10 IsAlive + * @run main/othervm IsAlive */ public class IsAlive { diff --git a/test/jdk/javax/security/auth/callback/PasswordCallback/CheckCleanerBound.java b/test/jdk/javax/security/auth/callback/PasswordCallback/CheckCleanerBound.java index cc995893f65..5d8a5cfea27 100644 --- a/test/jdk/javax/security/auth/callback/PasswordCallback/CheckCleanerBound.java +++ b/test/jdk/javax/security/auth/callback/PasswordCallback/CheckCleanerBound.java @@ -47,6 +47,7 @@ public static void main(String[] args) throws Exception { // Wait to trigger the cleanup. for (int i = 0; i < 10 && weakHashMap.size() != 0; i++) { System.gc(); + Thread.sleep(100); } // Check if the object has been collected. The collection will not diff --git a/test/jdk/javax/swing/JTableHeader/6889007/bug6889007.java b/test/jdk/javax/swing/JTableHeader/6889007/bug6889007.java index cdceac1f9f2..7b120024186 100644 --- a/test/jdk/javax/swing/JTableHeader/6889007/bug6889007.java +++ b/test/jdk/javax/swing/JTableHeader/6889007/bug6889007.java @@ -53,7 +53,6 @@ public class bug6889007 { public static void main(String[] args) throws Exception { try { robot = new Robot(); - robot.setAutoDelay(100); SwingUtilities.invokeAndWait(() -> { frame = new JFrame(); @@ -69,6 +68,7 @@ public static void main(String[] args) throws Exception { frame.add(th); frame.pack(); frame.setLocationRelativeTo(null); + frame.setAlwaysOnTop(true); frame.setVisible(true); }); robot.waitForIdle(); @@ -83,7 +83,7 @@ public static void main(String[] args) throws Exception { int y = point.y + height/2; for(int i = -shift; i < width + 2*shift; i++) { robot.mouseMove(x++, y); - robot.waitForIdle(); + robot.delay(100); } robot.waitForIdle(); // 9 is a magic test number @@ -109,6 +109,8 @@ protected void rolloverColumnUpdated(int oldColumn, int newColumn) { Cursor cursor = Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR); if (oldColumn != -1 && newColumn != -1 && header.getCursor() != cursor) { + System.out.println("oldColumn " + oldColumn + " newColumn " + newColumn + + "header.getCursor " + header.getCursor() + " cursor " + cursor); try { Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); diff --git a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java index a890040e3a1..62157256422 100644 --- a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java +++ b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java @@ -301,6 +301,26 @@ * @run main/othervm -Djava.security.debug=certpath CAInterop quovadisrootca3g3 CRL */ +/* + * @test id=digicerttlseccrootg5 + * @bug 8318759 + * @summary Interoperability tests with DigiCert TLS ECC P384 Root G5 + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop digicerttlseccrootg5 OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop digicerttlseccrootg5 CRL + */ + +/* + * @test id=digicerttlsrsarootg5 + * @bug 8318759 + * @summary Interoperability tests with DigiCert TLS RSA4096 Root G5 + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop digicerttlsrsarootg5 OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop digicerttlsrsarootg5 CRL + */ + /* * @test id=sslrootrsaca * @bug 8243320 @@ -509,6 +529,7 @@ private CATestURLs getTestURLs(String alias) { new CATestURLs("https://actrsaroot2017.pki.microsoft.com", "https://rvkrsaroot2017.pki.microsoft.com"); + // Test URLs are listed at https://www.digicert.com/kb/digicert-root-certificates.htm case "quovadisrootca1g3" -> new CATestURLs("https://quovadis-root-ca-1-g3.chain-demos.digicert.com", "https://quovadis-root-ca-1-g3-revoked.chain-demos.digicert.com"); @@ -518,6 +539,12 @@ private CATestURLs getTestURLs(String alias) { case "quovadisrootca3g3" -> new CATestURLs("https://quovadis-root-ca-3-g3.chain-demos.digicert.com", "https://quovadis-root-ca-3-g3-revoked.chain-demos.digicert.com"); + case "digicerttlseccrootg5" -> + new CATestURLs("https://digicert-tls-ecc-p384-root-g5.chain-demos.digicert.com", + "https://digicert-tls-ecc-p384-root-g5-revoked.chain-demos.digicert.com"); + case "digicerttlsrsarootg5" -> + new CATestURLs("https://digicert-tls-rsa4096-root-g5.chain-demos.digicert.com", + "https://digicert-tls-rsa4096-root-g5-revoked.chain-demos.digicert.com"); case "sslrootrsaca" -> new CATestURLs("https://test-dv-rsa.ssl.com", diff --git a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/DigicertCSRootG5.java b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/DigicertCSRootG5.java new file mode 100644 index 00000000000..30ad81b1755 --- /dev/null +++ b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/DigicertCSRootG5.java @@ -0,0 +1,303 @@ +/* + * Copyright (c) 2023, 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 8318759 + * @summary Interoperability tests with Digicert CS Root G5 certificates + * @build ValidatePathWithParams + * @run main/othervm -Djava.security.debug=ocsp,certpath DigicertCSRootG5 OCSP + * @run main/othervm -Djava.security.debug=certpath DigicertCSRootG5 CRL + */ + +public class DigicertCSRootG5 { + + public static void main(String[] args) throws Exception { + + ValidatePathWithParams pathValidator = new ValidatePathWithParams(null); + + if (args.length >= 1 && "CRL".equalsIgnoreCase(args[0])) { + pathValidator.enableCRLCheck(); + } else { + // OCSP check by default + pathValidator.enableOCSPCheck(); + } + + new Digicert_CS_ECC().runTest(pathValidator); + new Digicert_CS_RSA().runTest(pathValidator); + } +} + +class Digicert_CS_ECC { + + // Owner: CN=DigiCert G5 CS ECC SHA384 2021 CA1, O="DigiCert, Inc.", C=US + // Issuer: CN=DigiCert CS ECC P384 Root G5, O="DigiCert, Inc.", C=US + // Serial number: d926818addd3c47758f0ace9379b2e7 + // Valid from: Wed Feb 10 16:00:00 PST 2021 until: Sun Feb 10 15:59:59 PST 2036 + private static final String INT = "-----BEGIN CERTIFICATE-----\n" + + "MIIDOTCCAsCgAwIBAgIQDZJoGK3dPEd1jwrOk3my5zAKBggqhkjOPQQDAzBNMQsw\n" + + "CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMTHERp\n" + + "Z2lDZXJ0IENTIEVDQyBQMzg0IFJvb3QgRzUwHhcNMjEwMjExMDAwMDAwWhcNMzYw\n" + + "MjEwMjM1OTU5WjBTMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIElu\n" + + "Yy4xKzApBgNVBAMTIkRpZ2lDZXJ0IEc1IENTIEVDQyBTSEEzODQgMjAyMSBDQTEw\n" + + "djAQBgcqhkjOPQIBBgUrgQQAIgNiAAS/zvKH4sLLu/zze3/+vHyfRE5OcO77TNw3\n" + + "MCMAlad2Y/ja50KTooGSmXhfwMXpbBTob7hsoxpvIU92W6DhFn9lg4pcKf5UHLEi\n" + + "0iDdHQ9w0hpFJiMABwK60nk+OwsGTZSjggFdMIIBWTASBgNVHRMBAf8ECDAGAQH/\n" + + "AgEAMB0GA1UdDgQWBBTXHcf6xvqCdCBFcTQSL1XVmEGSXjAfBgNVHSMEGDAWgBTw\n" + + "jJhxOThlwjobphdmHcjtZd6SNjAOBgNVHQ8BAf8EBAMCAYYwEwYDVR0lBAwwCgYI\n" + + "KwYBBQUHAwMweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz\n" + + "cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj\n" + + "ZXJ0LmNvbS9EaWdpQ2VydENTRUNDUDM4NFJvb3RHNS5jcnQwRQYDVR0fBD4wPDA6\n" + + "oDigNoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0Q1NFQ0NQMzg0\n" + + "Um9vdEc1LmNybDAcBgNVHSAEFTATMAcGBWeBDAEDMAgGBmeBDAEEATAKBggqhkjO\n" + + "PQQDAwNnADBkAjByCWijRCnJogZf94U5HG/5S4QFMxEOBSAyxECbFxgrXMKXh5qa\n" + + "7oS2F+hT2DPzxTwCMCIthK0X/14bxZvrNNiNSWzer2TDUyRw6HNIfnkHgqaGFQVA\n" + + "KyS5I77prv53stK0XQ==\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN="Win The Customer, LLC", O="Win The Customer, LLC", L=Saratoga + // Springs, ST=Utah, C=US, SERIALNUMBER=9637546-0160, OID.2.5.4.15=Private + // Organization, OID.1.3.6.1.4.1.311.60.2.1.2=Utah, OID.1.3.6.1.4.1.311.60.2.1.3=US + // Issuer: CN=DigiCert G5 CS ECC SHA384 2021 CA1, O="DigiCert, Inc.", C=US + // Serial number: b13737c3caf58eecb4359f441522133 + // Valid from: Wed Jan 25 16:00:00 PST 2023 until: Tue Jan 28 15:59:59 PST 2025 + private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + + "MIIEEjCCA5mgAwIBAgIQCxNzfDyvWO7LQ1n0QVIhMzAKBggqhkjOPQQDAzBTMQsw\n" + + "CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xKzApBgNVBAMTIkRp\n" + + "Z2lDZXJ0IEc1IENTIEVDQyBTSEEzODQgMjAyMSBDQTEwHhcNMjMwMTI2MDAwMDAw\n" + + "WhcNMjUwMTI4MjM1OTU5WjCB2TETMBEGCysGAQQBgjc8AgEDEwJVUzEVMBMGCysG\n" + + "AQQBgjc8AgECEwRVdGFoMR0wGwYDVQQPDBRQcml2YXRlIE9yZ2FuaXphdGlvbjEV\n" + + "MBMGA1UEBRMMOTYzNzU0Ni0wMTYwMQswCQYDVQQGEwJVUzENMAsGA1UECBMEVXRh\n" + + "aDEZMBcGA1UEBxMQU2FyYXRvZ2EgU3ByaW5nczEeMBwGA1UEChMVV2luIFRoZSBD\n" + + "dXN0b21lciwgTExDMR4wHAYDVQQDExVXaW4gVGhlIEN1c3RvbWVyLCBMTEMwWTAT\n" + + "BgcqhkjOPQIBBggqhkjOPQMBBwNCAASyShgaH44RcHazlEEMpwRKY4YebnygI9hG\n" + + "wTMQE/VFG40k3tR8lnyjgxTzZbC0aCVavdv1eglDGejQ+6iD8nzgo4IBxjCCAcIw\n" + + "HwYDVR0jBBgwFoAU1x3H+sb6gnQgRXE0Ei9V1ZhBkl4wHQYDVR0OBBYEFLGgEWb9\n" + + "GF89JoXyan/FD/auNIVVMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEF\n" + + "BQcDAzCBjQYDVR0fBIGFMIGCMD+gPaA7hjlodHRwOi8vY3JsMy5kaWdpY2VydC5j\n" + + "b20vRGlnaUNlcnRHNUNTRUNDU0hBMzg0MjAyMUNBMS5jcmwwP6A9oDuGOWh0dHA6\n" + + "Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEc1Q1NFQ0NTSEEzODQyMDIxQ0Ex\n" + + "LmNybDA9BgNVHSAENjA0MDIGBWeBDAEDMCkwJwYIKwYBBQUHAgEWG2h0dHA6Ly93\n" + + "d3cuZGlnaWNlcnQuY29tL0NQUzB+BggrBgEFBQcBAQRyMHAwJAYIKwYBBQUHMAGG\n" + + "GGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBIBggrBgEFBQcwAoY8aHR0cDovL2Nh\n" + + "Y2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0RzVDU0VDQ1NIQTM4NDIwMjFDQTEu\n" + + "Y3J0MAwGA1UdEwEB/wQCMAAwCgYIKoZIzj0EAwMDZwAwZAIwLkWJc/eLxftorFCv\n" + + "ocOA1dfUFx7Al18d5Xsgpkx47kj2DWgQU+/bQEbbyPrKzYgCAjAP5ErLauJRC2to\n" + + "pPk/yXZYXsusmWVH7ozl9O5WR7+a3gVQ1zwVFWuqdjbq3zWWqJM=\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=Win the Customer LLC, O=Win the Customer LLC, L=Saratoga Springs, ST=Utah, C=US + // Issuer: CN=DigiCert G5 CS ECC SHA384 2021 CA1, O="DigiCert, Inc.", C=US + // Serial number: 201e51cb1ec8a56a1e8438c95adf024 + // Valid from: Sun Oct 22 17:00:00 PDT 2023 until: Tue Oct 22 16:59:59 PDT 2024 + private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + + "MIIFdjCCBP2gAwIBAgIQAgHlHLHsilah6EOMla3wJDAKBggqhkjOPQQDAzBTMQsw\n" + + "CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xKzApBgNVBAMTIkRp\n" + + "Z2lDZXJ0IEc1IENTIEVDQyBTSEEzODQgMjAyMSBDQTEwHhcNMjMxMDIzMDAwMDAw\n" + + "WhcNMjQxMDIyMjM1OTU5WjB1MQswCQYDVQQGEwJVUzENMAsGA1UECBMEVXRhaDEZ\n" + + "MBcGA1UEBxMQU2FyYXRvZ2EgU3ByaW5nczEdMBsGA1UEChMUV2luIHRoZSBDdXN0\n" + + "b21lciBMTEMxHTAbBgNVBAMTFFdpbiB0aGUgQ3VzdG9tZXIgTExDMIICIjANBgkq\n" + + "hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0o+FWNSfYzJmz+XgA7SRAIQd1H1pYnzq\n" + + "dPyNJJsd1G/nqfeHk/ezEx8Wd7iMJjcPOvKSd14uniAC3ayi3XOKKeFqEw5g5m2/\n" + + "JTO3n8xy9DK5CN1ctpK5Zy+UppOXrtTdBZB74/qSaREOysIfRLnVR4fxNy39urtl\n" + + "TJf0lvzRU9V6BQ3zRjMOCQnY6sueAPoQpVgpCVXkr4obJCkI5arkIQHVpfrcScaJ\n" + + "IzLQ46xL8nxoXPcGhikRystJKdbzg/oCFt68x87uSviZMtkqTHQhzRCzpO5pdx/z\n" + + "g64XZP8fAzSrM/uJCETXxMmazK6ZVkgPu3X4GvjfTfulvcJdxZNMm877NOSICtbL\n" + + "dKoBpvIeKtuyxrvmoJUfNw4e+LLbAQOFznVy7UxkTzG1INPgd57zu3Sm3ALq/oJZ\n" + + "oKfheM4zo8UevYMKmoki+N+qMHcJplPF8C04/u8CNc1Jk8tKmjgof8ZsGbQCC2+l\n" + + "NKXzTUnPpza4mHBMU3Qdd4iV8oxd/9jQyE71h11ISakWSresbCyC6HSOVUh409A1\n" + + "Mhv9+aEbqBNhAHJIYrQSY1hb98CKLRS6cABKAzr+HdafiPCAN3cdLGgJ5TWTIiBj\n" + + "AcjyHseVU4jeLIQl7/4gZATjePzSy/bo62SZXWzCOFp6zzy8VGGavRmMobe193gn\n" + + "cz/17hmFvqECAwEAAaOCAcQwggHAMB8GA1UdIwQYMBaAFNcdx/rG+oJ0IEVxNBIv\n" + + "VdWYQZJeMB0GA1UdDgQWBBR5Hkdl3jgG88ixGc1wEwO6N9Rn2TA+BgNVHSAENzA1\n" + + "MDMGBmeBDAEEATApMCcGCCsGAQUFBwIBFhtodHRwOi8vd3d3LmRpZ2ljZXJ0LmNv\n" + + "bS9DUFMwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMIGNBgNV\n" + + "HR8EgYUwgYIwP6A9oDuGOWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2Vy\n" + + "dEc1Q1NFQ0NTSEEzODQyMDIxQ0ExLmNybDA/oD2gO4Y5aHR0cDovL2NybDQuZGln\n" + + "aWNlcnQuY29tL0RpZ2lDZXJ0RzVDU0VDQ1NIQTM4NDIwMjFDQTEuY3JsMH4GCCsG\n" + + "AQUFBwEBBHIwcDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29t\n" + + "MEgGCCsGAQUFBzAChjxodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNl\n" + + "cnRHNUNTRUNDU0hBMzg0MjAyMUNBMS5jcnQwCQYDVR0TBAIwADAKBggqhkjOPQQD\n" + + "AwNnADBkAjA9aX3CSzCOZiHdC6JBF0nQwPLGNipPdHFMSbINmfpuHCC3Go4prf8M\n" + + "WCsWEQr2gQYCMErfcrU8zfxnQ9SxsmGJ8jkM3MDGvAr0CtzDwmWis32V60jAUFBQ\n" + + "lGm/Mdb5/EqKpw==\n" + + "-----END CERTIFICATE-----"; + + public void runTest(ValidatePathWithParams pathValidator) throws Exception { + // Validate valid + pathValidator.validate(new String[]{VALID, INT}, + ValidatePathWithParams.Status.GOOD, null, System.out); + + // Validate Revoked + pathValidator.validate(new String[]{REVOKED, INT}, + ValidatePathWithParams.Status.REVOKED, + "Mon Oct 23 14:48:38 PDT 2023", System.out); + } +} + +class Digicert_CS_RSA { + + // Owner: CN=DigiCert G5 CS RSA4096 SHA384 2021 CA1, O="DigiCert, Inc.", C=US + // Issuer: CN=DigiCert CS RSA4096 Root G5, O="DigiCert, Inc.", C=US + // Serial number: 10262e16224ca6dfef584f8c63048db + // Valid from: Wed Feb 10 16:00:00 PST 2021 until: Sun Feb 10 15:59:59 PST 2036 + private static final String INT = "-----BEGIN CERTIFICATE-----\n" + + "MIIGjDCCBHSgAwIBAgIQAQJi4WIkym3+9YT4xjBI2zANBgkqhkiG9w0BAQwFADBM\n" + + "MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJDAiBgNVBAMT\n" + + "G0RpZ2lDZXJ0IENTIFJTQTQwOTYgUm9vdCBHNTAeFw0yMTAyMTEwMDAwMDBaFw0z\n" + + "NjAyMTAyMzU5NTlaMFcxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwg\n" + + "SW5jLjEvMC0GA1UEAxMmRGlnaUNlcnQgRzUgQ1MgUlNBNDA5NiBTSEEzODQgMjAy\n" + + "MSBDQTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC1GOMV0tdTLLBk\n" + + "Ylmccgb6bFa9By5zkuLg9NfFMl4y9P9f21C7N+mMA4fWgfjEs+7/3ByGLaB+7/Pi\n" + + "TT3qXpvBz4uVWob9xv3lkAsIpwh/TMJulijy3GdpAQBMdvW/+HFrbRJGaJ3MM9d1\n" + + "pC3CRPmFWyXUpxqhb0FbMPA8OlsZNjg9fd/zCLevSJlL6ZdjfZ/4FiF26OfO60V6\n" + + "bOuTnd8JbDuwPfMWLP6qEinlFr7V9mjcZc4dfUWH70y7M6av7R1Tc68YQjrtPwIA\n" + + "5pdEcG/VeBVplpne1uxuc61ucVgTpjwOTV6E2KrCe+OCG8/m4voN7T4GC1RfPH3n\n" + + "PlCNV6MeiCVwExPhJFxZ+eTvhVJe0W7mriYpEo2kNR4pnSUhiS92vF4lI3ToAdnH\n" + + "LV+yx0VdsPVwEO344rsVNQvP/hrCHefKm3HsirlazTKpiI9OgZlkXohHanp8IgMx\n" + + "2HvBE/6HcCq/5PiRaeSzvFfRuotLS/LMCXaQEGV9JNSd1omKeNyaDqs89cNbf0g7\n" + + "Tn1AhAxb/TDIkIAV/1bU1UFeq48ufRCRpPO145JQXL7hfdUIth3AkvFRqLPbTsCH\n" + + "v/PcnKScv/QCtoYRnYv5LwdIvYblC+yqe7a9CVARsaVsGBw45wBevcMR5fcdriET\n" + + "ZjRNmQ5gMBjm/ZlHlzyBgShH6U22TQIDAQABo4IBXTCCAVkwEgYDVR0TAQH/BAgw\n" + + "BgEB/wIBADAdBgNVHQ4EFgQUiRgH/z5tMBfJNa27i3GG5Z9mksMwHwYDVR0jBBgw\n" + + "FoAUaAGTsdJKQEJplEYsHFqIqSW0R08wDgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQM\n" + + "MAoGCCsGAQUFBwMDMHkGCCsGAQUFBwEBBG0wazAkBggrBgEFBQcwAYYYaHR0cDov\n" + + "L29jc3AuZGlnaWNlcnQuY29tMEMGCCsGAQUFBzAChjdodHRwOi8vY2FjZXJ0cy5k\n" + + "aWdpY2VydC5jb20vRGlnaUNlcnRDU1JTQTQwOTZSb290RzUuY3J0MEUGA1UdHwQ+\n" + + "MDwwOqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydENTUlNB\n" + + "NDA5NlJvb3RHNS5jcmwwHAYDVR0gBBUwEzAHBgVngQwBAzAIBgZngQwBBAEwDQYJ\n" + + "KoZIhvcNAQEMBQADggIBALBxItkM8LmHhbsnkykSN6+HnLj9/hUx9UUcym1Hwoii\n" + + "Bl9VCCpibLDJurx1w19KL5S6j2ggOMn/1zBugWMVhn6j12RzD4HUkfLqNBXzQmRc\n" + + "xZoXxspSgqpk+jd5iMtVSDBzlaF7s1feDh9qKa7O/7OB5KAiIO2VYFx1ia9ne3tV\n" + + "lY98G+3TnEdjo7r9lBi4KDGmDJv56h7Sb4WeVFlJ/8b4u9IHblq3ykQ/LyKuCYDf\n" + + "v2bnqlT+HY4mgU9ZA0WoO/L7V7m0sBrBYhpdM0pmxlqn6mpvWIHA2tC4rsTY2TXn\n" + + "ZlXbyJaMd5mvjRjvK0DF/2yoKC+us/1li2blLZKS9k0Z36/m4D7z5nVXkmUvRvE2\n" + + "70BhJ0NnM5lHtytTR+OgiaPapeiDy6AA+VbdnV7hhINGEhP7tF3IZPPfmKZN7/bN\n" + + "Qr7wuKZx/jO5sTBtblBaOU2+xric+MlTt2k3ilDnO3EzkZOp1JMWnNjAZciRa8Gy\n" + + "bYAXrsxY4vQnxgA7dj1/3KDB+pCRT7CTMOJJQu27OOv0MuNkb1E+8chPx/eFwfrN\n" + + "rft1Eiqp3Te0w4njDkzukP6EMhebcTp3POm0YhMZl8s1fTI6DCcHFwcMVywXiWwv\n" + + "QG+Td+dHlFT0P8jq/ecaMj6s8j69q36MER+QMyrxGAl3MHyEA7BBut1WCh9dsOnY\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN="Win The Customer, LLC", O="Win The Customer, LLC", L=Saratoga + // Springs, ST=Utah, C=US + // Issuer: CN=DigiCert G5 CS RSA4096 SHA384 2021 CA1, O="DigiCert, Inc.", C=US + // Serial number: bfec2fd49eeacb347ddbea5c1576083 + // Valid from: Fri Jun 23 17:00:00 PDT 2023 until: Wed Jun 26 16:59:59 PDT 2024 + private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + + "MIIGqzCCBJOgAwIBAgIQC/7C/UnurLNH3b6lwVdggzANBgkqhkiG9w0BAQsFADBX" + + "MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xLzAtBgNVBAMT" + + "JkRpZ2lDZXJ0IEc1IENTIFJTQTQwOTYgU0hBMzg0IDIwMjEgQ0ExMB4XDTIzMDYy" + + "NDAwMDAwMFoXDTI0MDYyNjIzNTk1OVowdzELMAkGA1UEBhMCVVMxDTALBgNVBAgT" + + "BFV0YWgxGTAXBgNVBAcTEFNhcmF0b2dhIFNwcmluZ3MxHjAcBgNVBAoTFVdpbiBU" + + "aGUgQ3VzdG9tZXIsIExMQzEeMBwGA1UEAxMVV2luIFRoZSBDdXN0b21lciwgTExD" + + "MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAsElsbtoNNIL5fCadUzW+" + + "aDl2LF0c6BRckZSuH1f88tFD5LDjuT+rdIxsjDS/dqedRiilJe40z/3973OZNaxs" + + "wxYCSHhUV9XimSHH0zQ2MpbupdA7aLDYM4tcypam1Zm9q6njLArBUgGVaKYBUZqW" + + "obVh+6aFBzj36u7EmPgLCJsre5oheo8+gOwfu+xVExceoHG+V7XTKhD6vhclS49B" + + "UIHgvpn+/BlB8kjf5M2XzmpfWg9aGq75gnd1ix4fU1BnA0A33cZPrFsi5cMh6NZd" + + "tI4WIpb5P8X17G3yRqNMM/noBvBrtpQHVLpN2C2NLg0YX1FjIK7bcBKFOnIG36ou" + + "vs+QesMyVOXeKKnt1ERBSqwrMjUuqN7W6YnXjoIp7xWxEdIdae+1fDK702zhGaYv" + + "b6pYGoJ7HQI/x7S6kF462qvXsf++yA5kxr2qNTSNY4ZggzEwubvu0PYRYjMHwIUn" + + "SV3ZlRAKXK2AO7GydecWr2QVRra4+myCznsil/rKasWTAgMBAAGjggHRMIIBzTAf" + + "BgNVHSMEGDAWgBSJGAf/Pm0wF8k1rbuLcYbln2aSwzAdBgNVHQ4EFgQUfr+syABm" + + "R7FB/f155oky+e5fLR8wDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUF" + + "BwMDMIGVBgNVHR8EgY0wgYowQ6BBoD+GPWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNv" + + "bS9EaWdpQ2VydEc1Q1NSU0E0MDk2U0hBMzg0MjAyMUNBMS5jcmwwQ6BBoD+GPWh0" + + "dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEc1Q1NSU0E0MDk2U0hBMzg0" + + "MjAyMUNBMS5jcmwwPgYDVR0gBDcwNTAzBgZngQwBBAEwKTAnBggrBgEFBQcCARYb" + + "aHR0cDovL3d3dy5kaWdpY2VydC5jb20vQ1BTMIGCBggrBgEFBQcBAQR2MHQwJAYI" + + "KwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBMBggrBgEFBQcwAoZA" + + "aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0RzVDU1JTQTQwOTZT" + + "SEEzODQyMDIxQ0ExLmNydDAJBgNVHRMEAjAAMA0GCSqGSIb3DQEBCwUAA4ICAQCj" + + "HCYM2aGyHFpdWRkbxa+so37uyPDJ27wpn4oNhaSKKletB8Xr6rMa5JBJ1NUa2S9Q" + + "3CYvdH9pGjjThUJPR0Lg8DrZNkPtqyjQLQ86tYfjteoKe5SXTxZ0epXikRTXySFa" + + "NM1KOEf5CJq7OywLLXVxm+F2VEX2+PzLAtHxViGeN7AsZMbWGlp3VkymVITcKkP3" + + "vnsoF6Teacb019xxBDCLuhNG91rlzhG0YrJ3qMlPyStmzxqy+2UIlPwFeLRkBkRG" + + "K7Kxi2xvYbgdFP93kRbwJbp8d3x/JG3LpwAZv+NV0TY3jBj7ymGoGuiSV0nU9XPt" + + "yDm1FYYZAH2ykwo8YPZqAcu+EHvyxi1dgOM3ABfoLJfOIYJv2gxPx+KIKzn1wzBS" + + "kk1HMf8xbYXs40vF2Lrb7AQIyLa2ZskJTyfb0dyEyOq+vvVgLA9ZdwidzD1RnVf6" + + "vOb7KbMSBCLK+HGqHrW+hhSDi2vHvSit7Cn+q80ZmzRqvJ/+mVl+ppnjDC7nSLIa" + + "qeG0fvUz6SabPX7yV92D5ARrJJ3xgAvgmgWfuKBV7WlEGCmj0QTWZ0/AFBLzNcq7" + + "+0rgP0GM98MZpKa8pHZaS1A3uP1TFzamfVGdv0FVHXSkN5Kvg0iPh4Qz9TRiCkyE" + + "boJeU1LYdyTrP/+q3zQqsGa9xdQ50EovjWymbvWzCQ==\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=Win the Customer LLC, O=Win the Customer LLC, L=Saratoga Springs, + // ST=Utah, C=US + // Issuer: CN=DigiCert G5 CS RSA4096 SHA384 2021 CA1, O="DigiCert, Inc.", C=US + // Serial number: f409d101094769abaf06f085f11ca4f + // Valid from: Sun Oct 22 17:00:00 PDT 2023 until: Tue Oct 22 16:59:59 PDT 2024 + private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + + "MIIHKTCCBRGgAwIBAgIQD0CdEBCUdpq68G8IXxHKTzANBgkqhkiG9w0BAQsFADBX\n" + + "MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xLzAtBgNVBAMT\n" + + "JkRpZ2lDZXJ0IEc1IENTIFJTQTQwOTYgU0hBMzg0IDIwMjEgQ0ExMB4XDTIzMTAy\n" + + "MzAwMDAwMFoXDTI0MTAyMjIzNTk1OVowdTELMAkGA1UEBhMCVVMxDTALBgNVBAgT\n" + + "BFV0YWgxGTAXBgNVBAcTEFNhcmF0b2dhIFNwcmluZ3MxHTAbBgNVBAoTFFdpbiB0\n" + + "aGUgQ3VzdG9tZXIgTExDMR0wGwYDVQQDExRXaW4gdGhlIEN1c3RvbWVyIExMQzCC\n" + + "AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANKPhVjUn2MyZs/l4AO0kQCE\n" + + "HdR9aWJ86nT8jSSbHdRv56n3h5P3sxMfFne4jCY3DzrykndeLp4gAt2sot1ziinh\n" + + "ahMOYOZtvyUzt5/McvQyuQjdXLaSuWcvlKaTl67U3QWQe+P6kmkRDsrCH0S51UeH\n" + + "8Tct/bq7ZUyX9Jb80VPVegUN80YzDgkJ2OrLngD6EKVYKQlV5K+KGyQpCOWq5CEB\n" + + "1aX63EnGiSMy0OOsS/J8aFz3BoYpEcrLSSnW84P6AhbevMfO7kr4mTLZKkx0Ic0Q\n" + + "s6TuaXcf84OuF2T/HwM0qzP7iQhE18TJmsyumVZID7t1+Br43037pb3CXcWTTJvO\n" + + "+zTkiArWy3SqAabyHirbssa75qCVHzcOHviy2wEDhc51cu1MZE8xtSDT4Hee87t0\n" + + "ptwC6v6CWaCn4XjOM6PFHr2DCpqJIvjfqjB3CaZTxfAtOP7vAjXNSZPLSpo4KH/G\n" + + "bBm0AgtvpTSl801Jz6c2uJhwTFN0HXeIlfKMXf/Y0MhO9YddSEmpFkq3rGwsguh0\n" + + "jlVIeNPQNTIb/fmhG6gTYQBySGK0EmNYW/fAii0UunAASgM6/h3Wn4jwgDd3HSxo\n" + + "CeU1kyIgYwHI8h7HlVOI3iyEJe/+IGQE43j80sv26OtkmV1swjhaes88vFRhmr0Z\n" + + "jKG3tfd4J3M/9e4Zhb6hAgMBAAGjggHRMIIBzTAfBgNVHSMEGDAWgBSJGAf/Pm0w\n" + + "F8k1rbuLcYbln2aSwzAdBgNVHQ4EFgQUeR5HZd44BvPIsRnNcBMDujfUZ9kwPgYD\n" + + "VR0gBDcwNTAzBgZngQwBBAEwKTAnBggrBgEFBQcCARYbaHR0cDovL3d3dy5kaWdp\n" + + "Y2VydC5jb20vQ1BTMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcD\n" + + "AzCBlQYDVR0fBIGNMIGKMEOgQaA/hj1odHRwOi8vY3JsMy5kaWdpY2VydC5jb20v\n" + + "RGlnaUNlcnRHNUNTUlNBNDA5NlNIQTM4NDIwMjFDQTEuY3JsMEOgQaA/hj1odHRw\n" + + "Oi8vY3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRHNUNTUlNBNDA5NlNIQTM4NDIw\n" + + "MjFDQTEuY3JsMIGCBggrBgEFBQcBAQR2MHQwJAYIKwYBBQUHMAGGGGh0dHA6Ly9v\n" + + "Y3NwLmRpZ2ljZXJ0LmNvbTBMBggrBgEFBQcwAoZAaHR0cDovL2NhY2VydHMuZGln\n" + + "aWNlcnQuY29tL0RpZ2lDZXJ0RzVDU1JTQTQwOTZTSEEzODQyMDIxQ0ExLmNydDAJ\n" + + "BgNVHRMEAjAAMA0GCSqGSIb3DQEBCwUAA4ICAQAKCH6ri6f507/j2ifF7VQbavWE\n" + + "Wn4T63PzJveL6/kedV7avhrQ/B6uHrez1xy/RH/MlL/B+TF6YTg+ILqtKR/PyJrg\n" + + "N+1RON0Eg3AEWWDtGl3KBYFlklz8Szo+xmXf5GYiqueejbxscH1BA0PU/5CgGkr6\n" + + "1Kk4OXqKqmpuPeQCxca1ARDD749E/2IFsDGC8kBCWepV62l0/xcDKWD5Zn+y4Tkh\n" + + "5+YJJ21D746sNDOsDNJ4DuqEYrXWUH6BlT5EDYelGqRCOdyTYUdDg+QcSFWnH7wR\n" + + "O+eIA3BLSw0x1Vh6DJRKm5H644sPVppaI1jVZDe+zBwp2e/j8XH7KDlp/WaRUhcU\n" + + "bjGg2Ss5TMbBjR6B4nMwjvqaCIFoAD6aFRYc80px/KY6KTSyOFF0FBQNuhSsUZQy\n" + + "p74aRjUraSu/RiJMA8A6OYGo1b7W9o/UOg0MB4WQkfwl+Mxh+58QKjLjZr9VVapW\n" + + "4yv0G/G6rT/pHrRiyBcT7Kt4xNFsmMFAN4BXL9WI9mkGDa4iwDmWVjIjAaiilaaC\n" + + "MIXwwm3eg/QBgWBUrwXf3YC+1HXkaFDZc5apQ5uaNJPjQo9nQ6xqfpnACXTJ/Lwm\n" + + "JBu4YlXPby5Vh6mWWSyVdbICrCD7BtGP8aSBPFGPEuPEjK32uyeoGWVwwSubVFPX\n" + + "ARhLX5oSFZUySvHgYg==\n" + + "-----END CERTIFICATE-----"; + + public void runTest(ValidatePathWithParams pathValidator) throws Exception { + // Validate valid + pathValidator.validate(new String[]{VALID, INT}, + ValidatePathWithParams.Status.GOOD, null, System.out); + + // Validate Revoked + pathValidator.validate(new String[]{REVOKED, INT}, + ValidatePathWithParams.Status.REVOKED, + "Mon Oct 23 14:44:23 PDT 2023", System.out); + } +} diff --git a/test/jdk/sun/management/jmxremote/RunTest.sh b/test/jdk/sun/management/jmxremote/RunTest.sh deleted file mode 100644 index e9a924a89b8..00000000000 --- a/test/jdk/sun/management/jmxremote/RunTest.sh +++ /dev/null @@ -1,33 +0,0 @@ -# -# Copyright (c) 2003, 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. -# - -# Execute the test. -# No need to compile (now done by JTReg tags in calling file) -# -echo ${TESTJAVA}/bin/java ${TESTVMOPTS} -Dtest.src=${TESTCLASSES} \ - -classpath ${TESTCLASSPATH} $* || exit 20 - -${TESTJAVA}/bin/java ${TESTVMOPTS} -Dtest.src=${TESTCLASSES} \ - -classpath ${TESTCLASSPATH} $* || exit 20 - -exit 0 diff --git a/test/jdk/sun/management/jmxremote/bootstrap/GeneratePropertyPassword.sh b/test/jdk/sun/management/jmxremote/bootstrap/GeneratePropertyPassword.sh deleted file mode 100644 index 98a20edc631..00000000000 --- a/test/jdk/sun/management/jmxremote/bootstrap/GeneratePropertyPassword.sh +++ /dev/null @@ -1,131 +0,0 @@ -# -# Copyright (c) 2003, 2020, 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 Shell Script for generating .properties files or .password files -# or .access files from a list of input .in files. -# -# Source in this GeneratePropertyPassword.sh and call the function -# generatePropertyPasswordFiles. -# Call restoreFilePermissions to restore file permissions after the test completes -# - - -OS=`uname -s` -UMASK=`umask` - -case $OS in -CYGWIN_NT*) - OS="Windows_NT" - if [ -z "$SystemRoot" ] ; then - SystemRoot=`cygpath $SYSTEMROOT` - fi -esac - -case $OS in -Linux | Darwin | AIX ) - PATHSEP=":" - FILESEP="/" - DFILESEP=$FILESEP - TMP_FILE=${TESTCLASSES}${FILESEP}${TESTCLASS}.sed.tmpfile - -cat < ${TMP_FILE} -s^@TEST-SRC@/^${TESTCLASSES}${DFILESEP}^g -EOF - ;; -Windows_95 | Windows_98 | Windows_NT | Windows_ME | CYGWIN*) - PATHSEP=";" - FILESEP="\\" - DFILESEP=$FILESEP$FILESEP - TMP_FILE=${TESTCLASSES}${FILESEP}${TESTCLASS}.sed.tmpfile - -cat < ${TMP_FILE}0 -s^@TEST-SRC@/^${TESTCLASSES}${DFILESEP}^g -EOF - # Need to put double backslash in the .properties files - cat ${TMP_FILE}0 | sed -e 's^\\\\^ZZZZ^g' | \ - sed -e 's^\\^ZZZZ^g' | \ - sed -e 's^ZZZZ^\\\\\\\\^g' > ${TMP_FILE} - - if [ "$OS" = "Windows_NT" ]; then - USER=`id -u -n` - CACLS="$SystemRoot/system32/cacls.exe" - REVOKEALL="$TESTNATIVEPATH/revokeall.exe" - if [ ! -x "$REVOKEALL" ] ; then - echo "$REVOKEALL doesn't exist or is not executable" - exit 1 - fi - fi - ;; -*) - echo "Unrecognized system! $OS" - exit 1 - ;; -esac - -generatePropertyPasswordFiles() -{ - for f in $@ - do - echo processing $f - suffix=`basename $f .in` - f2="${TESTCLASSES}${FILESEP}${suffix}" - - if [ -f "$f2" ] ; then - rm -f $f2 || echo WARNING: $f2 already exits - unable to remove old copy - fi - - echo creating $f2 - sed -f $TMP_FILE $f > $f2 - - if [ "$OS" = "Windows_NT" ]; then - chown $USER $f2 - # Grant this user full access - echo Y|$CACLS $f2 \/E \/G $USER:F - # Revoke everyone else - $REVOKEALL $f2 - # Display ACLs - $CACLS $f2 - else - chmod 600 $f2 - fi - done -} - -restoreFilePermissions() -{ - for f in $@ - do - suffix=`basename $f .in` - f2="${TESTCLASSES}${FILESEP}${suffix}" - - if [ "$OS" = "Windows_NT" ]; then - # Grant everyone full control - $CACLS $f2 \/E \/G Everyone:F - else - chmod 777 $f2 - fi - - done -} - diff --git a/test/jdk/sun/management/jmxremote/bootstrap/RmiBootstrapTest.java b/test/jdk/sun/management/jmxremote/bootstrap/RmiBootstrapTest.java index 6fe3dab6970..2c494a58c92 100644 --- a/test/jdk/sun/management/jmxremote/bootstrap/RmiBootstrapTest.java +++ b/test/jdk/sun/management/jmxremote/bootstrap/RmiBootstrapTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, 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 @@ -20,29 +20,57 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ + import sun.management.jmxremote.ConnectorBootstrap; import java.io.File; import java.io.FileInputStream; -import java.io.FilenameFilter; import java.io.IOException; import java.net.BindException; +import java.nio.file.Path; import java.rmi.server.ExportException; -import java.util.Properties; -import java.util.Iterator; -import java.util.Set; +import jdk.internal.agent.AgentConfigurationError; + +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanInfo; +import javax.management.MBeanServerConnection; +import javax.management.ObjectName; +import javax.management.QueryExp; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXConnectorServer; +import javax.management.remote.JMXServiceURL; +import java.security.Security; import java.util.ArrayList; +import java.util.Enumeration; import java.util.HashMap; +import java.util.List; import java.util.Map; -import java.util.Enumeration; - -import javax.management.remote.*; -import javax.management.*; +import java.util.Properties; +import java.util.Set; -import jdk.internal.agent.AgentConfigurationError; +/* + * @test + * @bug 6528083 + * @key intermittent + * @summary Test RMI Bootstrap + * + * @library /test/lib + * + * @run main/timeout=300 RmiBootstrapTest .*_test.*.in + * */ -import java.security.Security; +/* + * @test + * @bug 6528083 + * @key intermittent + * @summary Test RMI Bootstrap + * + * @library /test/lib + * + * @run main/timeout=300 RmiBootstrapTest .*_ssltest.*.in + * */ /** *

This class implements unit test for RMI Bootstrap. @@ -56,7 +84,7 @@ *

The rmi port number can be specified with the "rmi.port" system property. * If not, this test will use the first available port

* - *

When called with some argument, the main() will interprete its args to + *

When called with some argument, the main() will interpret its args to * be Java M&M configuration file names. The filenames are expected to end * with ok.properties or ko.properties - and are interpreted as above.

* @@ -68,160 +96,57 @@ * *

Debug traces are logged in "sun.management.test"

**/ -public class RmiBootstrapTest { +public class RmiBootstrapTest extends RmiTestBase { + static TestLogger log = new TestLogger("RmiBootstrapTest"); // the number of consecutive ports to test for availability private static int MAX_GET_FREE_PORT_TRIES = 10; - static TestLogger log = - new TestLogger("RmiBootstrapTest"); - - /** - * Default values for RMI configuration properties. - **/ - public static interface DefaultValues { - public static final String PORT="0"; - public static final String CONFIG_FILE_NAME="management.properties"; - public static final String USE_SSL="true"; - public static final String USE_AUTHENTICATION="true"; - public static final String PASSWORD_FILE_NAME="jmxremote.password"; - public static final String ACCESS_FILE_NAME="jmxremote.access"; - public static final String KEYSTORE="keystore"; - public static final String KEYSTORE_PASSWD="password"; - public static final String TRUSTSTORE="truststore"; - public static final String TRUSTSTORE_PASSWD="trustword"; - public static final String SSL_NEED_CLIENT_AUTH="false"; - } - - /** - * Names of RMI configuration properties. - **/ - public static interface PropertyNames { - public static final String PORT= - "com.sun.management.jmxremote.port"; - public static final String CONFIG_FILE_NAME= - "com.sun.management.config.file"; - public static final String USE_SSL= - "com.sun.management.jmxremote.ssl"; - public static final String USE_AUTHENTICATION= - "com.sun.management.jmxremote.authenticate"; - public static final String PASSWORD_FILE_NAME= - "com.sun.management.jmxremote.password.file"; - public static final String ACCESS_FILE_NAME= - "com.sun.management.jmxremote.access.file"; - public static final String INSTRUMENT_ALL= - "com.sun.management.instrumentall"; - public static final String CREDENTIALS = - "jmx.remote.credentials"; - public static final String KEYSTORE= - "javax.net.ssl.keyStore"; - public static final String KEYSTORE_PASSWD= - "javax.net.ssl.keyStorePassword"; - public static final String TRUSTSTORE= - "javax.net.ssl.trustStore"; - public static final String TRUSTSTORE_PASSWD= - "javax.net.ssl.trustStorePassword"; - public static final String SSL_ENABLED_CIPHER_SUITES = - "com.sun.management.jmxremote.ssl.enabled.cipher.suites"; - public static final String SSL_ENABLED_PROTOCOLS = - "com.sun.management.jmxremote.ssl.enabled.protocols"; - public static final String SSL_NEED_CLIENT_AUTH = - "com.sun.management.jmxremote.ssl.need.client.auth"; - public static final String SSL_CLIENT_ENABLED_CIPHER_SUITES = - "javax.rmi.ssl.client.enabledCipherSuites"; - } - - /** - * A filter to find all filenames who match *. - * Note that and can overlap. - **/ - private static class ConfigFilenameFilter implements FilenameFilter { - final String suffix; - final String prefix; - ConfigFilenameFilter(String prefix, String suffix) { - this.suffix=suffix; - this.prefix=prefix; - } - public boolean accept(File dir, String name) { - return (name.startsWith(prefix) && name.endsWith(suffix)); - } - } - - /** - * Get all "management*ok.properties" files in the directory - * indicated by the "test.src" management property. - **/ - private static File[] findConfigurationFilesOk() { - final String testSrc = System.getProperty("test.src"); - final File dir = new File(testSrc); - final FilenameFilter filter = - new ConfigFilenameFilter("management_test","ok.properties"); - return dir.listFiles(filter); - } - - /** - * Get all "management*ko.properties" files in the directory - * indicated by the "test.src" management property. - **/ - private static File[] findConfigurationFilesKo() { - final String testSrc = System.getProperty("test.src"); - final File dir = new File(testSrc); - final FilenameFilter filter = - new ConfigFilenameFilter("management_test","ko.properties"); - return dir.listFiles(filter); - } /** * List all MBeans and their attributes. Used to test communication * with the Java M&M MBean Server. + * * @return the number of queried MBeans. */ - public static int listMBeans(MBeanServerConnection server) - throws IOException { - return listMBeans(server,null,null); + public static int listMBeans(MBeanServerConnection server) throws IOException { + return listMBeans(server, null, null); } /** * List all matching MBeans and their attributes. * Used to test communication with the Java M&M MBean Server. + * * @return the number of matching MBeans. */ - public static int listMBeans(MBeanServerConnection server, - ObjectName pattern, QueryExp query) - throws IOException { - - final Set names = server.queryNames(pattern,query); - for (final Iterator i=names.iterator(); i.hasNext(); ) { - ObjectName name = (ObjectName)i.next(); - log.trace("listMBeans","Got MBean: "+name); + public static int listMBeans(MBeanServerConnection server, ObjectName pattern, QueryExp query) + throws IOException { + + final Set names = server.queryNames(pattern, query); + for (ObjectName name : names) { + log.trace("listMBeans", "Got MBean: " + name); try { - MBeanInfo info = - server.getMBeanInfo((ObjectName)name); + MBeanInfo info = server.getMBeanInfo(name); MBeanAttributeInfo[] attrs = info.getAttributes(); - if (attrs == null) continue; - for (int j=0; j credentialFiles = prepareTestFiles(args[0]); + Security.setProperty("jdk.tls.disabledAlgorithms", ""); + + try { + MAX_GET_FREE_PORT_TRIES = Integer.parseInt(System.getProperty("test.getfreeport.max.tries", "10")); + } catch (NumberFormatException ex) { + } + + RmiBootstrapTest manager = new RmiBootstrapTest(); + try { + manager.run(args); + } catch (RuntimeException r) { + System.out.println("Test Failed: " + r.getMessage()); + System.exit(1); + } catch (Throwable t) { + System.out.println("Test Failed: " + t); + t.printStackTrace(); + System.exit(2); + } + System.out.println("**** Test RmiBootstrap Passed ****"); + + grantFilesAccess(credentialFiles, AccessControl.EVERYONE); + } /** * Parses the password file to read the credentials. @@ -266,158 +195,151 @@ private static String getDefaultStoreName(String basename) { * If the password file does not exists, return an empty list. * (File not found = empty file). **/ - private ArrayList readCredentials(String passwordFileName) - throws IOException { + private ArrayList readCredentials(String passwordFileName) throws IOException { final Properties pws = new Properties(); - final ArrayList result = new ArrayList(); + final ArrayList result = new ArrayList(); final File f = new File(passwordFileName); - if (!f.exists()) return result; - FileInputStream fin = new FileInputStream(passwordFileName); - try {pws.load(fin);}finally{fin.close();} - for (Enumeration en=pws.propertyNames();en.hasMoreElements();) { + if (!f.exists()) { + return result; + } + try (FileInputStream fin = new FileInputStream(passwordFileName)){ + pws.load(fin); + } catch (IOException e) { + } + for (Enumeration en = pws.propertyNames(); en.hasMoreElements(); ) { final String[] cred = new String[2]; - cred[0]=(String)en.nextElement(); - cred[1]=pws.getProperty(cred[0]); + cred[0] = (String) en.nextElement(); + cred[1] = pws.getProperty(cred[0]); result.add(cred); } return result; } - /** * Connect with the given url, using all given credentials in turn. * A null entry in the useCredentials arrays indicate a connection * where no credentials are used. - * @param url JMXServiceURL of the server. - * @param useCredentials An array of credentials (a credential - * is a two String array, so this is an array of arrays - * of strings: - * useCredentials[i][0]=subject - * useCredentials[i][1]=password - * if useCredentials[i] == null means no credentials. + * + * @param url JMXServiceURL of the server. + * @param useCredentials An array of credentials (a credential + * is a two String array, so this is an array of + * arrays + * of strings: + * useCredentials[i][0]=subject + * useCredentials[i][1]=password + * if useCredentials[i] == null means no credentials. * @param expectConnectOk true if connection is expected to succeed - * Note: if expectConnectOk=false and the test fails to connect - * the number of failure is not incremented. Conversely, - * if expectConnectOk=false and the test does not fail to - * connect the number of failure is incremented. - * @param expectReadOk true if communication (listMBeans) is expected - * to succeed. - * Note: if expectReadOk=false and the test fails to read MBeans - * the number of failure is not incremented. Conversely, - * if expectReadOk=false and the test does not fail to - * read MBeans the number of failure is incremented. + * Note: if expectConnectOk=false and the test + * fails to connect + * the number of failure is not incremented. + * Conversely, + * if expectConnectOk=false and the test does not + * fail to + * connect the number of failure is incremented. + * @param expectReadOk true if communication (listMBeans) is expected + * to succeed. + * Note: if expectReadOk=false and the test fails + * to read MBeans + * the number of failure is not incremented. + * Conversely, + * if expectReadOk=false and the test does not + * fail to + * read MBeans the number of failure is incremented. * @return number of failure. **/ - public int connectAndRead(JMXServiceURL url, - Object[] useCredentials, - boolean expectConnectOk, - boolean expectReadOk) - throws IOException { + public int connectAndRead(JMXServiceURL url, Object[] useCredentials, + boolean expectConnectOk, boolean expectReadOk) + throws IOException { int errorCount = 0; - for (int i=0 ; i * This method calls connectAndRead(). **/ - public void testCommunication(JMXServiceURL url) - throws IOException { + public void testCommunication(JMXServiceURL url) throws IOException { - final String defaultConf = - getDefaultFileName(DefaultValues.CONFIG_FILE_NAME); - final String confname = - System.getProperty(PropertyNames.CONFIG_FILE_NAME,defaultConf); + final String defaultConf = defaultFileNamePrefix + DefaultValues.CONFIG_FILE_NAME; + final String confname = System.getProperty(PropertyNames.CONFIG_FILE_NAME, defaultConf); final Properties props = new Properties(); final File conf = new File(confname); if (conf.exists()) { FileInputStream fin = new FileInputStream(conf); - try {props.load(fin);} finally {fin.close();} + try { + props.load(fin); + } finally { + fin.close(); + } } // Do we use authentication? - final String useAuthenticationStr = - props.getProperty(PropertyNames.USE_AUTHENTICATION, - DefaultValues.USE_AUTHENTICATION); - final boolean useAuthentication = - Boolean.valueOf(useAuthenticationStr).booleanValue(); + final String useAuthenticationStr = + props.getProperty(PropertyNames.USE_AUTHENTICATION, DefaultValues.USE_AUTHENTICATION); + final boolean useAuthentication = Boolean.valueOf(useAuthenticationStr).booleanValue(); // Get Password File - final String defaultPasswordFileName = Utils.convertPath( - getDefaultFileName(DefaultValues.PASSWORD_FILE_NAME)); - final String passwordFileName = Utils.convertPath( - props.getProperty(PropertyNames.PASSWORD_FILE_NAME, - defaultPasswordFileName)); + final String defaultPasswordFileName = + Utils.convertPath(defaultFileNamePrefix + DefaultValues.PASSWORD_FILE_NAME); + final String passwordFileName = + Utils.convertPath(props.getProperty(PropertyNames.PASSWORD_FILE_NAME, defaultPasswordFileName)); // Get Access File - final String defaultAccessFileName = Utils.convertPath( - getDefaultFileName(DefaultValues.ACCESS_FILE_NAME)); - final String accessFileName = Utils.convertPath( - props.getProperty(PropertyNames.ACCESS_FILE_NAME, - defaultAccessFileName)); + final String defaultAccessFileName = Utils.convertPath(defaultFileNamePrefix + DefaultValues.ACCESS_FILE_NAME); + final String accessFileName = + Utils.convertPath(props.getProperty(PropertyNames.ACCESS_FILE_NAME, defaultAccessFileName)); if (useAuthentication) { System.out.println("PasswordFileName: " + passwordFileName); @@ -580,55 +471,52 @@ public void testCommunication(JMXServiceURL url) } final Object[] allCredentials; - final Object[] noCredentials = { null }; + final Object[] noCredentials = {null}; if (useAuthentication) { final ArrayList l = readCredentials(passwordFileName); - if (l.size() == 0) allCredentials = null; - else allCredentials = l.toArray(); - } else allCredentials = noCredentials; + if (l.size() == 0) { + allCredentials = null; + } else { + allCredentials = l.toArray(); + } + } else { + allCredentials = noCredentials; + } int errorCount = 0; - if (allCredentials!=null) { + if (allCredentials != null) { // Tests that the registered user/passwords are allowed to // connect & read // - errorCount += connectAndRead(url,allCredentials,true,true); + errorCount += connectAndRead(url, allCredentials, true, true); } else { // Tests that no one is allowed // connect & read // - final String[][] someCredentials = { - null, - { "modify", "R&D" }, - { "measure", "QED" } - }; - errorCount += connectAndRead(url,someCredentials,false,false); + final String[][] someCredentials = {null, {"modify", "R&D"}, {"measure", "QED"}}; + errorCount += connectAndRead(url, someCredentials, false, false); } if (useAuthentication && allCredentials != noCredentials) { // Tests that the registered user/passwords are not allowed to // connect & read // - final String[][] badCredentials = { - { "bad.user", "R&D" }, - { "measure", "bad.password" } - }; - errorCount += connectAndRead(url,badCredentials,false,false); + final String[][] badCredentials = {{"bad.user", "R&D"}, {"measure", "bad.password"}}; + errorCount += connectAndRead(url, badCredentials, false, false); } if (errorCount > 0) { - final String err = "Test " + confname + " failed with " + - errorCount + " error(s)"; - log.debug("testCommunication",err); + final String err = "Test " + confname + " failed with " + errorCount + " error(s)"; + log.debug("testCommunication", err); throw new RuntimeException(err); } } - /** * Test the configuration indicated by `file'. * Sets the appropriate System properties for config file and * port and then calls ConnectorBootstrap.initialize(). * eventually cleans up by calling ConnectorBootstrap.terminate(). + * * @return null if the test succeeds, an error message otherwise. **/ private String testConfiguration(File file) throws IOException, InterruptedException { @@ -638,32 +526,30 @@ private String testConfiguration(File file) throws IOException, InterruptedExcep int port = jdk.test.lib.Utils.getFreePort(); final String path; try { - path=(file==null)?null:file.getCanonicalPath(); - } catch(IOException x) { - final String err = "Failed to test configuration " + file + - ": " + x; - log.trace("testConfiguration",err); - log.debug("testConfiguration",x); + path = (file == null) ? null : file.getCanonicalPath(); + } catch (IOException x) { + final String err = "Failed to test configuration " + file + ": " + x; + log.trace("testConfiguration", err); + log.debug("testConfiguration", x); return err; } - final String config = (path==null)?"Default config file":path; + final String config = (path == null) ? "Default config file" : path; System.out.println("***"); - System.out.println("*** Testing configuration (port=" + port + "): " - + path); + System.out.println("*** Testing configuration (port=" + port + "): " + path); System.out.println("***"); - System.setProperty("com.sun.management.jmxremote.port", - Integer.toString(port)); - if (path != null) + System.setProperty("com.sun.management.jmxremote.port", Integer.toString(port)); + if (path != null) { System.setProperty("com.sun.management.config.file", path); - else + } else { System.getProperties().remove("com.sun.management.config.file"); + } - log.trace("testConfiguration","com.sun.management.jmxremote.port="+port); - if (path != null && log.isDebugOn()) - log.trace("testConfiguration", - "com.sun.management.config.file="+path); + log.trace("testConfiguration", "com.sun.management.jmxremote.port=" + port); + if (path != null && log.isDebugOn()) { + log.trace("testConfiguration", "com.sun.management.config.file=" + path); + } checkSslConfiguration(); @@ -673,54 +559,49 @@ private String testConfiguration(File file) throws IOException, InterruptedExcep } catch (AgentConfigurationError x) { if (x.getCause() instanceof ExportException) { if (x.getCause().getCause() instanceof BindException) { - throw (BindException)x.getCause().getCause(); + throw (BindException) x.getCause().getCause(); } } - final String err = "Failed to initialize connector:" + - "\n\tcom.sun.management.jmxremote.port=" + port + - ((path!=null)?"\n\tcom.sun.management.config.file="+path: - "\n\t"+config) + - "\n\tError is: " + x; - log.trace("testConfiguration",err); - log.debug("testConfiguration",x); + final String err = + "Failed to initialize connector:" + "\n\tcom.sun.management.jmxremote.port=" + port + + ((path != null) ? "\n\tcom.sun.management.config.file=" + path : "\n\t" + config) + + "\n\tError is: " + x; + log.trace("testConfiguration", err); + log.debug("testConfiguration", x); return err; } catch (Exception x) { - log.debug("testConfiguration",x); + log.debug("testConfiguration", x); return x.toString(); } try { - JMXServiceURL url = - new JMXServiceURL("rmi",null,0,"/jndi/rmi://localhost:"+ - port+"/jmxrmi"); + JMXServiceURL url = new JMXServiceURL("rmi", null, 0, "/jndi/rmi://localhost:" + port + "/jmxrmi"); try { testCommunication(url); } catch (Exception x) { - final String err = "Failed to connect to agent {url="+url+ - "}: " + x; - log.trace("testConfiguration",err); - log.debug("testConfiguration",x); + final String err = "Failed to connect to agent {url=" + url + "}: " + x; + log.trace("testConfiguration", err); + log.debug("testConfiguration", x); return err; } } catch (Exception x) { - final String err = "Failed to test configuration "+config+ - ": "+x; - log.trace("testConfiguration",err); - log.debug("testConfiguration",x); + final String err = "Failed to test configuration " + config + ": " + x; + log.trace("testConfiguration", err); + log.debug("testConfiguration", x); return err; } finally { try { cs.stop(); } catch (Exception x) { - final String err = "Failed to terminate: "+x; - log.trace("testConfiguration",err); - log.debug("testConfiguration",x); + final String err = "Failed to terminate: " + x; + log.trace("testConfiguration", err); + log.debug("testConfiguration", x); } } System.out.println("Configuration " + config + " successfully tested"); return null; - } catch(BindException ex) { + } catch (BindException ex) { } } System.err.println("Cannot find a free port after " + MAX_GET_FREE_PORT_TRIES + " tries"); @@ -730,17 +611,15 @@ private String testConfiguration(File file) throws IOException, InterruptedExcep /** * Test a configuration file which should make the bootstrap fail. * The test is assumed to have succeeded if the bootstrap fails. + * * @return null if the test succeeds, an error message otherwise. **/ private String testConfigurationKo(File conf) throws InterruptedException, IOException { - String errStr = null; - errStr = testConfiguration(conf); + String errStr = testConfiguration(conf); if (errStr == null) { - return "Configuration " + - conf + " should have failed!"; + return "Configuration " + conf + " should have failed!"; } - System.out.println("Configuration " + - conf + " failed as expected"); + System.out.println("Configuration " + conf + " failed as expected"); log.debug("runko", "Error was: " + errStr); return null; } @@ -748,8 +627,9 @@ private String testConfigurationKo(File conf) throws InterruptedException, IOExc /** * Test a configuration file. Determines whether the bootstrap * should succeed or fail depending on the file name: - * *ok.properties: bootstrap should succeed. - * *ko.properties: bootstrap or connection should fail. + * *ok.properties: bootstrap should succeed. + * *ko.properties: bootstrap or connection should fail. + * * @return null if the test succeeds, an error message otherwise. **/ private String testConfigurationFile(String fileName) throws InterruptedException, IOException { @@ -763,22 +643,23 @@ private String testConfigurationFile(String fileName) throws InterruptedExceptio if (fileName.endsWith("ko.properties")) { return testConfigurationKo(file); } - return fileName + - ": test file suffix must be one of [ko|ok].properties"; + return fileName + ": test file suffix must be one of [ko|ok].properties"; } /** * Find all *ko.property files and test them. * (see findConfigurationFilesKo() and testConfigurationKo()) + * * @throws RuntimeException if the test fails. **/ - public void runko() throws InterruptedException, IOException { - final File[] conf = findConfigurationFilesKo(); - if ((conf == null)||(conf.length == 0)) + public void runko(boolean useSsl) throws InterruptedException, IOException { + final File[] conf = RmiTestBase.findConfigurationFilesKo(useSsl); + if ((conf == null) || (conf.length == 0)) { throw new RuntimeException("No configuration found"); + } String errStr; - for (int i=0;iThis class implements unit test for RMI Bootstrap. * When called with no arguments main() looks in the directory indicated @@ -69,163 +75,113 @@ * *

Debug traces are logged in "sun.management.test"

**/ -public class RmiSslNoKeyStoreTest { - - static TestLogger log = - new TestLogger("RmiSslNoKeyStoreTest"); +public class RmiSslNoKeyStoreTest extends RmiTestBase { + static TestLogger log = new TestLogger("RmiSslNoKeyStoreTest"); /** * When launching several registries, we increment the port number * to avoid falling into "port number already in use" problems. **/ static int testPort = 0; + final String DEFAULT_KEY_STORE = defaultStoreNamePrefix + DefaultValues.KEYSTORE; + final String KEY_STORE = System.getProperty(PropertyNames.KEYSTORE, DEFAULT_KEY_STORE); - /** - * Default values for RMI configuration properties. - **/ - public static interface DefaultValues { - public static final String PORT="0"; - public static final String CONFIG_FILE_NAME="management.properties"; - public static final String USE_SSL="true"; - public static final String USE_AUTHENTICATION="true"; - public static final String PASSWORD_FILE_NAME="jmxremote.password"; - public static final String ACCESS_FILE_NAME="jmxremote.access"; - public static final String KEYSTORE="keystore"; - public static final String KEYSTORE_PASSWD="password"; - public static final String TRUSTSTORE="truststore"; - public static final String TRUSTSTORE_PASSWD="trustword"; - } - - /** - * Names of RMI configuration properties. - **/ - public static interface PropertyNames { - public static final String PORT="com.sun.management.jmxremote.port"; - public static final String CONFIG_FILE_NAME= - "com.sun.management.config.file"; - public static final String USE_SSL="com.sun.management.jmxremote.ssl"; - public static final String USE_AUTHENTICATION= - "com.sun.management.jmxremote.authenticate"; - public static final String PASSWORD_FILE_NAME= - "com.sun.management.jmxremote.password.file"; - public static final String ACCESS_FILE_NAME= - "com.sun.management.jmxremote.access.file"; - public static final String INSTRUMENT_ALL= - "com.sun.management.instrumentall"; - public static final String CREDENTIALS = - "jmx.remote.credentials"; - public static final String KEYSTORE="javax.net.ssl.keyStore"; - public static final String KEYSTORE_PASSWD= - "javax.net.ssl.keyStorePassword"; - public static final String KEYSTORE_TYPE="javax.net.ssl.keyStoreType"; - public static final String TRUSTSTORE="javax.net.ssl.trustStore"; - public static final String TRUSTSTORE_PASSWD= - "javax.net.ssl.trustStorePassword"; - } - - /** - * Compute the full path name for a default file. - * @param basename basename (with extension) of the default file. - * @return ${JRE}/conf/management/${basename} - **/ - private static String getDefaultFileName(String basename) { - final String fileSeparator = File.separator; - final StringBuffer defaultFileName = - new StringBuffer(System.getProperty("java.home")). - append(fileSeparator).append("conf").append(fileSeparator). - append("management").append(fileSeparator). - append(basename); - return defaultFileName.toString(); - } + private static void checkKeystore(Properties props) + throws IOException, GeneralSecurityException { + if (log.isDebugOn()) { + log.debug("checkKeystore", "Checking Keystore configuration"); + } - /** - * Compute the full path name for a default file. - * @param basename basename (with extension) of the default file. - * @return ${JRE}/conf/management/${basename} - **/ - private static String getDefaultStoreName(String basename) { - final String fileSeparator = File.separator; - final StringBuffer defaultFileName = - new StringBuffer(System.getProperty("test.src")). - append(fileSeparator).append("ssl").append(fileSeparator). - append(basename); - return defaultFileName.toString(); - } + final String keyStore = System.getProperty(PropertyNames.KEYSTORE); + if (keyStore == null) { + throw new IllegalArgumentException("System property " + PropertyNames.KEYSTORE + " not specified"); + } - private static void checkKeystore(Properties props) - throws IOException, GeneralSecurityException { - if (log.isDebugOn()) - log.debug("checkKeystore","Checking Keystore configuration"); - - final String keyStore = - System.getProperty(PropertyNames.KEYSTORE); - if (keyStore == null) - throw new IllegalArgumentException("System property " + - PropertyNames.KEYSTORE + - " not specified"); - - final String keyStorePass = - System.getProperty(PropertyNames.KEYSTORE_PASSWD); + final String keyStorePass = System.getProperty(PropertyNames.KEYSTORE_PASSWD); if (keyStorePass == null) { // We don't have the password, we can only check whether the // file exists... // final File ksf = new File(keyStore); - if (! ksf.canRead()) + if (!ksf.canRead()) { throw new IOException(keyStore + ": not readable"); + } - if (log.isDebugOn()) + if (log.isDebugOn()) { log.debug("checkSSL", "No password."); - throw new IllegalArgumentException("System property " + - PropertyNames.KEYSTORE_PASSWD + - " not specified"); + } + throw new IllegalArgumentException("System property " + PropertyNames.KEYSTORE_PASSWD + " not specified"); } // Now we're going to load the keyStore - just to check it's // correct. // - final String keyStoreType = - System.getProperty(PropertyNames.KEYSTORE_TYPE, - KeyStore.getDefaultType()); - final KeyStore ks = KeyStore.getInstance(keyStoreType); + final String keyStoreType = System.getProperty(PropertyNames.KEYSTORE_TYPE, KeyStore.getDefaultType()); + final KeyStore ks = KeyStore.getInstance(keyStoreType); final FileInputStream fin = new FileInputStream(keyStore); - final char keypassword[] = keyStorePass.toCharArray(); + final char keypassword[] = keyStorePass.toCharArray(); try { - ks.load(fin,keypassword); + ks.load(fin, keypassword); } finally { - Arrays.fill(keypassword,' '); + Arrays.fill(keypassword, ' '); fin.close(); } - if (log.isDebugOn()) - log.debug("checkSSL","SSL configuration successfully checked"); + if (log.isDebugOn()) { + log.debug("checkSSL", "SSL configuration successfully checked"); + } + } + + /** + * Calls run(args[]). + * exit(1) if the test fails. + **/ + public static void main(String args[]) throws Exception { + if (args.length == 0) { + throw new IllegalArgumentException("Argument is required for this" + " test"); + } + + final List credentialFiles = prepareTestFiles(args[0]); + + RmiSslNoKeyStoreTest manager = new RmiSslNoKeyStoreTest(); + try { + manager.run(args); + } catch (RuntimeException r) { + System.err.println("Test Failed: " + r.getMessage()); + System.exit(1); + } catch (Throwable t) { + System.err.println("Test Failed: " + t); + t.printStackTrace(); + System.exit(2); + } + System.out.println("**** Test RmiSslNoKeyStoreTest Passed ****"); + + grantFilesAccess(credentialFiles, AccessControl.EVERYONE); } private void checkSslConfiguration() throws Exception { - final String defaultConf = - getDefaultFileName(DefaultValues.CONFIG_FILE_NAME); - final String confname = - System.getProperty(PropertyNames.CONFIG_FILE_NAME,defaultConf); + final String defaultConf = defaultFileNamePrefix + DefaultValues.CONFIG_FILE_NAME; + final String confname = System.getProperty(PropertyNames.CONFIG_FILE_NAME, defaultConf); final Properties props = new Properties(); final File conf = new File(confname); if (conf.exists()) { FileInputStream fin = new FileInputStream(conf); - try {props.load(fin);} finally {fin.close();} + try { + props.load(fin); + } finally { + fin.close(); + } } // Do we use SSL? - final String useSslStr = - props.getProperty(PropertyNames.USE_SSL, - DefaultValues.USE_SSL); - final boolean useSsl = - Boolean.valueOf(useSslStr).booleanValue(); + final String useSslStr = props.getProperty(PropertyNames.USE_SSL, DefaultValues.USE_SSL); + final boolean useSsl = Boolean.valueOf(useSslStr).booleanValue(); - log.debug("checkSslConfiguration",PropertyNames.USE_SSL+"="+useSsl); + log.debug("checkSslConfiguration", PropertyNames.USE_SSL + "=" + useSsl); if (useSsl == false) { - final String msg = - PropertyNames.USE_SSL+"="+useSsl+", can't run test"; + final String msg = PropertyNames.USE_SSL + "=" + useSsl + ", can't run test"; throw new IllegalArgumentException(msg); } @@ -233,7 +189,7 @@ private void checkSslConfiguration() throws Exception { checkKeystore(props); } catch (Exception x) { // Ok! - log.debug("checkSslConfiguration","Test configuration OK: " + x); + log.debug("checkSslConfiguration", "Test configuration OK: " + x); return; } @@ -246,31 +202,30 @@ private void checkSslConfiguration() throws Exception { * Sets the appropriate System properties for config file and * port and then calls ConnectorBootstrap.initialize(). * eventually cleans up by calling ConnectorBootstrap.terminate(). + * * @return null if the test succeeds, an error message otherwise. **/ - private String testConfiguration(File file,int port) { + private String testConfiguration(File file, int port) { - final String path = (file==null)?null:file.getAbsolutePath(); - final String config = (path==null)?"Default config file":path; + final String path = (file == null) ? null : file.getAbsolutePath(); + final String config = (path == null) ? "Default config file" : path; try { System.out.println("***"); - System.out.println("*** Testing configuration (port="+ - port + "): "+ path); + System.out.println("*** Testing configuration (port=" + port + "): " + path); System.out.println("***"); - System.setProperty("com.sun.management.jmxremote.port", - Integer.toString(port)); - if (path != null) + System.setProperty("com.sun.management.jmxremote.port", Integer.toString(port)); + if (path != null) { System.setProperty("com.sun.management.config.file", path); - else - System.getProperties(). - remove("com.sun.management.config.file"); + } else { + System.getProperties().remove("com.sun.management.config.file"); + } - log.trace("testConfiguration","com.sun.management.jmxremote.port="+port); - if (path != null && log.isDebugOn()) - log.trace("testConfiguration", - "com.sun.management.config.file="+path); + log.trace("testConfiguration", "com.sun.management.jmxremote.port=" + port); + if (path != null && log.isDebugOn()) { + log.trace("testConfiguration", "com.sun.management.config.file=" + path); + } checkSslConfiguration(); @@ -278,61 +233,52 @@ private String testConfiguration(File file,int port) { try { cs = ConnectorBootstrap.initialize(); } catch (AgentConfigurationError x) { - final String err = "Failed to initialize connector:" + - "\n\tcom.sun.management.jmxremote.port=" + port + - ((path!=null)?"\n\tcom.sun.management.config.file="+path: - "\n\t"+config) + - "\n\tError is: " + x; + final String err = "Failed to initialize connector:" + "\n\tcom.sun.management.jmxremote.port=" + port + + ((path != null) ? "\n\tcom.sun.management.config.file=" + path : "\n\t" + config) + + "\n\tError is: " + x; - log.trace("testConfiguration","Expected failure: " + err); - log.debug("testConfiguration",x); + log.trace("testConfiguration", "Expected failure: " + err); + log.debug("testConfiguration", x); System.out.println("Got expected failure: " + x); return null; } catch (Exception x) { - log.debug("testConfiguration",x); + log.debug("testConfiguration", x); return x.toString(); } try { - JMXConnector cc = - JMXConnectorFactory.connect(cs.getAddress(), null); + JMXConnector cc = JMXConnectorFactory.connect(cs.getAddress(), null); cc.close(); } catch (IOException x) { - final String err = "Failed to initialize connector:" + - "\n\tcom.sun.management.jmxremote.port=" + port + - ((path!=null)?"\n\tcom.sun.management.config.file="+path: - "\n\t"+config) + - "\n\tError is: " + x; + final String err = "Failed to initialize connector:" + "\n\tcom.sun.management.jmxremote.port=" + port + + ((path != null) ? "\n\tcom.sun.management.config.file=" + path : "\n\t" + config) + + "\n\tError is: " + x; - log.trace("testConfiguration","Expected failure: " + err); - log.debug("testConfiguration",x); + log.trace("testConfiguration", "Expected failure: " + err); + log.debug("testConfiguration", x); System.out.println("Got expected failure: " + x); return null; } catch (Exception x) { - log.debug("testConfiguration",x); + log.debug("testConfiguration", x); return x.toString(); } try { cs.stop(); } catch (Exception x) { - final String err = "Failed to terminate: "+x; - log.trace("testConfiguration",err); - log.debug("testConfiguration",x); + final String err = "Failed to terminate: " + x; + log.trace("testConfiguration", err); + log.debug("testConfiguration", x); } - final String err = "Bootstrap should have failed:" + - "\n\tcom.sun.management.jmxremote.port=" + port + - ((path!=null)?"\n\tcom.sun.management.config.file="+path: - "\n\t"+config); - log.trace("testConfiguration",err); + final String err = "Bootstrap should have failed:" + "\n\tcom.sun.management.jmxremote.port=" + port + + ((path != null) ? "\n\tcom.sun.management.config.file=" + path : "\n\t" + config); + log.trace("testConfiguration", err); return err; } catch (Exception x) { - final String err = "Failed to test bootstrap for:" + - "\n\tcom.sun.management.jmxremote.port=" + port + - ((path!=null)?"\n\tcom.sun.management.config.file="+path: - "\n\t"+config)+ - "\n\tError is: " + x; - - log.trace("testConfiguration",err); - log.debug("testConfiguration",x); + final String err = "Failed to test bootstrap for:" + "\n\tcom.sun.management.jmxremote.port=" + port + + ((path != null) ? "\n\tcom.sun.management.config.file=" + path : "\n\t" + config) + + "\n\tError is: " + x; + + log.trace("testConfiguration", err); + log.debug("testConfiguration", x); return err; } } @@ -340,79 +286,82 @@ private String testConfiguration(File file,int port) { /** * Test a configuration file. Determines whether the bootstrap * should succeed or fail depending on the file name: - * *ok.properties: bootstrap should succeed. - * *ko.properties: bootstrap or connection should fail. + * *ok.properties: bootstrap should succeed. + * *ko.properties: bootstrap or connection should fail. + * * @return null if the test succeeds, an error message otherwise. **/ private String testConfigurationFile(String fileName) { File file = new File(fileName); - final String portStr = System.getProperty("rmi.port","12424"); - final int port = Integer.parseInt(portStr); + final String portStr = System.getProperty("rmi.port", "12424"); + final int port = Integer.parseInt(portStr); - return testConfiguration(file,port+testPort++); + return testConfiguration(file, port + testPort++); } - /** - * Tests the specified configuration files. - * If args[] is not empty, each element in args[] is expected to be - * a filename ending either by ok.properties or ko.properties. - * Otherwise, the configuration files will be automatically determined - * by looking at all *.properties files located in the directory - * indicated by the System property "test.src". - * @throws RuntimeException if the test fails. + * Test a configuration file. **/ - public void run(String args[]) { - final String defaultKeyStore = - getDefaultStoreName(DefaultValues.KEYSTORE); - final String keyStore = - System.getProperty(PropertyNames.KEYSTORE, defaultKeyStore); + private void runConfigurationFile(String fileName) { + String errStr = testConfigurationFile(fileName); + if (errStr != null) { + throw new RuntimeException(errStr); + } - for (int i=0; i*. + * Note that and can overlap. + **/ + static class FilenameFilterFactory { + static FilenameFilter prefixSuffix(final String p, final String s) { + return (dir, name) -> name.startsWith(p) && name.endsWith(s); + } + } + + enum AccessControl { + OWNER, + EVERYONE, + } + + /** + * Default values for RMI configuration properties. + **/ + public interface DefaultValues { + String PORT = "0"; + String CONFIG_FILE_NAME = "management.properties"; + String USE_SSL = "true"; + String USE_AUTHENTICATION = "true"; + String PASSWORD_FILE_NAME = "jmxremote.password"; + String ACCESS_FILE_NAME = "jmxremote.access"; + String KEYSTORE = "keystore"; + String KEYSTORE_PASSWD = "password"; + String TRUSTSTORE = "truststore"; + String TRUSTSTORE_PASSWD = "trustword"; + String SSL_NEED_CLIENT_AUTH = "false"; + } + + /** + * Names of RMI configuration properties. + **/ + public interface PropertyNames { + String PORT = "com.sun.management.jmxremote.port"; + String CONFIG_FILE_NAME = "com.sun.management.config.file"; + String USE_SSL = "com.sun.management.jmxremote.ssl"; + String USE_AUTHENTICATION = "com.sun.management.jmxremote.authenticate"; + String PASSWORD_FILE_NAME = "com.sun.management.jmxremote.password.file"; + String ACCESS_FILE_NAME = "com.sun.management.jmxremote.access.file"; + String INSTRUMENT_ALL = "com.sun.management.instrumentall"; + String CREDENTIALS = "jmx.remote.credentials"; + String KEYSTORE = "javax.net.ssl.keyStore"; + String KEYSTORE_PASSWD = "javax.net.ssl.keyStorePassword"; + String KEYSTORE_TYPE = "javax.net.ssl.keyStoreType"; + String TRUSTSTORE = "javax.net.ssl.trustStore"; + String TRUSTSTORE_PASSWD = "javax.net.ssl.trustStorePassword"; + String SSL_ENABLED_CIPHER_SUITES = "com.sun.management.jmxremote.ssl.enabled.cipher.suites"; + String SSL_ENABLED_PROTOCOLS = "com.sun.management.jmxremote.ssl.enabled.protocols"; + String SSL_NEED_CLIENT_AUTH = "com.sun.management.jmxremote.ssl.need.client.auth"; + String SSL_CLIENT_ENABLED_CIPHER_SUITES = "javax.rmi.ssl.client.enabledCipherSuites"; + } + + /** + * Copy test artifacts to test folder. + * + * @param filenamePattern the filename pattern to look for + * @return files who match the filename pattern + * @throws IOException if error occurs + */ + static List prepareTestFiles(String filenamePattern) throws IOException { + copySsl(); + List files = Utils.findFiles(Paths.get(SRC), (dir, name) -> name.matches(filenamePattern)); + + final Function removeSuffix = (s) -> s.substring(0, s.lastIndexOf(".")); + + List propertyFiles = + Utils.copyFiles(files, Paths.get(DEST), removeSuffix, StandardCopyOption.REPLACE_EXISTING); + + // replace @TEST-SRC@ with the path of the current test folder + if (Platform.isWindows()) { + // On Windows, also replace forward slash or single backslash to double backslashes + Utils.replaceFilesString(propertyFiles, + (s) -> s.replace(TEST_SRC, DEST).replaceAll("[/\\\\]", "\\\\\\\\")); + } else { + Utils.replaceFilesString(propertyFiles, (s) -> s.replace(TEST_SRC, DEST)); + } + + grantFilesAccess(propertyFiles, AccessControl.OWNER); + + return Collections.unmodifiableList(files); + } + + /** + * Grant file access. + * + * @param file file to grant access + * @param access user access or full access + * @throws IOException if error occurs + */ + static void grantAccess(Path file, AccessControl access) throws IOException { + Set attr = file.getFileSystem().supportedFileAttributeViews(); + if (attr.contains("posix")) { + String perms = access == AccessControl.OWNER ? "rw-------" : "rwxrwxrwx"; + Files.setPosixFilePermissions(file, PosixFilePermissions.fromString(perms)); + } else if (attr.contains("acl")) { + AclFileAttributeView view = Files.getFileAttributeView(file, AclFileAttributeView.class); + List acl = new ArrayList<>(); + for (AclEntry thisEntry : view.getAcl()) { + if (access == AccessControl.OWNER) { + if (thisEntry.principal().getName().equals(view.getOwner().getName())) { + acl.add(Utils.allowAccess(thisEntry)); + } else if (thisEntry.type() == AclEntryType.ALLOW) { + acl.add(Utils.revokeAccess(thisEntry)); + } else { + acl.add(thisEntry); + } + } else { + if (!thisEntry.principal().getName().contains("NULL SID") + && thisEntry.type() != AclEntryType.ALLOW) { + acl.add(Utils.allowAccess(thisEntry)); + } else { + acl.add(thisEntry); + } + } + } + view.setAcl(acl); + } else { + throw new RuntimeException("Unsupported file attributes: " + attr); + } + } + + /** + * Grant files' access. + * + * @param files files to grant access + * @param access user access or full access + * @throws IOException if error occurs + */ + static void grantFilesAccess(List files, AccessControl access) throws IOException { + for (Path thisFile : files) { + grantAccess(thisFile, access); + } + } + + /** + * Copy SSL files to test folder. + * + * @throws IOException + */ + static void copySsl() throws IOException { + Path sslSource = Paths.get(SRC_SSL); + Path sslTarget = Paths.get(DEST_SSL); + + List files = Arrays.stream(sslSource.toFile().listFiles()).map(File::toPath).collect(Collectors.toList()); + Utils.copyFiles(files, sslTarget, StandardCopyOption.REPLACE_EXISTING); + + for (Path file : files) { + grantAccess(sslTarget.resolve(file.getFileName()), AccessControl.EVERYONE); + } + } + + /** + * Get all "management*ok.properties" files in the directory + * indicated by the "test.src" management property. + * + * @param useSsl boolean that indicates if test uses SSL + * @return configuration files + **/ + static File[] findConfigurationFilesOk(boolean useSsl) { + String prefix = useSsl ? "management_ssltest" : "management_test"; + return findAllConfigurationFiles(prefix, "ok.properties"); + } + + /** + * Get all "management*ko.properties" files in the directory + * indicated by the "test.src" management property. + * + * @param useSsl boolean that indicates if test uses SSL + * @return configuration files + **/ + static File[] findConfigurationFilesKo(boolean useSsl) { + String prefix = useSsl ? "management_ssltest" : "management_test"; + return findAllConfigurationFiles(prefix, "ko.properties"); + } + + /** + * Get all "management*.properties" files in the directory + * indicated by the "test.src" management property. + * + * @param useSsl boolean that indicates if test uses SSL + * @return configuration files + **/ + static File[] findAllConfigurationFiles(boolean useSsl) { + String prefix = useSsl ? "management_ssltest" : "management_test"; + return findAllConfigurationFiles(prefix, "properties"); + } + + /** + * Get all "management*.properties" files in the directory + * indicated by the "test.src" management property. + * + * @param prefix filename prefix + * @param suffix filename suffix + * @return configuration files + **/ + static File[] findAllConfigurationFiles(String prefix, String suffix) { + final File dir = new File(DEST); + final FilenameFilter filter = FilenameFilterFactory.prefixSuffix(prefix, suffix); + return dir.listFiles(filter); + } +} diff --git a/test/jdk/sun/management/jmxremote/bootstrap/Utils.java b/test/jdk/sun/management/jmxremote/bootstrap/Utils.java index e9325c17eed..3a7819fc61b 100644 --- a/test/jdk/sun/management/jmxremote/bootstrap/Utils.java +++ b/test/jdk/sun/management/jmxremote/bootstrap/Utils.java @@ -21,6 +21,15 @@ * questions. */ +import java.io.*; +import java.nio.file.CopyOption; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.attribute.*; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + /** * Utility class. */ @@ -46,4 +55,141 @@ static String convertPath(String path) { String newPath = new String(cs); return newPath; } + + /** + * Return file directories that satisfy the specified filter. + * + * @param searchDirectory the base directory to search + * @param filter a filename filter + * @return file directories + */ + public static List findFiles(Path searchDirectory, + FilenameFilter filter) { + return Arrays.stream(searchDirectory.toFile().listFiles(filter)) + .map(f -> f.toPath()) + .collect(Collectors.toList()); + } + + /** + * Copy files to the target path. + * + * @param source the paths to the files to copy + * @param target the path to the target files + * @param filenameMapper mapper function applied to filenames + * @param options options specifying how the copy should be done + * @return the paths to the target files + * @throws IOException if error occurs + */ + public static List copyFiles(List source, Path target, + Function filenameMapper, + CopyOption... options) throws IOException { + List result = new ArrayList<>(); + + if (!target.toFile().exists()) { + Files.createDirectory(target); + } + + for (Path file : source) { + if (!file.toFile().exists()) { + continue; + } + + String baseName = file.getFileName().toString(); + + Path targetFile = target.resolve(filenameMapper.apply(baseName)); + Files.copy(file, targetFile, options); + result.add(targetFile); + } + return result; + } + + /** + * Copy files to the target path. + * + * @param source the paths to the files to copy + * @param target the path to the target files + * @param options options specifying how the copy should be done + * @return the paths to the target files + * @throws IOException if error occurs + */ + public static List copyFiles(List source, Path target, + CopyOption... options) throws IOException { + return copyFiles(source, target, (s) -> s, options); + } + + /** + * Return an ACL entry that revokes owner access. + * + * @param acl original ACL entry to build from + * @return an ACL entry that revokes all access + */ + public static AclEntry revokeAccess(AclEntry acl) { + return buildAclEntry(acl, AclEntryType.DENY); + } + + /** + * Return an ACL entry that allow owner access. + * @param acl original ACL entry to build from + * @return an ACL entry that allows all access + */ + public static AclEntry allowAccess(AclEntry acl) { + return buildAclEntry(acl, AclEntryType.ALLOW); + } + + /** + * Build an ACL entry with a given ACL entry type. + * + * @param acl original ACL entry to build from + * @return an ACL entry with a given ACL entry type + */ + public static AclEntry buildAclEntry(AclEntry acl, AclEntryType type) { + return AclEntry.newBuilder() + .setType(type) + .setPrincipal(acl.principal()) + .setPermissions(acl.permissions()) + .build(); + } + + /** + * Replace file string by applying the given mapper function. + * + * @param source the file to read + * @param contentMapper the mapper function applied to file's content + * @throws IOException if an I/O error occurs + */ + public static void replaceFileString(Path source, + Function contentMapper) throws IOException { + StringBuilder sb = new StringBuilder(); + String lineSep = System.getProperty("line.separator"); + + try (BufferedReader reader = + new BufferedReader(new FileReader(source.toFile()))) { + + String line; + + // read all and replace all at once?? + while ((line = reader.readLine()) != null) { + sb.append(contentMapper.apply(line)) + .append(lineSep); + } + } + + try (FileWriter writer = new FileWriter(source.toFile())) { + writer.write(sb.toString()); + } + } + + /** + * Replace files' string by applying the given mapper function. + * + * @param source the file to read + * @param contentMapper the mapper function applied to files' content + * @throws IOException if an I/O error occurs + */ + public static void replaceFilesString(List source, + Function contentMapper) throws IOException { + for (Path file : source) { + replaceFileString(file, contentMapper); + } + } } diff --git a/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java b/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java index 5084c77e25c..53a98159116 100644 --- a/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java +++ b/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java @@ -28,7 +28,7 @@ * 8209452 8209506 8210432 8195793 8216577 8222089 8222133 8222137 8222136 * 8223499 8225392 8232019 8234245 8233223 8225068 8225069 8243321 8243320 * 8243559 8225072 8258630 8259312 8256421 8225081 8225082 8225083 8245654 - * 8305975 8304760 8307134 8295894 8314960 8317373 8317374 + * 8305975 8304760 8307134 8295894 8314960 8317373 8317374 8318759 * @summary Check root CA entries in cacerts file */ import java.io.ByteArrayInputStream; @@ -47,12 +47,12 @@ public class VerifyCACerts { + File.separator + "security" + File.separator + "cacerts"; // The numbers of certs now. - private static final int COUNT = 99; + private static final int COUNT = 103; // SHA-256 of cacerts, can be generated with // shasum -a 256 cacerts | sed -e 's/../&:/g' | tr '[:lower:]' '[:upper:]' | cut -c1-95 private static final String CHECKSUM - = "DA:61:45:1C:93:F3:6A:30:24:68:C6:72:BC:C5:E6:E4:E3:BA:6A:AE:36:29:7B:45:53:B7:10:53:52:7D:7E:A5"; + = "A6:73:50:DD:6B:49:E6:F0:E7:E7:7B:F9:F9:11:9F:83:2D:FD:95:97:69:03:54:54:9C:B7:DF:46:A4:05:7A:15"; // Hex formatter to upper case with ":" delimiter private static final HexFormat HEX = HexFormat.ofDelimiter(":").withUpperCase(); @@ -162,6 +162,14 @@ public class VerifyCACerts { "18:F1:FC:7F:20:5D:F8:AD:DD:EB:7F:E0:07:DD:57:E3:AF:37:5A:9C:4D:8D:73:54:6B:F4:F1:FE:D1:E1:8D:35"); put("quovadisrootca3g3 [jdk]", "88:EF:81:DE:20:2E:B0:18:45:2E:43:F8:64:72:5C:EA:5F:BD:1F:C2:D9:D2:05:73:07:09:C5:D8:B8:69:0F:46"); + put("digicertcseccrootg5 [jdk]", + "26:C5:6A:D2:20:8D:1E:9B:15:2F:66:85:3B:F4:79:7C:BE:B7:55:2C:1F:3F:47:72:51:E8:CB:1A:E7:E7:97:BF"); + put("digicertcsrsarootg5 [jdk]", + "73:53:B6:D6:C2:D6:DA:42:47:77:3F:3F:07:D0:75:DE:CB:51:34:21:2B:EA:D0:92:8E:F1:F4:61:15:26:09:41"); + put("digicerttlseccrootg5 [jdk]", + "01:8E:13:F0:77:25:32:CF:80:9B:D1:B1:72:81:86:72:83:FC:48:C6:E1:3B:E9:C6:98:12:85:4A:49:0C:1B:05"); + put("digicerttlsrsarootg5 [jdk]", + "37:1A:00:DC:05:33:B3:72:1A:7E:EB:40:E8:41:9E:70:79:9D:2B:0A:0F:2C:1D:80:69:31:65:F7:CE:C4:AD:75"); put("secomscrootca2 [jdk]", "51:3B:2C:EC:B8:10:D4:CD:E5:DD:85:39:1A:DF:C6:C2:DD:60:D8:7B:B7:36:D2:B5:21:48:4A:A4:7A:0E:BE:F6"); put("swisssigngoldg2ca [jdk]", diff --git a/test/jdk/sun/security/ssl/SSLContextImpl/MultipleChooseAlias.java b/test/jdk/sun/security/ssl/SSLContextImpl/MultipleChooseAlias.java new file mode 100644 index 00000000000..5ba949d134d --- /dev/null +++ b/test/jdk/sun/security/ssl/SSLContextImpl/MultipleChooseAlias.java @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2021, 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. +// + +import javax.net.ssl.KeyManager; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.KeyManagerFactorySpi; +import javax.net.ssl.ManagerFactoryParameters; +import javax.net.ssl.SSLServerSocket; +import javax.net.ssl.X509KeyManager; +import java.net.Socket; +import java.security.InvalidAlgorithmParameterException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.Principal; +import java.security.PrivateKey; +import java.security.Provider; +import java.security.Security; +import java.security.UnrecoverableKeyException; +import java.security.cert.X509Certificate; +import java.util.Arrays; + +/* + * @test + * @bug 8262186 + * @summary Callback semantics of the method X509KeyManager.chooseClientAlias(...) + * @library /javax/net/ssl/templates + * @modules java.base/sun.security.ssl:+open + * java.base/javax.net.ssl:+open + * @run main/othervm MultipleChooseAlias PKIX + * @run main/othervm MultipleChooseAlias SunX509 + */ +public class MultipleChooseAlias extends SSLSocketTemplate { + + static volatile int numOfCalls = 0; + static String kmfAlgorithm = null; + + @Override + protected void configureServerSocket(SSLServerSocket socket) { + socket.setNeedClientAuth(true); + } + + @Override + protected ContextParameters getClientContextParameters() { + return new ContextParameters("TLS", "PKIX", "Mine"); + } + + public static void main(String[] args) throws Exception { + kmfAlgorithm = args[0]; + Security.addProvider(new MyProvider()); + try { + new MultipleChooseAlias().run(); + } catch (Exception e) { + // expected + } + if (numOfCalls != 1) { + throw new RuntimeException("Too many times " + numOfCalls); + } + } + + static class MyProvider extends Provider { + public MyProvider() { + super("Mine", "1", "many many things"); + put("KeyManagerFactory.Mine", "MultipleChooseAlias$MyKMF"); + } + } + + // This KeyManagerFactory impl returns key managers + // wrapped in MyKM + public static class MyKMF extends KeyManagerFactorySpi { + KeyManagerFactory fac; + + public MyKMF() { + try { + fac = KeyManagerFactory.getInstance(kmfAlgorithm); + } catch (Exception e) { + throw new AssertionError(e); + } + } + + @Override + protected void engineInit(KeyStore ks, char[] password) + throws KeyStoreException, NoSuchAlgorithmException, + UnrecoverableKeyException { + fac.init(ks, password); + } + + @Override + protected void engineInit(ManagerFactoryParameters spec) + throws InvalidAlgorithmParameterException { + fac.init(spec); + } + + @Override + protected KeyManager[] engineGetKeyManagers() { + KeyManager[] result = fac.getKeyManagers(); + for (int i = 0; i < result.length; i++) { + result[i] = new MyKM((X509KeyManager)result[i]); + } + return result; + } + } + + // This KeyManager remembers how many times chooseClientAlias is called. + static class MyKM implements X509KeyManager { + + X509KeyManager km; + + MyKM(X509KeyManager km) { + this.km = km; + } + + public String[] getClientAliases(String keyType, Principal[] issuers) { + return km.getClientAliases(keyType, issuers); + } + + public String chooseClientAlias(String[] keyType, Principal[] issuers, + Socket socket) { + System.out.println("chooseClientAlias called on " + + Arrays.toString(keyType)); + numOfCalls++; + return null; // so it will try all key types and finally fails + } + + public String[] getServerAliases(String keyType, Principal[] issuers) { + return getServerAliases(keyType, issuers); + } + + public String chooseServerAlias(String keyType, Principal[] issuers, + Socket socket) { + return km.chooseServerAlias(keyType, issuers, socket); + } + + public X509Certificate[] getCertificateChain(String alias) { + return km.getCertificateChain(alias); + } + + public PrivateKey getPrivateKey(String alias) { + return km.getPrivateKey(alias); + } + } +} diff --git a/test/jtreg-ext/requires/VMProps.java b/test/jtreg-ext/requires/VMProps.java index 08979baae6d..f127253ee79 100644 --- a/test/jtreg-ext/requires/VMProps.java +++ b/test/jtreg-ext/requires/VMProps.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,10 +27,13 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.io.File; +import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; +import java.time.Instant; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -87,6 +90,7 @@ public void put(String key, Supplier s) { */ @Override public Map call() { + log("Entering call()"); SafeMap map = new SafeMap(); map.put("vm.flavor", this::vmFlavor); map.put("vm.compMode", this::vmCompMode); @@ -125,6 +129,7 @@ public Map call() { vmOptFinalFlags(map); dump(map.map); + log("Leaving call()"); return map.map; } @@ -432,6 +437,8 @@ protected String isCompiler2Enabled() { * @return true if docker is supported in a given environment */ protected String dockerSupport() { + log("Entering dockerSupport()"); + boolean isSupported = false; if (Platform.isLinux()) { // currently docker testing is only supported for Linux, @@ -450,6 +457,8 @@ protected String dockerSupport() { } } + log("dockerSupport(): platform check: isSupported = " + isSupported); + if (isSupported) { try { isSupported = checkDockerSupport(); @@ -458,15 +467,59 @@ protected String dockerSupport() { } } + log("dockerSupport(): returning isSupported = " + isSupported); return "" + isSupported; } + // Configures process builder to redirect process stdout and stderr to a file. + // Returns file names for stdout and stderr. + private Map redirectOutputToLogFile(String msg, ProcessBuilder pb, String fileNameBase) { + Map result = new HashMap<>(); + String timeStamp = Instant.now().toString().replace(":", "-").replace(".", "-"); + + String stdoutFileName = String.format("./%s-stdout--%s.log", fileNameBase, timeStamp); + pb.redirectOutput(new File(stdoutFileName)); + log(msg + ": child process stdout redirected to " + stdoutFileName); + result.put("stdout", stdoutFileName); + + String stderrFileName = String.format("./%s-stderr--%s.log", fileNameBase, timeStamp); + pb.redirectError(new File(stderrFileName)); + log(msg + ": child process stderr redirected to " + stderrFileName); + result.put("stderr", stderrFileName); + + return result; + } + + private void printLogfileContent(Map logFileNames) { + logFileNames.entrySet().stream() + .forEach(entry -> + { + log("------------- " + entry.getKey()); + try { + Files.lines(Path.of(entry.getValue())) + .forEach(line -> log(line)); + } catch (IOException ie) { + log("Exception while reading file: " + ie); + } + log("-------------"); + }); + } + private boolean checkDockerSupport() throws IOException, InterruptedException { + log("checkDockerSupport(): entering"); ProcessBuilder pb = new ProcessBuilder(Container.ENGINE_COMMAND, "ps"); + Map logFileNames = redirectOutputToLogFile("checkDockerSupport(): ps", + pb, "container-ps"); Process p = pb.start(); p.waitFor(10, TimeUnit.SECONDS); + int exitValue = p.exitValue(); + + log(String.format("checkDockerSupport(): exitValue = %s, pid = %s", exitValue, p.pid())); + if (exitValue != 0) { + printLogfileContent(logFileNames); + } - return (p.exitValue() == 0); + return (exitValue == 0); } /** @@ -581,6 +634,40 @@ protected static void dump(Map map) { } } + /** + * Log diagnostic message. + * + * @param msg + */ + protected static void log(String msg) { + // Always log to a file. + logToFile(msg); + + // Also log to stderr; guarded by property to avoid excessive verbosity. + // By jtreg design stderr produced here will be visible + // in the output of a parent process. Note: stdout should not be used + // for logging as jtreg parses that output directly and only echoes it + // in the event of a failure. + if (Boolean.getBoolean("jtreg.log.vmprops")) { + System.err.println("VMProps: " + msg); + } + } + + /** + * Log diagnostic message to a file. + * + * @param msg + */ + protected static void logToFile(String msg) { + String fileName = "./vmprops.log"; + try { + Files.writeString(Paths.get(fileName), msg + "\n", Charset.forName("ISO-8859-1"), + StandardOpenOption.APPEND, StandardOpenOption.CREATE); + } catch (IOException e) { + throw new RuntimeException("Failed to log into '" + fileName + "'", e); + } + } + /** * This method is for the testing purpose only. *