Skip to content

Commit

Permalink
Merge pull request #218 from sstefonic/addRsaPss
Browse files Browse the repository at this point in the history
Add rsa_pss support in wolfJSSE
  • Loading branch information
cconlon authored Sep 5, 2024
2 parents 74101dd + bde37ee commit 6f16431
Show file tree
Hide file tree
Showing 13 changed files with 171 additions and 1 deletion.
Binary file modified examples/provider/ca-client.jks
Binary file not shown.
Binary file modified examples/provider/ca-server.jks
Binary file not shown.
Binary file added examples/provider/client-rsapss.jks
Binary file not shown.
Binary file added examples/provider/server-rsapss.jks
Binary file not shown.
16 changes: 16 additions & 0 deletions examples/provider/update-jks.sh
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,12 @@ rm client-ecc.jks &> /dev/null
add_cert_key "client-ecc.jks" "/client-ecc-cert.pem" "/ecc-client-key.pem" "client-ecc" "wolfSSL test"
printf "done\n"

# Client cert: RSAPSS only
printf "\tCreating client-rsapss.jks ..."
rm client-rsapss.jks &> /dev/null
add_cert_key "client-rsapss.jks" "/rsapss/client-rsapss.pem" "/rsapss/client-rsapss-priv.pem" "client-rsapss" "wolfSSL test"
printf "done\n"

#################### SERVER KEYSTORES ####################

# Server cert: both RSA 2048-bit and ECC
Expand Down Expand Up @@ -134,6 +140,12 @@ rm server-ecc.jks &> /dev/null
add_cert_key "server-ecc.jks" "/server-ecc.pem" "/ecc-key.pem" "server-ecc" "wolfSSL test"
printf "done\n"

# Server cert: RSAPSS only
printf "\tCreating server-rsapss.jks ..."
rm server-rsapss.jks &> /dev/null
add_cert_key "server-rsapss.jks" "/rsapss/server-rsapss.pem" "/rsapss/server-rsapss-priv.pem" "server-rsapss" "wolfSSL test"
printf "done\n"

#################### CA CERT KEYSTORES ###################

# Contains all CA certs (RSA and ECC), verifies both client and server certs
Expand All @@ -150,18 +162,22 @@ printf "done\n"
# Contains CA certs used to verify client certs:
# client-cert.pem verifies itself (self signed)
# client-ecc-cert.pem verifies itself (self signed)
# client-rsapss.pem verifies itself (self signed)
printf "\tCreating ca-client.jks ..."
rm ca-client.jks &> /dev/null
add_cert_key "ca-client.jks" "/client-cert.pem" "/client-key.pem" "client-rsa" "wolfSSL test"
add_cert_key "ca-client.jks" "/client-ecc-cert.pem" "/ecc-client-key.pem" "client-ecc" "wolfSSL test"
add_cert_key "ca-client.jks" "/rsapss/client-rsapss.pem" "/rsapss/client-rsapss-priv.pem" "client-rsapss" "wolfSSL test"
printf "done\n"

# Contains CA certs used to verify server certs:
# ca-cert.pem verifies server-cert.pem
# ca-ecc-cert.pem verifies server-ecc.pem
# ca-rsapss.pem verifies server-rsapss.pem
printf "\tCreating ca-server.jks ..."
rm ca-server.jks &> /dev/null
add_cert_key "ca-server.jks" "/ca-cert.pem" "/ca-key.pem" "ca-rsa" "wolfSSL test"
add_cert_key "ca-server.jks" "/ca-ecc-cert.pem" "/ca-ecc-key.pem" "ca-ecc" "wolfSSL test"
add_cert_key "ca-server.jks" "/rsapss/ca-rsapss.pem" "/rsapss/ca-rsapss-priv.pem" "ca-rsapss" "wolfSSL test"
printf "done\n"

13 changes: 13 additions & 0 deletions native/com_wolfssl_WolfSSL.c
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,19 @@ JNIEXPORT jboolean JNICALL Java_com_wolfssl_WolfSSL_RsaEnabled
#endif
}

JNIEXPORT jboolean JNICALL Java_com_wolfssl_WolfSSL_RsaPssEnabled
(JNIEnv* jenv, jclass jcl)
{
(void)jenv;
(void)jcl;

#if !defined(NO_RSA) && defined(WC_RSA_PSS)
return JNI_TRUE;
#else
return JNI_FALSE;
#endif
}

