View Javadoc
1   /*
2    * junixsocket
3    *
4    * Copyright 2009-2024 Christian Kohlschütter
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.newsclub.net.unix.demo.ssl;
19  
20  import java.io.File;
21  import java.io.FileDescriptor;
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.io.OutputStream;
25  import java.nio.charset.StandardCharsets;
26  import java.security.GeneralSecurityException;
27  
28  import javax.net.ssl.SSLSocket;
29  import javax.net.ssl.SSLSocketFactory;
30  import javax.security.auth.DestroyFailedException;
31  
32  import org.newsclub.net.unix.AFUNIXSocket;
33  import org.newsclub.net.unix.AFUNIXSocketAddress;
34  import org.newsclub.net.unix.ssl.SSLContextBuilder;
35  
36  /**
37   * A simple SSL demo client.
38   *
39   * @author Christian Kohlschütter
40   * @see SSLDemoServer
41   * @see SSLDemoPrerequisites
42   */
43  public class SSLDemoClient {
44    public static void main(String[] args) throws InterruptedException, IOException,
45        GeneralSecurityException, DestroyFailedException {
46  
47      // Enable to see SSL debugging
48      // System.setProperty("javax.net.debug", "all");
49  
50      AFUNIXSocketAddress addr = AFUNIXSocketAddress.of(new File("/tmp/ssldemo"));
51  
52      SSLSocketFactory clientSocketFactory = SSLContextBuilder.forClient() //
53          .withKeyStore(new File("juxclient.p12"), () -> "clientpass".toCharArray()) //
54          .withTrustStore(new File("juxclient.truststore"), () -> "clienttrustpass".toCharArray())
55          .withDefaultSSLParameters((p) -> {
56            // A simple way to disable some undesired protocols:
57            // SSLParametersUtil.disableProtocols(p, "TLSv1.0", "TLSv1.1", "TLSv1.2");
58  
59            // Uncomment to perform endpoint checking of server certificates
60            // p.setEndpointIdentificationAlgorithm("HTTPS");
61  
62          }) //
63          .buildAndDestroyBuilder().getSocketFactory();
64  
65      System.out.println("Connecting to " + addr);
66  
67      try (AFUNIXSocket plainSocket = AFUNIXSocket.connectTo(addr);
68          SSLSocket sslSocket = (SSLSocket) clientSocketFactory.createSocket(plainSocket,
69              // This hostname is sent to the server, unless we define an SNI hostname below
70              "localhost.junixsocket", //
71              plainSocket.getPort(), false)) {
72  
73        // Setting the client mode manually is not necessary when using SSLContextBuilder
74        // sslSocket.setUseClientMode(false);
75  
76        // Uncomment to send SNI hostname to server
77        // SSLParametersUtil.setSNIServerName(sslSocket, new SNIHostName("subdomain.example.com"));
78  
79        try (InputStream in = sslSocket.getInputStream();
80            OutputStream out = sslSocket.getOutputStream()) {
81          plainSocket.setOutboundFileDescriptors(FileDescriptor.err);
82          System.out.println("Writing byte...");
83          out.write(0xAF);
84          out.flush();
85  
86          byte[] by = new byte[11];
87          int r = in.read(by);
88          System.out.println("Received string: " + new String(by, 0, r, StandardCharsets.UTF_8));
89        }
90      }
91    }
92  }