ua_transport_binary_secure.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  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. #include "ua_stack_session_manager.h"
  9. #include "ua_stack_session.h"
  10. #define SIZE_SECURECHANNEL_HEADER 12
  11. #define SIZE_SEQHEADER_HEADER 8
  12. static UA_Int32 SL_Send(SL_Channel channel,
  13. const UA_ByteString * responseMessage, UA_Int32 type)
  14. {
  15. UA_UInt32 pos = 0;
  16. UA_Int32 isAsym = (type == UA_OPENSECURECHANNELRESPONSE_NS0); // FIXME: this is a to dumb method to determine asymmetric algorithm setting
  17. UA_UInt32 channelId;
  18. UA_UInt32 sequenceNumber;
  19. UA_UInt32 requestId;
  20. UA_TL_Connection connection;
  21. UA_NodeId resp_nodeid;
  22. UA_AsymmetricAlgorithmSecurityHeader *asymAlgSettings = UA_NULL;
  23. resp_nodeid.encodingByte = UA_NODEIDTYPE_FOURBYTE;
  24. resp_nodeid.namespace = 0;
  25. resp_nodeid.identifier.numeric = type + 2; // binary encoding
  26. const UA_ByteString *response_gather[2]; // securechannel_header, seq_header, security_encryption_header, message_length (eventually + padding + size_signature);
  27. UA_alloc((void ** )&response_gather[0], sizeof(UA_ByteString));
  28. if (isAsym)
  29. {
  30. SL_Channel_getLocalAsymAlgSettings(channel, &asymAlgSettings);
  31. UA_ByteString_newMembers((UA_ByteString *) response_gather[0],
  32. SIZE_SECURECHANNEL_HEADER + SIZE_SEQHEADER_HEADER
  33. + UA_AsymmetricAlgorithmSecurityHeader_calcSizeBinary(
  34. asymAlgSettings)
  35. + UA_NodeId_calcSizeBinary(&resp_nodeid));
  36. }
  37. else
  38. {
  39. UA_ByteString_newMembers((UA_ByteString *) response_gather[0], 8 + 16 + // normal header + 4*32bit secure channel information
  40. UA_NodeId_calcSizeBinary(&resp_nodeid));
  41. }
  42. // sizePadding = 0;
  43. // sizeSignature = 0;
  44. UA_ByteString *header = (UA_ByteString *) response_gather[0];
  45. /*---encode Secure Conversation Message Header ---*/
  46. if (isAsym)
  47. {
  48. header->data[0] = 'O';
  49. header->data[1] = 'P';
  50. header->data[2] = 'N';
  51. }
  52. else
  53. {
  54. header->data[0] = 'M';
  55. header->data[1] = 'S';
  56. header->data[2] = 'G';
  57. }
  58. pos += 3;
  59. header->data[pos] = 'F';
  60. pos += 1;
  61. UA_Int32 packetSize = response_gather[0]->length + responseMessage->length;
  62. UA_Int32_encodeBinary(&packetSize, header,&pos);
  63. //use get accessor to read the channel Id
  64. SL_Channel_getChannelId(channel, &channelId);
  65. UA_UInt32_encodeBinary(&channelId, header,&pos);
  66. /*---encode Algorithm Security Header ---*/
  67. if (isAsym)
  68. {
  69. UA_AsymmetricAlgorithmSecurityHeader_encodeBinary(asymAlgSettings,
  70. header,&pos);
  71. UA_free(asymAlgSettings);
  72. }
  73. else
  74. {
  75. UA_UInt32 tokenId = 0;
  76. SL_Channel_getTokenId(channel, &tokenId);
  77. UA_UInt32_encodeBinary(&tokenId, header,&pos);
  78. }
  79. /*---encode Sequence Header ---*/
  80. SL_Channel_getSequenceNumber(channel, &sequenceNumber);
  81. UA_UInt32_encodeBinary(&sequenceNumber, header, &pos);
  82. SL_Channel_getRequestId(channel, &requestId);
  83. UA_UInt32_encodeBinary(&requestId, header,&pos);
  84. /*---add payload type---*/
  85. UA_NodeId_encodeBinary(&resp_nodeid, header,&pos);
  86. /*---add encoded Message ---*/
  87. response_gather[1] = responseMessage; // is deleted in the calling function
  88. /* sign Data*/
  89. /* encrypt Data*/
  90. /* send Data */
  91. SL_Channel_getConnection(channel, &connection);
  92. TL_Send(connection, response_gather, 2);
  93. UA_ByteString_delete((UA_ByteString *) response_gather[0]);
  94. return UA_SUCCESS;
  95. }
  96. static void init_response_header(UA_RequestHeader const * p,
  97. UA_ResponseHeader * r)
  98. {
  99. memset((void*) r, 0, sizeof(UA_ResponseHeader));
  100. r->requestHandle = p->requestHandle;
  101. r->serviceResult = UA_STATUSCODE_GOOD;
  102. r->stringTableSize = 0;
  103. r->timestamp = UA_DateTime_now();
  104. }
  105. #define RESPONSE_PREPARE(TYPE) \
  106. UA_##TYPE##Request p; \
  107. UA_##TYPE##Response r; \
  108. UA_Session session = UA_NULL; \
  109. UA_##TYPE##Request_decodeBinary(msg, &recvOffset, &p); \
  110. UA_##TYPE##Response_init(&r); \
  111. init_response_header(&p.requestHeader, &r.responseHeader); \
  112. UA_SessionManager_getSessionByToken(&p.requestHeader.authenticationToken, &session); \
  113. DBG_VERBOSE(printf("Invoke Service: %s\n", #TYPE)); \
  114. #define INVOKE_SERVICE(TYPE) \
  115. UA_##TYPE##Request p; \
  116. UA_##TYPE##Response r; \
  117. UA_Session session = UA_NULL; \
  118. UA_##TYPE##Request_decodeBinary(msg, &recvOffset, &p); \
  119. UA_##TYPE##Response_init(&r); \
  120. init_response_header(&p.requestHeader, &r.responseHeader); \
  121. UA_SessionManager_getSessionByToken(&p.requestHeader.authenticationToken, &session); \
  122. DBG_VERBOSE(printf("Invoke Service: %s\n", #TYPE)); \
  123. Service_##TYPE(session, &p, &r); \
  124. DBG_VERBOSE(printf("Finished Service: %s\n", #TYPE)); \
  125. sendOffset = 0; \
  126. UA_ByteString_newMembers(&response_msg, UA_##TYPE##Response_calcSizeBinary(&r)); \
  127. UA_##TYPE##Response_encodeBinary(&r, &sendOffset, &response_msg); \
  128. UA_##TYPE##Request_deleteMembers(&p); \
  129. UA_##TYPE##Response_deleteMembers(&r); \
  130. /*
  131. #define INVOKE_SERVICE(TYPE) \
  132. DBG_VERBOSE(printf("Invoke Service: %s\n", #TYPE)); \
  133. Service_##TYPE(session, &p, &r); \
  134. DBG_VERBOSE(printf("Finished Service: %s\n", #TYPE)); \
  135. */
  136. #define RESPONSE_CLEANUP(TYPE) \
  137. DBG_VERBOSE(printf("Finished Service: %s\n", #TYPE)); \
  138. sendOffset = 0; \
  139. UA_ByteString_newMembers(&response_msg, UA_##TYPE##Response_calcSizeBinary(&r)); \
  140. UA_##TYPE##Response_encodeBinary(&r, &response_msg,&sendOffset); \
  141. UA_##TYPE##Request_deleteMembers(&p); \
  142. UA_##TYPE##Response_deleteMembers(&r); \
  143. UA_Int32 SL_handleRequest(SL_Channel channel, const UA_ByteString* msg,
  144. UA_UInt32 *pos)
  145. {
  146. UA_Int32 retval = UA_SUCCESS;
  147. UA_UInt32 recvOffset = *pos;
  148. UA_UInt32 sendOffset = 0;
  149. // Every Message starts with a NodeID which names the serviceRequestType
  150. UA_NodeId serviceRequestType;
  151. UA_NodeId_decodeBinary(msg, &recvOffset,&serviceRequestType);
  152. #ifdef DEBUG
  153. UA_NodeId_printf("SL_processMessage - serviceRequestType=",
  154. &serviceRequestType);
  155. #endif
  156. UA_ByteString response_msg;
  157. UA_Int32 serviceid = serviceRequestType.identifier.numeric - 2; // binary encoding has 2 added to the id
  158. UA_Int32 responsetype;
  159. /* stack related services which only need information about the secure Channel */
  160. if (serviceid == UA_GETENDPOINTSREQUEST_NS0)
  161. {
  162. RESPONSE_PREPARE(GetEndpoints);
  163. Service_GetEndpoints(channel,&p, &r);
  164. RESPONSE_CLEANUP(GetEndpoints);
  165. //INVOKE_SERVICE(GetEndpoints);
  166. responsetype = UA_GETENDPOINTSRESPONSE_NS0;
  167. }
  168. else if (serviceid == UA_OPENSECURECHANNELREQUEST_NS0)
  169. {
  170. RESPONSE_PREPARE(OpenSecureChannel);
  171. Service_OpenSecureChannel(channel,&p, &r);
  172. RESPONSE_CLEANUP(OpenSecureChannel);
  173. responsetype = UA_OPENSECURECHANNELRESPONSE_NS0;
  174. }
  175. else if (serviceid == UA_CLOSESECURECHANNELREQUEST_NS0)
  176. {
  177. RESPONSE_PREPARE(CloseSecureChannel);
  178. Service_CloseSecureChannel(channel,&p,&r);
  179. RESPONSE_CLEANUP(CloseSecureChannel);
  180. responsetype = UA_CLOSESECURECHANNELRESPONSE_NS0;
  181. }
  182. else if (serviceid == UA_CREATESESSIONREQUEST_NS0)
  183. {
  184. RESPONSE_PREPARE(CreateSession);
  185. Service_CreateSession(channel,&p, &r);
  186. RESPONSE_CLEANUP(CreateSession);
  187. responsetype = UA_CREATESESSIONRESPONSE_NS0;
  188. }
  189. /* services which need a session object */
  190. else if (serviceid == UA_ACTIVATESESSIONREQUEST_NS0)
  191. {
  192. RESPONSE_PREPARE(ActivateSession);
  193. UA_Session_updateLifetime(session); //renew session timeout
  194. Service_ActivateSession(channel, session,&p, &r);
  195. RESPONSE_CLEANUP(ActivateSession);
  196. responsetype = UA_ACTIVATESESSIONRESPONSE_NS0;
  197. }
  198. else if (serviceid == UA_CLOSESESSIONREQUEST_NS0)
  199. {
  200. RESPONSE_PREPARE(CloseSession);
  201. if (UA_Session_verifyChannel(session,channel)){
  202. UA_Session_updateLifetime(session); //renew session timeout
  203. Service_CloseSession(session,&p, &r);
  204. RESPONSE_CLEANUP(CloseSession);
  205. }
  206. else
  207. {
  208. DBG_VERBOSE(printf("session does not match secure channel"));
  209. }
  210. responsetype = UA_CLOSESESSIONRESPONSE_NS0;
  211. }
  212. else if (serviceid == UA_READREQUEST_NS0)
  213. {
  214. RESPONSE_PREPARE(Read);
  215. UA_Session_updateLifetime(session); //renew session timeout
  216. DBG_VERBOSE(printf("Finished Service: %s\n", Read));
  217. if (UA_Session_verifyChannel(session,channel)){
  218. UA_Session_updateLifetime(session); //renew session timeout
  219. Service_Read(session,&p, &r);
  220. }
  221. else
  222. {
  223. DBG_VERBOSE(printf("session does not match secure channel"));
  224. }
  225. DBG_VERBOSE(printf("Finished Service: %s\n", Read));
  226. RESPONSE_CLEANUP(Read);
  227. responsetype = UA_READRESPONSE_NS0;
  228. }
  229. else if (serviceid == UA_WRITEREQUEST_NS0)
  230. {
  231. RESPONSE_PREPARE(Write);
  232. DBG_VERBOSE(printf("Finished Service: %s\n", Write));
  233. if (UA_Session_verifyChannel(session,channel)){
  234. UA_Session_updateLifetime(session); //renew session timeout
  235. Service_Write(session,&p, &r);
  236. }
  237. else
  238. {
  239. DBG_VERBOSE(printf("session does not match secure channel"));
  240. }
  241. DBG_VERBOSE(printf("Finished Service: %s\n", Write));
  242. RESPONSE_CLEANUP(Write);
  243. responsetype = UA_WRITERESPONSE_NS0;
  244. }
  245. else if (serviceid == UA_BROWSEREQUEST_NS0)
  246. {
  247. RESPONSE_PREPARE(Browse);
  248. DBG_VERBOSE(printf("Finished Service: %s\n", Browse));
  249. if (UA_Session_verifyChannel(session,channel)){
  250. Service_Browse(session,&p, &r);
  251. }
  252. else
  253. {
  254. DBG_VERBOSE(printf("session does not match secure channel"));
  255. }
  256. DBG_VERBOSE(printf("Finished Service: %s\n", Browse));
  257. RESPONSE_CLEANUP(Browse);
  258. responsetype = UA_BROWSERESPONSE_NS0;
  259. }
  260. else if (serviceid == UA_CREATESUBSCRIPTIONREQUEST_NS0)
  261. {
  262. RESPONSE_PREPARE(CreateSubscription);
  263. DBG_VERBOSE(printf("Finished Service: %s\n", CreateSubscription));
  264. if (UA_Session_verifyChannel(session,channel)){
  265. Service_CreateSubscription(session, &p, &r);
  266. }
  267. else
  268. {
  269. DBG_VERBOSE(printf("session does not match secure channel"));
  270. }
  271. DBG_VERBOSE(printf("Finished Service: %s\n", CreateSubscription));
  272. RESPONSE_CLEANUP(CreateSubscription);
  273. responsetype = UA_CREATESUBSCRIPTIONRESPONSE_NS0;
  274. }
  275. else if (serviceid == UA_TRANSLATEBROWSEPATHSTONODEIDSREQUEST_NS0)
  276. {
  277. RESPONSE_PREPARE(TranslateBrowsePathsToNodeIds);
  278. DBG_VERBOSE(printf("Finished Service: %s\n", TranslateBrowsePathsToNodeIds));
  279. if (UA_Session_verifyChannel(session,channel)){
  280. Service_TranslateBrowsePathsToNodeIds(session, &p, &r);
  281. }
  282. else
  283. {
  284. DBG_VERBOSE(printf("session does not match secure channel"));
  285. }
  286. DBG_VERBOSE(printf("Finished Service: %s\n", TranslateBrowsePathsToNodeIds));
  287. RESPONSE_CLEANUP(TranslateBrowsePathsToNodeIds);
  288. responsetype = UA_TRANSLATEBROWSEPATHSTONODEIDSRESPONSE_NS0;
  289. }
  290. else if (serviceid == UA_PUBLISHREQUEST_NS0)
  291. {
  292. RESPONSE_PREPARE(Publish);
  293. DBG_VERBOSE(printf("Finished Service: %s\n", Publish));
  294. if (UA_Session_verifyChannel(session,channel)){
  295. Service_Publish(session, &p, &r);
  296. }
  297. else
  298. {
  299. DBG_VERBOSE(printf("session does not match secure channel"));
  300. }
  301. DBG_VERBOSE(printf("Finished Service: %s\n", Publish));
  302. RESPONSE_CLEANUP(Publish);
  303. responsetype = UA_PUBLISHRESPONSE_NS0;
  304. }
  305. else if (serviceid == UA_CREATEMONITOREDITEMSREQUEST_NS0)
  306. {
  307. RESPONSE_PREPARE(CreateMonitoredItems);
  308. DBG_VERBOSE(printf("Finished Service: %s\n", CreateMonitoredItems));
  309. if (UA_Session_verifyChannel(session,channel)){
  310. Service_CreateMonitoredItems(session, &p, &r);
  311. }
  312. else
  313. {
  314. DBG_VERBOSE(printf("session does not match secure channel"));
  315. }
  316. DBG_VERBOSE(printf("Finished Service: %s\n", CreateMonitoredItems));
  317. RESPONSE_CLEANUP(CreateMonitoredItems);
  318. responsetype = UA_CREATEMONITOREDITEMSRESPONSE_NS0;
  319. }
  320. else if (serviceid == UA_SETPUBLISHINGMODEREQUEST_NS0)
  321. {
  322. RESPONSE_PREPARE(SetPublishingMode);
  323. DBG_VERBOSE(printf("Finished Service: %s\n",SetPublishingMode));
  324. if (UA_Session_verifyChannel(session,channel)){
  325. Service_SetPublishingMode(session, &p, &r);
  326. }
  327. else
  328. {
  329. DBG_VERBOSE(printf("session does not match secure channel"));
  330. }
  331. DBG_VERBOSE(printf("Finished Service: %s\n", SetPublishingMode));
  332. RESPONSE_CLEANUP(SetPublishingMode);
  333. responsetype = UA_SETPUBLISHINGMODERESPONSE_NS0;
  334. }
  335. else
  336. {
  337. printf(
  338. "SL_processMessage - unknown request, namespace=%d, request=%d\n",
  339. serviceRequestType.namespace,
  340. serviceRequestType.identifier.numeric);
  341. retval = UA_ERROR;
  342. UA_RequestHeader p;
  343. UA_ResponseHeader r;
  344. UA_RequestHeader_decodeBinary(msg, &recvOffset, &p);
  345. UA_ResponseHeader_init(&r);
  346. r.requestHandle = p.requestHandle;
  347. r.serviceResult = UA_STATUSCODE_BADSERVICEUNSUPPORTED;
  348. sendOffset = 0;
  349. UA_ByteString_newMembers(&response_msg, UA_ResponseHeader_calcSizeBinary(&r));
  350. UA_ResponseHeader_encodeBinary(&r, &response_msg,&sendOffset);
  351. responsetype = UA_RESPONSEHEADER_NS0;
  352. }
  353. if(serviceid != UA_CLOSESECURECHANNELREQUEST_NS0){
  354. SL_Send(channel, &response_msg, responsetype);
  355. }
  356. UA_ByteString_deleteMembers(&response_msg);
  357. *pos = recvOffset;
  358. return retval;
  359. }
  360. UA_Int32 SL_ProcessOpenChannel(SL_Channel channel, const UA_ByteString* msg,
  361. UA_UInt32 *pos)
  362. {
  363. UA_Int32 retval = UA_SUCCESS;
  364. UA_SequenceHeader sequenceHeader;
  365. UA_AsymmetricAlgorithmSecurityHeader asymHeader;
  366. *pos+=4; //skip secure channel id
  367. UA_AsymmetricAlgorithmSecurityHeader_decodeBinary(msg,pos,&asymHeader);
  368. UA_SequenceHeader_decodeBinary(msg,pos,&sequenceHeader);
  369. //init remote security settings from the security header
  370. SL_Channel_setRemoteSecuritySettings(channel,&asymHeader,&sequenceHeader);
  371. return SL_handleRequest(channel, msg, pos) | retval;
  372. }
  373. UA_Int32 SL_ProcessCloseChannel(SL_Channel channel, const UA_ByteString* msg,
  374. UA_UInt32 *pos)
  375. {
  376. return SL_handleRequest(channel, msg, pos);
  377. }
  378. UA_Int32 SL_Process(const UA_ByteString* msg,
  379. UA_UInt32* pos)
  380. {
  381. DBG_VERBOSE(printf("SL_process - entered \n"));
  382. UA_UInt32 secureChannelId;
  383. UA_UInt32 foundChannelId;
  384. SL_Channel channel;
  385. UA_SequenceHeader sequenceHeader;
  386. UA_UInt32_decodeBinary(msg, pos, &secureChannelId);
  387. //FIXME: we assume SAS, need to check if AAS or SAS
  388. UA_SymmetricAlgorithmSecurityHeader symAlgSecHeader;
  389. // if (connection->securityMode == UA_MESSAGESECURITYMODE_NONE) {
  390. UA_SymmetricAlgorithmSecurityHeader_decodeBinary(msg, pos,
  391. &symAlgSecHeader);
  392. if (SL_ChannelManager_getChannel(secureChannelId,
  393. &channel) == UA_SUCCESS)
  394. {
  395. SL_Channel_getChannelId(channel, &foundChannelId);
  396. printf("SL_process - received msg, with channel id: %i \n",
  397. foundChannelId);
  398. //sequence number processing
  399. UA_SequenceHeader_decodeBinary(msg, pos,
  400. &sequenceHeader);
  401. SL_Channel_checkSequenceNumber(channel,sequenceHeader.sequenceNumber);
  402. SL_Channel_checkRequestId(channel,sequenceHeader.requestId);
  403. //request id processing
  404. SL_handleRequest(channel, msg, pos);
  405. }
  406. else
  407. {
  408. //TODO generate ERROR_Bad_SecureChannelUnkown
  409. }
  410. return UA_SUCCESS;
  411. }