diff --git a/eng/spotbugs/spotbugs-excludes.xml b/eng/spotbugs/spotbugs-excludes.xml
new file mode 100644
index 0000000..77d6647
--- /dev/null
+++ b/eng/spotbugs/spotbugs-excludes.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pom.xml b/pom.xml
index f63d54a..5c4fcb1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -49,8 +49,8 @@
1.7.28
- 4.13.1
5.8.0-M1
+ 4.13.1
3.0.0
@@ -58,11 +58,15 @@
3.8.1
3.1.2
3.1.1
+ 3.1.2
+ 3.9.1
3.0.1
+ 4.2.0
3.0.0-M3
8.42
+ 4.2.3
@@ -82,6 +86,21 @@
+
+
+ com.github.spotbugs
+ spotbugs-maven-plugin
+ ${maven-spotbugs-plugin.version}
+
+
+ verify
+
+ check
+
+
+
+
+
org.apache.maven.plugins
@@ -137,7 +156,7 @@
org.apache.maven.plugins
maven-compiler-plugin
- 3.8.1
+ ${maven-compiler-plugin.version}
true
true
@@ -212,6 +231,9 @@
https://docs.oracle.com/javase/8/docs/api/
false
+
+ *.impl*
+
@@ -227,10 +249,66 @@
false
+
+
+
+ com.github.spotbugs
+ spotbugs-maven-plugin
+ ${maven-spotbugs-plugin.version}
+
+
+ com.github.spotbugs
+ spotbugs
+ ${spotbugs.version}
+
+
+
+ max
+ Low
+ true
+ eng/spotbugs/spotbugs-excludes.xml
+ true
+ true
+
+
+ false
+
+
+
+
+ org.apache.maven.plugins
+ maven-site-plugin
+ ${maven-site-plugin.version}
+
+
+ org.apache.maven.plugins
+ maven-project-info-reports-plugin
+ ${maven-project-info-reports-plugin.version}
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ ${maven-javadoc-plugin.version}
+
+
+
+
+ com.github.spotbugs
+ spotbugs-maven-plugin
+ ${maven-spotbugs-plugin.version}
+
+ target/site
+
+
+
+
+
diff --git a/src/main/java/com/microsoft/azure/proton/transport/proxy/impl/DigestProxyChallengeProcessorImpl.java b/src/main/java/com/microsoft/azure/proton/transport/proxy/impl/DigestProxyChallengeProcessorImpl.java
index b30842c..e8736a7 100644
--- a/src/main/java/com/microsoft/azure/proton/transport/proxy/impl/DigestProxyChallengeProcessorImpl.java
+++ b/src/main/java/com/microsoft/azure/proton/transport/proxy/impl/DigestProxyChallengeProcessorImpl.java
@@ -30,6 +30,7 @@ public class DigestProxyChallengeProcessorImpl implements ProxyChallengeProcesso
static final String DEFAULT_ALGORITHM = "MD5";
private static final String PROXY_AUTH_DIGEST = Constants.PROXY_AUTHENTICATE_HEADER + " " + Constants.DIGEST;
private static final char[] HEX_CODE = "0123456789ABCDEF".toCharArray();
+ private static final SecureRandom SECURE_RANDOM = new SecureRandom();
private final Logger logger = LoggerFactory.getLogger(DigestProxyChallengeProcessorImpl.class);
private final AtomicInteger nonceCounter = new AtomicInteger(0);
@@ -134,13 +135,12 @@ private void computeDigestAuthHeader(Map challengeQuestionValues
final String qop = challengeQuestionValues.get("qop");
final MessageDigest md5 = MessageDigest.getInstance(DEFAULT_ALGORITHM);
- final SecureRandom secureRandom = new SecureRandom();
final String a1 = printHexBinary(md5.digest(String.format("%s:%s:%s", proxyUserName, realm, proxyPassword).getBytes(UTF_8)));
final String a2 = printHexBinary(md5.digest(String.format("%s:%s", Constants.CONNECT, uri).getBytes(UTF_8)));
final byte[] cnonceBytes = new byte[16];
- secureRandom.nextBytes(cnonceBytes);
+ SECURE_RANDOM.nextBytes(cnonceBytes);
final String cnonce = printHexBinary(cnonceBytes);
String response;
diff --git a/src/main/java/com/microsoft/azure/proton/transport/proxy/impl/ProxyImpl.java b/src/main/java/com/microsoft/azure/proton/transport/proxy/impl/ProxyImpl.java
index 09949c9..eedaa6f 100644
--- a/src/main/java/com/microsoft/azure/proton/transport/proxy/impl/ProxyImpl.java
+++ b/src/main/java/com/microsoft/azure/proton/transport/proxy/impl/ProxyImpl.java
@@ -153,6 +153,9 @@ protected void writeProxyRequest() {
LOGGER.info("Writing proxy request:{}{}", System.lineSeparator(), request);
}
+ //TODO (conniey): HTTP headers are encoded using StandardCharsets.ISO_8859_1. update proxyHandler.createProxyRequest to return bytes instead
+ // of String because encoding is not UTF-16. https://stackoverflow.com/a/655948/4220757
+ // See https://datatracker.ietf.org/doc/html/rfc2616#section-3.7.1
outputBuffer.put(request.getBytes());
}
diff --git a/src/main/java/com/microsoft/azure/proton/transport/ws/WebSocketHeader.java b/src/main/java/com/microsoft/azure/proton/transport/ws/WebSocketHeader.java
index 124c291..3baa17a 100644
--- a/src/main/java/com/microsoft/azure/proton/transport/ws/WebSocketHeader.java
+++ b/src/main/java/com/microsoft/azure/proton/transport/ws/WebSocketHeader.java
@@ -102,7 +102,7 @@ public interface WebSocketHeader {
byte FINAL_OPCODE_BINARY = FINBIT_MASK | OPCODE_BINARY;
/**
- * Maximum size in bytes for the payload when using 7 bits to represent the size.
+ * Maximum size (125) in bytes for the payload when using 7 bits to represent the size.
*/
byte PAYLOAD_SHORT_MAX = 0x7D;
/**
@@ -113,6 +113,12 @@ public interface WebSocketHeader {
* Maximum size in bytes for the payload when using 7 + 64 bits to represent the size.
*/
int PAYLOAD_LARGE_MAX = 0x7FFFFFFF;
+ /**
+ * Size is 126.
+ */
byte PAYLOAD_EXTENDED_16 = 0x7E;
+ /**
+ * Size is 127.
+ */
byte PAYLOAD_EXTENDED_64 = 0x7F;
}
diff --git a/src/main/java/com/microsoft/azure/proton/transport/ws/impl/Base64.java b/src/main/java/com/microsoft/azure/proton/transport/ws/impl/Base64.java
index 038452e..09066bd 100644
--- a/src/main/java/com/microsoft/azure/proton/transport/ws/impl/Base64.java
+++ b/src/main/java/com/microsoft/azure/proton/transport/ws/impl/Base64.java
@@ -3,6 +3,8 @@
package com.microsoft.azure.proton.transport.ws.impl;
+import java.nio.charset.StandardCharsets;
+
/**
* Class to encode to base 64.
*/
@@ -251,12 +253,12 @@ public static String encodeBase64StringLocal(byte[] dataValues) throws IllegalAr
/* Codes_SRS_BASE64_21_010: [If the `dataValues` is empty, the encodeBase64StringLocal shall return a empty string.] */
if (dataValues.length == 0) {
- return new String();
+ return "";
}
/* Codes_SRS_BASE64_21_008: [The encodeBase64StringLocal shall encoded the provided `dataValues`
in a string using the Base64 format define in the RFC2045.] */
- return new String(encodeBase64Internal(dataValues));
+ return new String(encodeBase64Internal(dataValues), StandardCharsets.US_ASCII);
}
private static byte[] encodeBase64Internal(byte[] dataValues) throws IllegalArgumentException {
diff --git a/src/main/java/com/microsoft/azure/proton/transport/ws/impl/Utils.java b/src/main/java/com/microsoft/azure/proton/transport/ws/impl/Utils.java
new file mode 100644
index 0000000..8a9976b
--- /dev/null
+++ b/src/main/java/com/microsoft/azure/proton/transport/ws/impl/Utils.java
@@ -0,0 +1,28 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.microsoft.azure.proton.transport.ws.impl;
+
+import java.security.SecureRandom;
+
+/**
+ * Utility methods.
+ */
+final class Utils {
+ private static final SecureRandom SECURE_RANDOM = new SecureRandom();
+
+ /**
+ * Gets an instance of secure random.
+ *
+ * @return An instance of secure random.
+ */
+ static SecureRandom getSecureRandom() {
+ return SECURE_RANDOM;
+ }
+
+ /**
+ * So an instance of class cannot be created.
+ */
+ private Utils() {
+ }
+}
diff --git a/src/main/java/com/microsoft/azure/proton/transport/ws/impl/WebSocketHandlerImpl.java b/src/main/java/com/microsoft/azure/proton/transport/ws/impl/WebSocketHandlerImpl.java
index 943ce13..a75bc24 100644
--- a/src/main/java/com/microsoft/azure/proton/transport/ws/impl/WebSocketHandlerImpl.java
+++ b/src/main/java/com/microsoft/azure/proton/transport/ws/impl/WebSocketHandlerImpl.java
@@ -9,9 +9,7 @@
import java.io.ByteArrayOutputStream;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
-import java.security.SecureRandom;
import java.util.Map;
-import java.util.Random;
/**
* Implementation for {@link WebSocketHandler}.
@@ -175,11 +173,13 @@ public WebsocketTuple unwrapBuffer(ByteBuffer srcBuffer) {
// Read the second byte
byte secondByte = srcBuffer.get();
- byte maskBit = (byte) (secondByte & WebSocketHeader.MASKBIT_MASK);
+ // The MASK bit is never used.
+ // byte maskBit = (byte) (secondByte & WebSocketHeader.MASKBIT_MASK);
byte payloadLength = (byte) (secondByte & WebSocketHeader.PAYLOAD_MASK);
long finalPayloadLength = -1;
+ // We want to be explicit about the WebSocket payload length because the RFC specifies these ranges.
if (payloadLength <= WebSocketHeader.PAYLOAD_SHORT_MAX) {
finalPayloadLength = payloadLength;
} else if (payloadLength == WebSocketHeader.PAYLOAD_EXTENDED_16) {
@@ -232,8 +232,7 @@ protected WebSocketUpgrade createWebSocketUpgrade(
protected byte[] createRandomMaskingKey() {
final byte[] maskingKey = new byte[4];
- Random random = new SecureRandom();
- random.nextBytes(maskingKey);
+ Utils.getSecureRandom().nextBytes(maskingKey);
return maskingKey;
}
diff --git a/src/main/java/com/microsoft/azure/proton/transport/ws/impl/WebSocketImpl.java b/src/main/java/com/microsoft/azure/proton/transport/ws/impl/WebSocketImpl.java
index 82ca9bd..c48393d 100644
--- a/src/main/java/com/microsoft/azure/proton/transport/ws/impl/WebSocketImpl.java
+++ b/src/main/java/com/microsoft/azure/proton/transport/ws/impl/WebSocketImpl.java
@@ -90,12 +90,7 @@ public WebSocketImpl(int customMaxFrameSize) {
@Override
public TransportWrapper wrap(final TransportInput input, final TransportOutput output) {
- return new WebSocketSniffer(new WebSocketTransportWrapper(input, output), new PlainTransportWrapper(output, input)) {
- protected boolean isDeterminationMade() {
- _selectedTransportWrapper = _wrapper1;
- return true;
- }
- };
+ return new WebSocketSnifferTransportWrapper(input, output);
}
@Override
@@ -207,6 +202,10 @@ public String toString() {
protected void writeUpgradeRequest() {
outputBuffer.clear();
+
+ //TODO (conniey): HTTP headers are encoded using StandardCharsets.ISO_8859_1. update webSocketHandler.createProxyRequest to return bytes
+ // instead of String because encoding is not UTF-16. https://stackoverflow.com/a/655948/4220757
+ // See https://datatracker.ietf.org/doc/html/rfc2616#section-3.7.1
String request = webSocketHandler.createUpgradeRequest(host, path, query, port, protocol, additionalHeaders);
outputBuffer.put(request.getBytes());
}
@@ -241,9 +240,6 @@ private boolean sendToUnderlyingInput() {
boolean readComplete = false;
switch (lastType) {
case WEB_SOCKET_MESSAGE_TYPE_UNKNOWN:
- wsInputBuffer.position(wsInputBuffer.limit());
- wsInputBuffer.limit(wsInputBuffer.capacity());
- break;
case WEB_SOCKET_MESSAGE_TYPE_CHUNK:
wsInputBuffer.position(wsInputBuffer.limit());
wsInputBuffer.limit(wsInputBuffer.capacity());
@@ -624,46 +620,16 @@ public void pop(int bytes) {
public void close_head() {
underlyingOutput.close_head();
}
+ }
- private final char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
-
- private String convertToHex(byte[] bb) {
- final int lgt = bb.length;
-
- final char[] out = new char[5 * lgt];
- for (int i = 0, j = 0; i < lgt; i++) {
- out[j++] = '0';
- out[j++] = 'x';
- out[j++] = hexDigits[(0xF0 & bb[i]) >>> 4];
- out[j++] = hexDigits[0x0F & bb[i]];
- out[j++] = '|';
- }
- return new String(out);
- }
-
- private String convertToHex(ByteBuffer bb) {
- final byte[] data = new byte[bb.remaining()];
- bb.duplicate().get(data);
-
- return convertToHex(data);
- }
-
- private String convertToBinary(byte[] bb) {
- StringBuilder sb = new StringBuilder();
-
- for (byte b : bb) {
- sb.append(String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0'));
- sb.append('|');
- }
-
- return sb.toString();
+ private final class WebSocketSnifferTransportWrapper extends WebSocketSniffer {
+ private WebSocketSnifferTransportWrapper(TransportInput input, TransportOutput output) {
+ super(new WebSocketTransportWrapper(input, output), new PlainTransportWrapper(output, input));
}
- private String convertToBinary(ByteBuffer bb) {
- final byte[] data = new byte[bb.remaining()];
- bb.duplicate().get(data);
-
- return convertToBinary(data);
+ protected boolean isDeterminationMade() {
+ _selectedTransportWrapper = _wrapper1;
+ return true;
}
}
}
diff --git a/src/main/java/com/microsoft/azure/proton/transport/ws/impl/WebSocketUpgrade.java b/src/main/java/com/microsoft/azure/proton/transport/ws/impl/WebSocketUpgrade.java
index c28fe9a..5999f76 100644
--- a/src/main/java/com/microsoft/azure/proton/transport/ws/impl/WebSocketUpgrade.java
+++ b/src/main/java/com/microsoft/azure/proton/transport/ws/impl/WebSocketUpgrade.java
@@ -7,6 +7,7 @@
import java.security.InvalidParameterException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
+import java.util.Locale;
import java.util.Map;
import java.util.Scanner;
@@ -14,9 +15,10 @@
* Represents a web socket upgrade request.
*/
public class WebSocketUpgrade {
- private final String rfcGuid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
- private final char questionMark = '?';
- private final char slash = '/';
+ private static final String RFC_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
+ private static final char QUESTION_MARK = '?';
+ private static final char SLASH = '/';
+
private final String query;
private final String host;
private final String path;
@@ -44,12 +46,12 @@ public WebSocketUpgrade(
String webSocketProtocol,
Map additionalHeaders) {
this.host = hostName;
- this.path = webSocketPath.isEmpty() || webSocketPath.charAt(0) == this.slash
+ this.path = webSocketPath.isEmpty() || webSocketPath.charAt(0) == SLASH
? webSocketPath
- : this.slash + webSocketPath;
- this.query = webSocketQuery.isEmpty() || webSocketQuery.charAt(0) == this.questionMark
+ : SLASH + webSocketPath;
+ this.query = webSocketQuery.isEmpty() || webSocketQuery.charAt(0) == QUESTION_MARK
? webSocketQuery
- : this.questionMark + webSocketQuery;
+ : QUESTION_MARK + webSocketQuery;
this.port = webSocketPort == 0 ? "" : String.valueOf(webSocketPort);
this.protocol = webSocketProtocol;
this.additionalHeaders = additionalHeaders;
@@ -62,7 +64,7 @@ private String createWebSocketKey() {
byte[] key = new byte[16];
for (int i = 0; i < 16; i++) {
- key[i] = (byte) (int) (Math.random() * 256);
+ key[i] = (byte) (int) (Utils.getSecureRandom().nextDouble() * 256);
}
return Base64.encodeBase64StringLocal(key).trim();
@@ -99,7 +101,7 @@ public String createUpgradeRequest() {
if (additionalHeaders != null) {
for (Map.Entry entry : additionalHeaders.entrySet()) {
- stringBuilder.append(entry.getKey() + ": " + entry.getValue()).append(endOfLine);
+ stringBuilder.append(entry.getKey()).append(": ").append(entry.getValue()).append(endOfLine);
}
}
@@ -116,44 +118,45 @@ public String createUpgradeRequest() {
public Boolean validateUpgradeReply(byte[] responseBytes) {
final String httpString = new String(responseBytes, StandardCharsets.UTF_8);
- Boolean isStatusLineOk = false;
- Boolean isUpgradeHeaderOk = false;
- Boolean isConnectionHeaderOk = false;
- Boolean isProtocolHeaderOk = false;
- Boolean isAcceptHeaderOk = false;
+ boolean isStatusLineOk = false;
+ boolean isUpgradeHeaderOk = false;
+ boolean isConnectionHeaderOk = false;
+ boolean isProtocolHeaderOk = false;
+ boolean isAcceptHeaderOk = false;
final Scanner scanner = new Scanner(httpString);
while (scanner.hasNextLine()) {
final String line = scanner.nextLine();
+ final String lowercase = line.toLowerCase(Locale.ROOT);
- if ((line.toLowerCase().contains("http/1.1"))
+ if ((lowercase.contains("http/1.1"))
&& (line.contains("101"))
- && (line.toLowerCase().contains("switching protocols"))) {
+ && (lowercase.contains("switching protocols"))) {
isStatusLineOk = true;
continue;
}
- if ((line.toLowerCase().contains("upgrade")) && (line.toLowerCase().contains("websocket"))) {
+ if ((lowercase.contains("upgrade")) && (lowercase.contains("websocket"))) {
isUpgradeHeaderOk = true;
continue;
}
- if ((line.toLowerCase().contains("connection")) && (line.toLowerCase().contains("upgrade"))) {
+ if ((lowercase.contains("connection")) && (lowercase.contains("upgrade"))) {
isConnectionHeaderOk = true;
continue;
}
- if (line.toLowerCase().contains("sec-websocket-protocol") && (line.toLowerCase().contains(this.protocol.toLowerCase()))) {
+ if (lowercase.contains("sec-websocket-protocol") && (lowercase.contains(protocol.toLowerCase(Locale.ROOT)))) {
isProtocolHeaderOk = true;
continue;
}
- if (line.toLowerCase().contains("sec-websocket-accept")) {
+ if (lowercase.contains("sec-websocket-accept")) {
MessageDigest messageDigest = null;
try {
@@ -163,14 +166,12 @@ public Boolean validateUpgradeReply(byte[] responseBytes) {
break;
}
- final String expectedKey = Base64.encodeBase64StringLocal(
- messageDigest.digest((this.webSocketKey + this.rfcGuid).getBytes())).trim();
+ final byte[] bytes = (this.webSocketKey + RFC_GUID).getBytes(StandardCharsets.ISO_8859_1);
+ final String expectedKey = Base64.encodeBase64StringLocal(messageDigest.digest(bytes)).trim();
if (line.contains(expectedKey)) {
isAcceptHeaderOk = true;
}
-
- continue;
}
}
@@ -197,7 +198,7 @@ public String toString() {
builder.append(", additionalHeaders=");
for (Map.Entry entry : additionalHeaders.entrySet()) {
- builder.append(entry.getKey() + ":" + entry.getValue()).append(", ");
+ builder.append(entry.getKey()).append(":").append(entry.getValue()).append(", ");
}
final int lastIndex = builder.lastIndexOf(", ");
diff --git a/src/test/java/com/microsoft/azure/proton/transport/proxy/impl/ProxyConfigurationTest.java b/src/test/java/com/microsoft/azure/proton/transport/proxy/impl/ProxyConfigurationTest.java
index a7aa508..08b377d 100644
--- a/src/test/java/com/microsoft/azure/proton/transport/proxy/impl/ProxyConfigurationTest.java
+++ b/src/test/java/com/microsoft/azure/proton/transport/proxy/impl/ProxyConfigurationTest.java
@@ -61,6 +61,8 @@ public void userDefinedConfiguration() {
/**
* Verify that if the user has not provided a username or password, we cannot construct valid credentials from that.
+ *
+ * @param configuration Configuration to test out.
*/
@Theory
public void userDefinedConfigurationMissingData(@FromDataPoints("userConfigurations") ProxyConfiguration configuration) {
diff --git a/src/test/java/com/microsoft/azure/proton/transport/ws/impl/WebSocketHandlerImplTest.java b/src/test/java/com/microsoft/azure/proton/transport/ws/impl/WebSocketHandlerImplTest.java
index d3c4a1c..0fcda57 100644
--- a/src/test/java/com/microsoft/azure/proton/transport/ws/impl/WebSocketHandlerImplTest.java
+++ b/src/test/java/com/microsoft/azure/proton/transport/ws/impl/WebSocketHandlerImplTest.java
@@ -12,7 +12,6 @@
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
-import java.util.Random;
import java.util.Scanner;
import static org.junit.Assert.assertEquals;
@@ -25,6 +24,8 @@
import static org.mockito.Mockito.verify;
public class WebSocketHandlerImplTest {
+ private static SecureRandom SECURE_RANDOM = new SecureRandom();
+
@Test
public void testCreateUpgradeRequest() {
String hostName = "host_XXX";
@@ -291,8 +292,7 @@ public void testWrapBuffer_short_payload() {
byte[] maskingKey = new byte[]{0x01, 0x02, 0x03, 0x04};
byte[] data = new byte[payloadLength];
- Random random = new SecureRandom();
- random.nextBytes(data);
+ SECURE_RANDOM.nextBytes(data);
ByteBuffer srcBuffer = ByteBuffer.allocate(payloadLength);
ByteBuffer dstBuffer = ByteBuffer.allocate(messageLength);
@@ -346,8 +346,7 @@ public void testWrapBuffer_short_payload_min() {
byte[] maskingKey = new byte[]{0x01, 0x02, 0x03, 0x04};
byte[] data = new byte[payloadLength];
- Random random = new SecureRandom();
- random.nextBytes(data);
+ SECURE_RANDOM.nextBytes(data);
ByteBuffer srcBuffer = ByteBuffer.allocate(payloadLength);
ByteBuffer dstBuffer = ByteBuffer.allocate(messageLength);
@@ -401,8 +400,7 @@ public void testWrapBuffer_short_payload_max() {
byte[] maskingKey = new byte[]{0x01, 0x02, 0x03, 0x04};
byte[] data = new byte[payloadLength];
- Random random = new SecureRandom();
- random.nextBytes(data);
+ SECURE_RANDOM.nextBytes(data);
ByteBuffer srcBuffer = ByteBuffer.allocate(payloadLength);
ByteBuffer dstBuffer = ByteBuffer.allocate(messageLength);
@@ -456,8 +454,7 @@ public void testWrapBuffer_medium_payload() {
byte[] maskingKey = new byte[]{0x01, 0x02, 0x03, 0x04};
byte[] data = new byte[payloadLength];
- Random random = new SecureRandom();
- random.nextBytes(data);
+ SECURE_RANDOM.nextBytes(data);
ByteBuffer srcBuffer = ByteBuffer.allocate(payloadLength);
ByteBuffer dstBuffer = ByteBuffer.allocate(messageLength);
@@ -518,8 +515,7 @@ public void testWrapBuffer_medium_payload_min() {
byte[] maskingKey = new byte[]{0x01, 0x02, 0x03, 0x04};
byte[] data = new byte[payloadLength];
- Random random = new SecureRandom();
- random.nextBytes(data);
+ SECURE_RANDOM.nextBytes(data);
ByteBuffer srcBuffer = ByteBuffer.allocate(messageLength);
ByteBuffer dstBuffer = ByteBuffer.allocate(messageLength);
@@ -580,8 +576,7 @@ public void testWrapBuffer_medium_payload_max() {
byte[] maskingKey = new byte[]{0x01, 0x02, 0x03, 0x04};
byte[] data = new byte[payloadLength];
- Random random = new SecureRandom();
- random.nextBytes(data);
+ SECURE_RANDOM.nextBytes(data);
ByteBuffer srcBuffer = ByteBuffer.allocate(messageLength);
ByteBuffer dstBuffer = ByteBuffer.allocate(messageLength);
@@ -642,8 +637,7 @@ public void testWrapBuffer_large_payload() {
byte[] maskingKey = new byte[]{0x01, 0x02, 0x03, 0x04};
byte[] data = new byte[payloadLength];
- Random random = new SecureRandom();
- random.nextBytes(data);
+ SECURE_RANDOM.nextBytes(data);
ByteBuffer srcBuffer = ByteBuffer.allocate(messageLength);
ByteBuffer dstBuffer = ByteBuffer.allocate(messageLength);
@@ -716,8 +710,7 @@ public void testWrapBuffer_large_payload_min() {
byte[] maskingKey = new byte[]{0x01, 0x02, 0x03, 0x04};
byte[] data = new byte[payloadLength];
- Random random = new SecureRandom();
- random.nextBytes(data);
+ SECURE_RANDOM.nextBytes(data);
ByteBuffer srcBuffer = ByteBuffer.allocate(messageLength);
ByteBuffer dstBuffer = ByteBuffer.allocate(messageLength);
@@ -791,8 +784,7 @@ public void testWrapBuffer_large_payload_min() {
// byte[] maskingKey = new byte[]{0x01, 0x02, 0x03, 0x04};
//
// byte[] data = new byte[payloadLength];
-// Random random = new SecureRandom();
-// //random.nextBytes(data);
+// SECURE_RANDOM.nextBytes(data);
//
// ByteBuffer srcBuffer = ByteBuffer.allocate(messageLength);
// ByteBuffer dstBuffer = ByteBuffer.allocate(messageLength);
@@ -915,8 +907,7 @@ public void testUnwrapBuffer_opcode_ping() {
int messageLength = payloadLength + WebSocketHeader.MIN_HEADER_LENGTH;
byte[] data = new byte[messageLength];
- Random random = new SecureRandom();
- random.nextBytes(data);
+ SECURE_RANDOM.nextBytes(data);
data[0] = (byte) (WebSocketHeader.FINBIT_MASK | WebSocketHeader.OPCODE_PING);
data[1] = (byte) (payloadLength);
@@ -942,8 +933,7 @@ public void testUnwrapBuffer_opcode_close() {
int messageLength = payloadLength + WebSocketHeader.MIN_HEADER_LENGTH;
byte[] data = new byte[messageLength];
- Random random = new SecureRandom();
- random.nextBytes(data);
+ SECURE_RANDOM.nextBytes(data);
data[0] = (byte) (WebSocketHeader.FINBIT_MASK | WebSocketHeader.OPCODE_CLOSE);
data[1] = (byte) (payloadLength);
@@ -969,8 +959,7 @@ public void testUnwrapBuffer_short_message() {
int messageLength = payloadLength + WebSocketHeader.MIN_HEADER_LENGTH;
byte[] data = new byte[messageLength];
- Random random = new SecureRandom();
- random.nextBytes(data);
+ SECURE_RANDOM.nextBytes(data);
data[0] = (byte) (WebSocketHeader.FINBIT_MASK | WebSocketHeader.OPCODE_BINARY);
data[1] = (byte) (payloadLength);
@@ -996,8 +985,7 @@ public void testUnwrapBuffer_short_message_min() {
int messageLength = payloadLength + WebSocketHeader.MIN_HEADER_LENGTH;
byte[] data = new byte[messageLength];
- Random random = new SecureRandom();
- random.nextBytes(data);
+ SECURE_RANDOM.nextBytes(data);
data[0] = (byte) (WebSocketHeader.FINBIT_MASK | WebSocketHeader.OPCODE_BINARY);
data[1] = (byte) (payloadLength);
@@ -1023,8 +1011,7 @@ public void testUnwrapBuffer_short_message_max() {
int messageLength = payloadLength + WebSocketHeader.MIN_HEADER_LENGTH;
byte[] data = new byte[messageLength];
- Random random = new SecureRandom();
- random.nextBytes(data);
+ SECURE_RANDOM.nextBytes(data);
data[0] = (byte) (WebSocketHeader.FINBIT_MASK | WebSocketHeader.OPCODE_BINARY);
data[1] = (byte) (payloadLength);
@@ -1050,8 +1037,7 @@ public void testUnwrapBuffer_medium_message() {
int messageLength = payloadLength + WebSocketHeader.MED_HEADER_LENGTH_NOMASK;
byte[] data = new byte[messageLength];
- Random random = new SecureRandom();
- random.nextBytes(data);
+ SECURE_RANDOM.nextBytes(data);
data[0] = (byte) (WebSocketHeader.FINBIT_MASK | WebSocketHeader.OPCODE_BINARY);
data[1] = WebSocketHeader.PAYLOAD_EXTENDED_16;
@@ -1079,8 +1065,7 @@ public void testUnwrapBuffer_medium_message_min() {
int messageLength = payloadLength + WebSocketHeader.MED_HEADER_LENGTH_NOMASK;
byte[] data = new byte[messageLength];
- Random random = new SecureRandom();
- random.nextBytes(data);
+ SECURE_RANDOM.nextBytes(data);
data[0] = (byte) (WebSocketHeader.FINBIT_MASK | WebSocketHeader.OPCODE_BINARY);
data[1] = WebSocketHeader.PAYLOAD_EXTENDED_16;
@@ -1108,8 +1093,7 @@ public void testUnwrapBuffer_medium_message_max() {
int messageLength = payloadLength + WebSocketHeader.MED_HEADER_LENGTH_NOMASK;
byte[] data = new byte[messageLength];
- Random random = new SecureRandom();
- random.nextBytes(data);
+ SECURE_RANDOM.nextBytes(data);
data[0] = (byte) (WebSocketHeader.FINBIT_MASK | WebSocketHeader.OPCODE_BINARY);
data[1] = WebSocketHeader.PAYLOAD_EXTENDED_16;
@@ -1137,8 +1121,7 @@ public void testUnwrapBuffer_large_message() {
int messageLength = payloadLength + WebSocketHeader.MAX_HEADER_LENGTH_NOMASK;
byte[] data = new byte[messageLength];
- Random random = new SecureRandom();
- random.nextBytes(data);
+ SECURE_RANDOM.nextBytes(data);
data[0] = (byte) (WebSocketHeader.FINBIT_MASK | WebSocketHeader.OPCODE_BINARY);
data[1] = WebSocketHeader.PAYLOAD_EXTENDED_64;
@@ -1206,8 +1189,7 @@ public void testUnwrapBuffer_src_buffer_medium_invalid_length() {
int messageLength = WebSocketHeader.MIN_HEADER_LENGTH + 1;
byte[] data = new byte[messageLength];
- Random random = new SecureRandom();
- random.nextBytes(data);
+ SECURE_RANDOM.nextBytes(data);
data[0] = (byte) (WebSocketHeader.FINBIT_MASK | WebSocketHeader.OPCODE_BINARY);
data[1] = WebSocketHeader.PAYLOAD_EXTENDED_16;
@@ -1228,8 +1210,7 @@ public void testUnwrapBuffer_src_buffer_large_invalid_length() {
int messageLength = WebSocketHeader.MED_HEADER_LENGTH_NOMASK + 1;
byte[] data = new byte[messageLength];
- Random random = new SecureRandom();
- random.nextBytes(data);
+ SECURE_RANDOM.nextBytes(data);
data[0] = (byte) (WebSocketHeader.FINBIT_MASK | WebSocketHeader.OPCODE_BINARY);
data[1] = WebSocketHeader.PAYLOAD_EXTENDED_64;
diff --git a/src/test/java/com/microsoft/azure/proton/transport/ws/impl/WebSocketImplTest.java b/src/test/java/com/microsoft/azure/proton/transport/ws/impl/WebSocketImplTest.java
index 56f0f79..ae4992a 100644
--- a/src/test/java/com/microsoft/azure/proton/transport/ws/impl/WebSocketImplTest.java
+++ b/src/test/java/com/microsoft/azure/proton/transport/ws/impl/WebSocketImplTest.java
@@ -20,11 +20,9 @@
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
-import java.util.Random;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -1072,8 +1070,7 @@ public void testProcess_state_pong_changes_to_flow_head_closed() {
private byte[] createMessage(int size) {
byte[] data = new byte[size];
- Random random = new SecureRandom();
- random.nextBytes(data);
+ Utils.getSecureRandom().nextBytes(data);
byte finbit = (byte) (WebSocketHeader.FINBIT_MASK & 0xFF);
byte opcode = WebSocketHeader.OPCODE_MASK & 0x2;