JNI: add support for Java Security properties:
- wolfssl.readWriteByteBufferPool.disabled - wolfssl.readWriteByteBufferPool.size - wolfssl.readWriteByteBufferPool.bufferSizepull/268/head
parent
1c8963e4fe
commit
0c4b3190c7
63
README.md
63
README.md
|
@ -431,8 +431,15 @@ used as the default descriptor monitoring function.
|
||||||
wolfJSSE allows for some customization through the `java.security` file
|
wolfJSSE allows for some customization through the `java.security` file
|
||||||
and use of Security properties.
|
and use of Security properties.
|
||||||
|
|
||||||
|
#### Pre-Existing Java Security Properties
|
||||||
|
|
||||||
Support is included for the following pre-existing Java Security properties.
|
Support is included for the following pre-existing Java Security properties.
|
||||||
|
|
||||||
|
| System Property | Default | To Enable | Description |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| keystore.type | JKS | String | Specifies the default KeyStore type |
|
||||||
|
| jdk.tls.disabledAlgorithms | | String | Disables algorithms, TLS protocol versions, and key lengths |
|
||||||
|
|
||||||
**keystore.type (String)** - Specifies the default KeyStore type. This defaults
|
**keystore.type (String)** - Specifies the default KeyStore type. This defaults
|
||||||
to JKS, but could be set to something else if desired.
|
to JKS, but could be set to something else if desired.
|
||||||
|
|
||||||
|
@ -446,12 +453,60 @@ minimum RSA/ECC/DH key sizes. An example of potential use:
|
||||||
jdk.tls.disabledAlgorithms=SSLv3, TLSv1.1, DH keySize < 1024, EC keySize < 224, RSA keySize < 1024
|
jdk.tls.disabledAlgorithms=SSLv3, TLSv1.1, DH keySize < 1024, EC keySize < 224, RSA keySize < 1024
|
||||||
```
|
```
|
||||||
|
|
||||||
The following custom wolfJSSE-specific Security property settings are supported.
|
#### wolfSSL JNI/JSSE Specific Security Properties
|
||||||
These can be placed into the `java.security` file and will be parsed and used
|
|
||||||
by wolfJSSE.
|
The following custom wolfSSL JNI/JSSE specific Security property settings are
|
||||||
|
supported. These can be placed into the `java.security` file and will be parsed
|
||||||
|
and used by wolfSSL JNI/JSSE.
|
||||||
|
|
||||||
|
| System Property | Default | To Enable | Description |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| wolfssl.readWriteByteBufferPool.disabled | "false" | "true" | Disables the read/write ByteBuffer pool |
|
||||||
|
| wolfssl.readWriteByteBufferPool.size | 16 | Integer | Sets the read/write per-thread ByteBuffer pool size |
|
||||||
|
| wolfssl.readWriteByteBufferPool.bufferSize | 17408 | String | Sets the read/write per-thread ByteBuffer size |
|
||||||
|
| wolfjsse.enabledCipherSuites | | String | Restricts enabled cipher suites |
|
||||||
|
| wolfjsse.enabledSupportedCurves | | String | Restricts enabled ECC curves |
|
||||||
|
| wolfjsse.enabledSignatureAlgorithms | | String | Restricts enabled signature algorithms |
|
||||||
|
| wolfjsse.keystore.type.required | | String | Restricts KeyStore type |
|
||||||
|
| wolfjsse.clientSessionCache.disabled | | "true" | Disables client session cache |
|
||||||
|
|
||||||
|
**wolfssl.readWriteByteBufferPool.disabled (String)** - Can be used to disable
|
||||||
|
the static per-thread ByteBuffer pool used in com.wolfssl.WolfSSLSession
|
||||||
|
for native JNI wolfSS\_read() and wolfSSL\_write() calls. This pool is in place
|
||||||
|
to prevent unaligned memory access at the JNI level when using byte array
|
||||||
|
offsets. This pool is enabled by default unless explicitly disabled by setting
|
||||||
|
this property to "true":
|
||||||
|
|
||||||
|
```
|
||||||
|
wolfssl.readWriteByteBufferPool.disabled=true
|
||||||
|
```
|
||||||
|
|
||||||
|
**wolfssl.readWriteByteBufferPool.size (Integer)** - Can be used to set the
|
||||||
|
maximum per-thread ByteBuffer pool size. This is the maximum number of
|
||||||
|
direct ByteBuffer objects that will be allocated and added to the pool. The
|
||||||
|
pool starts at size 0, then grows as needed up to this maximum size. The
|
||||||
|
default is 16. This should be set to a positive integer value:
|
||||||
|
|
||||||
|
```
|
||||||
|
wolfssl.readWriteByteBufferPool.size=16
|
||||||
|
```
|
||||||
|
|
||||||
|
**wolfssl.readWriteByteBufferPool.bufferSize (String)** - Can be used to set
|
||||||
|
the size of each direct ByteBuffer in the static per-thread WolfSSLSession
|
||||||
|
pool. This is set to 17k (17 * 1024) by default which allows for the maximum
|
||||||
|
SSL/TLS record size of 2^14 (16k) plus some extra space for the record header
|
||||||
|
overhead. This should be set to a positive integer value. This can be used
|
||||||
|
to optimize performance if the size of data an application is reading/writing
|
||||||
|
is known. If sized properly, fewer read/write loops will need to be done
|
||||||
|
when calling native `wolfSSL_read()` and `wolfSSL_write()` inside
|
||||||
|
com.wolfssl.WolfSSLSession read() and write() methods.
|
||||||
|
|
||||||
|
```
|
||||||
|
wolfssl.readWriteByteBufferPool.bufferSize=17408
|
||||||
|
```
|
||||||
|
|
||||||
**wolfjsse.enabledCipherSuites (String)** - Allows restriction of the enabled
|
**wolfjsse.enabledCipherSuites (String)** - Allows restriction of the enabled
|
||||||
cipher suiets to those listed in this Security property. When set, applications
|
cipher suites to those listed in this Security property. When set, applications
|
||||||
wil not be able to override or add additional suites at runtime without
|
wil not be able to override or add additional suites at runtime without
|
||||||
changing this property. This should be a comma-delimited String. Example use:
|
changing this property. This should be a comma-delimited String. Example use:
|
||||||
|
|
||||||
|
|
|
@ -7,10 +7,6 @@
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
#undef com_wolfssl_WolfSSLSession_MAX_POOL_SIZE
|
|
||||||
#define com_wolfssl_WolfSSLSession_MAX_POOL_SIZE 32L
|
|
||||||
#undef com_wolfssl_WolfSSLSession_BUFFER_SIZE
|
|
||||||
#define com_wolfssl_WolfSSLSession_BUFFER_SIZE 17408L
|
|
||||||
/*
|
/*
|
||||||
* Class: com_wolfssl_WolfSSLSession
|
* Class: com_wolfssl_WolfSSLSession
|
||||||
* Method: newSSL
|
* Method: newSSL
|
||||||
|
|
|
@ -31,6 +31,7 @@ import java.lang.StringBuilder;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
|
import java.security.Security;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wraps a native WolfSSL session object and contains methods directly related
|
* Wraps a native WolfSSL session object and contains methods directly related
|
||||||
|
@ -109,6 +110,9 @@ public class WolfSSLSession {
|
||||||
/* lock around native WOLFSSL pointer use */
|
/* lock around native WOLFSSL pointer use */
|
||||||
private final Object sslLock = new Object();
|
private final Object sslLock = new Object();
|
||||||
|
|
||||||
|
/* Is static direct ByteBuffer pool enabled for read/write() calls */
|
||||||
|
private boolean byteBufferPoolEnabled = true;
|
||||||
|
|
||||||
/* Maximum direct ByteBuffer pool size */
|
/* Maximum direct ByteBuffer pool size */
|
||||||
private static int MAX_POOL_SIZE = 16;
|
private static int MAX_POOL_SIZE = 16;
|
||||||
|
|
||||||
|
@ -127,13 +131,134 @@ public class WolfSSLSession {
|
||||||
private static final ThreadLocal<ConcurrentLinkedQueue<ByteBuffer>> directBufferPool =
|
private static final ThreadLocal<ConcurrentLinkedQueue<ByteBuffer>> directBufferPool =
|
||||||
ThreadLocal.withInitial(() -> new ConcurrentLinkedQueue<>());
|
ThreadLocal.withInitial(() -> new ConcurrentLinkedQueue<>());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if static direct ByteBuffer pool has been disabled for
|
||||||
|
* use in read/write() methods.
|
||||||
|
*
|
||||||
|
* The pool is enabled by default, unless explicitly disabled by setting
|
||||||
|
* the "wolfssl.readWriteByteBufferPool.disabled" property to "true".
|
||||||
|
*
|
||||||
|
* @return true if disabled, otherwise false
|
||||||
|
*/
|
||||||
|
private boolean readWritePoolDisabled() {
|
||||||
|
|
||||||
|
String disabled =
|
||||||
|
Security.getProperty("wolfssl.readWriteByteBufferPool.disabled");
|
||||||
|
|
||||||
|
if (disabled == null || disabled.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (disabled.equalsIgnoreCase("true")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the maximum size of the static per-thread direct
|
||||||
|
* ByteBuffer pool has been adjusted by setting of the
|
||||||
|
* "wolfssl.readWriteByteBufferPool.size" Security property.
|
||||||
|
*
|
||||||
|
* @return the size set, or the current default
|
||||||
|
* (MAX_POOL_SIZE) if not.
|
||||||
|
*/
|
||||||
|
private int readWritePoolGetMaxSizeFromProperty() {
|
||||||
|
|
||||||
|
int maxSize = MAX_POOL_SIZE;
|
||||||
|
|
||||||
|
String sizeProp =
|
||||||
|
Security.getProperty("wolfssl.readWriteByteBufferPool.size");
|
||||||
|
|
||||||
|
if (sizeProp == null || sizeProp.isEmpty()) {
|
||||||
|
return maxSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
int size = Integer.parseInt(sizeProp);
|
||||||
|
if (size > 0) {
|
||||||
|
maxSize = size;
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
WolfSSLDebug.log(getClass(),
|
||||||
|
WolfSSLDebug.Component.JNI, WolfSSLDebug.ERROR, 0,
|
||||||
|
() -> "Invalid value for " +
|
||||||
|
"wolfssl.readWriteByteBufferPool.size: " + sizeProp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return maxSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the size of the ByteBuffers in the static per-thread
|
||||||
|
* pool has been adjusted by setting of the
|
||||||
|
* "wolfssl.readWriteByteBufferPool.bufferSize" Security property.
|
||||||
|
*
|
||||||
|
* @return the size set, or the current default (BUFFER_SIZE) if not.
|
||||||
|
*/
|
||||||
|
private int readWritePoolGetBufferSizeFromProperty() {
|
||||||
|
|
||||||
|
int bufferSize = BUFFER_SIZE;
|
||||||
|
|
||||||
|
String sizeProp =
|
||||||
|
Security.getProperty("wolfssl.readWriteByteBufferPool.bufferSize");
|
||||||
|
|
||||||
|
if (sizeProp == null || sizeProp.isEmpty()) {
|
||||||
|
return bufferSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
int size = Integer.parseInt(sizeProp);
|
||||||
|
if (size > 0) {
|
||||||
|
bufferSize = size;
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
WolfSSLDebug.log(getClass(),
|
||||||
|
WolfSSLDebug.Component.JNI, WolfSSLDebug.ERROR, 0,
|
||||||
|
() -> "Invalid value for " +
|
||||||
|
"wolfssl.readWriteByteBufferPool.bufferSize: " + sizeProp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bufferSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read current values of relevant Security properties and set
|
||||||
|
* internal behavior.
|
||||||
|
*/
|
||||||
|
private void detectSecurityPropertySettings() {
|
||||||
|
|
||||||
|
/* Re-use sslLock for synchronization here */
|
||||||
|
synchronized (sslLock) {
|
||||||
|
/* Check if static direct ByteBuffer pool has been disabled
|
||||||
|
* with the "wolfssl.readWriteByteBufferPool.disabled"
|
||||||
|
* Security property. */
|
||||||
|
if (readWritePoolDisabled()) {
|
||||||
|
this.byteBufferPoolEnabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if the maximum size of the static per-thread direct
|
||||||
|
* ByteBuffer pool has been adjusted by setting of the
|
||||||
|
* "wolfssl.readWriteByteBufferPool.size" Security property. */
|
||||||
|
WolfSSLSession.MAX_POOL_SIZE =
|
||||||
|
readWritePoolGetMaxSizeFromProperty();
|
||||||
|
|
||||||
|
/* Check if the size of the ByteBuffers in the static per-thread
|
||||||
|
* pool has been adjusted by setting of the
|
||||||
|
* "wolfssl.readWriteByteBufferPool.bufferSize" Security property. */
|
||||||
|
WolfSSLSession.BUFFER_SIZE =
|
||||||
|
readWritePoolGetBufferSizeFromProperty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a DirectByteBuffer from the thread-local pool or allocate a new one
|
* Get a DirectByteBuffer from the thread-local pool or allocate a new one
|
||||||
* if the pool is empty.
|
* if the pool is empty.
|
||||||
*
|
*
|
||||||
* @return a direct ByteBuffer ready to use
|
* @return a direct ByteBuffer ready to use
|
||||||
*/
|
*/
|
||||||
private static ByteBuffer acquireDirectBuffer() {
|
private static synchronized ByteBuffer acquireDirectBuffer() {
|
||||||
ConcurrentLinkedQueue<ByteBuffer> threadPool = directBufferPool.get();
|
ConcurrentLinkedQueue<ByteBuffer> threadPool = directBufferPool.get();
|
||||||
ByteBuffer buffer = threadPool.poll();
|
ByteBuffer buffer = threadPool.poll();
|
||||||
if (buffer == null) {
|
if (buffer == null) {
|
||||||
|
@ -159,7 +284,7 @@ public class WolfSSLSession {
|
||||||
*
|
*
|
||||||
* @param buffer the buffer to return to the pool
|
* @param buffer the buffer to return to the pool
|
||||||
*/
|
*/
|
||||||
private static void releaseDirectBuffer(ByteBuffer buffer) {
|
private static synchronized void releaseDirectBuffer(ByteBuffer buffer) {
|
||||||
|
|
||||||
if (buffer != null && buffer.isDirect()) {
|
if (buffer != null && buffer.isDirect()) {
|
||||||
|
|
||||||
|
@ -207,6 +332,8 @@ public class WolfSSLSession {
|
||||||
WolfSSLDebug.INFO, sslPtr,
|
WolfSSLDebug.INFO, sslPtr,
|
||||||
() -> "creating new WolfSSLSession (with I/O pipe)");
|
() -> "creating new WolfSSLSession (with I/O pipe)");
|
||||||
|
|
||||||
|
detectSecurityPropertySettings();
|
||||||
|
|
||||||
synchronized (stateLock) {
|
synchronized (stateLock) {
|
||||||
this.active = true;
|
this.active = true;
|
||||||
}
|
}
|
||||||
|
@ -254,6 +381,8 @@ public class WolfSSLSession {
|
||||||
() -> "creating new WolfSSLSession (without I/O pipe)");
|
() -> "creating new WolfSSLSession (without I/O pipe)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
detectSecurityPropertySettings();
|
||||||
|
|
||||||
synchronized (stateLock) {
|
synchronized (stateLock) {
|
||||||
this.active = true;
|
this.active = true;
|
||||||
}
|
}
|
||||||
|
@ -1111,6 +1240,12 @@ public class WolfSSLSession {
|
||||||
* "buffer + offset" and end up with unaligned memory which
|
* "buffer + offset" and end up with unaligned memory which
|
||||||
* can be slow on some targets (ex: ARM/Aarch64) */
|
* can be slow on some targets (ex: ARM/Aarch64) */
|
||||||
try {
|
try {
|
||||||
|
if (!this.byteBufferPoolEnabled) {
|
||||||
|
/* Throw exception so we fall back to using byte[] in the
|
||||||
|
* catch block below */
|
||||||
|
throw new Exception("ByteBuffer pool not enabled");
|
||||||
|
}
|
||||||
|
|
||||||
/* Get a buffer from the pool */
|
/* Get a buffer from the pool */
|
||||||
directBuffer = acquireDirectBuffer();
|
directBuffer = acquireDirectBuffer();
|
||||||
|
|
||||||
|
@ -1137,6 +1272,7 @@ public class WolfSSLSession {
|
||||||
|
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
/* Error occurred, break out of loop */
|
/* Error occurred, break out of loop */
|
||||||
|
err = getError(ret);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1164,7 +1300,7 @@ public class WolfSSLSession {
|
||||||
|
|
||||||
/* Return total bytes written, or last error code */
|
/* Return total bytes written, or last error code */
|
||||||
final int finalRet = (totalWritten > 0) ? totalWritten : ret;
|
final int finalRet = (totalWritten > 0) ? totalWritten : ret;
|
||||||
final int finalErr = getError(finalRet);
|
final int finalErr = err;
|
||||||
final int finalTotal = totalWritten;
|
final int finalTotal = totalWritten;
|
||||||
|
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
||||||
|
@ -1331,6 +1467,12 @@ public class WolfSSLSession {
|
||||||
* do "buffer + offset" and end up with unaligned memory which
|
* do "buffer + offset" and end up with unaligned memory which
|
||||||
* can be slow on some targets (ex: ARM/Aarch64) */
|
* can be slow on some targets (ex: ARM/Aarch64) */
|
||||||
try {
|
try {
|
||||||
|
if (!this.byteBufferPoolEnabled) {
|
||||||
|
/* Throw exception so we fall back to using byte[] in the
|
||||||
|
* catch block below */
|
||||||
|
throw new Exception("ByteBuffer pool not enabled");
|
||||||
|
}
|
||||||
|
|
||||||
/* Get a buffer from the pool */
|
/* Get a buffer from the pool */
|
||||||
directBuffer = acquireDirectBuffer();
|
directBuffer = acquireDirectBuffer();
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@ import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.security.Security;
|
||||||
|
|
||||||
import com.wolfssl.WolfSSL;
|
import com.wolfssl.WolfSSL;
|
||||||
import com.wolfssl.WolfSSLDebug;
|
import com.wolfssl.WolfSSLDebug;
|
||||||
|
@ -70,6 +71,10 @@ public class WolfSSLSessionTest {
|
||||||
|
|
||||||
private static WolfSSLContext ctx = null;
|
private static WolfSSLContext ctx = null;
|
||||||
|
|
||||||
|
/* Lock around WolfSSLSession static per-thread ByteBuffer pool
|
||||||
|
* Security property use in this test class */
|
||||||
|
private static final Object byteBufferPoolPropertyLock = new Object();
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void loadLibrary()
|
public static void loadLibrary()
|
||||||
throws WolfSSLException{
|
throws WolfSSLException{
|
||||||
|
@ -1412,6 +1417,356 @@ public class WolfSSLSessionTest {
|
||||||
System.out.println("\t... passed");
|
System.out.println("\t... passed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal method that connects a client to a server and does
|
||||||
|
* one resumption.
|
||||||
|
*
|
||||||
|
* @throws Exception on error
|
||||||
|
*/
|
||||||
|
private void runClientServerOneResumption() throws Exception {
|
||||||
|
|
||||||
|
int ret = 0;
|
||||||
|
int err = 0;
|
||||||
|
long sessionPtr = 0;
|
||||||
|
long sesDup = 0;
|
||||||
|
Socket cliSock = null;
|
||||||
|
WolfSSLSession cliSes = null;
|
||||||
|
|
||||||
|
/* Create client/server WolfSSLContext objects, Server context
|
||||||
|
* must be final since used inside inner class. */
|
||||||
|
final WolfSSLContext srvCtx;
|
||||||
|
WolfSSLContext cliCtx;
|
||||||
|
|
||||||
|
/* Create ServerSocket first to get ephemeral port */
|
||||||
|
final ServerSocket srvSocket = new ServerSocket(0);
|
||||||
|
|
||||||
|
srvCtx = createAndSetupWolfSSLContext(srvCert, srvKey,
|
||||||
|
WolfSSL.SSL_FILETYPE_PEM, cliCert,
|
||||||
|
WolfSSL.SSLv23_ServerMethod());
|
||||||
|
cliCtx = createAndSetupWolfSSLContext(cliCert, cliKey,
|
||||||
|
WolfSSL.SSL_FILETYPE_PEM, caCert,
|
||||||
|
WolfSSL.SSLv23_ClientMethod());
|
||||||
|
|
||||||
|
/* Start server, handles 1 resumption */
|
||||||
|
try {
|
||||||
|
ExecutorService es = Executors.newSingleThreadExecutor();
|
||||||
|
es.submit(new Callable<Void>() {
|
||||||
|
@Override
|
||||||
|
public Void call() throws Exception {
|
||||||
|
int ret;
|
||||||
|
int err;
|
||||||
|
Socket server = null;
|
||||||
|
WolfSSLSession srvSes = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
/* Loop twice to allow handle one resumption */
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
server = srvSocket.accept();
|
||||||
|
srvSes = new WolfSSLSession(srvCtx);
|
||||||
|
|
||||||
|
ret = srvSes.setFd(server);
|
||||||
|
if (ret != WolfSSL.SSL_SUCCESS) {
|
||||||
|
throw new Exception(
|
||||||
|
"WolfSSLSession.setFd() failed: " +
|
||||||
|
ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
ret = srvSes.accept();
|
||||||
|
err = srvSes.getError(ret);
|
||||||
|
} while (ret != WolfSSL.SSL_SUCCESS &&
|
||||||
|
(err == WolfSSL.SSL_ERROR_WANT_READ ||
|
||||||
|
err == WolfSSL.SSL_ERROR_WANT_WRITE));
|
||||||
|
|
||||||
|
if (ret != WolfSSL.SSL_SUCCESS) {
|
||||||
|
throw new Exception(
|
||||||
|
"WolfSSLSession.accept() failed: " +
|
||||||
|
ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
srvSes.shutdownSSL();
|
||||||
|
srvSes.freeSSL();
|
||||||
|
srvSes = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
if (srvSes != null) {
|
||||||
|
srvSes.freeSSL();
|
||||||
|
}
|
||||||
|
if (server != null) {
|
||||||
|
server.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("\t... failed");
|
||||||
|
e.printStackTrace();
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
/* ------------------------------------------------------ */
|
||||||
|
/* Client connection #1 */
|
||||||
|
/* ------------------------------------------------------ */
|
||||||
|
cliSock = new Socket(InetAddress.getLocalHost(),
|
||||||
|
srvSocket.getLocalPort());
|
||||||
|
|
||||||
|
cliSes = new WolfSSLSession(cliCtx);
|
||||||
|
|
||||||
|
ret = cliSes.setFd(cliSock);
|
||||||
|
if (ret != WolfSSL.SSL_SUCCESS) {
|
||||||
|
throw new Exception(
|
||||||
|
"WolfSSLSession.setFd() failed, ret = " + ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
ret = cliSes.connect();
|
||||||
|
err = cliSes.getError(ret);
|
||||||
|
} while (ret != WolfSSL.SSL_SUCCESS &&
|
||||||
|
(err == WolfSSL.SSL_ERROR_WANT_READ ||
|
||||||
|
err == WolfSSL.SSL_ERROR_WANT_WRITE));
|
||||||
|
|
||||||
|
if (ret != WolfSSL.SSL_SUCCESS) {
|
||||||
|
throw new Exception(
|
||||||
|
"WolfSSLSession.connect() failed: " + err);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get WOLFSSL_SESSION pointer */
|
||||||
|
sessionPtr = cliSes.getSession();
|
||||||
|
if (sessionPtr == 0) {
|
||||||
|
throw new Exception(
|
||||||
|
"WolfSSLSession.getSession() failed, ptr == 0");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* wolfSSL_SessionIsSetup() may not be available, don't
|
||||||
|
* treat NOT_COMPILED_IN as an error */
|
||||||
|
ret = WolfSSLSession.sessionIsSetup(sessionPtr);
|
||||||
|
if ((ret != 1) && (ret != WolfSSL.NOT_COMPILED_IN)) {
|
||||||
|
throw new Exception(
|
||||||
|
"WolfSSLSession.sessionIsSetup() did not " +
|
||||||
|
"return 1: " + ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test duplicateSession(), wraps wolfSSL_SESSION_dup() */
|
||||||
|
sesDup = WolfSSLSession.duplicateSession(sessionPtr);
|
||||||
|
if (sesDup == 0) {
|
||||||
|
throw new Exception(
|
||||||
|
"WolfSSLSession.duplicateSession() returned 0");
|
||||||
|
}
|
||||||
|
if (sesDup == sessionPtr) {
|
||||||
|
throw new Exception(
|
||||||
|
"WolfSSLSession.duplicateSession() returned " +
|
||||||
|
"same pointer");
|
||||||
|
}
|
||||||
|
WolfSSLSession.freeSession(sesDup);
|
||||||
|
sesDup = 0;
|
||||||
|
|
||||||
|
cliSes.shutdownSSL();
|
||||||
|
cliSes.freeSSL();
|
||||||
|
cliSes = null;
|
||||||
|
cliSock.close();
|
||||||
|
cliSock = null;
|
||||||
|
|
||||||
|
/* ------------------------------------------------------ */
|
||||||
|
/* Client connection #2, set session and try resumption */
|
||||||
|
/* ------------------------------------------------------ */
|
||||||
|
cliSock = new Socket(InetAddress.getLocalHost(),
|
||||||
|
srvSocket.getLocalPort());
|
||||||
|
cliSes = new WolfSSLSession(cliCtx);
|
||||||
|
|
||||||
|
ret = cliSes.setFd(cliSock);
|
||||||
|
if (ret != WolfSSL.SSL_SUCCESS) {
|
||||||
|
throw new Exception(
|
||||||
|
"WolfSSLSession.setFd() failed, ret = " + ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set session pointer from original connection */
|
||||||
|
ret = cliSes.setSession(sessionPtr);
|
||||||
|
if (ret != WolfSSL.SSL_SUCCESS) {
|
||||||
|
throw new Exception(
|
||||||
|
"WolfSSLSession.setSession() failed: " + ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
ret = cliSes.connect();
|
||||||
|
err = cliSes.getError(ret);
|
||||||
|
} while (ret != WolfSSL.SSL_SUCCESS &&
|
||||||
|
(err == WolfSSL.SSL_ERROR_WANT_READ ||
|
||||||
|
err == WolfSSL.SSL_ERROR_WANT_WRITE));
|
||||||
|
|
||||||
|
if (ret != WolfSSL.SSL_SUCCESS) {
|
||||||
|
throw new Exception(
|
||||||
|
"WolfSSLSession.connect() failed: " + err);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get WOLFSSL_SESSION pointer, free original one first */
|
||||||
|
WolfSSLSession.freeSession(sessionPtr);
|
||||||
|
sessionPtr = cliSes.getSession();
|
||||||
|
if (sessionPtr == 0) {
|
||||||
|
throw new Exception(
|
||||||
|
"WolfSSLSession.getSession() failed, ptr == 0");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free WOLFSSL_SESSION pointer */
|
||||||
|
WolfSSLSession.freeSession(sessionPtr);
|
||||||
|
sessionPtr = 0;
|
||||||
|
|
||||||
|
/* Session should be marked as resumed */
|
||||||
|
if (cliSes.sessionReused() == 0) {
|
||||||
|
throw new Exception(
|
||||||
|
"Second connection not resumed");
|
||||||
|
}
|
||||||
|
|
||||||
|
cliSes.shutdownSSL();
|
||||||
|
cliSes.freeSSL();
|
||||||
|
cliSes = null;
|
||||||
|
cliSock.close();
|
||||||
|
cliSock = null;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("\t... failed");
|
||||||
|
e.printStackTrace();
|
||||||
|
fail();
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
/* Free resources */
|
||||||
|
if (sessionPtr != 0) {
|
||||||
|
WolfSSLSession.freeSession(sessionPtr);
|
||||||
|
}
|
||||||
|
if (sesDup != 0) {
|
||||||
|
WolfSSLSession.freeSession(sesDup);
|
||||||
|
}
|
||||||
|
if (cliSes != null) {
|
||||||
|
cliSes.freeSSL();
|
||||||
|
}
|
||||||
|
if (cliSock != null) {
|
||||||
|
cliSock.close();
|
||||||
|
}
|
||||||
|
if (srvSocket != null) {
|
||||||
|
srvSocket.close();
|
||||||
|
}
|
||||||
|
if (srvCtx != null) {
|
||||||
|
srvCtx.free();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_WolfSSLSession_disableByteBufferPool() throws Exception {
|
||||||
|
|
||||||
|
System.out.print("\tByteBuffer pool disabled");
|
||||||
|
|
||||||
|
synchronized (byteBufferPoolPropertyLock) {
|
||||||
|
|
||||||
|
String originalProp =
|
||||||
|
Security.getProperty("wolfssl.readWriteByteBufferPool.disabled");
|
||||||
|
|
||||||
|
try {
|
||||||
|
/* Disable WolfSSLSession internal direct ByteBuffer pool
|
||||||
|
* for use with read/write() calls */
|
||||||
|
Security.setProperty("wolfssl.readWriteByteBufferPool.disabled",
|
||||||
|
"true");
|
||||||
|
|
||||||
|
runClientServerOneResumption();
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
if (originalProp == null) {
|
||||||
|
originalProp = "";
|
||||||
|
}
|
||||||
|
/* restore system property */
|
||||||
|
Security.setProperty("wolfssl.readWriteByteBufferPool.disabled",
|
||||||
|
originalProp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("\t... passed");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_WolfSSLSession_byteBufferPoolSize() throws Exception {
|
||||||
|
|
||||||
|
System.out.print("\tByteBuffer pool size changes");
|
||||||
|
|
||||||
|
synchronized (byteBufferPoolPropertyLock) {
|
||||||
|
|
||||||
|
String originalProp =
|
||||||
|
Security.getProperty("wolfssl.readWriteByteBufferPool.size");
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
/* Pool size of 0 */
|
||||||
|
Security.setProperty("wolfssl.readWriteByteBufferPool.size",
|
||||||
|
"0");
|
||||||
|
runClientServerOneResumption();
|
||||||
|
|
||||||
|
/* Pool size of 1 */
|
||||||
|
Security.setProperty("wolfssl.readWriteByteBufferPool.size",
|
||||||
|
"1");
|
||||||
|
runClientServerOneResumption();
|
||||||
|
|
||||||
|
/* Pool size of 100 */
|
||||||
|
Security.setProperty("wolfssl.readWriteByteBufferPool.size",
|
||||||
|
"100");
|
||||||
|
runClientServerOneResumption();
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
if (originalProp == null) {
|
||||||
|
originalProp = "";
|
||||||
|
}
|
||||||
|
/* restore system property */
|
||||||
|
Security.setProperty("wolfssl.readWriteByteBufferPool.size",
|
||||||
|
originalProp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("\t... passed");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_WolfSSLSession_byteBufferPoolBufferSize() throws Exception {
|
||||||
|
|
||||||
|
System.out.print("\tByteBuffer pool buffer sizes");
|
||||||
|
|
||||||
|
synchronized (byteBufferPoolPropertyLock) {
|
||||||
|
|
||||||
|
String originalProp =
|
||||||
|
Security.getProperty(
|
||||||
|
"wolfssl.readWriteByteBufferPool.bufferSize");
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
/* Tiny buffer size of 128 bytes, lots of looping */
|
||||||
|
Security.setProperty(
|
||||||
|
"wolfssl.readWriteByteBufferPool.bufferSize", "128");
|
||||||
|
runClientServerOneResumption();
|
||||||
|
|
||||||
|
/* Bigger buffer size than default (17k), try 32k */
|
||||||
|
Security.setProperty(
|
||||||
|
"wolfssl.readWriteByteBufferPool.bufferSize", "32768");
|
||||||
|
runClientServerOneResumption();
|
||||||
|
|
||||||
|
/* Bigger buffer size than default (17k), try 64k */
|
||||||
|
Security.setProperty(
|
||||||
|
"wolfssl.readWriteByteBufferPool.bufferSize", "65536");
|
||||||
|
runClientServerOneResumption();
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
if (originalProp == null) {
|
||||||
|
originalProp = "";
|
||||||
|
}
|
||||||
|
/* restore system property */
|
||||||
|
Security.setProperty(
|
||||||
|
"wolfssl.readWriteByteBufferPool.bufferSize", originalProp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("\t... passed");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wolfSSL I/O context, is passed to I/O callbacks when called
|
* wolfSSL I/O context, is passed to I/O callbacks when called
|
||||||
* by native wolfSSL.
|
* by native wolfSSL.
|
||||||
|
|
Loading…
Reference in New Issue