Merge pull request #75 from cconlon/scr

wrap secure renegotiation API, enable in wolfJSSE
pull/107/head
JacobBarthelmeh 2022-08-19 10:10:31 -06:00 committed by GitHub
commit 0761b5fa21
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 257 additions and 2 deletions

View File

@ -155,8 +155,34 @@ in the [./platform/android_aosp](./platform/android_aosp) directory.
Additional instructions can be found on the wolfSSL.com website:
[Installing a JSSE Provider in Android OSP](https://www.wolfssl.com/docs/installing-a-jsse-provider-in-android-osp/).
## Behavior and Functionality Notes
### Secure Renegotiation Support
wolfSSL JNI and JSSE provider wrap native wolfSSL APIs to enable and conduct
secure renegotiation. For secure renegotiation functionality to be available
in wolfSSL JNI, and enabled for use in wolfJSSE, native wolfSSL must be
compiled with secure renegotiation support:
```
$ ./configure --enable-secure-renegotiation
```
Or by defining `-DHAVE_SECURE_RENEGOTIATION`.
## Release Notes
### wolfSSL JNI Release X.X.X (TBD)
Future release X.X.X has bug fixes and new features including:
**JNI and JSSE Changes:**
* Add support for secure renegotiation if available in native wolfSSL (PR 75)
The wolfSSL JNI Manual is available at:
https://www.wolfssl.com/documentation/manuals/wolfssljni. For build
instructions and more detailed comments, please check the manual.
### wolfSSL JNI Release 1.10.0 (8/11/2022)
Release 1.10.0 has bug fixes and new features including:

View File

@ -1267,11 +1267,13 @@ JNIEXPORT jstring JNICALL Java_com_wolfssl_WolfSSL_getAvailableCipherSuitesIana
if (ianaName != NULL) {
/* colon separated list */
if (i != 0 && (XSTRLEN(cipherList) + 1) < sizeof(cipherList)) {
XSTRNCAT(cipherList, ":", 1);
XSTRNCAT(cipherList, ":",
sizeof(cipherList) - XSTRLEN(cipherList) - 1);
}
if ((XSTRLEN(ianaName) + XSTRLEN(cipherList) + 1) <
sizeof(cipherList)) {
XSTRNCAT(cipherList, ianaName, XSTRLEN(ianaName));
XSTRNCAT(cipherList, ianaName,
sizeof(cipherList) - XSTRLEN(cipherList) - 1);
}
}
}

View File

@ -5271,3 +5271,17 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLContext_usePskIdentityHint
#endif
}
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLContext_useSecureRenegotiation
(JNIEnv* jenv, jobject jcl, jlong ctx)
{
(void)jenv;
(void)jcl;
#ifdef HAVE_SECURE_RENEGOTIATION
return (jint)wolfSSL_CTX_UseSecureRenegotiation(
(WOLFSSL_CTX*)(uintptr_t)ctx);
#else
(void)ctx;
return NOT_COMPILED_IN;
#endif
}

View File

@ -351,6 +351,14 @@ JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLContext_setPskServerCb
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLContext_usePskIdentityHint
(JNIEnv *, jobject, jlong, jstring);
/*
* Class: com_wolfssl_WolfSSLContext
* Method: useSecureRenegotiation
* Signature: (J)I
*/
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLContext_useSecureRenegotiation
(JNIEnv *, jobject, jlong);
#ifdef __cplusplus
}
#endif

View File

@ -3784,6 +3784,32 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_useALPN
return ret;
}
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_useSecureRenegotiation
(JNIEnv* jenv, jobject jcl, jlong ssl)
{
(void)jenv;
(void)jcl;
#ifdef HAVE_SECURE_RENEGOTIATION
return (jint)wolfSSL_UseSecureRenegotiation((WOLFSSL*)(uintptr_t)ssl);
#else
(void)ssl;
return NOT_COMPILED_IN;
#endif
}
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_rehandshake
(JNIEnv* jenv, jobject jcl, jlong ssl)
{
(void)jenv;
(void)jcl;
#ifdef HAVE_SECURE_RENEGOTIATION
return (jint)wolfSSL_Rehandshake((WOLFSSL*)(uintptr_t)ssl);
#else
(void)ssl;
return NOT_COMPILED_IN;
#endif
}
JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLSession_setSSLIORecv
(JNIEnv* jenv, jobject jcl, jlong sslPtr)
{

View File

@ -727,6 +727,22 @@ JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_WolfSSLSession_sslGet0AlpnSelected
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_useALPN
(JNIEnv *, jobject, jlong, jstring, jint);
/*
* Class: com_wolfssl_WolfSSLSession
* Method: useSecureRenegotiation
* Signature: (J)I
*/
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_useSecureRenegotiation
(JNIEnv *, jobject, jlong);
/*
* Class: com_wolfssl_WolfSSLSession
* Method: rehandshake
* Signature: (J)I
*/
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_rehandshake
(JNIEnv *, jobject, jlong);
#ifdef __cplusplus
}
#endif

