Skip to content

Commit a703c86

Browse files
committed
port over the changes to support token binding from the java 9 version of the project
1 parent 0e53815 commit a703c86

File tree

105 files changed

+3230
-29139
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

105 files changed

+3230
-29139
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
target
2+
*.iml
3+
*.ipr
4+
*.iws

LICENSE

Lines changed: 347 additions & 0 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
### todo
2+
3+
## Token Binding Protocol Negotiation TLS Extension support for Java 9
4+
5+
### Introduction
6+
Token Binding over HTTP [[I-D.ietf-tokbind-https]] provides a mechanism
7+
that enables HTTP servers to cryptographically bind cookies and other
8+
security tokens to a key held by the browser or other HTTP client,
9+
possession of which is proven on the TLS connections over
10+
which the tokens are used. When Token Binding is negotiated in the
11+
TLS handshake [[I-D.ietf-tokbind-negotiation]] the client sends an
12+
encoded Token Binding Message [[I-D.ietf-tokbind-protocol]] as a header
13+
in each HTTP request, which proves possession of one or more private
14+
keys held by the client. The public portion of the keys are
15+
represented in the Token Binding IDs of the Token Binding Message and
16+
for each one there is a signature over some data, which includes the
17+
exported keying material [[RFC 5705]] of the TLS connection. An HTTP
18+
server issuing cookies or other security tokens can associate them
19+
with the Token Binding ID, which ensures those tokens cannot be used
20+
successfully over a different TLS connection or by a different client
21+
than the one to which they were issued.
22+
23+
This project provides an implementation of the TLS Extension for Token Binding Protocol Negotiation as well as TLS Keying Material Exporters (also TLS Extended Master Secret Extension [[RFC 7627]] in some older versions) for Java 9. An an open source library for consuming or producing Token Binding message structures, which applications do after negotiation, can be found with the [token-binding-java] project.
24+
25+
### Usage
26+
This implementation relies on modifications of a few JDK classes in the `sun.security.ssl` package. The JVM needs to be told to use those modified classes in place of those in the base modul of the JRE. And your application needs to interact with the API of some of those classes, likely through reflection and dynamic method invocation.
27+
28+
#### Starting the JVM
29+
To use the functionality of this project, the JVM needs to be started using the `--patch-module` option as follows:
30+
31+
```
32+
java --patch-module java.base=<path-to-java9-token-binding-negotiation-jar> --add-exports java.base/sun.security.ssl=ALL-UNNAMED ...
33+
```
34+
35+
Where path-to-java9-token-binding-negotiation-jar is the path on the file system for this project's jar file. This prepends the jar file to the default bootstrap classpath so that its classes will be used in place of the default JRE classes. Be certain to use the jar version which corresponds to the version of the JRE being used (see [Versions](#versions) below).
36+
37+
#### API
38+
A few new methods have been added to the OpenJDK implementations of `SSLEngine` and `SSLSocket` to facilitate an application doing Token Binding using the functionality provided by this project.
39+
40+
##### Supported Key Parameters for Negotiation
41+
In order to negotiate the use of Token Binding, before handshaking begins, the list of identifiers of the supported key parameters needs to be indicated for the connection. For a client, this is the list that will be offered in the Client Hello Extension. For a server, this is the list of key parameter types that it is willing to successfully negotiate. In all cases the list indicates the Token Binding key parameters supported in descending order of preference. This can be accomplished by calling the following method on `SSLEngine` or `SSLSocket` before the handshaking process begins.
42+
43+
```java
44+
public void setSupportedTokenBindingKeyParams(byte[] supportedTokenBindingKeyParams)
45+
```
46+
47+
The `supportedTokenBindingKeyParams` byte array argument is the list of supported key parameters type identifiers (i.e. from [I-D.ietf-tokbind-protocol] `rsa2048_pkcs1.5(0), rsa2048_pss(1), ecdsap256(2)`). So, for example, the following would set up an `SSLEngine` to accept or offer `ecdsap256` and `rsa2048_pkcs1.5` (in that order of preference) during the handshake.
48+
49+
```java
50+
Class<? extends SSLEngine> engineClass = engine.getClass();
51+
Method supportedKeyParamsMethod = engineClass.getMethod("setSupportedTokenBindingKeyParams", byte[].class);
52+
Object supported = new byte[] {2, 0};
53+
supportedKeyParamsMethod.invoke(engine, supported);
54+
```
55+
56+
Alternately, the system properties `unbearable.server.defaultSupportedKeyParams` and `unbearable.client.defaultSupportedKeyParams` may be used to indicate the supported key parameters type identifiers for all connections when acting as the server or client respectively. The value is a comma seperated list of key parameters type identifiers. For example, adding the following argument when starting the JVM would say that TLS connections as the server will successfully negotiate Token Binding with `ecdsap256(2)` or `rsa2048_pkcs1.5(0)` when offered by the client.
57+
58+
```
59+
-Dunbearable.server.defaultSupportedKeyParams=2,0
60+
```
61+
62+
##### After Negotiation
63+
If the use of the Token Binding is successfully negotiated with HTTP, the client includes an encoded token binding message in each request via the `Sec-Token-Binding` header and the server validates the message. In order to produce or consume a Token Binding message, an application needs to know what key parameters type was negotiated and get the exported keying material (EKM) from the TLS connection. That data can be obtained using the following methods on `SSLEngine` or `SSLSocket` where `getNegotiatedTokenBindingKeyParams()` will give the the identifier of the negotiated key parameters (or `null`, if Token Binding was not negotiated) and `exportKeyingMaterial("EXPORTER-Token-Binding", 32)` will return the appropriate EKM.
64+
65+
66+
```java
67+
public Byte getNegotiatedTokenBindingKeyParams()
68+
69+
public byte[] exportKeyingMaterial(String label, int length)
70+
```
71+
72+
The following, for example, could be used to access the negotiated key parameters type and the EKM from an `SSLEngine`.
73+
74+
```java
75+
Class<? extends SSLEngine> engineClass = engine.getClass();
76+
Method tbKeyParamsMethod = engineClass.getMethod("getNegotiatedTokenBindingKeyParams");
77+
Method ekmMethod = engineClass.getMethod("exportKeyingMaterial", String.class, int.class);
78+
Byte negotiatedKeyParamsId = (Byte) tbKeyParamsMethod.invoke(object);
79+
byte[] ekm = (byte[]) ekmMethod.invoke(object, "EXPORTER-Token-Binding", 32);
80+
81+
```
82+
83+
With the EKM and the negotiated key parameters type, a library like [token-binding-java] can be used to consume or create Token Binding messages.
84+
85+
### <a name="versions"></a> Versions
86+
The Token Binding negotiation implementation relies on modifications to a few OpenJDK classes so needs to be updated to stay in sync when there are changes to those OpenJDK classes in a Java update. As such, the java9-token-binding-negotiation jar version matching the JRE version needs to be used. The following provides the version mappings.
87+
88+
| Java 9 Version | java9-token-binding-negotiation Version
89+
| ------------- |-------------
90+
| 9.0.4 | [1.0.0.v2]
91+
| 9.0.1 | [1.0.0.v1]
92+
| 9 | unsupported
93+
94+
See [java8-token-binding-negotiation] for Token Binding Protocol Negotiation support with Java 8.
95+
96+
### License
97+
The modified OpenJDK classes are released under the same GPLv2 + Classpath Exception license as the OpenJDK.
98+
99+
100+
[1.0.0.v1]:https://github.com/pingidentity/java9-token-binding-negotiation/releases/tag/java9-token-binding-negotiation-1.0.0.v1
101+
[1.0.0.v2]:https://github.com/pingidentity/java9-token-binding-negotiation/releases/tag/java9-token-binding-negotiation-1.0.0.v2
102+
103+
104+
[token-binding-java]:https://github.com/pingidentity/token-binding-java
105+
[java8-token-binding-negotiation]:https://github.com/pingidentity/java8-token-binding-negotiation
106+
107+
108+
[I-D.ietf-tokbind-https]:https://tools.ietf.org/html/draft-ietf-tokbind-https
109+
[I-D.ietf-tokbind-protocol]:https://tools.ietf.org/html/draft-ietf-tokbind-protocol
110+
[I-D.ietf-tokbind-negotiation]:https://tools.ietf.org/html/draft-ietf-tokbind-negotiation
111+
112+
[RFC 5705]:https://tools.ietf.org/html/rfc5705
113+
[RFC 7627]:https://tools.ietf.org/html/rfc7627

