opcua_secureChannelLayer.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. /*
  2. * opcua_secureChannelLayer.c
  3. *
  4. * Created on: Jan 13, 2014
  5. * Author: opcua
  6. */
  7. #include "opcua_secureChannelLayer.h"
  8. //memory calculation
  9. Int32 SL_openSecureChannelRequest_check(const UA_connection *connection, AD_RawMessage *secureChannelMessage)
  10. {
  11. return UA_NO_ERROR;
  12. }
  13. /*
  14. * respond the securechannel_open request
  15. */
  16. Int32 SL_secureChannel_ResponseHeader_get(const UA_connection *connection, T_ResponseHeader *responseHeader)
  17. {
  18. responseHeader->timestamp = 0;//TODO getCurrentTime();
  19. responseHeader->requestHandle = 0;
  20. responseHeader->serviceResult = 0; // TODO insert service result code
  21. responseHeader->serviceDiagnostics->EncodingMask = 0;
  22. responseHeader->noOfStringTable = 0;
  23. responseHeader->additionalHeader.Body.Length = 0;
  24. responseHeader->additionalHeader.Encoding = 0;
  25. responseHeader->additionalHeader.Length = 0;
  26. responseHeader->additionalHeader.TypeId.Namespace = 0;
  27. responseHeader->additionalHeader.TypeId.Identifier.Numeric = 0;
  28. responseHeader->requestHandle = 0;
  29. return UA_NO_ERROR;
  30. }
  31. /*
  32. * opens a secureChannel (server side)
  33. */
  34. Int32 SL_secureChannel_open(const UA_connection *connection,
  35. const AD_RawMessage *secureChannelMessage,
  36. const SL_SecureConversationMessageHeader *SCMHeader,
  37. const SL_AsymmetricAlgorithmSecurityHeader *AASHeader,
  38. const SL_SequenceHeader *SequenceHeader)
  39. {
  40. T_ResponseHeader responseHeader;
  41. AD_RawMessage rawMessage;
  42. Int32 position = 0;
  43. SL_secureChannel_ResponseHeader_get(connection,&responseHeader);
  44. Int32 size = responseHeader_calcSize(&responseHeader);
  45. rawMessage.message = (char*)opcua_malloc(size);
  46. encodeResponseHeader(&responseHeader, &position, &rawMessage);
  47. rawMessage.length = position;
  48. return UA_NO_ERROR;
  49. }
  50. Int32 SL_openSecureChannel_responseMessage_get(UA_connection *connection,SL_Response *response, Int32* sizeInOut)
  51. {
  52. response->ServerNonce.Length =0; // TODO set a valid value for the Server Nonce
  53. response->ServerProtocolVersion = UA_PROTOCOL_VERSION; //
  54. response->SecurityToken.createdAt = opcua_getTime(); //
  55. response->SecurityToken.revisedLifetime = 300000; //TODO set Lifetime of Security Token
  56. response->SecurityToken.secureChannelId = connection->secureLayer.UInt32_secureChannelId; //TODO set a valid value for secureChannel id
  57. return UA_NO_ERROR;
  58. }
  59. Int32 SL_openSecureChannel_responseMessage_calcSize(SL_Response *response, Int32* sizeInOut)
  60. {
  61. Int32 length = 0;
  62. length += sizeof(response->SecurityToken);
  63. length += UAString_calcSize(response->ServerNonce);
  64. length += sizeof(response->ServerProtocolVersion);
  65. return length;
  66. }
  67. /*
  68. * closes a secureChannel (server side)
  69. */
  70. void SL_secureChannel_close(UA_connection *connection)
  71. {
  72. }
  73. /*
  74. * receive and process data from underlying layer
  75. */
  76. void SL_receive(UA_connection *connection, AD_RawMessage *serviceMessage)
  77. {
  78. AD_RawMessage* secureChannelMessage;
  79. SL_SecureConversationMessageHeader SCM_Header;
  80. SL_AsymmetricAlgorithmSecurityHeader AAS_Header;
  81. SL_SequenceHeader SequenceHeader;
  82. //TODO Error Handling, length checking
  83. //get data from transport layer
  84. TL_receive(connection, secureChannelMessage);
  85. Int32 readPosition = 0;
  86. //get the Secure Channel Message Header
  87. decodeSCMHeader(secureChannelMessage,
  88. &readPosition, &SCM_Header);
  89. //get the Secure Channel Asymmetric Algorithm Security Header
  90. decodeAASHeader(secureChannelMessage,
  91. &readPosition, &AAS_Header);
  92. //get the Sequence Header
  93. decodeSequenceHeader(secureChannelMessage,
  94. &readPosition, &SequenceHeader);
  95. //get Secure Channel Message
  96. //SL_secureChannel_Message_get(connection, secureChannelMessage,
  97. // &readPosition,serviceMessage);
  98. if (secureChannelMessage->length > 0)
  99. {
  100. switch (SCM_Header.MessageType)
  101. {
  102. case packetType_MSG:
  103. if (connection->secureLayer.connectionState
  104. == connectionState_ESTABLISHED)
  105. {
  106. }
  107. else //receiving message, without secure channel
  108. {
  109. //TODO send back Error Message
  110. }
  111. break;
  112. case packetType_OPN:
  113. //Server Handling
  114. // if (openSecureChannelHeader_check(connection, secureChannelMessage))
  115. // {
  116. //check if the request is valid
  117. SL_openSecureChannelRequest_check(connection, secureChannelMessage);
  118. // }
  119. // else
  120. // {
  121. // //TODO send back Error Message
  122. // }
  123. //Client Handling
  124. //TODO free memory for secureChannelMessage
  125. break;
  126. case packetType_CLO:
  127. //TODO free memory for secureChannelMessage
  128. break;
  129. }
  130. }
  131. }
  132. /*
  133. * get the secure channel message header
  134. */
  135. Int32 decodeSCMHeader(AD_RawMessage *rawMessage,Int32 *pos,
  136. SL_SecureConversationMessageHeader* SC_Header)
  137. {
  138. SC_Header->MessageType = TL_getPacketType(rawMessage);
  139. *pos += 3;//TL_MESSAGE_TYPE_LEN;
  140. SC_Header->IsFinal = rawMessage->message[*pos];
  141. SC_Header->MessageSize = decodeUInt32(rawMessage, *pos);
  142. SC_Header->SecureChannelId = decodeUInt32(rawMessage, *pos);
  143. return UA_NO_ERROR;
  144. }
  145. Int32 encodeSCMHeader(SL_SecureConversationMessageHeader *SC_Header,
  146. Int32 *pos,AD_RawMessage *rawMessage)
  147. {
  148. char *type = "ERR";
  149. switch(SC_Header->MessageType)
  150. {
  151. case packetType_ACK:
  152. type = "ACK";
  153. break;
  154. case packetType_CLO:
  155. type = "CLO";
  156. break;
  157. case packetType_ERR:
  158. type = "ERR";
  159. break;
  160. case packetType_HEL:
  161. type = "HEL";
  162. break;
  163. case packetType_MSG:
  164. type = "MSG";
  165. break;
  166. case packetType_OPN:
  167. type = "OPN";
  168. break;
  169. default:
  170. return UA_ERROR;
  171. }
  172. memcpy(&(rawMessage->message[*pos]), &type, 3);
  173. return UA_NO_ERROR;
  174. }
  175. Int32 decodeSequenceHeader(AD_RawMessage *rawMessage, Int32 *pos,
  176. SL_SequenceHeader *SequenceHeader)
  177. {
  178. SequenceHeader->RequestId = decodeUInt32(rawMessage->message, pos);
  179. SequenceHeader->SequenceNumber = decodeUInt32(rawMessage->message, pos);
  180. return UA_NO_ERROR;
  181. }
  182. Int32 encodeSequenceHeader(SL_SequenceHeader *sequenceHeader,Int32 *pos,
  183. AD_RawMessage *dstRawMessage)
  184. {
  185. encodeUInt32(sequenceHeader->SequenceNumber,pos,&dstRawMessage->message[*pos]);
  186. return UA_NO_ERROR;
  187. }
  188. /*
  189. * get the asymmetric algorithm security header
  190. */
  191. Int32 decodeAASHeader(AD_RawMessage *rawMessage, Int32 *pos,
  192. SL_AsymmetricAlgorithmSecurityHeader* AAS_Header)
  193. {
  194. Int32 err = 0;
  195. err += decodeUAByteString(rawMessage->message,pos,AAS_Header->SecurityPolicyUri);
  196. err += decodeUAByteString(rawMessage->message,pos,AAS_Header->SenderCertificate);
  197. err += decodeUAByteString(rawMessage->message,pos,AAS_Header->ReceiverThumbprint);
  198. return err;
  199. }
  200. Int32 encodeAASHeader(SL_AsymmetricAlgorithmSecurityHeader *AAS_Header,
  201. Int32 *pos, AD_RawMessage* dstRawMessage)
  202. {
  203. encodeUAString(AAS_Header->SecurityPolicyUri,pos,&dstRawMessage->message[*pos]);
  204. encodeUAString(AAS_Header->SenderCertificate,pos,&dstRawMessage->message[*pos]);
  205. encodeUAString(AAS_Header->ReceiverThumbprint,pos,&dstRawMessage->message[*pos]);
  206. return UA_NO_ERROR;
  207. }
  208. void SL_secureChannel_Footer_get()
  209. {
  210. }