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

Add rsa_pss support in wolfJSSE #218

Merged
merged 1 commit into from
Sep 5, 2024
Merged
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
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