ua_transport_binary_secure.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  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. static UA_Int32 SL_Send(SL_secureChannel channel,
  12. const UA_ByteString * responseMessage, UA_Int32 type)
  13. {
  14. //access function for SL_secureChannel
  15. //SL_Channel_getId(secureChannel)
  16. //SL_Channel_getSequenceNumber(secureChannel)
  17. UA_Int32 pos = 0;
  18. UA_Int32 isAsym = (type == UA_OPENSECURECHANNELRESPONSE_NS0); // FIXME: this is a to dumb method to determine asymmetric algorithm setting
  19. UA_UInt32 channelId;
  20. UA_UInt32 sequenceNumber;
  21. UA_UInt32 requestId;
  22. UA_TL_Connection1 connection;
  23. UA_NodeId resp_nodeid;
  24. UA_AsymmetricAlgorithmSecurityHeader *asymAlgSettings = UA_NULL;
  25. //UA_AsymmetricAlgorithmSecurityHeader_new((void**)(&asymAlgSettings));
  26. resp_nodeid.encodingByte = UA_NODEIDTYPE_FOURBYTE;
  27. resp_nodeid.namespace = 0;
  28. resp_nodeid.identifier.numeric = type + 2; // binary encoding
  29. const UA_ByteString *response_gather[2]; // securechannel_header, seq_header, security_encryption_header, message_length (eventually + padding + size_signature);
  30. UA_alloc((void ** )&response_gather[0], sizeof(UA_ByteString));
  31. if (isAsym)
  32. {
  33. UA_ByteString_newMembers((UA_ByteString *) response_gather[0],
  34. SIZE_SECURECHANNEL_HEADER + SIZE_SEQHEADER_HEADER
  35. + UA_AsymmetricAlgorithmSecurityHeader_calcSize(
  36. asymAlgSettings)
  37. + UA_NodeId_calcSize(&resp_nodeid));
  38. }
  39. else
  40. {
  41. UA_ByteString_newMembers((UA_ByteString *) response_gather[0], 8 + 16 + // normal header + 4*32bit secure channel information
  42. UA_NodeId_calcSize(&resp_nodeid));
  43. }
  44. // sizePadding = 0;
  45. // sizeSignature = 0;
  46. UA_ByteString *header = (UA_ByteString *) response_gather[0];
  47. /*---encode Secure Conversation Message Header ---*/
  48. if (isAsym)
  49. {
  50. header->data[0] = 'O';
  51. header->data[1] = 'P';
  52. header->data[2] = 'N';
  53. }
  54. else
  55. {
  56. header->data[0] = 'M';
  57. header->data[1] = 'S';
  58. header->data[2] = 'G';
  59. }
  60. pos += 3;
  61. header->data[pos] = 'F';
  62. pos += 1;
  63. UA_Int32 packetSize = response_gather[0]->length + responseMessage->length;
  64. UA_Int32_encodeBinary(&packetSize, &pos, header);
  65. //use get accessor to read the channel Id
  66. SL_Channel_getChannelId(channel, &channelId);
  67. UA_UInt32_encodeBinary(&channelId, &pos, header);
  68. /*---encode Algorithm Security Header ---*/
  69. if (isAsym)
  70. {
  71. SL_Channel_getLocalAsymAlgSettings(channel, asymAlgSettings);
  72. UA_AsymmetricAlgorithmSecurityHeader_encodeBinary(asymAlgSettings, &pos,
  73. header);
  74. }
  75. else
  76. {
  77. UA_UInt32 tokenId = 0;
  78. SL_Channel_getTokenId(channel, &tokenId);
  79. UA_UInt32_encodeBinary(&tokenId, &pos, header);
  80. }
  81. /*---encode Sequence Header ---*/
  82. SL_Channel_getSequenceNumber(channel, &sequenceNumber);
  83. UA_UInt32_encodeBinary(&sequenceNumber, &pos, header);
  84. SL_Channel_getRequestId(channel, &requestId);
  85. UA_UInt32_encodeBinary(&requestId, &pos, header);
  86. /*---add payload type---*/
  87. UA_NodeId_encodeBinary(&resp_nodeid, &pos, header);
  88. /*---add encoded Message ---*/
  89. response_gather[1] = responseMessage; // is deleted in the calling function
  90. /* sign Data*/
  91. /* encrypt Data*/
  92. /* send Data */
  93. SL_Channel_getConnection(channel, &connection);
  94. TL_Send(connection, response_gather, 2);
  95. UA_ByteString_delete((UA_ByteString *) response_gather[0]);
  96. return UA_SUCCESS;
  97. }
  98. static void init_response_header(UA_RequestHeader const * p,
  99. UA_ResponseHeader * r)
  100. {
  101. memset((void*) r, 0, sizeof(UA_ResponseHeader));
  102. r->requestHandle = p->requestHandle;
  103. r->serviceResult = UA_STATUSCODE_GOOD;
  104. r->stringTableSize = 0;
  105. r->timestamp = UA_DateTime_now();
  106. }
  107. #define INVOKE_SERVICE(TYPE) \
  108. UA_##TYPE##Request p; \
  109. UA_##TYPE##Response r; \
  110. UA_##TYPE##Request_decodeBinary(msg, pos, &p); \
  111. UA_##TYPE##Response_init(&r); \
  112. init_response_header(&p.requestHeader, &r.responseHeader); \
  113. DBG_VERBOSE(printf("Invoke Service: %s\n", #TYPE)); \
  114. Service_##TYPE(&p, &r); \
  115. DBG_VERBOSE(printf("Finished Service: %s\n", #TYPE)); \
  116. *pos = 0; \
  117. UA_ByteString_newMembers(&response_msg, UA_##TYPE##Response_calcSize(&r)); \
  118. UA_##TYPE##Response_encodeBinary(&r, pos, &response_msg); \
  119. UA_##TYPE##Request_deleteMembers(&p); \
  120. UA_##TYPE##Response_deleteMembers(&r); \
  121. /** this function manages all the generic stuff for the request-response game */
  122. //UA_Int32 SL_handleRequest(SL_Channel *channel, const UA_ByteString* msg,
  123. // UA_Int32 *pos)
  124. UA_Int32 SL_handleRequest(SL_secureChannel channel, const UA_ByteString* msg,
  125. UA_Int32 *pos)
  126. {
  127. UA_Int32 retval = UA_SUCCESS;
  128. // Every Message starts with a NodeID which names the serviceRequestType
  129. UA_NodeId serviceRequestType;
  130. UA_NodeId_decodeBinary(msg, pos, &serviceRequestType);
  131. UA_NodeId_printf("SL_processMessage - serviceRequestType=",
  132. &serviceRequestType);
  133. UA_ByteString response_msg;
  134. UA_Int32 serviceid = serviceRequestType.identifier.numeric - 2; // binary encoding has 2 added to the id
  135. UA_Int32 responsetype;
  136. if (serviceid == UA_GETENDPOINTSREQUEST_NS0)
  137. {
  138. INVOKE_SERVICE(GetEndpoints);
  139. responsetype = UA_GETENDPOINTSRESPONSE_NS0;
  140. }
  141. else if (serviceid == UA_OPENSECURECHANNELREQUEST_NS0)
  142. {
  143. //I see at the moment no other way to handle this
  144. UA_OpenSecureChannelRequest p;
  145. UA_OpenSecureChannelResponse r;
  146. UA_OpenSecureChannelRequest_decodeBinary(msg, pos, &p);
  147. UA_OpenSecureChannelResponse_init(&r);
  148. init_response_header(&p.requestHeader, &r.responseHeader);
  149. DBG_VERBOSE(printf("Invoke Service: %s\n", #TYPE));
  150. Service_OpenSecureChannel(channel,&p, &r);
  151. DBG_VERBOSE(printf("Finished Service: %s\n", #TYPE));
  152. *pos = 0; \
  153. UA_ByteString_newMembers(&response_msg, UA_OpenSecureChannelResponse_calcSize(&r));
  154. UA_OpenSecureChannelResponse_encodeBinary(&r, pos, &response_msg);
  155. UA_OpenSecureChannelRequest_deleteMembers(&p);
  156. UA_OpenSecureChannelResponse_deleteMembers(&r);
  157. //INVOKE_SERVICE(OpenSecureChannel);
  158. responsetype = UA_OPENSECURECHANNELRESPONSE_NS0;
  159. }
  160. else if (serviceid == UA_CLOSESECURECHANNELREQUEST_NS0)
  161. {
  162. INVOKE_SERVICE(CloseSecureChannel);
  163. responsetype = UA_CLOSESECURECHANNELRESPONSE_NS0;
  164. }
  165. else if (serviceid == UA_CREATESESSIONREQUEST_NS0)
  166. {
  167. //TODO prepare userdefined implementation
  168. INVOKE_SERVICE(CreateSession);
  169. responsetype = UA_CREATESESSIONRESPONSE_NS0;
  170. }
  171. else if (serviceid == UA_ACTIVATESESSIONREQUEST_NS0)
  172. {
  173. //TODO prepare userdefined implementation
  174. INVOKE_SERVICE(ActivateSession);
  175. responsetype = UA_ACTIVATESESSIONRESPONSE_NS0;
  176. }
  177. else if (serviceid == UA_CLOSESESSIONREQUEST_NS0)
  178. {
  179. //TODO prepare userdefined implementation
  180. INVOKE_SERVICE(CloseSession);
  181. responsetype = UA_CLOSESESSIONRESPONSE_NS0;
  182. }
  183. else if (serviceid == UA_READREQUEST_NS0)
  184. {
  185. //TODO prepare userdefined implementation
  186. INVOKE_SERVICE(Read);
  187. responsetype = UA_READRESPONSE_NS0;
  188. }
  189. else
  190. {
  191. printf(
  192. "SL_processMessage - unknown request, namespace=%d, request=%d\n",
  193. serviceRequestType.namespace,
  194. serviceRequestType.identifier.numeric);
  195. retval = UA_ERROR;
  196. UA_RequestHeader p;
  197. UA_ResponseHeader r;
  198. UA_RequestHeader_decodeBinary(msg, pos, &p);
  199. UA_ResponseHeader_init(&r);
  200. r.requestHandle = p.requestHandle;
  201. r.serviceResult = UA_STATUSCODE_BADSERVICEUNSUPPORTED;
  202. *pos = 0;
  203. UA_ByteString_newMembers(&response_msg, UA_ResponseHeader_calcSize(&r));
  204. UA_ResponseHeader_encodeBinary(&r, pos, &response_msg);
  205. responsetype = UA_RESPONSEHEADER_NS0;
  206. }
  207. SL_Send(channel, &response_msg, responsetype);
  208. UA_ByteString_deleteMembers(&response_msg);
  209. return retval;
  210. }
  211. UA_Int32 SL_ProcessOpenChannel(SL_secureChannel channel, const UA_ByteString* msg,
  212. UA_Int32 *pos)
  213. {
  214. return SL_handleRequest(channel, msg, pos);
  215. }
  216. /**
  217. *
  218. * @param connection
  219. * @param msg
  220. * @param pos
  221. * @return
  222. */
  223. //UA_Int32 SL_Channel_new(TL_Connection *connection, const UA_ByteString* msg,
  224. // UA_Int32* pos)
  225. //{
  226. // DBG_VERBOSE(printf("SL_Channel_new - entered\n"));
  227. // UA_Int32 retval = UA_SUCCESS;
  228. //
  229. // /* Create New Channel*/
  230. // SL_Channel *channel = &slc; // FIXME: generate new secure channel
  231. // UA_AsymmetricAlgorithmSecurityHeader_init(&(channel->localAsymAlgSettings));
  232. // UA_ByteString_copy(&UA_ByteString_securityPoliceNone,
  233. // &(channel->localAsymAlgSettings.securityPolicyUri));
  234. // UA_alloc((void** )&(channel->localNonce.data), sizeof(UA_Byte));
  235. // channel->localNonce.length = 1;
  236. // channel->connectionState = CONNECTIONSTATE_CLOSED; // the state of the channel will be opened in the service
  237. // channel->sequenceHeader.requestId = 0;
  238. // channel->sequenceHeader.sequenceNumber = 1;
  239. // UA_String_init(&(channel->secureChannelId));
  240. // channel->securityMode = UA_SECURITYMODE_INVALID;
  241. // channel->securityToken.secureChannelId = 25; //TODO set a valid start secureChannelId number
  242. // channel->securityToken.tokenId.tokenId = 1; //TODO set a valid start TokenId
  243. // connection->secureChannel = channel;
  244. // connection->secureChannel->tlConnection = connection;
  245. /* Read the OPN message headers */
  246. // *pos += 4; // skip the securechannelid
  247. // UA_AsymmetricAlgorithmSecurityHeader_decodeBinary(msg, pos,
  248. // &connection->secureChannel->remoteAsymAlgSettings);
  249. // UA_SequenceHeader_decodeBinary(msg, pos,
  250. // &connection->secureChannel->sequenceHeader);
  251. // //TODO check that the sequence number is smaller than MaxUInt32 - 1024
  252. // //TODO check if a OpenSecureChannelRequest follows
  253. // retval |= SL_handleRequest(channel, msg, pos);
  254. // return retval;
  255. // FIXME: reject
  256. //}
  257. /**
  258. * process the rest of the header. TL already processed MessageType
  259. * (OPN,MSG,...), isFinal and MessageSize. SL_process cares for
  260. * secureChannelId, XASHeader and sequenceHeader
  261. * */
  262. UA_Int32 SL_Process(const UA_ByteString* msg,
  263. UA_Int32* pos)
  264. {
  265. DBG_VERBOSE(printf("SL_process - entered \n"));
  266. UA_UInt32 secureChannelId;
  267. UA_UInt32 foundChannelId;
  268. SL_secureChannel channel;
  269. UA_SequenceHeader sequenceHeader;
  270. UA_UInt32_decodeBinary(msg, pos, &secureChannelId);
  271. //FIXME: we assume SAS, need to check if AAS or SAS
  272. UA_SymmetricAlgorithmSecurityHeader symAlgSecHeader;
  273. // if (connection->securityMode == UA_MESSAGESECURITYMODE_NONE) {
  274. UA_SymmetricAlgorithmSecurityHeader_decodeBinary(msg, pos,
  275. &symAlgSecHeader);
  276. if (SL_ChannelManager_getChannel(secureChannelId,
  277. &channel) == UA_SUCCESS)
  278. {
  279. SL_Channel_getChannelId(channel, &foundChannelId);
  280. printf("SL_process - received msg, with channel id: %i \n",
  281. foundChannelId);
  282. //sequence number processing
  283. UA_SequenceHeader_decodeBinary(msg, pos,
  284. &sequenceHeader);
  285. SL_Channel_checkSequenceNumber(channel,sequenceHeader.sequenceNumber);
  286. //request id processing
  287. SL_handleRequest(channel, msg, pos);
  288. }
  289. else
  290. {
  291. //TODO generate ERROR_Bad_SecureChannelUnkown
  292. }
  293. return UA_SUCCESS;
  294. }