forked from spiffe/java-spiffe
-
Notifications
You must be signed in to change notification settings - Fork 0
/
HttpsClient.java
93 lines (78 loc) · 3.61 KB
/
HttpsClient.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package io.spiffe.provider.examples.mtls;
import io.spiffe.exception.SocketEndpointAddressException;
import io.spiffe.exception.X509SourceException;
import io.spiffe.provider.SpiffeKeyManager;
import io.spiffe.provider.SpiffeSslContextFactory;
import io.spiffe.provider.SpiffeSslContextFactory.SslContextOptions;
import io.spiffe.provider.SpiffeTrustManager;
import io.spiffe.spiffeid.SpiffeId;
import io.spiffe.spiffeid.SpiffeIdUtils;
import io.spiffe.workloadapi.DefaultX509Source;
import lombok.val;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Paths;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.Set;
import java.util.function.Supplier;
/**
* Example of a simple HTTPS Client backed by the Workload API to get the X.509 Certificates
* and trusted cert bundles.
* <p>
* The purpose of this class is to show the use of the {@link SpiffeSslContextFactory} to create
* a {@link SSLContext} that uses X.509-SVID provided by a Workload API. The SSLContext uses the
* {@link SpiffeKeyManager} and {@link SpiffeTrustManager} for
* providing certificates and doing chain and SPIFFE ID validation.
*/
public class HttpsClient {
String spiffeSocket;
Supplier<Set<SpiffeId>> acceptedSpiffeIdsSetSupplier;
int serverPort;
public static void main(String[] args) {
String spiffeSocket = "unix:/tmp/agent.sock";
HttpsClient httpsClient = new HttpsClient(4000, spiffeSocket, () -> new AcceptedSpiffeIds().getSet());
try {
httpsClient.run();
} catch (KeyManagementException | NoSuchAlgorithmException | IOException | SocketEndpointAddressException | X509SourceException e) {
throw new RuntimeException("Error starting Https Client", e);
}
}
HttpsClient(int serverPort, String spiffeSocket, Supplier<Set<SpiffeId>> acceptedSpiffeIdsSetSupplier) {
this.serverPort = serverPort;
this.spiffeSocket = spiffeSocket;
this.acceptedSpiffeIdsSetSupplier = acceptedSpiffeIdsSetSupplier;
}
void run() throws IOException, SocketEndpointAddressException, KeyManagementException, NoSuchAlgorithmException, X509SourceException {
val sourceOptions = DefaultX509Source.X509SourceOptions
.builder()
.spiffeSocketPath(spiffeSocket)
.build();
val x509Source = DefaultX509Source.newSource(sourceOptions);
SslContextOptions sslContextOptions = SslContextOptions
.builder()
.acceptedSpiffeIdsSupplier(acceptedSpiffeIdsSetSupplier)
.x509Source(x509Source)
.build();
SSLContext sslContext = SpiffeSslContextFactory.getSslContext(sslContextOptions);
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket("localhost", serverPort);
new WorkloadThread(sslSocket, x509Source).start();
}
private static class AcceptedSpiffeIds {
Set<SpiffeId> getSet() {
try {
return SpiffeIdUtils.getSpiffeIdSetFromFile(Paths.get(toUri("testdata/spiffeIds.txt")));
} catch (IOException | URISyntaxException e) {
throw new RuntimeException("Error getting list of spiffeIds", e);
}
}
URI toUri(String path) throws URISyntaxException {
return Thread.currentThread().getContextClassLoader().getResource(path).toURI();
}
}
}