Skip to content

Commit

Permalink
Add a demo for tls1.3 shangmi cipher suit
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffery.wsj authored and superajun-wsj committed Jun 28, 2023
1 parent 63e8c20 commit 350704e
Show file tree
Hide file tree
Showing 6 changed files with 270 additions and 0 deletions.
77 changes: 77 additions & 0 deletions examples/tls/demo/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.alibaba.dragonwell.security.tls.demo</groupId>
<artifactId>demo</artifactId>
<version>1.0-SNAPSHOT</version>
<name>demo</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<jmh.version>1.35</jmh.version>
</properties>
<dependencies>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>${jmh.version}</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>${jmh.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.70</version>
</dependency>
<dependency>
<groupId>com.alibaba.dragonwell</groupId>
<artifactId>security-native-uber</artifactId>
<version>1.0.0</version>
<!--classifier>${os.detected.classifier}</classifier-->
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.4.1.Final</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
5 changes: 5 additions & 0 deletions examples/tls/demo/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/sh

mvn clean package

java -cp ./target/demo-1.0-SNAPSHOT-jar-with-dependencies.jar com.alibaba.dragonwell.security.tls.demo.SMDemo
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package com.alibaba.dragonwell.security.tls.demo;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;

import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import org.conscrypt.OpenSSLX509Certificate;

public class CertificateBuild {
private static final char[] EMPTY_PASSWORD = new char[0];
private static final String SERVER_CA = "/cert/sm2-root.crt";
private static final String PRIVATE_KEY = "/cert/sm2-root.key";
private static KeyStore ks = null;

static {
try {
// Create an empty keystore
ks = KeyStore.getInstance("PKCS12", new BouncyCastleProvider());
ks.load(null, null);

// Build a service CA
X509Certificate ca = OpenSSLX509Certificate
.fromX509PemInputStream(CertificateBuild.class.getResourceAsStream(SERVER_CA));
PrivateKey privateKey = readSM2PrivateKeyPemFile(PRIVATE_KEY);

ks.setKeyEntry("default", privateKey, EMPTY_PASSWORD, new X509Certificate[] { ca });
ks.setCertificateEntry("CA", ca);
} catch (Exception e) {
e.printStackTrace();
}
}

private static PrivateKey readSM2PrivateKeyPemFile(String name) throws Exception {
InputStream inputStream = CertificateBuild.class.getResourceAsStream(name);
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = bufferedReader.readLine()) != null) {
if (line.startsWith("-")) {
continue;
}
sb.append(line).append("\n");
}
String ecKey = sb.toString().replaceAll("\\r\\n|\\r|\\n", "");
Base64.Decoder base64Decoder = Base64.getDecoder();
byte[] keyByte = base64Decoder.decode(ecKey.getBytes(StandardCharsets.UTF_8));
PKCS8EncodedKeySpec eks2 = new PKCS8EncodedKeySpec(keyByte);
KeyFactory keyFactory = KeyFactory.getInstance("EC", new BouncyCastleProvider());
PrivateKey privateKey = keyFactory.generatePrivate(eks2);
return privateKey;
}

public static KeyManager[] keyManagerBuilder() throws Exception {
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, EMPTY_PASSWORD);
return kmf.getKeyManagers();
}

