Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "Jetty/Feature/NPN"

< Jetty‎ | Feature
m
m
Line 3: Line 3:
  
 
The Jetty project provides an implementation of the [http://technotes.googlecode.com/git/nextprotoneg.html Next Protocol Negotiation TLS Extension] (NPN) for OpenJDK 7 or greater.
 
The Jetty project provides an implementation of the [http://technotes.googlecode.com/git/nextprotoneg.html Next Protocol Negotiation TLS Extension] (NPN) for OpenJDK 7 or greater.
NPN is a Transport Layer Security (TLS) extension for application layer protocol negotiation. It allows the application layer to negotiate which protocol to use over the secure connection.
+
NPN allows the application layer to negotiate which protocol to use over the secure connection.
  
 
NPN currently negotiates using SPDY as an application level protocol on port 443, and also negotiates the SPDY version. However, NPN is not SPDY specific in any way.  
 
NPN currently negotiates using SPDY as an application level protocol on port 443, and also negotiates the SPDY version. However, NPN is not SPDY specific in any way.  
 
Jetty's NPN implementation, although hosted under the umbrella of the Jetty project, is independent of Jetty (the servlet container); you can use it in any other Java network server.
 
Jetty's NPN implementation, although hosted under the umbrella of the Jetty project, is independent of Jetty (the servlet container); you can use it in any other Java network server.
  
===JVM Startup Use===
+
===JVM Startup===
  
 
To enable NPN support, you need to start the JVM with:
 
To enable NPN support, you need to start the JVM with:
Line 18: Line 18:
 
where <code>path_to_npn_boot_jar</code> is the path on the file system for the NPN Boot jar file, for example one at the following Maven coordinates [http://repo2.maven.org/maven2/org/mortbay/jetty/npn/npn-boot org.mortbay.jetty.npn:npn-boot].
 
where <code>path_to_npn_boot_jar</code> is the path on the file system for the NPN Boot jar file, for example one at the following Maven coordinates [http://repo2.maven.org/maven2/org/mortbay/jetty/npn/npn-boot org.mortbay.jetty.npn:npn-boot].
  
===API Use===
+
===NPN API===
  
Applications needs to interact with NPN TLS extension protocol negotiations. For example, server applications need to know whether the client supports NPN, and client applications needs to know the list of protocols supported by the server, and so on.
+
Applications need to interact with NPN TLS extension protocol negotiations. For example, server applications need to know whether the client supports NPN, and client applications needs to know the list of protocols supported by the server, and so on.
  
To provide this interaction, Jetty's NPN implementation provides an API to applications, hosted at Maven coordinates <code>org.eclipse.jetty.npn:npn-api</code>.
+
To implement this interaction, Jetty's NPN implementation provides an API to applications, hosted at Maven coordinates <code>org.eclipse.jetty.npn:npn-api</code>.
You need to declare this dependency ''provided'', because the <code>npn-boot</code> jar already includes it (see the previous section above) and it is therefore available in the boot classpath.
+
You need to declare this dependency as ''provided'', because the <code>npn-boot</code> jar already includes it (see the previous section above), and it is therefore available in the boot classpath.
  
 
The API consists of a single class, <code>org.eclipse.jetty.npn.NextProtoNego</code>, and applications need to register instances of <code>SSLSocket</code> or <code>SSLEngine</code> with a <code>ClientProvider</code> or <code>ServerProvider</code> (depending on whether the application is a client or server application).
 
The API consists of a single class, <code>org.eclipse.jetty.npn.NextProtoNego</code>, and applications need to register instances of <code>SSLSocket</code> or <code>SSLEngine</code> with a <code>ClientProvider</code> or <code>ServerProvider</code> (depending on whether the application is a client or server application).
Line 56: Line 56:
 
</source>
 
</source>
  
TheNPN implementation calls <code>NextProtoNego.ClientProvider</code> methods <code>supports()</code>, <code>unsupported()</code> and <code>selectProtocol(List&lt;String&gt;)</code>, so that the client application can decide:
+
The NPN implementation calls <code>NextProtoNego.ClientProvider</code> methods <code>supports()</code>, <code>unsupported()</code> and <code>selectProtocol(List&lt;String&gt;)</code>, so that the client application can decide:
 
* whether to support NPN.
 
* whether to support NPN.
 
* whether the server supports NPN.
 
* whether the server supports NPN.
Line 100: Line 100:
 
The <code>NextProtoNego</code> class is released under same license as the classes of the Jetty project.  
 
The <code>NextProtoNego</code> class is released under same license as the classes of the Jetty project.  
  
===Use in Unit Tests===
+
===Unit Tests===
  
 
You can write and run unit tests that use the NPN implementation.
 
You can write and run unit tests that use the NPN implementation.

Revision as of 15:37, 12 March 2012



Introduction

The Jetty project provides an implementation of the Next Protocol Negotiation TLS Extension (NPN) for OpenJDK 7 or greater. NPN allows the application layer to negotiate which protocol to use over the secure connection.

NPN currently negotiates using SPDY as an application level protocol on port 443, and also negotiates the SPDY version. However, NPN is not SPDY specific in any way. Jetty's NPN implementation, although hosted under the umbrella of the Jetty project, is independent of Jetty (the servlet container); you can use it in any other Java network server.

JVM Startup

To enable NPN support, you need to start the JVM with:

java -Xbootclasspath/p:<path_to_npn_boot_jar> ...

where path_to_npn_boot_jar is the path on the file system for the NPN Boot jar file, for example one at the following Maven coordinates org.mortbay.jetty.npn:npn-boot.

NPN API

Applications need to interact with NPN TLS extension protocol negotiations. For example, server applications need to know whether the client supports NPN, and client applications needs to know the list of protocols supported by the server, and so on.

To implement this interaction, Jetty's NPN implementation provides an API to applications, hosted at Maven coordinates org.eclipse.jetty.npn:npn-api. You need to declare this dependency as provided, because the npn-boot jar already includes it (see the previous section above), and it is therefore available in the boot classpath.

The API consists of a single class, org.eclipse.jetty.npn.NextProtoNego, and applications need to register instances of SSLSocket or SSLEngine with a ClientProvider or ServerProvider (depending on whether the application is a client or server application). Refer to NextProtoNego javadocs and to the examples below for further details about client and server provider methods.

Client Example

SSLContext sslContext = ...;
SSLSocket sslSocket = (SSLSocket)context.getSocketFactory()
        .createSocket("localhost", server.getLocalPort());
 
NextProtoNego.put(sslSocket, new NextProtoNego.ClientProvider()
{
    @Override
    public boolean supports()
    {
        return true;
    }
 
    @Override
    public void unsupported()
    {
    }
 
    @Override
    public String selectProtocol(List<String> protocols)
    {
        return protocols.get(0);
    }
});

The NPN implementation calls NextProtoNego.ClientProvider methods supports(), unsupported() and selectProtocol(List<String>), so that the client application can decide:

  • whether to support NPN.
  • whether the server supports NPN.
  • to select one of the protocols the server supports.

The example for SSLEngine is identical, and you just need to replace the SSLSocket instance with a SSLEngine instance.

Server Example

SSLSocket sslSocket = ...;
NextProtoNego.put(sslSocket, new NextProtoNego.ServerProvider()
{
    @Override
    public void unsupported()
    {
    }
 
    @Override
    public List<String> protocols()
    {
        return Arrays.asList("http/1.1");
    }
 
    @Override
    public void protocolSelected(String protocol)
    {
        System.out.println("Protocol Selected is: " + protocol);
    }
});

The NPN implementation calls NextProtoNego.ServerProvider methods unsupported(), protocols() and protocolSelected(String), so that the server application can

  • know whether the client supports NPN.
  • provide the list of protocols the server suports.
  • know which protocol the client chooses.

Implementation Details

The NPN implementation relies on modification of a few OpenJDK classes and on a few new classes that need to live in the sun.security.ssl package. These classes are released under the same GPLv2+exception license of OpenJDK.

The NextProtoNego class is released under same license as the classes of the Jetty project.

Unit Tests

You can write and run unit tests that use the NPN implementation. The solution that we use with Maven is to specify an additional command line argument to the Surefire plugin:

<project ...>
 
  <properties>
    <npn-version>7.6.2.v20120308</npn-version>
  </properties>
 
  <build>
    <plugins>
      <plugin>
        <artifactId>maven-surefire-plugin</artifactId>
        <configuration>
          <argLine>-Xbootclasspath/p:${settings.localRepository}/org/mortbay/jetty/npn/npn-boot/${npn-version}/npn-boot-${npn-version}.jar</argLine>
        </configuration>
      </plugin>
 
      ...
 
    </plugins>
  </build>
 
  ...
 
</project>

Debugging

You can enable debug logging for the NPN implementation in this way:

NextProtoNego.debug = true;

Since the NextProtoNego class is in the boot classpath, we chose not to use logging libraries because we do not want to override application logging library choices; therefore the logging is performed directly on System.err.

Feature

{{{body}}}

Back to the top