1. Introduction This feature is to support the Application Layer Protocol Negotiation (ALPN) TLS extension as defined in RFC 7301. 2. Specification This section describes the integrated API. (See JDK-8051498 for additional information.) ALPN configuration and state are currently handled by the javax.net.ssl.SSLParameters and javax.net.ssl.SSLSocket/javax.net.ssl.SSLEngine JSSE classes. This design defines 6 new public methods for managing application layer protocol names: SSLEngine/SSLSocket =================== /** * Returns the most recent application protocol value negotiated for this * connection. * <p> * If supported by the underlying SSL/TLS/DTLS implementation, * application name negotiation mechanisms such as <a * href="http://www.ietf.org/rfc/rfc7301.txt"> RFC 7301 </a>, the * Application-Layer Protocol Negotiation (ALPN), can negotiate * application-level values between peers. * <p> * @implSpec * The implementation in this class throws * {@code UnsupportedOperationException} and performs no other action. * * @return null if it has not yet been determined if application * protocols might be used for this connection, an empty * {@code String} if application protocols values will not * be used, or a non-empty application protocol {@code String} * if a value was successfully negotiated. * @throws UnsupportedOperationException if the underlying provider * does not implement the operation. * @since 9 */ public String getApplicationProtocol() { throw new UnsupportedOperationException(); } /** * Returns the application protocol value negotiated on a SSL/TLS * handshake currently in progress. * <p> * Like {@link #getHandshakeSession()}, * a connection may be in the middle of a handshake. The * application protocol may or may not yet be available. * <p> * @implSpec * The implementation in this class throws * {@code UnsupportedOperationException} and performs no other action. * * @return null if it has not yet been determined if application * protocols might be used for this handshake, an empty * {@code String} if application protocols values will not * be used, or a non-empty application protocol {@code String} * if a value was successfully negotiated. * @throws UnsupportedOperationException if the underlying provider * does not implement the operation. * @since 9 */ public String getHandshakeApplicationProtocol() { throw new UnsupportedOperationException(); } SSLParameters ============= /** * Returns a prioritized array of application-layer protocol names that * can be negotiated over the SSL/TLS/DTLS protocols. * <p> * The array could be empty (zero-length), in which case protocol * indications will not be used. * <p> * This method will return a new array each time it is invoked. * * @return a non-null, possibly zero-length array of application protocol * {@code String}s. The array is ordered based on protocol * preference, with {@code protocols[0]} being the most preferred. * @see #setApplicationProtocols * @since 9 */ public String[] getApplicationProtocols() { return applicationProtocols.clone(); } /** * Sets the prioritized array of application-layer protocol names that * can be negotiated over the SSL/TLS/DTLS protocols. * <p> * If application-layer protocols are supported by the underlying * SSL/TLS implementation, this method configures which values can * be negotiated by protocols such as <a * href="http://www.ietf.org/rfc/rfc7301.txt"> RFC 7301 </a>, the * Application Layer Protocol Negotiation (ALPN). * <p> * If this end of the connection is expected to offer application protocol * values, all protocols configured by this method will be sent to the * peer. * <p> * If this end of the connection is expected to select the application * protocol value, the {@code protocols} configured by this method are * compared with those sent by the peer. The first matched value becomes * the negotiated value. If none of the {@code protocols} were actually * requested by the peer, the underlying protocol will determine what * action to take. (For example, ALPN will send a * {@code "no_application_protocol"} alert and terminate the connection.) * <p> * @implSpec * This method will make a copy of the {@code protocols} array. * * @param protocols an ordered array of application protocols, * with {@code protocols[0]} being the most preferred. * If the array is empty (zero-length), protocol * indications will not be used. * @throws IllegalArgumentException if protocols is null, or if * any element in a non-empty array is null or an * empty (zero-length) string * @see #getApplicationProtocols * @since 9 */ public void setApplicationProtocols(String[] protocols) { if (protocols == null) { throw new IllegalArgumentException("protocols was null"); } String[] tempProtocols = protocols.clone(); for (String p : tempProtocols) { if (p == null || p.equals("")) { throw new IllegalArgumentException( "An element of protocols was null/empty"); } } applicationProtocols = tempProtocols; } 3. Implementation The following existing JSSE implementation classes are enhanced to support handling of an ALPN extension in the TLS client and server Hello messages: sun.security.ssl.Alerts.java sun.security.ssl.ClientHandshaker.java sun.security.ssl.ExtensionType.java sun.security.ssl.HandshakeMessage.java sun.security.ssl.Handshaker.java sun.security.ssl.HelloExtensions.java sun.security.ssl.SSLServerSocketImpl.java sun.security.ssl.SSLSessionImpl.java sun.security.ssl.SSLSocketImpl.java sun.security.ssl.ServerHandshaker.java Along with a new implementation class: sun.security.ssl.ALPNExtension implements HelloExtension 4. Issues ALPN support may be backported to JDK 8 so an implementation is needed that does not introduce any new Java SE 8 APIs. This may require creating something in a jdk.* or com.oracle.ssl.net package.
|