Browse Source

implementation in various function of the secureChannelLayer

FlorianPalm 11 years ago
parent
commit
8dccdff636

+ 0 - 110
OPCUAServer/src/opcuaServer.c.orig

@@ -1,110 +0,0 @@
-/*
- ============================================================================
- Name        : opcuaServer.c
- Author      :
- Version     :
- Copyright   : Your copyright notice
- Description :
- ============================================================================
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-
-//#include "opcua_binaryEncDec.h"
-#include "opcua_builtInDatatypes.h"
-#include "opcua_transportLayer.h"
-#include "opcua_types.h"
-
-/*#include <sys/socket.h>
-#include <netinet/in.h>
-*/
-
-int main(void)
-{
-	puts("OPC ua Stack");
-	//struct BED_ApplicationDescription nStruct;
-	//UA_String s;
-	puts("running tests...");
-	TL_getMessageHeader_test();
-	TL_getHELMessage_test();
-	puts("...done");
-
-	server_init();
-	server_run();
-
-	return EXIT_SUCCESS;
-
-}
-
-void server_init()
-{
-	puts("starting demo Server");
-	//call listen
-
-}
-void server_run()
-{
-	int server_state = 0;
-	int recv_data = 0;
-	int send_data = 1;
-	int new_client = 2;
-	int new_request = 3;
-
-	while(1)
-	{
-		//call recv (nonblocking)
-
-		//call TL_getPacketType
-
-		//if newData
-		//
-		UA_connection connection;
-		AD_RawMessage *rawMessage;
-		switch(server_state)
-		{
-
-			recv_data :
-			{
-				//call receive function
-
-				break;
-			}
-			send_data :
-			{
-				//call send function
-				break;
-			}
-			new_client :
-			{
-				if(connection->transportLayer.connectionState != connectionState_ESTABLISHED)
-				{
-					TL_open(connection,rawMessage);
-				}
-/*				else
-				{
-					SL_open(connection,rawMessage);
-
-				}
-*/
-			}
-			new_request :
-			{
-
-
-				break;
-			}
-
-		}
-		//if newClient
-
-
-		//TL_processHELMessage(&connection,);
-
-		//--------
-		//call listen
-	}
-
-}
-

+ 1 - 3
OPCUAServer/src/opcua_advancedDatatypes.h

@@ -129,9 +129,7 @@ struct BED_DataValue
 /**
 * DiagnosticInfo
 * Part: 4
-* Chapter: 7.9
-* Page: 116
-*/
+* Chapter: 7.9*/
 struct BED_DiagnosticInfo
 {
 //ToDo	struct ???? identifier;				//ToDo: what kind of strcuture?

+ 23 - 18
OPCUAServer/src/opcua_binaryEncDec.c

@@ -77,15 +77,22 @@ Int64 convertToInt64(char* buf, int pos)
 	return t1 + t2 + t3 + t4 + t5 + t6 + t7 + t8;
 }
 
-UA_String convertToUAString(char* buf, int pos)
+convertToUAString(char* buf, int pos,UA_String *dstUAString)
 {
-	UA_String tmpUAString;
-	tmpUAString.Length = convertToInt32(buf,pos);
-	tmpUAString.Data = &(buf[sizeof(UInt32)]);
-	return tmpUAString;
+
+	dstUAString.Length = convertToInt32(buf,pos);
+	if(dstUAString.Length > 0)
+	{
+		dstUAString.Data = &(buf[sizeof(UInt32)]);
+	}
+	else
+	{
+		dstUAString.Length = 0;
+		dstUAString->Data = NULL;
+	}
 }
 
-UA_Guid convertToUAGuid(char* buf, int pos)
+UA_Guid* convertToUAGuid(char* buf, int pos)
 {
 	UA_Guid tmpUAGuid;
 	int counter = 0;
@@ -113,43 +120,43 @@ UA_Guid convertToUAGuid(char* buf, int pos)
 	return tmpUAGuid;
 }
 
