ua_transport_binary_secure.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. #include <stdio.h>
  2. #include <memory.h> // memcpy
  3. #include "opcua.h"
  4. #include "ua_transport_binary.h"
  5. #include "ua_transport_binary_secure.h"
  6. #include "ua_transport.h"
  7. #include "ua_statuscodes.h"
  8. #include "ua_services.h"
  9. #define SIZE_SECURECHANNEL_HEADER 12
  10. #define SIZE_SEQHEADER_HEADER 8
  11. SL_Channel slc;
  12. static UA_Int32 SL_Send(SL_Channel* channel, const UA_ByteString * responseMessage, UA_Int32 type) {
  13. UA_Int32 pos = 0;
  14. UA_Int32 isAsym = (type == UA_OPENSECURECHANNELRESPONSE_NS0); // FIXME: this is a to dumb method to determine asymmetric algorithm setting
  15. UA_NodeId resp_nodeid;
  16. resp_nodeid.encodingByte = UA_NODEIDTYPE_FOURBYTE;
  17. resp_nodeid.namespace = 0;
  18. resp_nodeid.identifier.numeric = type+2; // binary encoding
  19. const UA_ByteString *response_gather[2]; // securechannel_header, seq_header, security_encryption_header, message_length (eventually + padding + size_signature);
  20. UA_alloc((void **)&response_gather[0], sizeof(UA_ByteString));
  21. UA_ByteString_newMembers((UA_ByteString *)response_gather[0], SIZE_SECURECHANNEL_HEADER + SIZE_SEQHEADER_HEADER +
  22. (isAsym ? UA_AsymmetricAlgorithmSecurityHeader_calcSize(&(channel->localAsymAlgSettings)) :
  23. UA_AsymmetricAlgorithmSecurityHeader_calcSize(&(channel->localAsymAlgSettings))) +
  24. UA_NodeId_calcSize(&resp_nodeid));
  25. // sizePadding = 0;
  26. // sizeSignature = 0;
  27. UA_ByteString *header = (UA_ByteString *)response_gather[0];
  28. /*---encode Secure Conversation Message Header ---*/
  29. if (isAsym) {
  30. header->data[0] = 'O';
  31. header->data[1] = 'P';
  32. header->data[2] = 'N';
  33. } else {
  34. header->data[0] = 'M';
  35. header->data[1] = 'S';
  36. header->data[2] = 'G';
  37. }
  38. pos += 3;
  39. header->data[pos] = 'F';
  40. pos += 1;
  41. UA_Int32 packetSize = response_gather[0]->length + responseMessage->length;
  42. UA_Int32_encodeBinary(&packetSize, &pos, header);
  43. UA_UInt32_encodeBinary(&channel->securityToken.secureChannelId, &pos, header);
  44. /*---encode Algorithm Security Header ---*/
  45. if (isAsym) {
  46. UA_AsymmetricAlgorithmSecurityHeader_encodeBinary(&channel->localAsymAlgSettings, &pos, header);
  47. } else {
  48. UA_SymmetricAlgorithmSecurityHeader_encodeBinary(&channel->securityToken.tokenId, &pos, header);
  49. }
  50. /*---encode Sequence Header ---*/
  51. UA_UInt32_encodeBinary(&channel->sequenceHeader.sequenceNumber, &pos, header);
  52. UA_UInt32_encodeBinary(&channel->sequenceHeader.requestId, &pos, header);
  53. /*---add payload type---*/
  54. UA_NodeId_encodeBinary(&resp_nodeid, &pos, header);
  55. /*---add encoded Message ---*/
  56. response_gather[1] = responseMessage; // is deleted in the calling function
  57. /* sign Data*/
  58. /* encrypt Data*/
  59. /* send Data */
  60. TL_Send(channel->tlConnection, response_gather, 2);
  61. UA_ByteString_delete((UA_ByteString *)response_gather[0]);
  62. return UA_SUCCESS;
  63. }
  64. static void init_response_header(UA_RequestHeader const * p, UA_ResponseHeader * r) {
  65. memset((void*) r, 0, sizeof(UA_ResponseHeader));
  66. r->requestHandle = p->requestHandle;
  67. r->serviceResult = UA_STATUSCODE_GOOD;
  68. r->stringTableSize = 0;
  69. r->timestamp = UA_DateTime_now();
  70. }
  71. #define INVOKE_SERVICE(TYPE) \
  72. UA_##TYPE##Request p; \
  73. UA_##TYPE##Response r; \
  74. UA_##TYPE##Request_decodeBinary(msg, pos, &p); \
  75. init_response_header((UA_RequestHeader*)&p, (UA_ResponseHeader*)&r); \
  76. DBG_VERBOSE(printf("Invoke Service: %s\n", #TYPE)); \
  77. Service_##TYPE(channel, &p, &r); \
  78. DBG_VERBOSE(printf("Finished Service: %s\n", #TYPE)); \
  79. *pos = 0; \
  80. UA_ByteString_newMembers(&response_msg, UA_##TYPE##Response_calcSize(&r)); \
  81. UA_##TYPE##Response_encodeBinary(&r, pos, &response_msg); \
  82. /** this function manages all the generic stuff for the request-response game */
  83. UA_Int32 SL_handleRequest(SL_Channel *channel, const UA_ByteString* msg, UA_Int32 *pos) {
  84. UA_Int32 retval = UA_SUCCESS;
  85. // Every Message starts with a NodeID which names the serviceRequestType
  86. UA_NodeId serviceRequestType;
  87. UA_NodeId_decodeBinary(msg, pos, &serviceRequestType);
  88. UA_NodeId_printf("SL_processMessage - serviceRequestType=", &serviceRequestType);
  89. UA_ByteString response_msg;
  90. int serviceid = serviceRequestType.identifier.numeric-2; // binary encoding has 2 added to the id
  91. UA_Int32 responsetype;
  92. if(serviceid == UA_GETENDPOINTSREQUEST_NS0) {
  93. INVOKE_SERVICE(GetEndpoints);
  94. responsetype = UA_GETENDPOINTSRESPONSE_NS0;
  95. }
  96. else if(serviceid == UA_OPENSECURECHANNELREQUEST_NS0) {
  97. INVOKE_SERVICE(OpenSecureChannel);
  98. responsetype = UA_OPENSECURECHANNELRESPONSE_NS0;
  99. }
  100. else if(serviceid == UA_CLOSESECURECHANNELREQUEST_NS0) {
  101. INVOKE_SERVICE(CloseSecureChannel);
  102. responsetype = UA_CLOSESECURECHANNELRESPONSE_NS0;
  103. }
  104. else if(serviceid == UA_CREATESESSIONREQUEST_NS0) {
  105. INVOKE_SERVICE(CreateSession);
  106. responsetype = UA_CREATESESSIONRESPONSE_NS0;
  107. }
  108. else if(serviceid == UA_ACTIVATESESSIONREQUEST_NS0) {
  109. INVOKE_SERVICE(ActivateSession);
  110. responsetype = UA_ACTIVATESESSIONRESPONSE_NS0;
  111. }
  112. else if(serviceid == UA_CLOSESESSIONREQUEST_NS0) {
  113. INVOKE_SERVICE(CloseSession);
  114. responsetype = UA_CLOSESESSIONRESPONSE_NS0;
  115. }
  116. else if(serviceid == UA_READREQUEST_NS0) {
  117. INVOKE_SERVICE(Read);
  118. responsetype = UA_READRESPONSE_NS0;
  119. }
  120. else {
  121. printf("SL_processMessage - unknown request, namespace=%d, request=%d\n", serviceRequestType.namespace,serviceRequestType.identifier.numeric);
  122. retval = UA_ERROR;
  123. responsetype = 0; //FIXME
  124. }
  125. SL_Send(channel, &response_msg, responsetype);
  126. return retval;
  127. }
  128. UA_Int32 SL_Channel_new(TL_Connection *connection, const UA_ByteString* msg, UA_Int32* pos) {
  129. DBG_VERBOSE(printf("SL_Channel_new - entered\n"));
  130. UA_Int32 retval = UA_SUCCESS;
  131. /* Create New Channel*/
  132. SL_Channel *channel = &slc; // FIXME: generate new secure channel
  133. UA_AsymmetricAlgorithmSecurityHeader_init(&(channel->localAsymAlgSettings));
  134. UA_ByteString_copy(&UA_ByteString_securityPoliceNone, &(channel->localAsymAlgSettings.securityPolicyUri));
  135. UA_alloc((void**)&(channel->localNonce.data), sizeof(UA_Byte));
  136. channel->localNonce.length = 1;
  137. channel->connectionState = CONNECTIONSTATE_CLOSED; // the state of the channel will be opened in the service
  138. channel->sequenceHeader.requestId = 0;
  139. channel->sequenceHeader.sequenceNumber = 1;
  140. UA_String_init(&(channel->secureChannelId));
  141. channel->securityMode = UA_SECURITYMODE_INVALID;
  142. channel->securityToken.secureChannelId = 25; //TODO set a valid start secureChannelId number
  143. channel->securityToken.tokenId = 1; //TODO set a valid start TokenId
  144. connection->secureChannel = channel;
  145. connection->secureChannel->tlConnection = connection;
  146. /* Read the OPN message headers */
  147. *pos += 4; // skip the securechannelid
  148. UA_AsymmetricAlgorithmSecurityHeader_decodeBinary(msg, pos, &connection->secureChannel->remoteAsymAlgSettings);
  149. UA_SequenceHeader_decodeBinary(msg, pos, &connection->secureChannel->sequenceHeader);
  150. //TODO check that the sequence number is smaller than MaxUInt32 - 1024
  151. //TODO check if a OpenSecureChannelRequest follows
  152. retval |= SL_handleRequest(channel, msg, pos);
  153. return retval;
  154. // FIXME: reject
  155. }
  156. /**
  157. * process the rest of the header. TL already processed MessageType
  158. * (OPN,MSG,...), isFinal and MessageSize. SL_process cares for
  159. * secureChannelId, XASHeader and sequenceHeader
  160. * */
  161. UA_Int32 SL_Process(SL_Channel* connection, const UA_ByteString* msg, UA_Int32* pos) {
  162. DBG_VERBOSE(printf("SL_process - entered \n"));
  163. UA_UInt32 secureChannelId;
  164. if (connection->connectionState == CONNECTIONSTATE_ESTABLISHED) {
  165. UA_UInt32_decodeBinary(msg,pos,&secureChannelId);
  166. //FIXME: we assume SAS, need to check if AAS or SAS
  167. UA_SymmetricAlgorithmSecurityHeader symAlgSecHeader;
  168. // if (connection->securityMode == UA_MESSAGESECURITYMODE_NONE) {
  169. UA_SymmetricAlgorithmSecurityHeader_decodeBinary(msg, pos, &symAlgSecHeader);
  170. printf("SL_process - securityToken received=%d, expected=%d\n",secureChannelId,connection->securityToken.secureChannelId);
  171. if (secureChannelId == connection->securityToken.secureChannelId) {
  172. UA_SequenceHeader_decodeBinary(msg, pos, &(connection->sequenceHeader));
  173. SL_handleRequest(&slc, msg, pos);
  174. } else {
  175. //TODO generate ERROR_Bad_SecureChannelUnkown
  176. }
  177. }
  178. return UA_SUCCESS;
  179. }