# HG changeset patch # User igerasim # Date 1461571413 -10800 # Mon Apr 25 11:03:33 2016 +0300 # Node ID 877db9b653e610d5b9505f0439b8361b948d22af # Parent e8217d94b72e185af3f81f12c13243772bfe7e92 [mq]: 8154947-Send-empty-list-of-authorities-in-CertificateRequest-if-server-has-too-many-of-them diff --git a/src/java.base/share/classes/sun/security/ssl/HandshakeMessage.java b/src/java.base/share/classes/sun/security/ssl/HandshakeMessage.java --- a/src/java.base/share/classes/sun/security/ssl/HandshakeMessage.java +++ b/src/java.base/share/classes/sun/security/ssl/HandshakeMessage.java @@ -1676,6 +1676,7 @@ byte[] types; // 1 to 255 types DistinguishedName[] authorities; // 3 to 2^16 - 1 // ... "3" because that's the smallest DER-encoded X500 DN + boolean authoritiesDropped = false; // protocol version being established using this CertificateRequest message ProtocolVersion protocolVersion; @@ -1686,6 +1687,10 @@ // length of supported_signature_algorithms private int algorithmsLen; + + private static final boolean allowDropAuthorites = + Debug.getBooleanProperty("jdk.tls.allowDropCertReqAuthorites", false); + CertificateRequest(X509Certificate[] ca, KeyExchange keyExchange, Collection signAlgs, ProtocolVersion protocolVersion) throws IOException { @@ -1694,9 +1699,17 @@ // always use X500Principal authorities = new DistinguishedName[ca.length]; - for (int i = 0; i < ca.length; i++) { + for (int i = 0, len = 0; i < ca.length; i++) { X500Principal x500Principal = ca[i].getSubjectX500Principal(); authorities[i] = new DistinguishedName(x500Principal); + if (allowDropAuthorites) { + len += authorities[i].length(); + if (len >= Record.OVERFLOW_OF_INT16) { + authorities = new DistinguishedName[0]; + authoritiesDropped = true; + break; + } + } } // we support RSA, DSS, and ECDSA client authentication and they // can be used with all ciphersuites. If this changes, the code @@ -1887,7 +1900,7 @@ s.println("Cert Authorities:"); if (authorities.length == 0) { - s.println(""); + s.println("" + (authoritiesDropped ? " (dropped)" : "")); } else { for (int i = 0; i < authorities.length; i++) { authorities[i].print(s); diff --git a/test/sun/security/ssl/X509TrustManagerImpl/CertRequestOverflow.java b/test/sun/security/ssl/X509TrustManagerImpl/CertRequestOverflow.java --- a/test/sun/security/ssl/X509TrustManagerImpl/CertRequestOverflow.java +++ b/test/sun/security/ssl/X509TrustManagerImpl/CertRequestOverflow.java @@ -28,10 +28,11 @@ /* * @test - * @bug 7200295 + * @bug 7200295 8154947 * @summary CertificateRequest message is wrapping when using large * numbers of Certs - * @run main/othervm CertRequestOverflow + * @run main/othervm -Djdk.tls.allowDropCertReqAuthorites=true CertRequestOverflow + * @run main/othervm -Djdk.tls.allowDropCertReqAuthorites=false CertRequestOverflow */ import java.io.*; @@ -76,6 +77,14 @@ static boolean debug = false; /* + * Is server allowed to send empty list of authorities in + * CertificateRequest message? + */ + static boolean allowDropAuthorities = + System.getProperty("jdk.tls.allowDropCertReqAuthorites", "") + .equalsIgnoreCase("true"); + + /* * If the client or server is doing some kind of object creation * that the other side depends on, and that thread prematurely * exits, you may experience a hang. The test harness will @@ -118,16 +127,22 @@ sslIS.read(); sslOS.write(85); sslOS.flush(); - - throw new Exception("SERVER TEST FAILED! " + - "It is expected to fail with field length overflow"); + if (!allowDropAuthorities) { + throw new Exception("SERVER TEST FAILED! " + + "It is expected to fail with field length overflow"); + } } catch (SSLException ssle) { - Throwable cause = ssle.getCause(); - if (!(cause instanceof RuntimeException)) { - System.out.println("We are expecting a RuntimeException!"); - throw ssle; + if (allowDropAuthorities) { + throw new RuntimeException("Unexpected exception at server side", + ssle); + } else { + Throwable cause = ssle.getCause(); + if (!(cause instanceof RuntimeException)) { + System.out.println("We are expecting a RuntimeException!"); + throw ssle; + } + System.out.println("The expected exception! " + ssle); } - System.out.println("The expected exception! " + ssle); } finally { sslSocket.close(); } @@ -167,7 +182,12 @@ sslOS.flush(); sslIS.read(); } catch (SSLException ssle) { - System.out.println("An expected exception!"); + if (allowDropAuthorities) { + throw new RuntimeException("Unexpected exception at client side", + ssle); + } else { + System.out.println("An expected exception!"); + } } finally { sslSocket.close(); }