Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vanilla Java client #103

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ node_modules
.next
yarn-error.log
dist
assets
assets
.yarnrc.yml
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v16
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ If you notice any outdated, missing, or errant docs, pull requests are strongly

Documentation for each technology lives in its corresponding directory in the [docs/](docs/) folder.

To get rolling on local development, clone this repository and start the local dev server:
To get rolling on local development, clone this repository, have yarn ready (`yarn set version classic` if you have yarn 3 installed)
and use Node 16 (`nvm use`) and start the local dev server:

```
$ yarn install
Expand Down
12 changes: 12 additions & 0 deletions docs/java/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: Java
protocol: https
server_port: 443
topics:
client:
links:
- text: Java Key Store format
url: https://docs.oracle.com/cd/E19509-01/820-3503/ggfen/index.html
- text: "PKCS #12"
url: https://en.wikipedia.org/wiki/PKCS_12
- text: Introduction to the Java HTTP Client
url: https://openjdk.org/groups/net/httpclient/intro.html
Binary file added docs/java/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
56 changes: 56 additions & 0 deletions docs/java/topics/client.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
This example assumes only Java 11 or newer and does not require any libraries.

There are multiple ways to convert certificate, private key and root CA certificate to a format that java can digest.
Java works with "key stores" which can be in the (java proprietary) `JKS` or `PKCS #12` format (among others),
and can also be created at runtime. But here we will use only `step` and a minimal amount of code.

Trust store and key store can also be configured on a JVM level, but on the client we probably want to configure
them on a per-connection basis, so this is what we will do here.

Make sure to set a password for trust and key store in the next steps:

1. Package the root CA certificate: `step certificate p12 truststore.p12 --ca {{ ca_cert }}`
2. Package certificate and key: `step certificate p12 keystore.p12 {{ client_cert }} {{ client_key }} --ca {{ ca_cert }}`

You can now put these files on your classpath or read them from the file system:

```java
// imports omitted

public class HelloMtlsClient {
public static void main(String[] args) throws Exception {
var keyStore = KeyStore.getInstance("PKCS12");
var trustStore = KeyStore.getInstance("PKCS12");
var keyStorePassword = "changeit";
var trustStorePassword = "changeit";

try (var keystoreFile = Files.newInputStream(Path.of("keystore.p12"));
var truststoreFile = Files.newInputStream(Path.of("truststore.p12"))) {
keyStore.load(keystoreFile, keyStorePassword.toCharArray());
trustStore.load(truststoreFile, trustStorePassword.toCharArray());
}

var keyManager = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManager.init(keyStore, keyStorePassword.toCharArray());

var trustManager = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManager.init(trustStore);

var sslContext = SSLContext.getInstance("TLSv1.3");
sslContext.init(keyManager.getKeyManagers(), trustManager.getTrustManagers(), null);

SSLParameters sslParameters = new SSLParameters();
sslParameters.setNeedClientAuth(true);

var httpClient = HttpClient.newBuilder()
.sslContext(sslContext)
.sslParameters(sslParameters)
.build();

var request = HttpRequest.newBuilder(URI.create("https://{{ server_name }}:{{ server_port }}")).GET().build();
var response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());

// Do something with the response
}
}
```
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,6 @@
"peerDependencies": {
"react": "^16.9.0",
"react-dom": "^16.9.0"
}
},
"packageManager": "[email protected]"
}