ua_transport_binary_secure.c 10 KB

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