JNIEXPORT jboolean JNICALL Java_com_wolfssl_WolfSSL_Curve25519Enabled
(JNIEnv* jenv, jclass jcl)
{
Expand Down
8 changes: 8 additions & 0 deletions native/com_wolfssl_WolfSSL.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions native/com_wolfssl_WolfSSLCertificate.c
Original file line number Diff line number Diff line change
Expand Up @@ -1174,6 +1174,8 @@ JNIEXPORT jstring JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1get_1signatu
return (*jenv)->NewStringUTF(jenv, "SHA512withECDSA");
case CTC_ED25519:
return (*jenv)->NewStringUTF(jenv, "ED25519");
case CTC_RSASSAPSS:
return (*jenv)->NewStringUTF(jenv, "RSASSA-PSS");

default:
(*jenv)->ThrowNew(jenv, jcl, "Unknown signature type");
Expand Down
8 changes: 8 additions & 0 deletions src/java/com/wolfssl/WolfSSL.java
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,14 @@ protected static byte[] fileToBytes(File file)
*/
public static native boolean RsaEnabled();

/**
* Tests if RSA_PSS support has been compiled into the native wolfSSL
* library.
*
* @return true if enabled, otherwise false if not compiled in.
*/
public static native boolean RsaPssEnabled();

/**
* Tests if Curve25519/X25519 support has been compiled into the native
* wolfSSL library.
Expand Down
3 changes: 3 additions & 0 deletions src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,9 @@ private String GetKeyAndCertChainAlias(X509KeyManager km, Socket sock,
}
if (WolfSSL.RsaEnabled()) {
keyAlgos.add("RSA");
if (WolfSSL.RsaPssEnabled()) {
keyAlgos.add("RSASSA-PSS");
}
}

String[] keyTypes = new String[keyAlgos.size()];
Expand Down
4 changes: 3 additions & 1 deletion src/java/com/wolfssl/provider/jsse/WolfSSLKeyX509.java
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,9 @@ public PrivateKey getPrivateKey(String alias) {
try {
key = (PrivateKey)store.getKey(alias, password);
} catch (Exception e) {
/* @TODO unable to get key */
/* @TODO unable to get key */
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
"failed to load private key: " + e);
}
return key;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,12 @@ class WolfSSLTestFactory {
protected String clientRSA1024JKS;
protected String clientRSAJKS;
protected String clientECCJKS;
protected String clientRSAPSSJKS;
protected static String serverJKS;
protected String serverRSA1024JKS;
protected String serverRSAJKS;
protected String serverECCJKS;
protected String serverRSAPSSJKS;
protected String caJKS;
protected static String caClientJKS;
protected String caServerJKS;
Expand All @@ -91,10 +93,12 @@ protected WolfSSLTestFactory() throws WolfSSLException {
* client-rsa-1024.jks RSA 1024-bit only client cert
* client-rsa.jks RSA 2048-bit only client cert
* client-ecc.jks ECC only client cert
* client-rsapss.jks RSA_PSS only client cert
* server.jks RSA 2048-bit and ECC server certs
* server-rsa-1024.jks RSA 1024-bit only server cert
* server-rsa.jks RSA 2048-bit only server cert
* server-ecc.jks ECC only server cert
* server-rsapss.jks RSA_PSS only server cert
* cacerts.jks All CA certs (RSA, ECC, 1024, 2048, etc)
* ca-client.jks CA certs used to verify client certs
* ca-server.jks CA certs used to verify server certs */
Expand All @@ -104,10 +108,12 @@ protected WolfSSLTestFactory() throws WolfSSLException {
clientRSA1024JKS = "examples/provider/client-rsa-1024.jks";
clientRSAJKS = "examples/provider/client-rsa.jks";
clientECCJKS = "examples/provider/client-ecc.jks";
clientRSAPSSJKS = "examples/provider/client-rsapss.jks";
serverJKS = "examples/provider/server.jks";
serverRSA1024JKS = "examples/provider/server-rsa-1024.jks";
serverRSAJKS = "examples/provider/server-rsa.jks";
serverECCJKS = "examples/provider/server-ecc.jks";
serverRSAPSSJKS = "examples/provider/server-rsapss.jks";
caJKS = "examples/provider/cacerts.jks";
caClientJKS = "examples/provider/ca-client.jks";
caServerJKS = "examples/provider/ca-server.jks";
Expand Down Expand Up @@ -141,10 +147,12 @@ private void setPaths(String in) {
clientRSA1024JKS = in.concat(clientRSA1024JKS);
clientRSAJKS = in.concat(clientRSAJKS);
clientECCJKS = in.concat(clientECCJKS);
clientRSAPSSJKS = in.concat(clientRSAPSSJKS);
serverJKS = in.concat(serverJKS);
serverRSA1024JKS = in.concat(serverRSA1024JKS);
serverRSAJKS = in.concat(serverRSAJKS);
serverECCJKS = in.concat(serverECCJKS);
serverRSAPSSJKS = in.concat(serverRSAPSSJKS);
caJKS = in.concat(caJKS);
caClientJKS = in.concat(caClientJKS);
caServerJKS = in.concat(caServerJKS);
Expand Down
110 changes: 110 additions & 0 deletions src/test/com/wolfssl/provider/jsse/test/WolfSSLTrustX509Test.java
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,57 @@ public void testVerify()
pass("\t\t\t... passed");
}

@Test
public void testVerifyRsaPss()
throws NoSuchProviderException, NoSuchAlgorithmException,
KeyStoreException, FileNotFoundException, IOException,
CertificateException {

/* skip if RSA_PSS is not compiled in at native level */
if (WolfSSL.RsaPssEnabled() == false) {
return;
}

TrustManager[] tm;
X509TrustManager x509tm;
X509Certificate cas[];
InputStream stream;
KeyStore ks;

System.out.print("\tTesting verify rsa_pss");

tm = tf.createTrustManager("SunX509", tf.caServerJKS, provider);
if (tm == null) {
error("\t\t\t... failed");
fail("failed to create trustmanager");
return;
}

x509tm = (X509TrustManager) tm[0];
cas = x509tm.getAcceptedIssuers();
if (cas == null) {
error("\t\t\t... failed");
fail("no CAs where found");
return;
}

ks = KeyStore.getInstance(tf.keyStoreType);
stream = new FileInputStream(tf.serverRSAPSSJKS);
ks.load(stream, "wolfSSL test".toCharArray());
stream.close();
try {
x509tm.checkServerTrusted(new X509Certificate[] {
(X509Certificate)ks.getCertificate("server-rsapss") }, "RSASSA-PSS");
}
catch (Exception e) {
e.printStackTrace();
error("\t\t... failed");
fail("failed to verify");
}

pass("\t\t... passed");
}

@Test
public void testCheckServerTrustedWithChain()
throws NoSuchProviderException, NoSuchAlgorithmException,
Expand Down Expand Up @@ -1447,6 +1498,65 @@ public void testCheckServerTrustedWithDuplicatedRootInChain()
pass("\t... passed");
}

@Test
public void testUsingRsaPssCert()
throws Exception {
/* skip if RSA_PSS is not compiled in at native level */
if (WolfSSL.RsaPssEnabled() == false) {
return;
}

System.out.print("\tTest using rsa_pss certs");

SSLContext srvCtx = tf.createSSLContext("TLSv1.3", provider,
tf.createTrustManager("SunX509", tf.caClientJKS, provider),
tf.createKeyManager("SunX509", tf.serverRSAPSSJKS, provider));

SSLContext cliCtx = tf.createSSLContext("TLSv1.3", provider,
tf.createTrustManager("SunX509", tf.caServerJKS, provider),
tf.createKeyManager("SunX509", tf.clientRSAPSSJKS, provider));

SSLServerSocket ss = (SSLServerSocket)srvCtx.getServerSocketFactory()
.createServerSocket(0);

TestArgs serverArgs = new TestArgs(null, null, true, true, true, null);
TestSSLSocketServer server = new TestSSLSocketServer(
srvCtx, ss, serverArgs, 1);
server.start();

TestArgs clientArgs = new TestArgs(
"HTTPS", "www.wolfssl.com", false, false, true, null);
TestSSLSocketClient client = new TestSSLSocketClient(
cliCtx, ss.getLocalPort(), clientArgs);
client.start();

try {
client.join(1000);
server.join(1000);
} catch (InterruptedException e) {
System.out.println("interrupt happened");
fail("RSA_PSS cert test failed");
}

/* Fail if client or server encountered exception */
Exception srvException = server.getException();
Exception cliException = client.getException();
if (srvException != null || cliException != null) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
if (srvException != null) {
srvException.printStackTrace(pw);
}
if (cliException != null) {
cliException.printStackTrace(pw);
}
String traceString = sw.toString();
throw new Exception(traceString);
}

pass("\t... passed");
}

@Test
public void testX509ExtendedTrustManagerInternal()
throws CertificateException, IOException, Exception {
Expand Down

0 comments on commit 6f16431

Please sign in to comment.