소스 검색

a first alpha version of building a secureChannel response message, refactoring needs to be done(naming conventions, size calculations).

FlorianPalm 11 년 전
부모
커밋
0cbe409542
5개의 변경된 파일133개의 추가작업 그리고 74개의 파일을 삭제
  1. 80 36
      src/opcua_binaryEncDec.c
  2. 2 2
      src/opcua_binaryEncDec.h
  3. 2 1
      src/opcua_connectionHelper.h
  4. 32 23
      src/opcua_secureChannelLayer.c
  5. 17 12
      tests/check_stack.c

+ 80 - 36
src/opcua_binaryEncDec.c

@@ -431,89 +431,126 @@ Int32 decoder_decodeBuiltInDatatype(char const * srcBuf, Int32 type, Int32 *pos,
 
 
  /* not tested */
-/*needs to be reimplemented */
-Int32 encode_builtInDatatypeArray(void *data, Int32 size, Int32 type,
-		Int32 *pos, char *dstBuf) {
-	int i;
-	void * pItem;
-	encoder_encodeBuiltInDatatype((void*) (size), INT32, pos, dstBuf);
-	for (i = 0; i < size;) {
-		encoder_encodeBuiltInDatatype(pItem, type, pos, dstBuf);
-		switch (type) {
+Int32 encoder_encodeBuiltInDatatypeArray(void **data, Int32 size, Int32 arrayType, Int32 *pos, char *dstBuf)
+{
+	Int32 i;
+	Int32 type;
+	void* pElement = NULL;
+	//encode the length
+	encoder_encodeBuiltInDatatype((void*) (&size), INT32, pos, dstBuf);
+
+	if(data != NULL)
+	{
+		pElement = *data;
+	}
+
+	//get the element type from array type
+	type = arrayType - 128; //TODO replace with define
+
+	//encode data elements
+	for (i = 0; i < size; i++) {
+		switch(type)
+		{
 		case BOOLEAN:
-			pItem = (Boolean*) (data) + 1;
+			encoder_encodeBuiltInDatatype((Boolean*)pElement, type, pos, dstBuf);
+			pElement = (Boolean*)pElement + 1;
 			break;
 		case SBYTE:
-			pItem = (SByte*) (data) + 1;
+			encoder_encodeBuiltInDatatype((SByte*)pElement, type, pos, dstBuf);
+			pElement = (SByte*)pElement + 1;
 			break;
 		case BYTE:
-			pItem = (Byte*) (data) + 1;
+			encoder_encodeBuiltInDatatype((Byte*)pElement, type, pos, dstBuf);
+			pElement = (Byte*)pElement + 1;
 			break;
 		case INT16:
-			pItem = (Int16*) (data) + 1;
+			encoder_encodeBuiltInDatatype((Int16*)pElement, type, pos, dstBuf);
+			pElement = (Int16*)pElement + 1;
 			break;
 		case UINT16:
-			pItem = (UInt16*) (data) + 1;
+			encoder_encodeBuiltInDatatype((UInt16*)pElement, type, pos, dstBuf);
+			pElement = (UInt16*)pElement + 1;
 			break;
 		case INT32:
-			pItem = (Int32*) (data) + 1;
+			encoder_encodeBuiltInDatatype((Int32*)pElement, type, pos, dstBuf);
+			pElement = (Int32*)pElement + 1;
 			break;
 		case UINT32:
-			pItem = (UInt32*) (data) + 1;
+			encoder_encodeBuiltInDatatype((UInt32*)pElement, type, pos, dstBuf);
+			pElement = (UInt32*)pElement + 1;
 			break;
 		case INT64:
-			pItem = (Int64*) (data) + 1;
+			encoder_encodeBuiltInDatatype((Int64*)pElement, type, pos, dstBuf);
+			pElement = (Int64*)pElement + 1;
 			break;
 		case UINT64:
-			pItem = (UInt64*) (data) + 1;
+			encoder_encodeBuiltInDatatype((UInt64*)pElement, type, pos, dstBuf);
+			pElement = (UInt64*)pElement + 1;
 			break;
 		case FLOAT:
-			pItem = (Float*) (data) + 1;
+			encoder_encodeBuiltInDatatype((Float*)pElement, type, pos, dstBuf);
+			pElement = (Float*)pElement + 1;
 			break;
 		case DOUBLE:
-			pItem = (Double*) (data) + 1;
+			encoder_encodeBuiltInDatatype((Double*)pElement, type, pos, dstBuf);
+			pElement = (Double*)pElement + 1;
 			break;
 		case STRING:
-			pItem = (UA_String*) (data) + 1;
+			encoder_encodeBuiltInDatatype((UA_String*)pElement, type, pos, dstBuf);
+			pElement = (UA_String*)pElement + 1;
 			break;
 		case DATE_TIME:
-			pItem = (UA_DateTime*) (data) + 1;
+			encoder_encodeBuiltInDatatype((UA_DateTime*)pElement, type, pos, dstBuf);
+			pElement = (UA_DateTime*)pElement + 1;
 			break;
 		case GUID:
-			pItem = (UA_Guid*) (data) + 1;
+			encoder_encodeBuiltInDatatype((UA_Guid*)pElement, type, pos, dstBuf);
+			pElement = (UA_Guid*)pElement + 1;
 			break;
 		case BYTE_STRING:
-			pItem = (UA_ByteString*) (data) + 1;
+			encoder_encodeBuiltInDatatype((UA_ByteString*)pElement, type, pos, dstBuf);
+			pElement = (UA_ByteString*)pElement + 1;
 			break;
 		case XML_ELEMENT:
-			pItem = (UA_XmlElement*) (data) + 1;
+			encoder_encodeBuiltInDatatype((UA_XmlElement*)pElement, type, pos, dstBuf);
+			pElement = (UA_XmlElement*)pElement + 1;
 			break;
 		case NODE_ID:
-			pItem = (UA_NodeId*) (data) + 1;
+			encoder_encodeBuiltInDatatype((UA_NodeId*)pElement, type, pos, dstBuf);
+			pElement = (UA_NodeId*)pElement + 1;
 			break;
 		case EXPANDED_NODE_ID:
-			pItem = (UA_ExpandedNodeId*) (data) + 1;
+			encoder_encodeBuiltInDatatype((UA_ExpandedNodeId*)pElement, type, pos, dstBuf);
+			pElement = (UA_ExpandedNodeId*)pElement + 1;
 			break;
 		case STATUS_CODE:
-			pItem = (UA_StatusCode*) (data) + 1;
+			encoder_encodeBuiltInDatatype((UA_StatusCode*)pElement, type, pos, dstBuf);
+			pElement = (UA_StatusCode*)pElement + 1;
 			break;
 		case QUALIFIED_NAME:
-			pItem = (UA_QualifiedName*) (data) + 1;
+			encoder_encodeBuiltInDatatype((UA_QualifiedName*)pElement, type, pos, dstBuf);
+			pElement = (UA_QualifiedName*)pElement + 1;
 			break;
 		case LOCALIZED_TEXT:
-			pItem = (UA_LocalizedText*) (data) + 1;
+			encoder_encodeBuiltInDatatype((UA_LocalizedText*)pElement, type, pos, dstBuf);
+			pElement = (UA_LocalizedText*)pElement + 1;
 			break;
 		case EXTENSION_OBJECT:
-			pItem = (UA_ExtensionObject*) (data) + 1;
+			encoder_encodeBuiltInDatatype((UA_ExtensionObject*)pElement, type, pos, dstBuf);
+			pElement = (UA_ExtensionObject*)pElement + 1;
 			break;
 		case DATA_VALUE:
-			pItem = (UA_DataValue*) (data) + 1;
+			encoder_encodeBuiltInDatatype((UA_DataValue*)pElement, type, pos, dstBuf);
+			pElement = (UA_DataValue*)pElement + 1;
 			break;
 		case VARIANT:
-			pItem = (UA_Variant*) (data) + 1;
+			encoder_encodeBuiltInDatatype((UA_Variant*)pElement, type, pos, dstBuf);
+			pElement = (UA_Variant*)pElement + 1;
 			break;
 		case DIAGNOSTIC_INFO:
-			pItem = (UA_DiagnosticInfo*) (data) + 1;
+			encoder_encodeBuiltInDatatype((UA_DiagnosticInfo*)pElement, type, pos, dstBuf);
+			pElement = (UA_DiagnosticInfo*)pElement + 1;
+
 			break;
 		}
 	}
@@ -1156,7 +1193,7 @@ Int32 encodeVariant(UA_Variant *variant, Int32 *pos, char *dstBuf) {
 				pos, dstBuf);
 		if (variant->ArrayLength > 0) {
 			//encode array as given by variant type
-			encode_builtInDatatypeArray((void*) variant->Value,
+			encoder_encodeBuiltInDatatypeArray((void*) variant->Value,
 					variant->ArrayLength, (variant->EncodingMask & 31), pos,
 					dstBuf);
 		}
@@ -1355,7 +1392,7 @@ Int32 encodeDiagnosticInfo(UA_DiagnosticInfo *diagnosticInfo, Int32 *pos,
 
 	encoder_encodeBuiltInDatatype((void*) (&(diagnosticInfo->EncodingMask)),
 			BYTE, pos, dstbuf);
-	for (mask = 1; mask <= 0x40; mask = mask << 2) {
+	for (mask = 1; mask <= 0x40; mask = mask << 1) {
 
 		switch (mask & (diagnosticInfo->EncodingMask)) {
 		case DIEMT_SYMBOLIC_ID:
@@ -1480,6 +1517,13 @@ Int32 encodeResponseHeader(UA_AD_ResponseHeader const * responseHeader,
 	encodeUADateTime(responseHeader->timestamp, pos, dstBuf->Data);
 	encodeIntegerId(responseHeader->requestHandle, pos, dstBuf->Data);
 	encodeUInt32(responseHeader->serviceResult, pos, dstBuf->Data);
+	encodeDiagnosticInfo(responseHeader->serviceDiagnostics, pos, dstBuf->Data);
+
+	encoder_encodeBuiltInDatatypeArray(responseHeader->stringTable,
+			responseHeader->noOfStringTable, STRING_ARRAY, pos, dstBuf->Data);
+
+	encodeExtensionObject(responseHeader->additionalHeader, pos, dstBuf->Data);
+
 	//Kodieren von String Datentypen
 
 	return 0;

+ 2 - 2
src/opcua_binaryEncDec.h

@@ -49,8 +49,8 @@ Int32 encoder_encodeBuiltInDatatype(void *data, Int32 type, Int32 *pos, char *ds
  * @param dstBuf
  * @return
  */
-Int32 encoder_encodeBuiltInDatatypeArray(void *data, Int32 size,
-		Int32 type, Int32 *pos,
+Int32 encoder_encodeBuiltInDatatypeArray(void **data, Int32 size,
+		Int32 arrayType, Int32 *pos,
 		char *dstBuf);
 /**
  *

+ 2 - 1
src/opcua_connectionHelper.h

@@ -76,7 +76,8 @@ struct SL_connection
 	UA_String secureChannelId;
 	//UInt32 UInt32_secureChannelId;
 	UInt32 securityMode;
-	UA_ByteString clientNonce;
+	UA_ByteString remoteNonce;
+	UA_ByteString localNonce;
 	UInt32 connectionState;
 	SL_ChannelSecurityToken securityToken;
 	UInt32 requestId; // request Id of the current request

+ 32 - 23
src/opcua_secureChannelLayer.c

@@ -28,8 +28,12 @@ Int32 SL_initConnectionObject(UA_connection *connection)
 	connection->secureLayer.localtAsymAlgSettings.SenderCertificate.Data = NULL;
 	connection->secureLayer.localtAsymAlgSettings.SenderCertificate.Length = 0;
 
-	connection->secureLayer.clientNonce.Data = NULL;
-	connection->secureLayer.clientNonce.Length = 0;
+	connection->secureLayer.remoteNonce.Data = NULL;
+	connection->secureLayer.remoteNonce.Length = 0;
+
+	connection->secureLayer.localNonce.Data = (Byte*)opcua_malloc(sizeof(Byte));
+	*connection->secureLayer.localNonce.Data = sizeof(Byte);
+	connection->secureLayer.localNonce.Length = 1;
 
 	connection->secureLayer.connectionState = connectionState_CLOSED;
 
@@ -41,7 +45,11 @@ Int32 SL_initConnectionObject(UA_connection *connection)
 	connection->secureLayer.secureChannelId.Length = 0;
 
 	connection->secureLayer.securityMode = securityMode_INVALID;
+	//TODO set a valid start secureChannelId number
+	connection->secureLayer.securityToken.secureChannelId = 25;
 
+	//TODO set a valid start TokenId
+	connection->secureLayer.securityToken.tokenId = 1;
 	connection->secureLayer.sequenceNumber = 1;
 
 	return UA_NO_ERROR;
@@ -146,7 +154,6 @@ Int32 SL_openSecureChannel(UA_connection *connection,
 	SL_ChannelSecurityToken securityToken;
 	UA_ByteString serverNonce;
 	UA_NodeId responseType;
-	UA_ExtensionObject additionalHeader;
 	//sizes for memory allocation
 	Int32 sizeResponse;
 	Int32 sizeRespHeader;
@@ -155,7 +162,7 @@ Int32 SL_openSecureChannel(UA_connection *connection,
 	Int32 sizeSecurityToken;
 	UA_ByteString response;
 	UInt32 serverProtocolVersion;
-	Int32 *pos;
+	Int32 pos;
 	UA_DiagnosticInfo serviceDiagnostics;
 
 	if(requestHeader->returnDiagnostics != 0)
@@ -227,9 +234,9 @@ Int32 SL_openSecureChannel(UA_connection *connection,
 	//                  secureChannelId + TokenId + CreatedAt + RevisedLifetime
 	sizeSecurityToken = sizeof(UInt32) + sizeof(UInt32) + sizeof(UA_DateTime) + sizeof(Int32);
 
-	//ignore server nonce
-	serverNonce.Length = 0;
-	serverNonce.Data = NULL;
+
+	serverNonce.Length = connection->secureLayer.localNonce.Length;
+	serverNonce.Data = connection->secureLayer.localNonce.Data;
 
 	//fill token structure with default server information
 	securityToken.secureChannelId = connection->secureLayer.securityToken.secureChannelId;
@@ -240,39 +247,41 @@ Int32 SL_openSecureChannel(UA_connection *connection,
 	serverProtocolVersion = connection->transportLayer.localConf.protocolVersion;
 
 	//                ProtocolVersion + SecurityToken + Nonce
-	sizeRespMessage = sizeof(UInt32) + sizeSecurityToken + serverNonce.Length + sizeof(Int32) + sizeSecurityToken;
+	sizeRespMessage = sizeof(UInt32) + serverNonce.Length + sizeof(Int32) + sizeSecurityToken;
 	printf("SL_openSecureChannel - size of response message=%d\n",sizeRespMessage);
+
+
 	//get memory for response
 	sizeResponseType = nodeId_calcSize(&responseType);
-	response.Data = (char*)opcua_malloc(sizeResponseType + sizeRespHeader + sizeRespMessage);
+
 	response.Length = sizeResponseType + sizeRespHeader + sizeRespMessage;
 
 	//get memory for response
-	response.Data = (char*)opcua_malloc(nodeId_calcSize(responseType) + sizeRespHeader + sizeRespMessage);
-	*pos = 0;
+	response.Data = (char*)opcua_malloc(nodeId_calcSize(&responseType) + sizeRespHeader + sizeRespMessage);
+	pos = 0;
 	//encode responseType (NodeId)
 	UA_NodeId_printf("SL_openSecureChannel - TypeId =",&responseType);
-	encoder_encodeBuiltInDatatype(&responseType, NODE_ID, pos, response.Data);
+	encoder_encodeBuiltInDatatype(&responseType, NODE_ID, &pos, response.Data);
 
 	//encode header
 	printf("SL_openSecureChannel - encoding response header \n");
 
-	encodeResponseHeader(&responseHeader, pos, &response);
+	encodeResponseHeader(&responseHeader, &pos, &response);
 	printf("SL_openSecureChannel - response header encoded \n");
 
 	//encode message
 	printf("SL_openSecureChannel - serverProtocolVersion = %d \n",serverProtocolVersion);
-	encoder_encodeBuiltInDatatype(&serverProtocolVersion, UINT32, pos,response.Data);
+	encoder_encodeBuiltInDatatype(&serverProtocolVersion, UINT32, &pos,response.Data);
 	printf("SL_openSecureChannel - secureChannelId = %d \n",securityToken.secureChannelId);
-	encoder_encodeBuiltInDatatype(&(securityToken.secureChannelId), UINT32, pos,response.Data);
+	encoder_encodeBuiltInDatatype(&(securityToken.secureChannelId), UINT32, &pos,response.Data);
 	printf("SL_openSecureChannel - tokenId = %d \n",securityToken.tokenId);
-	encoder_encodeBuiltInDatatype(&(securityToken.tokenId), INT32, pos,response.Data);
+	encoder_encodeBuiltInDatatype(&(securityToken.tokenId), INT32, &pos,response.Data);
 
-	encoder_encodeBuiltInDatatype(&(securityToken.createdAt), DATE_TIME, pos,response.Data);
+	encoder_encodeBuiltInDatatype(&(securityToken.createdAt), DATE_TIME, &pos,response.Data);
 	printf("SL_openSecureChannel - revisedLifetime = %d \n",securityToken.revisedLifetime);
-	encoder_encodeBuiltInDatatype(&(securityToken.revisedLifetime), INT32, pos,response.Data);
+	encoder_encodeBuiltInDatatype(&(securityToken.revisedLifetime), INT32, &pos,response.Data);
 
-	encoder_encodeBuiltInDatatype(&serverNonce, BYTE_STRING, pos,response.Data);
+	encoder_encodeBuiltInDatatype(&serverNonce, BYTE_STRING, &pos,response.Data);
 
 	printf("SL_openSecureChannel - response.Length = %d \n",response.Length);
 	//449 = openSecureChannelResponse
@@ -396,8 +405,8 @@ Int32 SL_processMessage(UA_connection *connection, UA_ByteString message) {
 		printf("SL_processMessage - securityMode=%d\n", securityMode);
 		switch (securityMode) {
 		case securityMode_INVALID:
-			connection->secureLayer.clientNonce.Data = NULL;
-			connection->secureLayer.clientNonce.Length = 0;
+			connection->secureLayer.remoteNonce.Data = NULL;
+			connection->secureLayer.remoteNonce.Length = 0;
 			printf("SL_processMessage - client demands no security \n");
 			break;
 
@@ -424,7 +433,7 @@ Int32 SL_processMessage(UA_connection *connection, UA_ByteString message) {
 		//TODO process requestedLifetime
 
 		// 62541-4 §7.27 "The requestHandle given by the Client to the request."
-		return SL_openSecureChannel(connection, requestHeader.requestHandle, SC_Good, &serviceDiagnostics);
+		return SL_openSecureChannel(connection, &requestHeader, SC_Good);
 	} else {
 		printf("SL_processMessage - unknown service request");
 		//TODO change error code
@@ -637,8 +646,8 @@ Int32 encodeSCMHeader(SL_SecureConversationMessageHeader *SC_Header, Int32 *pos,
 
 Int32 decodeSequenceHeader(UA_ByteString *rawMessage, Int32 *pos,
 		SL_SequenceHeader *SequenceHeader) {
-	decodeUInt32(rawMessage->Data, pos, &(SequenceHeader->RequestId));
 	decodeUInt32(rawMessage->Data, pos, &(SequenceHeader->SequenceNumber));
+	decodeUInt32(rawMessage->Data, pos, &(SequenceHeader->RequestId));
 	return UA_NO_ERROR;
 }
 

+ 17 - 12
tests/check_stack.c

@@ -628,25 +628,29 @@ END_TEST
 START_TEST(encoder_encodeBuiltInDatatypeArray_test)
 {
 	Int32 position = 0;
+	Int32 i;
+	char vals[9];
+	char *pVals[9];
+
+	//generate data, numbers from 0-9
+	for(i = 0; i < 9; i++){
+		vals[i] = i;
+		pVals[i] = &vals[i];
+	}
 
-	char input = {1,2,3,4,5,6,7,8,9};
 	Int32 len = 9;
 	Int32 ret;
-	char *mem = malloc(13 * sizeof(Byte));
 
+	char *mem = malloc(13 * sizeof(Byte));
 
-	ret = encoder_encodeBuiltInDatatypeArray((void*)input,len, BYTE_ARRAY,
+	ret = encoder_encodeBuiltInDatatypeArray((void*)pVals,len, BYTE_ARRAY,
 			&position, mem);
 
-	ck_assert_int_eq(mem[4], 0x01);
-	ck_assert_int_eq(mem[5], 0x02);
-	ck_assert_int_eq(mem[6], 0x03);
-	ck_assert_int_eq(mem[7], 0x04);
-	ck_assert_int_eq(mem[8], 0x05);
-	ck_assert_int_eq(mem[9], 0x06);
-	ck_assert_int_eq(mem[10], 0x07);
-	ck_assert_int_eq(mem[11], 0x08);
-	ck_assert_int_eq(mem[12], 0x09);
+	for(i = 0; i < 9; i++){
+		ck_assert_int_eq(mem[i+sizeof(Int32)], i);
+	}
+
+
 
 	ck_assert_int_eq(position, sizeof(Int32) + 9);
 	ck_assert_int_eq(ret, UA_NO_ERROR);
@@ -910,6 +914,7 @@ Suite *testSuite_encoder_encodeBuiltInDatatypeArray_test(void)
 	suite_add_tcase(s,tc_core);
 	return s;
 }
+
 int main (void)
 {
 	int number_failed = 0;