public static TrustManager[] trustManagerBuilder() throws Exception {
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
return tmf.getTrustManagers();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package com.alibaba.dragonwell.security.tls.demo;

import javax.net.ssl.*;

import com.alibaba.dragonwell.security.DragonwellSecurityProvider;

import java.io.*;
import java.security.*;
import java.util.concurrent.CountDownLatch;

/**
* tls1.3 + rfc8998 demo
*/
public class SMDemo {
private static final String SSL_13_TYPE = "TLSv1.3";
private static final String CIPHER_SUITE = "TLS_SM4_GCM_SM3";
private static final String HELLO_REQUEST = "hello request";
private static final String HELLO_RESPONSE = "hello response";

private static volatile int port = -1;

private static SSLContext createServerSSLContext() throws Exception {
TrustManager[] tms = CertificateBuild.trustManagerBuilder();
KeyManager[] kms = CertificateBuild.keyManagerBuilder();

SSLContext sslContext = SSLContext.getInstance(SSL_13_TYPE, new DragonwellSecurityProvider());
sslContext.init(kms, tms, new SecureRandom());
return sslContext;
}

private static SSLServerSocket buildSSLServerSocket(SSLContext serverContext) throws Exception {
SSLServerSocketFactory serverFactory = serverContext.getServerSocketFactory();
SSLServerSocket svrSocket = (SSLServerSocket) serverFactory.createServerSocket(0);
port = svrSocket.getLocalPort();
svrSocket.setNeedClientAuth(false);
return svrSocket;
}

private static SSLContext createClientSSLContext() throws Exception {
TrustManager[] tms = CertificateBuild.trustManagerBuilder();
SSLContext sslContext = SSLContext.getInstance(SSL_13_TYPE, new DragonwellSecurityProvider());
sslContext.init(null, tms, new SecureRandom());
return sslContext;
}

private static SSLSocket buildSSLClientSocket(SSLContext clientContext) throws Exception {
SSLSocketFactory sslCntFactory = clientContext.getSocketFactory();
SSLSocket sslSocket = (SSLSocket) sslCntFactory.createSocket("localhost", port);
sslSocket.setEnabledCipherSuites(new String[] { CIPHER_SUITE });
return sslSocket;
}

public static void main(String[] args) throws Exception {
CountDownLatch downLatch = new CountDownLatch(1);

// Start server asynchronously.
SSLServerSocket serverSocket = buildSSLServerSocket(createServerSSLContext());
Thread serverThread = new Thread(() -> {
try {
downLatch.countDown();
SSLSocket sslSocket = (SSLSocket) serverSocket.accept();
BufferedReader ioReader = new BufferedReader(new InputStreamReader(sslSocket.getInputStream()));
PrintWriter ioWriter = new PrintWriter(sslSocket.getOutputStream());
String tmpMsg = ioReader.readLine();
if (tmpMsg != null) {
ioWriter.println(HELLO_RESPONSE);
ioWriter.flush();
System.out.println(sslSocket.getSession().getCipherSuite());
Thread.sleep(1_000);
}
} catch (Exception e) {
e.printStackTrace();
}
});
serverThread.setDaemon(true);
serverThread.start();

// Start client.
downLatch.await();
// Wait for server startup.
Thread.sleep(2_000);
SSLSocket clientSocket = buildSSLClientSocket(createClientSSLContext());
BufferedReader ioReader = new BufferedReader(new InputStreamReader(
clientSocket.getInputStream()));
PrintWriter ioWriter = new PrintWriter(clientSocket.getOutputStream());
ioWriter.println(HELLO_REQUEST);
ioWriter.flush();
System.out.println(ioReader.readLine());
clientSocket.close();
}
}
13 changes: 13 additions & 0 deletions examples/tls/demo/src/main/resources/cert/sm2-root.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
-----BEGIN CERTIFICATE-----
MIIB6jCCAZECFE4j9T8o2H4CqpaqcnhX2AenXBR2MAoGCCqBHM9VAYN1MHgxCzAJ
BgNVBAYTAkNIMQswCQYDVQQIDAJaSjELMAkGA1UEBwwCSFoxDDAKBgNVBAoMA0pW
TTEMMAoGA1UECwwDQWxpMQ8wDQYDVQQDDAZzZXJ2ZXIxIjAgBgkqhkiG9w0BCQEW
E3N1cGVyYWp1bkBnbWFpbC5jb20wHhcNMjIxMjI1MTIzNjQzWhcNMjMwMTI0MTIz
NjQzWjB4MQswCQYDVQQGEwJDSDELMAkGA1UECAwCWkoxCzAJBgNVBAcMAkhaMQww
CgYDVQQKDANKVk0xDDAKBgNVBAsMA0FsaTEPMA0GA1UEAwwGc2VydmVyMSIwIAYJ
KoZIhvcNAQkBFhNzdXBlcmFqdW5AZ21haWwuY29tMFkwEwYHKoZIzj0CAQYIKoEc
z1UBgi0DQgAEiyrkFGrfi23L8jWC99NGtX1ph9t8UwPHiAixb3DvRisb5zaHzMJJ
Lmb1wm7iaNRxSNagEq4dcPv7XwhxD7B8sDAKBggqgRzPVQGDdQNHADBEAiBa542C
GtKPrCN2isAJ+snocHZgoWH3r6aSCL889psVMgIgUxt7TquMmZ7EGJBrDDb0sstN
6nksnUhXejscUV6/hdg=
-----END CERTIFICATE-----
5 changes: 5 additions & 0 deletions examples/tls/demo/src/main/resources/cert/sm2-root.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQgaWifCWJvYzRRI3Dq
0rhmNwID3+HF2VE+iD5HPd4DfPihRANCAASLKuQUat+LbcvyNYL300a1fWmH23xT
A8eICLFvcO9GKxvnNofMwkkuZvXCbuJo1HFI1qASrh1w+/tfCHEPsHyw
-----END PRIVATE KEY-----

0 comments on commit 350704e

Please sign in to comment.