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

Update SecurityQueryPayload to include json data #1758

Merged
merged 8 commits into from
Nov 22, 2021
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
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public static SecurityQueryPayload createDummyBqh() {
bqh.setQueryID(SecurityQueryID.SEND_HANDSHAKE_DATA);
bqh.setQueryType(SecurityQueryType.REQUEST);
bqh.setBulkData(null);
bqh.setJsonSize(0);
bqh.setJsonData(null);
return bqh;
}

Expand Down Expand Up @@ -66,9 +66,9 @@ public void testCorrectHeaderAssembly() {
dummyBqh.setQueryType(SecurityQueryType.REQUEST);
dummyBqh.setQueryID(SecurityQueryID.SEND_HANDSHAKE_DATA);
dummyBqh.setCorrelationID(3);
dummyBqh.setJsonSize(0);
dummyBqh.setJsonData(new byte[0]);

byte[] assembledHeader = dummyBqh.assembleHeaderBytes();
byte[] assembledHeader = dummyBqh.assembleBinaryData();
assertEquals(dummyBqh.getQueryType(), SecurityQueryType.valueOf(assembledHeader[0]));
byte[] queryIDFromHeader = new byte[3];
System.arraycopy(assembledHeader, 1, queryIDFromHeader, 0, 3);
Expand All @@ -81,7 +81,7 @@ public void testCorrectHeaderAssembly() {
public void testAssemblyAndParse() {
SecurityQueryPayload bqh = createDummyBqh();

byte[] bqhBytes = bqh.assembleHeaderBytes();
byte[] bqhBytes = bqh.assembleBinaryData();
assertNotNull(bqhBytes);

SecurityQueryPayload parsedBqh = SecurityQueryPayload.parseBinaryQueryHeader(bqhBytes);
Expand All @@ -99,7 +99,7 @@ public void testAssemblyAndParse() {
public void testCorruptHeader() {
SecurityQueryPayload bqh = createDummyBqh();

byte[] bqhBytes = bqh.assembleHeaderBytes();
byte[] bqhBytes = bqh.assembleBinaryData();

assertNotNull(safeParse(bqhBytes));

Expand All @@ -114,13 +114,18 @@ public void testCorruptHeader() {
}

@Test
public void testJsonSetException() {
try {
SecurityQueryPayload bqh = createDummyBqh();
bqh.setJsonData(null);
fail("Setting JSON data to null should have thrown an exception");
} catch (Exception e) {
//Pass
}
public void testNullJsonData() {
SecurityQueryPayload bqh = createDummyBqh();
bqh.setJsonData(null);
assertEquals(0, bqh.getJsonSize());
assertEquals(null, bqh.getJsonData());
}

@Test
public void testNullBulkData() {
SecurityQueryPayload bqh = createDummyBqh();
bqh.setBulkData(null);
assertEquals(0, bqh.getBulkDataSize());
assertEquals(null, bqh.getBulkData());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class SecurityQueryPayload {
private SecurityQueryID _securityQueryID;
private int _correlationID;
private int _jsonSize;
private SecurityQueryErrorCode _errorCode;
private int _bulkDataSize;

private byte[] _jsonData = null;
private byte[] _bulkData = null;
Expand Down Expand Up @@ -51,11 +51,6 @@ public static SecurityQueryPayload parseBinaryQueryHeader(byte[] binHeader) {
int _jsonSize = BitConverter.intFromByteArray(binHeader, 8);
msg.setJsonSize(_jsonSize);

//If we get an error message we want the error code from the last 8 bits
if (msg.getQueryType() == SecurityQueryType.NOTIFICATION && msg.getQueryID() == SecurityQueryID.SEND_INTERNAL_ERROR) {
msg.setErrorCode(SecurityQueryErrorCode.valueOf(binHeader[binHeader.length - 1]));
}

try {
//Get the JsonData after the header (after 96 bits) based on the jsonData size
if (_jsonSize > 0 && _jsonSize <= (binHeader.length - SECURITY_QUERY_HEADER_SIZE)) {
Expand Down Expand Up @@ -84,18 +79,28 @@ public static SecurityQueryPayload parseBinaryQueryHeader(byte[] binHeader) {
return msg;
}

public byte[] assembleHeaderBytes() {
public byte[] assembleBinaryData() {
// From the properties, create a data buffer
// Query Type - first 8 bits
// Query ID - next 24 bits
// Sequence Number - next 32 bits
// JSON size - next 32 bits
byte[] ret = new byte[SECURITY_QUERY_HEADER_SIZE];
ret[0] = _securityQueryType.getValue();
System.arraycopy(_securityQueryID.getValue(), 0, ret, 1, 3);
System.arraycopy(BitConverter.intToByteArray(_correlationID), 0, ret, 4, 4);
System.arraycopy(BitConverter.intToByteArray(_jsonSize), 0, ret, 8, 4);
return ret;
byte[] header = new byte[SECURITY_QUERY_HEADER_SIZE];
header[0] = _securityQueryType.getValue();
System.arraycopy(_securityQueryID.getValue(), 0, header, 1, 3);
System.arraycopy(BitConverter.intToByteArray(_correlationID), 0, header, 4, 4);
System.arraycopy(BitConverter.intToByteArray(_jsonSize), 0, header, 8, 4);

int size = _jsonSize + _bulkDataSize + SECURITY_QUERY_HEADER_SIZE;
byte[] dataOut = new byte[size];
System.arraycopy(header, 0, dataOut, 0, SECURITY_QUERY_HEADER_SIZE);
if (_jsonData != null) {
System.arraycopy(_jsonData, 0, dataOut, SECURITY_QUERY_HEADER_SIZE, _jsonSize);
}
if (_bulkData != null) {
System.arraycopy(_bulkData, 0, dataOut, SECURITY_QUERY_HEADER_SIZE + _jsonSize, _bulkDataSize);
}
return dataOut;
}

public SecurityQueryType getQueryType() {
Expand Down Expand Up @@ -126,23 +131,29 @@ public int getJsonSize() {
return _jsonSize;
}

public void setJsonSize(int _jsonSize) {
private void setJsonSize(int _jsonSize) {
this._jsonSize = _jsonSize;
}

public SecurityQueryErrorCode getErrorCode() {
return _errorCode;
public int getBulkDataSize() {
return _bulkDataSize;
}

public void setErrorCode(SecurityQueryErrorCode _errorCode) {
this._errorCode = _errorCode;
private void setBulkDataSize(int _bulkDataSize) {
this._bulkDataSize = _bulkDataSize;
}

public byte[] getJsonData() {
return _jsonData;
}

public void setJsonData(byte[] _jsonData) {
if (_jsonData == null) {
this._jsonSize = 0;
this._jsonData = null;
return;
}
this._jsonSize = _jsonData.length;
this._jsonData = new byte[this._jsonSize];
System.arraycopy(_jsonData, 0, this._jsonData, 0, _jsonSize);
}
Expand All @@ -152,6 +163,13 @@ public byte[] getBulkData() {
}

public void setBulkData(byte[] _bulkData) {
this._bulkData = _bulkData;
if(_bulkData == null) {
this._bulkDataSize = 0;
this._bulkData = null;
return;
}
this._bulkDataSize = _bulkData.length;
this._bulkData = new byte[this._bulkDataSize];
System.arraycopy(_bulkData, 0, this._bulkData, 0, _bulkDataSize);
}
}
77 changes: 55 additions & 22 deletions base/src/main/java/com/smartdevicelink/session/BaseSdlSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import com.smartdevicelink.protocol.SdlPacket;
import com.smartdevicelink.protocol.SdlProtocolBase;
import com.smartdevicelink.protocol.enums.ControlFrameTags;
import com.smartdevicelink.protocol.enums.SecurityQueryErrorCode;
import com.smartdevicelink.protocol.enums.SecurityQueryID;
import com.smartdevicelink.protocol.enums.SecurityQueryType;
import com.smartdevicelink.protocol.enums.SessionType;
Expand All @@ -61,7 +62,9 @@
import com.smartdevicelink.util.SystemInfo;
import com.smartdevicelink.util.Version;

import java.util.ArrayList;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
Expand Down Expand Up @@ -217,8 +220,8 @@ protected void processControlService(ProtocolMessage msg) {
// If the query is of type `Notification` and the id represents a client internal error, we abort the response message and the encryptionManager will not be in state ready.
if (receivedHeader.getQueryID() == SecurityQueryID.SEND_INTERNAL_ERROR
&& receivedHeader.getQueryType() == SecurityQueryType.NOTIFICATION) {
if (receivedHeader.getErrorCode() != null) {
DebugTool.logError(TAG, "Security Query module internal error: " + receivedHeader.getErrorCode().getName());
if (receivedHeader.getBulkData() != null && receivedHeader.getBulkDataSize() == 1) {
DebugTool.logError(TAG, "Security Query module internal error: " + SecurityQueryErrorCode.valueOf(receivedHeader.getBulkData()[0]).getName());
} else {
DebugTool.logError(TAG, "Security Query module error: No information provided");
}
Expand All @@ -237,29 +240,28 @@ protected void processControlService(ProtocolMessage msg) {

iNumBytes = sdlSecurity.runHandshake(data, dataToRead);

// Assemble a security query payload header for our response
SecurityQueryPayload responseHeader = new SecurityQueryPayload();

byte[] returnBytes;
ProtocolMessage protocolMessage;
if (iNumBytes == null || iNumBytes <= 0) {
DebugTool.logError(TAG, "Internal Error processing control service");

responseHeader.setQueryID(SecurityQueryID.SEND_INTERNAL_ERROR);
responseHeader.setQueryType(SecurityQueryType.NOTIFICATION);
responseHeader.setCorrelationID(msg.getCorrID());
responseHeader.setJsonSize(0);
returnBytes = new byte[12];
protocolMessage = serverSecurityFailedMessageWithClientMessageHeader(msg.getCorrID());
} else {
responseHeader.setQueryID(SecurityQueryID.SEND_HANDSHAKE_DATA);
responseHeader.setQueryType(SecurityQueryType.RESPONSE);
responseHeader.setCorrelationID(msg.getCorrID());
responseHeader.setJsonSize(0);
returnBytes = new byte[iNumBytes + 12];
System.arraycopy(dataToRead, 0, returnBytes, 12, iNumBytes);
protocolMessage = serverSecurityHandshakeMessageWithData(msg.getCorrID(), dataToRead);
}

//sdlSecurity.hs();

sendMessage(protocolMessage);
}

private ProtocolMessage serverSecurityHandshakeMessageWithData(int correlationId, byte[] bulkData) {
SecurityQueryPayload responseHeader = new SecurityQueryPayload();
responseHeader.setQueryID(SecurityQueryID.SEND_HANDSHAKE_DATA);
responseHeader.setQueryType(SecurityQueryType.RESPONSE);
responseHeader.setCorrelationID(correlationId);
responseHeader.setBulkData(bulkData);
responseHeader.setJsonData(null);

System.arraycopy(responseHeader.assembleHeaderBytes(), 0, returnBytes, 0, 12);
byte[] returnBytes = responseHeader.assembleBinaryData();

ProtocolMessage protocolMessage = new ProtocolMessage();
protocolMessage.setSessionType(SessionType.CONTROL);
Expand All @@ -268,9 +270,40 @@ protected void processControlService(ProtocolMessage msg) {
protocolMessage.setVersion((byte) sdlProtocol.getProtocolVersion().getMajor());
protocolMessage.setSessionID((byte) this.sessionId);

//sdlSecurity.hs();
return protocolMessage;
}

sendMessage(protocolMessage);
private ProtocolMessage serverSecurityFailedMessageWithClientMessageHeader(int correlationId) {
SecurityQueryPayload responseHeader = new SecurityQueryPayload();
responseHeader.setQueryID(SecurityQueryID.SEND_INTERNAL_ERROR);
responseHeader.setQueryType(SecurityQueryType.NOTIFICATION);
responseHeader.setCorrelationID(correlationId);
byte[] jsonData;
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("id", SecurityQueryErrorCode.ERROR_UNKNOWN_INTERNAL_ERROR.getValue());
jsonObject.put("text", SecurityQueryErrorCode.ERROR_UNKNOWN_INTERNAL_ERROR.getName());
jsonData = jsonObject.toString().getBytes();
} catch (JSONException e) {
DebugTool.logError(TAG, "JSON exception when constructing handshake error Notification");
e.printStackTrace();
jsonData = new byte[0];
}
responseHeader.setJsonData(jsonData);
byte[] errorCode = new byte[1];
errorCode[0] = SecurityQueryErrorCode.ERROR_UNKNOWN_INTERNAL_ERROR.getValue();
responseHeader.setBulkData(errorCode);

byte[] returnBytes = responseHeader.assembleBinaryData();

ProtocolMessage protocolMessage = new ProtocolMessage();
protocolMessage.setSessionType(SessionType.CONTROL);
protocolMessage.setData(returnBytes);
protocolMessage.setFunctionID(0x01);
protocolMessage.setVersion((byte) sdlProtocol.getProtocolVersion().getMajor());
protocolMessage.setSessionID((byte) this.sessionId);

return protocolMessage;
}

/**
Expand Down