pom.xml

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3+
4+
<modelVersion>4.0.0</modelVersion>
5+
<groupId>com.pingidentity.oss</groupId>
6+
<packaging>jar</packaging>
7+
<artifactId>java10-token-binding-negotiation</artifactId>
8+
<name>Token Binding Negotiation for Java 10</name>
9+
<version>1.0.0.v1-SNAPSHOT</version>
10+
11+
<build>
12+
<plugins>
13+
<plugin>
14+
<artifactId>maven-compiler-plugin</artifactId>
15+
<configuration>
16+
<source>1.10</source>
17+
<target>1.10</target>
18+
<compilerArgs>
19+
<!-- from https://medium.com/codefx-weekly/java-9-maven-compile-errors-module-names-kill-switches-73411c511750
20+
<arg> will put arguments that contain a space into quotes before
21+
passing them, which javac doesn't like,
22+
so you'll have to do this
23+
<arg>-add-exports</arg><arg>java.base/sun.security.util=ALL-UNNAMED</arg>
24+
instead of this
25+
<arg>-add-exports java.base/sun.security.util=ALL-UNNAMED</arg>
26+
or you'll get invalid flag: -add-exports java.base/sun.security.util=ALL-UNNAMED
27+
-->
28+
<arg>--add-exports</arg><arg>java.base/sun.security.ssl=ALL-UNNAMED</arg>
29+
<arg>--add-exports</arg><arg>java.base/sun.security.util=ALL-UNNAMED</arg>
30+
<arg>--add-exports</arg><arg>java.base/com.sun.net.ssl.internal.ssl=ALL-UNNAMED</arg>
31+
<arg>--add-exports</arg><arg>java.base/sun.security.jca=ALL-UNNAMED</arg>
32+
<arg>--add-exports</arg><arg>java.base/sun.net.util=ALL-UNNAMED</arg>
33+
<arg>--add-exports</arg><arg>java.base/jdk.internal.misc=ALL-UNNAMED</arg>
34+
<arg>--add-exports</arg><arg>java.base/sun.security.internal.interfaces=ALL-UNNAMED</arg>
35+
<arg>--add-exports</arg><arg>java.base/sun.security.provider.certpath=ALL-UNNAMED</arg>
36+
<arg>--add-exports</arg><arg>java.base/sun.security.internal.spec=ALL-UNNAMED</arg>
37+
<arg>--add-exports</arg><arg>java.base/sun.security.validator=ALL-UNNAMED</arg>
38+
<arg>--add-exports</arg><arg>java.base/sun.security.action=ALL-UNNAMED</arg>
39+
<arg>--add-exports</arg><arg>java.base/sun.security.x509=ALL-UNNAMED</arg>
40+
41+
<!-- this arg syntax from the 1st comment at https://issues.apache.org/jira/browse/MCOMPILER-311
42+
and patch using src from https://stackoverflow.com/questions/36270671/how-to-patch-openjdk-9-with-jigsaw-integrated-->
43+
<arg>--patch-module=java.base=${basedir}/src/main/java</arg>
44+
45+
</compilerArgs>
46+
</configuration>
47+
</plugin>
48+
<plugin>
49+
<artifactId>maven-surefire-plugin</artifactId>
50+
<configuration>
51+
<argLine>
52+
--add-exports java.base/sun.security.ssl=ALL-UNNAMED --patch-module java.base=${basedir}/target/classes -Djavax.net.debug=ssl,handshake,session
53+
</argLine>
54+
</configuration>
55+
</plugin>
56+
</plugins>
57+
<pluginManagement>
58+
<plugins>
59+
<plugin>
60+
<groupId>org.apache.maven.plugins</groupId>
61+
<artifactId>maven-clean-plugin</artifactId>
62+
<version>3.0.0</version>
63+
</plugin>
64+
<plugin>
65+
<groupId>org.apache.maven.plugins</groupId>
66+
<artifactId>maven-compiler-plugin</artifactId>
67+
<version>3.7.0</version>
68+
</plugin>
69+
<plugin>
70+
<groupId>org.apache.maven.plugins</groupId>
71+
<artifactId>maven-deploy-plugin</artifactId>
72+
<version>2.8.2</version>
73+
</plugin>
74+
<plugin>
75+
<groupId>org.apache.maven.plugins</groupId>
76+
<artifactId>maven-install-plugin</artifactId>
77+
<version>2.5.2</version>
78+
</plugin>
79+
<plugin>
80+
<groupId>org.apache.maven.plugins</groupId>
81+
<artifactId>maven-jar-plugin</artifactId>
82+
<version>3.0.2</version>
83+
</plugin>
84+
<plugin>
85+
<groupId>org.apache.maven.plugins</groupId>
86+
<artifactId>maven-release-plugin</artifactId>
87+
<version>2.5.3</version>
88+
</plugin>
89+
<plugin>
90+
<groupId>org.apache.maven.plugins</groupId>
91+
<artifactId>maven-scm-plugin</artifactId>
92+
<version>1.9.5</version>
93+
</plugin>
94+
<plugin>
95+
<groupId>org.apache.maven.plugins</groupId>
96+
<artifactId>maven-source-plugin</artifactId>
97+
<version>3.0.1</version>
98+
</plugin>
99+
<plugin>
100+
<groupId>org.apache.maven.plugins</groupId>
101+
<artifactId>maven-surefire-plugin</artifactId>
102+
<version>2.21.0</version>
103+
</plugin>
104+
</plugins>
105+
</pluginManagement>
106+
</build>
107+
108+
<dependencies>
109+
<dependency>
110+
<groupId>junit</groupId>
111+
<artifactId>junit</artifactId>
112+
<version>4.11</version>
113+
<scope>test</scope>
114+
</dependency>
115+
</dependencies>
116+
117+
<properties>
118+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
119+
<maven.javadoc.skip>true</maven.javadoc.skip>
120+
</properties>
121+
122+
<scm>
123+
<connection>scm:git:https://github.com/pingidentity/java10-token-binding-negotiation.git</connection>
124+
<developerConnection>scm:git:git@github.com:pingidentity/java10-token-binding-negotiation.git</developerConnection>
125+
<tag>HEAD</tag>
126+
<url>https://github.com/pingidentity/java10-token-binding-negotiation</url>
127+
</scm>
128+
129+
<distributionManagement>
130+
<repository>
131+
<id>maven-repository-on-filesystem</id>
132+
<url>file:///${basedir}/target/pseudo-deploy</url>
133+
</repository>
134+
</distributionManagement>
135+
136+
</project>

0 commit comments

Comments
 (0)