opcua_secureChannelLayer.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. /*
  2. * opcua_secureChannelLayer.c
  3. *
  4. * Created on: Jan 13, 2014
  5. * Author: opcua
  6. */
  7. #include "opcua_secureChannelLayer.h"
  8. #include <stdio.h>
  9. #include "opcua_time.h"
  10. Int32 SL_send(UA_connection *connection, UA_ByteString responseMessage, Int32 type)
  11. {
  12. UInt32 sequenceNumber;
  13. UInt32 requestId;
  14. //TODO: fill with valid information
  15. char securityPolicy[] = "http://opcfoundation.org/UA/SecurityPolicy#None";
  16. //sequence header
  17. sequenceNumber = connection->secureLayer.sequenceNumber;
  18. requestId = connection->secureLayer.requestId;
  19. if(type == 449) //openSecureChannelResponse -> asymmetric algorithm
  20. {
  21. //TODO add Asymmetric Security Header
  22. }
  23. else
  24. {
  25. //TODO add Symmetric Security
  26. }
  27. return UA_NO_ERROR;
  28. }
  29. /*
  30. * opens a secure channel
  31. */
  32. Int32 SL_openSecureChannel(UA_connection *connection, IntegerId requestHandle, UA_StatusCode serviceResult, UA_DiagnosticInfo *serviceDiagnostics)
  33. {
  34. UA_AD_ResponseHeader responseHeader;
  35. UA_ExtensionObject additionalHeader;
  36. SL_ChannelSecurityToken securityToken;
  37. UA_ByteString serverNonce;
  38. UA_NodeId responseType;
  39. //sizes for memory allocation
  40. Int32 sizeResponse;
  41. Int32 sizeRespHeader;
  42. Int32 sizeRespMessage;
  43. Int32 sizeSecurityToken;
  44. UA_ByteString response;
  45. UInt32 serverProtocolVersion;
  46. Int32 *pos;
  47. /*--------------type ----------------------*/
  48. //Four Bytes Encoding
  49. responseType.EncodingByte = NIEVT_FOUR_BYTE;
  50. responseType.Identifier.Numeric = 449;
  51. /*--------------responseHeader-------------*/
  52. /* Res-1) ResponseHeader responseHeader
  53. * timestamp UtcTime
  54. * requestHandle IntegerId
  55. * serviceResult StatusCode
  56. * serviceDiagnostics DiagnosticInfo
  57. * stringTable[] String
  58. * addtionalHeader Extensible Parameter
  59. */
  60. //current time
  61. responseHeader.timestamp = opcua_getTime();
  62. //request Handle which client sent
  63. responseHeader.requestHandle = requestHandle;
  64. // StatusCode which informs client about quality of response
  65. responseHeader.serviceResult = serviceResult;
  66. //retrieve diagnosticInfo if client demands
  67. responseHeader.serviceDiagnostics = serviceDiagnostics;
  68. //text of fields defined in the serviceDiagnostics
  69. responseHeader.noOfStringTable = 0;
  70. responseHeader.stringTable = NULL;
  71. // no additional header
  72. responseHeader.additionalHeader = &the_empty_UA_ExtensionObject;
  73. //calculate the size
  74. sizeRespHeader = responseHeader_calcSize(&responseHeader);
  75. /*--------------responseMessage-------------*/
  76. /* Res-2) UInt32 ServerProtocolVersion
  77. * Res-3) SecurityToken channelSecurityToken
  78. * Res-5) ByteString ServerNonce
  79. */
  80. // secureChannelId + TokenId + CreatedAt + RevisedLifetime
  81. sizeSecurityToken = sizeof(UInt32) + sizeof(UInt32) + sizeof(UA_DateTime) + sizeof(Int32);
  82. //ignore server nonce
  83. serverNonce.Length = -1;
  84. serverNonce.Data = NULL;
  85. //fill toke structure with default server information
  86. securityToken.secureChannelId = connection->secureLayer.securityToken.secureChannelId;
  87. securityToken.tokenId = connection->secureLayer.securityToken.tokenId;
  88. securityToken.createdAt = opcua_getTime();
  89. securityToken.revisedLifetime = connection->secureLayer.securityToken.revisedLifetime;
  90. serverProtocolVersion = connection->transportLayer.localConf.protocolVersion;
  91. // ProtocolVersion + SecurityToken + Nonce
  92. sizeRespMessage = sizeof(UInt32) + sizeSecurityToken + UAByteString_calcSize(&serverNonce) + sizeof(Int32) + sizeSecurityToken;
  93. //get memory for response
  94. response.Data = (char*)opcua_malloc(nodeId_calcSize(responseType) + sizeRespHeader + sizeRespMessage);
  95. *pos = 0;
  96. //encode responseType (NodeId)
  97. encoder_encodeBuiltInDatatype(responseType,NODE_ID,pos,response.Data);
  98. //encode header
  99. encodeResponseHeader(&responseHeader,pos, &response);
  100. //encode message
  101. encoder_encodeBuiltInDatatype(serverProtocolVersion, UINT32, pos,response.Data);
  102. encoder_encodeBuiltInDatatype(securityToken.secureChannelId, UINT32, pos,response.Data);
  103. encoder_encodeBuiltInDatatype(securityToken.tokenId, INT32, pos,response.Data);
  104. encoder_encodeBuiltInDatatype(securityToken.createdAt, DATE_TIME, pos,response.Data);
  105. encoder_encodeBuiltInDatatype(securityToken.revisedLifetime, INT32, pos,response.Data);
  106. encoder_encodeBuiltInDatatype(serverNonce, BYTE_STRING, pos,response.Data);
  107. //449 = openSecureChannelResponse
  108. SL_send(connection,response,449);
  109. return UA_NO_ERROR;
  110. }
  111. /*
  112. * closes a secureChannel (server side)
  113. */
  114. void SL_secureChannel_close(UA_connection *connection) {
  115. }
  116. Int32 SL_check(UA_connection *connection, UA_ByteString secureChannelPacket) {
  117. return UA_NO_ERROR;
  118. }
  119. Int32 SL_createSecurityToken(UA_connection *connection, Int32 lifeTime) {
  120. return UA_NO_ERROR;
  121. }
  122. Int32 SL_processMessage(UA_connection *connection, UA_ByteString message) {
  123. UA_DiagnosticInfo serviceDiagnostics;
  124. Int32 pos = 0;
  125. // Every Message starts with a NodeID which names the serviceRequestType
  126. UA_NodeId serviceRequestType;
  127. decoder_decodeBuiltInDatatype(message.Data, NODE_ID, &pos,
  128. &serviceRequestType);
  129. UA_NodeId_printf("SL_processMessage - serviceRequestType=",
  130. &serviceRequestType);
  131. if (serviceRequestType.EncodingByte == NIEVT_FOUR_BYTE
  132. && serviceRequestType.Identifier.Numeric == 446) {
  133. /* OpenSecureChannelService, defined in 62541-6 §6.4.4, Table 34.
  134. * Note that part 6 adds ClientProtocolVersion and ServerProtocolVersion
  135. * to the definition in part 4 */
  136. // Req-1) RequestHeader requestHeader
  137. UA_AD_RequestHeader requestHeader;
  138. // Req-2) UInt32 ClientProtocolVersion
  139. UInt32 clientProtocolVersion;
  140. // Req-3) Enum SecurityTokenRequestType requestType
  141. Int32 requestType;
  142. // Req-4) Enum MessageSecurityMode SecurityMode
  143. Int32 securityMode;
  144. // Req-5) ByteString ClientNonce
  145. UA_ByteString clientNonce;
  146. // Req-6) Int32 RequestLifetime
  147. Int32 requestedLifetime;
  148. UA_ByteString_printx("SL_processMessage - message=", &message);
  149. // Req-1) RequestHeader requestHeader
  150. decoder_decodeRequestHeader(message.Data, &pos, &requestHeader);
  151. UA_String_printf("SL_processMessage - requestHeader.auditEntryId=",
  152. &requestHeader.auditEntryId);
  153. UA_NodeId_printf(
  154. "SL_processMessage - requestHeader.authenticationToken=",
  155. &requestHeader.authenticationToken);
  156. // Req-2) UInt32 ClientProtocolVersion
  157. decoder_decodeBuiltInDatatype(message.Data, UINT32, &pos,
  158. &clientProtocolVersion);
  159. printf("SL_processMessage - clientProtocolVersion=%d\n",
  160. clientProtocolVersion);
  161. if (clientProtocolVersion
  162. != connection->transportLayer.remoteConf.protocolVersion) {
  163. printf("SL_processMessage - error protocol version \n");
  164. //TODO error protocol version
  165. //TODO ERROR_Bad_ProtocolVersionUnsupported
  166. }
  167. // Req-3) SecurityTokenRequestType requestType
  168. decoder_decodeBuiltInDatatype(message.Data, INT32, &pos, &requestType);
  169. printf("SL_processMessage - requestType=%d\n", requestType);
  170. switch (requestType) {
  171. case securityToken_ISSUE:
  172. if (connection->secureLayer.connectionState
  173. == connectionState_ESTABLISHED) {
  174. printf("SL_processMessage - multiply security token request");
  175. //TODO return ERROR
  176. return UA_ERROR;
  177. }
  178. printf(
  179. "SL_processMessage - TODO: create new token for a new SecureChannel\n");
  180. // SL_createNewToken(connection);
  181. break;
  182. case securityToken_RENEW:
  183. if (connection->secureLayer.connectionState
  184. == connectionState_CLOSED) {
  185. printf(
  186. "SL_processMessage - renew token request received, but no secureChannel was established before");
  187. //TODO return ERROR
  188. return UA_ERROR;
  189. }
  190. printf("TODO: create new token for an existing SecureChannel\n");
  191. break;
  192. }
  193. // Req-4) MessageSecurityMode SecurityMode
  194. decoder_decodeBuiltInDatatype(message.Data, INT32, &pos, &securityMode);
  195. printf("SL_processMessage - securityMode=%d\n", securityMode);
  196. switch (securityMode) {
  197. case securityMode_INVALID:
  198. printf("SL_processMessage - client demands no security \n");
  199. break;
  200. case securityMode_SIGN:
  201. printf("SL_processMessage - client demands signed \n");
  202. //TODO check if senderCertificate and ReceiverCertificateThumbprint are present
  203. break;
  204. case securityMode_SIGNANDENCRYPT:
  205. printf("SL_processMessage - client demands signed & encrypted \n");
  206. //TODO check if senderCertificate and ReceiverCertificateThumbprint are present
  207. break;
  208. }
  209. // Req-5) ByteString ClientNonce
  210. decoder_decodeBuiltInDatatype(message.Data, BYTE_STRING, &pos,
  211. &clientNonce);
  212. UA_String_printf("SL_processMessage - clientNonce=", &clientNonce);
  213. // Req-6) Int32 RequestLifetime
  214. decoder_decodeBuiltInDatatype(message.Data, INT32, &pos,
  215. &requestedLifetime);
  216. printf("SL_processMessage - requestedLifeTime=%d\n", requestedLifetime);
  217. //TODO process requestedLifetime
  218. // 62541-4 §7.27 "The requestHandle given by the Client to the request."
  219. return SL_openSecureChannel(connection, requestHeader.requestHandle, SC_Good, &serviceDiagnostics);
  220. } else {
  221. printf("SL_processMessage - unknown service request");
  222. //TODO change error code
  223. return UA_ERROR;
  224. }
  225. return UA_NO_ERROR;
  226. }
  227. /*
  228. * receive and process data from underlying layer
  229. */
  230. void SL_receive(UA_connection *connection, UA_ByteString *serviceMessage) {
  231. UA_ByteString secureChannelPacket;
  232. UA_ByteString message;
  233. SL_SecureConversationMessageHeader SCM_Header;
  234. SL_AsymmetricAlgorithmSecurityHeader AAS_Header;
  235. SL_SequenceHeader SequenceHeader;
  236. Int32 packetType = 0;
  237. Int32 pos = 0;
  238. Int32 iTmp;
  239. //TODO Error Handling, length checking
  240. //get data from transport layer
  241. printf("SL_receive - entered \n");
  242. TL_receive(connection, &secureChannelPacket);
  243. if (secureChannelPacket.Length > 0 && secureChannelPacket.Data != NULL) {
  244. printf("SL_receive - data received \n");
  245. packetType = TL_getPacketType(&secureChannelPacket, &pos);
  246. decodeSCMHeader(&secureChannelPacket, &pos, &SCM_Header);
  247. switch (SCM_Header.MessageType) {
  248. case packetType_OPN: /* openSecureChannel Message received */
  249. decodeAASHeader(&secureChannelPacket, &pos, &AAS_Header);
  250. UA_String_printf("SL_receive - AAS_Header.ReceiverThumbprint=",
  251. &(AAS_Header.ReceiverThumbprint));
  252. UA_String_printf("SL_receive - AAS_Header.SecurityPolicyUri=",
  253. &(AAS_Header.SecurityPolicyUri));
  254. UA_String_printf("SL_receive - AAS_Header.SenderCertificate=",
  255. &(AAS_Header.SenderCertificate));
  256. if (SCM_Header.SecureChannelId != 0) {
  257. iTmp = UA_ByteString_compare(
  258. &(connection->secureLayer.SenderCertificate),
  259. &(AAS_Header.SenderCertificate));
  260. if (iTmp != UA_EQUAL) {
  261. printf("SL_receive - UA_ERROR_BadSecureChannelUnknown \n");
  262. //TODO return UA_ERROR_BadSecureChannelUnknown
  263. }
  264. }
  265. decodeSequenceHeader(&secureChannelPacket, &pos, &SequenceHeader);
  266. printf("SL_receive - SequenceHeader.RequestId=%d\n",
  267. SequenceHeader.RequestId);
  268. printf("SL_receive - SequenceHeader.SequenceNr=%d\n",
  269. SequenceHeader.SequenceNumber);
  270. //save request id to return it to client
  271. connection->secureLayer.requestId = SequenceHeader.RequestId;
  272. //TODO check that the sequence number is smaller than MaxUInt32 - 1024
  273. connection->secureLayer.sequenceNumber =
  274. SequenceHeader.SequenceNumber;
  275. //SL_decrypt(&secureChannelPacket);
  276. message.Data = &secureChannelPacket.Data[pos];
  277. message.Length = secureChannelPacket.Length - pos;
  278. SL_processMessage(connection, message);
  279. break;
  280. case packetType_MSG: /* secure Channel Message received */
  281. if (connection->secureLayer.connectionState
  282. == connectionState_ESTABLISHED) {
  283. if (SCM_Header.SecureChannelId
  284. == connection->secureLayer.securityToken.secureChannelId) {
  285. } else {
  286. //TODO generate ERROR_Bad_SecureChannelUnkown
  287. }
  288. }
  289. break;
  290. case packetType_CLO: /* closeSecureChannel Message received */
  291. if (SL_check(connection, secureChannelPacket) == UA_NO_ERROR) {
  292. }
  293. break;
  294. }
  295. } else {
  296. printf("SL_receive - no data received \n");
  297. }
  298. /*
  299. Int32 readPosition = 0;
  300. //get the Secure Channel Message Header
  301. decodeSCMHeader(secureChannelPacket,
  302. &readPosition, &SCM_Header);
  303. //get the Secure Channel Asymmetric Algorithm Security Header
  304. decodeAASHeader(secureChannelPacket,
  305. &readPosition, &AAS_Header);
  306. //get the Sequence Header
  307. decodeSequenceHeader(secureChannelPacket,
  308. &readPosition, &SequenceHeader);
  309. //get Secure Channel Message
  310. //SL_secureChannel_Message_get(connection, secureChannelPacket,
  311. // &readPosition,serviceMessage);
  312. if (secureChannelPacket->length > 0)
  313. {
  314. switch (SCM_Header.MessageType)
  315. {
  316. case packetType_MSG:
  317. if (connection->secureLayer.connectionState
  318. == connectionState_ESTABLISHED)
  319. {
  320. }
  321. else //receiving message, without secure channel
  322. {
  323. //TODO send back Error Message
  324. }
  325. break;
  326. case packetType_OPN:
  327. //Server Handling
  328. // if (openSecureChannelHeader_check(connection, secureChannelPacket))
  329. // {
  330. //check if the request is valid
  331. // SL_openSecureChannelRequest_check(connection, secureChannelPacket);
  332. // }
  333. // else
  334. // {
  335. // //TODO send back Error Message
  336. // }
  337. //Client Handling
  338. //TODO free memory for secureChannelPacket
  339. break;
  340. case packetType_CLO:
  341. //TODO free memory for secureChannelPacket
  342. break;
  343. }
  344. }
  345. */
  346. }
  347. /*
  348. * get the secure channel message header
  349. */
  350. Int32 decodeSCMHeader(UA_ByteString *rawMessage, Int32 *pos,
  351. SL_SecureConversationMessageHeader* SC_Header) {
  352. UInt32 err;
  353. printf("decodeSCMHeader - entered \n");
  354. // LU: wild guess - reset pos, we want to reread the message type again
  355. *pos = 0;
  356. SC_Header->MessageType = TL_getPacketType(rawMessage, pos);
  357. SC_Header->IsFinal = rawMessage->Data[*pos];
  358. *pos += 1;
  359. decodeUInt32(rawMessage->Data, pos, &(SC_Header->MessageSize));
  360. decodeUInt32(rawMessage->Data, pos, &(SC_Header->SecureChannelId));
  361. return UA_NO_ERROR;
  362. }
  363. Int32 encodeSCMHeader(SL_SecureConversationMessageHeader *SC_Header, Int32 *pos,
  364. AD_RawMessage *rawMessage) {
  365. const char *type = "ERR";
  366. switch (SC_Header->MessageType) {
  367. case packetType_ACK:
  368. type = "ACK";
  369. break;
  370. case packetType_CLO:
  371. type = "CLO";
  372. break;
  373. case packetType_ERR:
  374. type = "ERR";
  375. break;
  376. case packetType_HEL:
  377. type = "HEL";
  378. break;
  379. case packetType_MSG:
  380. type = "MSG";
  381. break;
  382. case packetType_OPN:
  383. type = "OPN";
  384. break;
  385. default:
  386. return UA_ERROR;
  387. }
  388. memcpy(&(rawMessage->message[*pos]), &type, 3);
  389. return UA_NO_ERROR;
  390. }
  391. Int32 decodeSequenceHeader(UA_ByteString *rawMessage, Int32 *pos,
  392. SL_SequenceHeader *SequenceHeader) {
  393. decodeUInt32(rawMessage->Data, pos, &(SequenceHeader->RequestId));
  394. decodeUInt32(rawMessage->Data, pos, &(SequenceHeader->SequenceNumber));
  395. return UA_NO_ERROR;
  396. }
  397. /*
  398. * get the asymmetric algorithm security header
  399. */
  400. Int32 decodeAASHeader(UA_ByteString *rawMessage, Int32 *pos,
  401. SL_AsymmetricAlgorithmSecurityHeader* AAS_Header) {
  402. Int32 err = 0;
  403. err += decodeUAByteString(rawMessage->Data, pos,
  404. &(AAS_Header->SecurityPolicyUri));
  405. err += decodeUAByteString(rawMessage->Data, pos,
  406. &(AAS_Header->SenderCertificate));
  407. err += decodeUAByteString(rawMessage->Data, pos,
  408. &(AAS_Header->ReceiverThumbprint));
  409. return err;
  410. }
  411. Int32 encodeAASHeader(SL_AsymmetricAlgorithmSecurityHeader *AAS_Header,
  412. Int32 *pos, AD_RawMessage* dstRawMessage) {
  413. encodeUAString(AAS_Header->SecurityPolicyUri, pos,
  414. &dstRawMessage->message[*pos]);
  415. encodeUAString(AAS_Header->SenderCertificate, pos,
  416. &dstRawMessage->message[*pos]);
  417. encodeUAString(AAS_Header->ReceiverThumbprint, pos,
  418. &dstRawMessage->message[*pos]);
  419. return UA_NO_ERROR;
  420. }