-UA_NodeId convertToUANodeId(char* buf, int pos){
-	UA_NodeId tmpUANodeId;
-	tmpUANodeId.EncodingByte = convertToInt32(*buf, 0);
+void convertToUANodeId(char* buf, int pos, UA_NodeId* dstNodeId){
+
+	dstNodeId->EncodingByte = convertToInt32(*buf, 0);
 	int counter = sizeof(UInt32);
 
-	UA_NodeIdEncodingValuesType encodingType = tmpUANodeId.EncodingByte;
+	UA_NodeIdEncodingValuesType encodingType = dstNodeId->EncodingByte;
 
 	switch(encodingType)
 	{
 		case NIEVT_TWO_BYTE:
 		{
-			tmpUANodeId.Identifier.Numeric = convertToInt32(*buf, counter);
+			dstNodeId->Identifier.Numeric = convertToInt32(*buf, counter);
 			counter += sizeof(UInt16);
 			break;
 		}
 		case NIEVT_FOUR_BYTE:
 		{
-			tmpUANodeId.Identifier.Numeric = convertToInt32(*buf, counter);
+			dstNodeId->Identifier.Numeric = convertToInt32(*buf, counter);
 			counter += sizeof(Int64);
 			break;
 		}
 		case NIEVT_NUMERIC:
 		{
-			tmpUANodeId.Identifier.Numeric = convertToInt32(*buf, counter);
+			dstNodeId->Identifier.Numeric = convertToInt32(*buf, counter);
 			counter += sizeof(UInt32);
 			break;
 		}
 		case NIEVT_STRING:
 		{
-			tmpUANodeId.Identifier.String = convertToUAString(*buf, counter);
-			counter += sizeof(sizeof(UInt32) + tmpUANodeId.Identifier.String.Length*sizeof(char));
+			dstNodeId->Identifier.String = convertToUAString(*buf, counter);
+			counter += sizeof(sizeof(UInt32) + dstNodeId->Identifier.String.Length*sizeof(char));
 			break;
 		}
 		case NIEVT_GUID:
 		{
 			UA_Guid tempGuid = convertToUAGuid(*buf, counter);
-			tmpUANodeId.Identifier.Guid = &tempGuid;
+			dstNodeId->Identifier.Guid = &tempGuid;
 			counter += sizeof(UA_Guid);
 			break;
 		}
@@ -167,8 +174,6 @@ UA_NodeId convertToUANodeId(char* buf, int pos){
 			break;
 		}
 	}
-
-	return tmpUANodeId;
 }
 
 

+ 0 - 20
OPCUAServer/src/opcua_binaryEncDec.h.orig

@@ -1,20 +0,0 @@
-/*
- * opcua_BinaryEncDec.h
- *
- *  Created on: Dec 18, 2013
- *      Author: opcua
- */
-
-#ifndef OPCUA_BINARYENCDEC_NEU_H_
-#define OPCUA_BINARYENCDEC_NEU_H_
-
-#include "opcua_builtInDatatypes.h"
-
-
-
-//functions
-Byte convertToByte(char* buf, int pos);
-Int32 convertToInt32(char* buf,int pos);
-UInt32 convertToUInt32(char* buf, int pos);
-
-#endif /* OPCUA_BINARYENCDEC_NEU_H_ */

+ 7 - 1
OPCUAServer/src/opcua_connectionHelper.h

@@ -47,7 +47,13 @@ struct TL_connection
 
 struct SL_connection
 {
-	UInt32 secureChannelId;
+
+	T_ApplicationInstanceCertificate clientCertificate;
+	UInt32 requestType;
+	UA_String secureChannelId;
+	UInt32 securityMode;
+	UA_String clientNonce;
+	UA_Duration requestedLifetime;
 	UInt32 connectionState;
 
 };

+ 35 - 8
OPCUAServer/src/opcua_encodingLayer.c

@@ -7,19 +7,25 @@
 #include "opcua_encodingLayer.h"
 #include "opcua_binaryEncDec.h"
 #include "opcua_types.h"
+#include "opcua_builtInDatatypes.h"
 
-T_RequestHeader encodeRequestHeader(char* buf){
+T_RequestHeader encodeRequestHeader(char* buf)
+{
 	T_RequestHeader tmpRequestHeader;
-	int counter = 0 ;
+	int counter = 0;
 	//ToDo: counter needs the length of the buffer,
 	//		strings have in this type just the size of the pointer not of the content
 	tmpRequestHeader.authenticationToken = convertToUANodeId(*buf, counter);
-	if(tmpRequestHeader.authenticationToken.EncodingByte ==  NIEVT_STRING){
-		counter = sizeof(tmpRequestHeader.authenticationToken.EncodingByte) +
-				sizeof(tmpRequestHeader.authenticationToken.Namespace) +
-				sizeof(tmpRequestHeader.authenticationToken.Identifier.String.Length) +
-				sizeof(tmpRequestHeader.authenticationToken.Identifier.String.Data);
-	}else{
+	if (tmpRequestHeader.authenticationToken.EncodingByte == NIEVT_STRING)
+	{
+		counter =
+				sizeof(tmpRequestHeader.authenticationToken.EncodingByte)
+						+ sizeof(tmpRequestHeader.authenticationToken.Namespace)
+						+ sizeof(tmpRequestHeader.authenticationToken.Identifier.String.Length)
+						+ sizeof(tmpRequestHeader.authenticationToken.Identifier.String.Data);
+	}
+	else
+	{
 		counter = sizeof(tmpRequestHeader.authenticationToken);
 	}
 	tmpRequestHeader.timestamp = convertToUADateTime(*buf, counter);
@@ -36,3 +42,24 @@ T_RequestHeader encodeRequestHeader(char* buf){
 
 	return tmpRequestHeader;
 }
+
+void decodeMessage_test()
+{
+
+	char testMessage = {01,0x20,0xbe,0x01,0x20,0x20,0xf2,0xd6,0xd6,0xc9,0x01,0x00,0xbe,0x01,0x00,0x00,0xf2,0xd6,0xd6,0xc9,0x87,0x0b,0xcf,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0xe0,0x93,0x04,0x00,0x,0x};
+	AD_RawMessage rawMessage;
+	rawMessage.message = testMessage;
+	rawMessage.length = 64;
+	decodeMessage(testMessage);
+}
+/*
+ * builds a message structure by decoding a byte stream
+ */
+UA_ExtensionObject processMessage(AD_RawMessage *rawMessage)
+{
+	UA_NodeId tmpNodeId = convertToUANodeId(rawMessage,0);
+
+
+	//callServiceHandler(tmpNodeId,rawMessage);
+
+}

+ 118 - 47
OPCUAServer/src/opcua_secureChannelLayer.c

@@ -6,79 +6,150 @@
  */
 #include "opcua_secureChannelLayer.h"
 
-void SL_open(UA_connection *connection,AD_RawMessage *rawMessage)
+SL_getRequestHeader()
 {
-	switch(connection->secureLayer.connectionState)
-	{
-		connectionState_OPENING :
-		{
-
-			break;
-		}
-
-		connectionState_ESTABLISHED :
-		{
-			break;
-		}
-
-		connectionState_CLOSED :
-		{
-			//open the connection on transport layer
-			if(connection->transportLayer.connectionState == connectionState_ESTABLISHED)
-			{
-				if (TL_getPacketType(rawMessage) == packetType_OPN)
-				{
-					SL_openSecureChannel(connection, rawMessage);
-				}
 
-			}
-			break;
-		}
+}
+/*
+ * opens a secureChannel (server side)
+ */
+void SL_secureChannel_open(UA_connection     *connection,
+		AD_RawMessage                        *secureChannelMessage,
+		SL_SecureConversationMessageHeader   *SCM_Header,
+		SL_AsymmetricAlgorithmSecurityHeader *AAS_Header
+		SL_openSecureChannelResponse *response )
+{
 
-	}
+	//connection->secureLayer.
 }
-void SL_openSecureChannel(UA_connection *connection)
+void SL_secureChannel_Request_get(AD_RawMessage        *secureChannelMessage,
+		                          secureChannelRequest *SC_request)
 {
 
+}
+/*
+ * closes a secureChannel (server side)
+ */
+void SL_secureChannel_close(UA_connection *connection)
+{
 
-	TL_send();
 }
 /*
-void SL_receive(UA_connection *connection, AD_RawMessage *serviceMessage)
+ * receive and process data from underlying layer
+ */
+void SL_receive(UA_connection *connection,
+		        AD_RawMessage *serviceMessage)
 {
 	AD_RawMessage* secureChannelMessage;
+	SL_SecureConversationMessageHeader SCM_Header;
+	SL_AsymmetricAlgorithmSecurityHeader AAS_Header;
 
+	//get data from transport layer
 	TL_receive(UA_connection, secureChannelMessage);
 
-	switch (SL_getMessageType(secureChannelMessage))
+	UInt32 readPosition = SL_secureChannel_SCMHeader_get(connection,secureChannelMessage,&SCM_Header);
+
+	readPosition = SL_secureChannel_AASHeader_get(connection,secureChannelMessage,readPosition,&AAS_Header);
+
+	SL_secureChannel_Message_get(connection,secureChannelMessage,readPosition,serviceMessage);
+
+
+	if (secureChannelMessage.length > 0)
 	{
-		case SL_messageType_MSG:
+		switch (SCM_Header.MessageType)
+		{
+		case packetType_MSG:
+		{
+			if (connection->secureLayer.connectionState
+					== connectionState_ESTABLISHED)
+			{
+
+			}
+			else //receiving message, without secure channel
+			{
+				//TODO send back Error Message
+			}
+			break;
+		}
+		case packetType_OPN:
+		{
+			if (openSecureChannelHeader_check(connection, secureChannelMessage))
+			{
+				SL_secureChannel_open(connection, serviceMessage);
+			}
+			else
+			{
+				//TODO send back Error Message
+			}
+			//TODO free memory for secureChannelMessage
+			break;
+		}
+		case packetType_CLO:
 		{
-			serviceMessage = secureChannelMessage;
+			SL_secureChannel_close(connection, secureChannelMessage);
+
+			//TODO free memory for secureChannelMessage
 			break;
 		}
+		}
 	}
 
 }
-*/
-UInt32 SL_getMessageType(UA_connection *connection, AD_RawMessage *rawMessage)
+UInt32 SL_secureChannel_SCMHeader_get(UA_connection *connection, AD_RawMessage *rawMessage, SL_SecureConversationMessageHeader* SC_Header)
+{
+	Int32 pos = 0;
+	SC_Header->MessageType = TL_getPacketType(rawMessage);
+	pos += TL_MESSAGE_TYPE_LEN;
+	SC_Header->IsFinal = rawMessage[pos];
+	pos += sizeof(Byte);
+	SC_Header->MessageSize = convertToUInt32(rawMessage,pos);
+	pos += sizeof(UInt32);
+	SC_Header->SecureChannelId = convertToUInt32(rawMessage,pos);
+	pos += sizeof(UInt32);
+	return pos;
+
+}
+UInt32 SL_secureChannel_AASHeader_get(UA_connection *connection, AD_RawMessage *rawMessage,UInt32 pos, SL_AsymmetricAlgorithmSecurityHeader* AAS_Header)
 {
-	if(rawMessage->message[0] == 'O' &&
-	   rawMessage->message[1] == 'P' &&
-	   rawMessage->message[2] == 'N')
+	AAS_Header->SecurityPolicyUri.Length = convertToInt32(rawMessage,pos);
+
+	pos += sizeof(Int32);
+	AAS_Header->SecurityPolicyUri.Data = rawMessage[pos];
+
+	if(AAS_Header->SecurityPolicyUri.Length < 0)
 	{
-		return SL_messageType_OPN;
+		AAS_Header->SecurityPolicyUri.Length = 0;
 	}
-	else if(rawMessage->message[0] == 'C' &&
-	        rawMessage->message[1] == 'L' &&
-	        rawMessage->message[2] == 'O')
+	pos +=  AAS_Header->SecurityPolicyUri.Length;
+
+	AAS_Header->SenderCertificate.Length = convertToInt32(rawMessage,pos);
+	pos += sizeof(Int32);
+	if(AAS_Header->SenderCertificate.Length < 0)
 	{
-		return SL_messageType_CLO;
+		AAS_Header->SenderCertificate.Length = 0;
 	}
-	else if(rawMessage->message[0] == 'M' &&
-			rawMessage->message[1] == 'S' &&
-			rawMessage->message[2] == 'G')
+	AAS_Header->SenderCertificate.Data = rawMessage[pos];
+
+	pos += AAS_Header->SenderCertificate.Length;
+
+	AAS_Header->ReceiverThumbprint.Length = convertToInt32(rawMessage,pos);
+	pos += sizeof(Int32);
+
+	if(AAS_Header->ReceiverThumbprint.Length < 0)
 	{
-		return SL_messageType_MSG;
+		AAS_Header->ReceiverThumbprint.Length = 0;
 	}
+	AAS_Header->ReceiverThumbprint.Data = rawMessage[pos];
+
+	pos += AAS_Header->ReceiverThumbprint.Length;
+	return pos;
+}
+void SL_secureChannel_Footer_get()
+{
+
+
+}
+void SL_secureChannel_Message_get(UA_connection *connection, AD_RawMessage *rawMessage,UInt32 pos, AD_RawMessage *message)
+{
+
 }

+ 39 - 0
OPCUAServer/src/opcua_secureChannelLayer.h

@@ -8,6 +8,45 @@
 #ifndef OPCUA_SECURECHANNELLAYER_H_
 #define OPCUA_SECURECHANNELLAYER_H_
 
+static const Int32 SL_HEADER_LENGTH = 0;
+typedef struct _SL_OpenSecureChannelResponse
+{
+
+};
+typedef struct _SL_SecureConversationMessageHeader
+{
+	UInt32 MessageType;
+	Byte   IsFinal;
+	UInt32 MessageSize;
+	UInt32 SecureChannelId;
+}SL_SecureConversationMessageHeader;
+typedef struct _SL_AsymmetricAlgorithmSecurityHeader
+{
+	UA_String SecurityPolicyUri;
+	UA_String SenderCertificate;
+	UA_String ReceiverThumbprint;
+}SL_AsymmetricAlgorithmSecurityHeader;
+
+typedef struct _SL_SequenceHeader
+{
+	UInt32 SequenceNumber;
+	UInt32 RequestId;
+}SL_SequenceHeader;
+
+/*
+ * optional, only if there is encryption present
+ */
+typedef struct _SL_AsymmetricAlgorithmSecurityFooter
+{
+	Byte PaddingSize;
+	Byte *Padding;
+
+	UInt32 SignatureSize;
+	Byte *Signature;
+}SL_AsymmetricAlgorithmSecurityFooter;
+
+
+
 
 
 #endif /* OPCUA_SECURECHANNELLAYER_H_ */

+ 1 - 1
OPCUAServer/src/opcua_serverAPI.h

@@ -15,7 +15,7 @@
 
 
 
-
+// registerServiceCallback(NodeTypeIde,)
 // sessionId = AcceptSecureChannel()
 
 // serviceRequest = receiveServiceRequest(sessionId)

+ 44 - 22
OPCUAServer/src/opcua_transportLayer.c

@@ -19,16 +19,30 @@ void TL_sendACK(UA_connection *connection)
 	//call send function
 
 }
-
+/*
+ * server answer to open message
+ */
 void TL_open(UA_connection *connection, AD_RawMessage *rawMessage)
 {
+	UA_connection tmpConnection;
 	switch(connection->transportLayer.connectionState)
 	{
 		connectionState_CLOSED :
 		{
+			//process the connection values received by the client
+			TL_processHELMessage(&tmpConnection,rawMessage);
+			connection->transportLayer.serverBuffers.protocolVersion = TL_SERVER_PROTOCOL_VERSION;
+
+			connection->transportLayer.serverBuffers.recvBufferSize =
+					tmpConnection->transportLayer.serverBuffers.recvBufferSize;
+
+			connection->transportLayer.serverBuffers.sendBufferSize =
+					tmpConnection->transportLayer.serverBuffers.sendBufferSize;
 
-			TL_processHELMessage(connection,rawMessage);
-			TL_sendACK(connection);
+			connection->transportLayer.serverBuffers.maxMessageSize = TL_SERVER_MAX_MESSAGE_SIZE;
+			connection->transportLayer.serverBuffers.maxChunkCount = TL_SERVER_MAX_CHUNK_COUNT;
+
+		    TL_sendACK(connection);
 			connection->transportLayer.connectionState = connectionState_ESTABLISHED;
 			break;
 		}
@@ -45,7 +59,7 @@ void TL_open(UA_connection *connection, AD_RawMessage *rawMessage)
 		}
 	}
 }
-/*
+
 void TL_receive(UA_connection *connection, AD_RawMessage *TL_message)
 {
 	UInt32 bufferSize = connection->transportLayer.serverBuffers.recvBufferSize = 8192;
@@ -62,34 +76,42 @@ void TL_receive(UA_connection *connection, AD_RawMessage *TL_message)
 	{
 		length = tcp_recv(connection, tmpRawMessage.message, bufferSize);
 	}
+
+
 	tmpRawMessage.length = length;
 	if(tmpRawMessage.length > 0)
 	{
-		TL_getMessageHeader(connection, &tmpHeader);
-		switch(tmpHeader->MessageType)
+		switch(TL_getPacketType(tmpRawMessage))
 		{
-			TL_OPN,TL_MSG,TL_CLO :
-			{
-
-				break;
-			}
-			TL_HEL :
-			{
-				break;
-			}
-			TL_ACK :
-			{
-				break;
-			}
-
-
+		packetType_MSG:
+		packetType_OPN:
+		packetType_CLO:
+			TL_message->length = tmpRawMessage.length;
+			TL_message->message = tmpRawMessage.message;
+			break;
+		packetType_HEL:
+			TL_message->length = 0;
+			TL_message->message = NULL;
+			TL_open(connection, tmpRawMessage);
+			break;
+		packetType_ACK:
+			TL_message->length = 0;
+			TL_message->message = NULL;
+			break;
+		packetType_ERR:
+			TL_message->length = 0;
+			TL_message->message = NULL;
+			//TODO ERROR HANDLING
+			break;
+		default:
+			//TODO ERROR HANDLING
 		}
 		//check in which state the connection is
 
 	}
 
 }
-*/
+
 void TL_getMessageHeader_test()
 {
 

+ 3 - 1
OPCUAServer/src/opcua_transportLayer.h

@@ -23,7 +23,9 @@ static const UInt32 TL_MESSAGE_TYPE_LEN = 3;
 static const UInt32 TL_RESERVED_LEN = 1;
 
 //variables which belong to layer
-
+static const TL_SERVER_PROTOCOL_VERSION = 0;
+static const TL_SERVER_MAX_CHUNK_COUNT = 1;
+static const TL_SERVER_MAX_MESSAGE_SIZE = 8192;
 
 enum TL_messageType_td
 {