View File

@ -361,6 +361,7 @@ public class WolfSSLContext {
private native void setPskClientCb(long ctx);
private native void setPskServerCb(long ctx);
private native int usePskIdentityHint(long ssl, String hint);
private native int useSecureRenegotiation(long ctx);
/* ------------------- context-specific methods --------------------- */
@ -1730,6 +1731,25 @@ public class WolfSSLContext {
return usePskIdentityHint(getContextPtr(), hint);
}
/**
* Enable use of secure renegotiation on this session. Calling this
* API does not initiate secure renegotiation, but enables it. If enabled,
* and peer requests secure renegotiation, this session will renegotiate.
*
* @return <code>WolfSSL.SSL_SUCCESS</code> on success, otherwise negative.
* Will return <code>WolfSSL.NOT_COMPILED_IN</code> if native
* wolfSSL has not been compiled with
* <code>HAVE_SECURE_RENEGOTIATION</code>.
* @throws IllegalStateException WolfSSLSession has been freed
*/
public int useSecureRenegotiation() throws IllegalStateException {
if (this.active == false)
throw new IllegalStateException("Object has been freed");
return useSecureRenegotiation(getContextPtr());
}
@SuppressWarnings("deprecation")
@Override
protected void finalize() throws Throwable

View File

@ -279,6 +279,8 @@ public class WolfSSLSession {
private native int sslSetAlpnProtos(long ssl, byte[] alpnProtos);
private native byte[] sslGet0AlpnSelected(long ssl);
private native int useALPN(long ssl, String protocols, int options);
private native int useSecureRenegotiation(long ssl);
private native int rehandshake(long ssl);
/* ------------------- session-specific methods --------------------- */
@ -2854,6 +2856,74 @@ public class WolfSSLSession {
}
}
/**
* Enable use of secure renegotiation on this session. Calling this
* API does not initiate secure renegotiation, but enables it. If enabled,
* and peer requests secure renegotiation, this session will renegotiate.
*
* @return <code>WolfSSL.SSL_SUCCESS</code> on success, otherwise negative.
* Will return <code>WolfSSL.NOT_COMPILED_IN</code> if native
* wolfSSL has not been compiled with
* <code>HAVE_SECURE_RENEGOTIATION</code>.
* @throws IllegalStateException WolfSSLSession has been freed
*/
public int useSecureRenegotiation() throws IllegalStateException {
if (this.active == false)
throw new IllegalStateException("Object has been freed");
return useSecureRenegotiation(getSessionPtr());
}
/**
* Enable use of secure renegotiation on this session. Calling this
* API does not initiate secure renegotiation, but enables it. If enabled,
* and peer requests secure renegotiation, this session will renegotiate.
*
* @return WolfSSL.SSL_SUCCESS on success, otherwise negative. Will
* return WolfSSL.NOT_COMPILED_IN if native wolfSSL has not been
* compiled with HAVE_SECURE_RENEGOTIATION.
* @throws IllegalStateException WolfSSLSession has been freed
*/
/**
* Initiates a secure renegotiation attempt with the peer.
* For this function to attempt a secure renegotiation,
* <code>useSecureRenegotiation()</code> must be called prior to calling
* this method. When called, the underlying communication channel should
* also already be set up.
* <p>
* <code>rehandshake()</code> works with both blocking and non-blocking I/O.
* When the underlying I/O is non-blocking, <code>rehandshake()</code> will
* return when the underlying I/O could not satisfy the needs of
* <code>rehandshake()</code> to continue the handshake. In this case, a
* call to <code>getError</code> will yield either
* <b>SSL_ERROR_WANT_READ</b> or <b>SSL_ERROR_WANT_WRITE</b>. The calling
* process must then repeat the call to <code>rehandshake()</code> when the
* underlying I/O is ready and wolfSSL will pick up where it left off.
* <p>
* If the underlying I/O is blocking, <code>rehandshake()</code> will only
* return once the handshake has been finished or an error occurred.
* </p>
*
* @return <code>SSL_SUCCESS</code> if successful, otherwise
* <code>SSL_FATAL_ERROR</code> if an error occurred. To get
* a more detailed error code, call <code>getError()</code>.
* <code>WolfSSL.NOT_COMPILED_IN</code> will be returned if
* native wolfSSL has not been compiled with
* <code>HAVE_SECURE_RENEGOTIATION</code>.
* <code>WolfSSL.SECURE_RENEGOTIATION_E</code> will be returned
* if secure renegotiation has not been enabled for this session,
* or a secure renegotiation error has occurred.
* @throws IllegalStateException WolfSSLContext has been freed
*/
public int rehandshake() throws IllegalStateException {
if (this.active == false)
throw new IllegalStateException("Object has been freed");
return rehandshake(getSessionPtr());
}
/**
* Getter function to tell if shutdown has been sent or received
* @return WolfSSL.SSL_SENT_SHUTDOWN or WolfSSL.SSL_RECEIVED_SHUTDOWN

View File

@ -647,6 +647,20 @@ public class WolfSSLEngineHelper {
}
}
private void setLocalSecureRenegotiation() {
/* Enable secure renegotiation if native wolfSSL has been compiled
* with HAVE_SECURE_RENEGOTIATION. Some JSSE consuming apps
* expect that secure renegotiation will be supported. */
int ret = this.ssl.useSecureRenegotiation();
if (ret != WolfSSL.SSL_SUCCESS && ret != WolfSSL.NOT_COMPILED_IN) {
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
"error enabling secure renegotiation, ret = " + ret);
} else if (ret == 0) {
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
"enabled secure renegotiation support for session");
}
}
private void setLocalParams() {
this.setLocalCiphers(this.params.getCipherSuites());
this.setLocalProtocol(this.params.getProtocols());
@ -654,6 +668,7 @@ public class WolfSSLEngineHelper {
this.setLocalServerNames();
this.setLocalSessionTicket();
this.setLocalAlpnProtocols();
this.setLocalSecureRenegotiation();
}
/**

View File

@ -61,6 +61,7 @@ public class WolfSSLContextTest {
test_WolfSSLContext_setPskClientCb();
test_WolfSSLContext_setPskServerCb();
test_WolfSSLContext_usePskIdentityHint();
test_WolfSSLContext_useSecureRenegotiation();
test_WolfSSLContext_free();
}
@ -328,6 +329,22 @@ public class WolfSSLContextTest {
System.out.println("\t\t... passed");
}
public void test_WolfSSLContext_useSecureRenegotiation() {
System.out.print("\tuseSecureRenegotiation()");
try {
int ret = ctx.useSecureRenegotiation();
if (ret != WolfSSL.SSL_SUCCESS &&
ret != WolfSSL.NOT_COMPILED_IN) {
System.out.println("\t... failed");
fail("useSecureRenegotiation failed");
}
} catch (IllegalStateException e) {
System.out.println("\t... failed");
e.printStackTrace();
}
System.out.println("\t... passed");
}
public void test_WolfSSLContext_free() {
System.out.print("\tfree()");

View File

@ -83,6 +83,7 @@ public class WolfSSLSessionTest {
test_WolfSSLSession_freeSSL();
test_WolfSSLSession_UseAfterFree();
test_WolfSSLSession_getSessionID();
test_WolfSSLSession_useSecureRenegotiation();
}
public void test_WolfSSLSession_new() {
@ -611,5 +612,45 @@ public class WolfSSLSessionTest {
System.out.println("\t\t... passed");
}
public void test_WolfSSLSession_useSecureRenegotiation() {
int ret, err;
WolfSSL sslLib = null;
WolfSSLContext sslCtx = null;
WolfSSLSession ssl = null;
Socket sock = null;
byte[] sessionID = null;
System.out.print("\tTesting useSecureRenegotiation()");
try {
/* setup library, context, session, socket */
sslLib = new WolfSSL();
sslCtx = new WolfSSLContext(WolfSSL.TLSv1_2_ClientMethod());
sslCtx.setVerify(WolfSSL.SSL_VERIFY_NONE, null);
ssl = new WolfSSLSession(sslCtx);
/* test if enable call succeeds */
ret = ssl.useSecureRenegotiation();
if (ret != WolfSSL.SSL_SUCCESS && ret != WolfSSL.NOT_COMPILED_IN) {
System.out.println("... failed");
ssl.freeSSL();
sslCtx.free();
return;
}
ssl.freeSSL();
sslCtx.free();
} catch (Exception e) {
System.out.println("... failed");
e.printStackTrace();
return;
}
System.out.println("... passed");
}
}