ua_transport_binary_secure.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  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, UA_ByteString const * responseMessage, UA_Int32 type) {
  13. UA_Int32 pos = 0;
  14. UA_Int32 isAsym = (type == 449); // FIXME: this is a to dumb method to determine asymmetric algorithm setting
  15. UA_ByteString response_gather[2]; // securechannel_header, seq_header, security_encryption_header, message_length (eventually + padding + size_signature);
  16. UA_ByteString_newMembers(&response_gather[0], SIZE_SECURECHANNEL_HEADER + SIZE_SEQHEADER_HEADER +
  17. + (isAsym ? UA_AsymmetricAlgorithmSecurityHeader_calcSize(&(channel->localAsymAlgSettings)) :
  18. UA_AsymmetricAlgorithmSecurityHeader_calcSize(&(channel->localAsymAlgSettings))));
  19. // sizePadding = 0;
  20. // sizeSignature = 0;
  21. UA_ByteString *header = &response_gather[0];
  22. /*---encode Secure Conversation Message Header ---*/
  23. if (isAsym) {
  24. header->data[0] = 'O';
  25. header->data[1] = 'P';
  26. header->data[2] = 'N';
  27. } else {
  28. header->data[0] = 'M';
  29. header->data[1] = 'S';
  30. header->data[2] = 'G';
  31. }
  32. pos += 3;
  33. header->data[pos] = 'F';
  34. pos += 1;
  35. UA_Int32 packetSize = response_gather[0].length + responseMessage->length;
  36. UA_Int32_encodeBinary(&packetSize, &pos, header);
  37. UA_UInt32_encodeBinary(&channel->securityToken.secureChannelId, &pos, header);
  38. /*---encode Algorithm Security Header ---*/
  39. if (isAsym) {
  40. UA_AsymmetricAlgorithmSecurityHeader_encodeBinary(&channel->localAsymAlgSettings, &pos, header);
  41. } else {
  42. UA_SymmetricAlgorithmSecurityHeader_encodeBinary(&channel->securityToken.tokenId, &pos, header);
  43. }
  44. /*---encode Sequence Header ---*/
  45. UA_UInt32_encodeBinary(&channel->sequenceHeader.sequenceNumber, &pos, header);
  46. UA_UInt32_encodeBinary(&channel->sequenceHeader.requestId, &pos, header);
  47. /*---add encoded Message ---*/
  48. response_gather[1] = *responseMessage;
  49. /* sign Data*/
  50. /* encrypt Data*/
  51. /* send Data */
  52. TL_send(channel->tlConnection, (UA_ByteString **) &response_gather, 2);
  53. UA_ByteString_deleteMembers(&response_gather[0]);
  54. return UA_SUCCESS;
  55. }
  56. static void init_response_header(UA_RequestHeader const * p, UA_ResponseHeader * r) {
  57. r->requestHandle = p->requestHandle;
  58. r->serviceResult = UA_STATUSCODE_GOOD;
  59. r->stringTableSize = 0;
  60. r->timestamp = UA_DateTime_now();
  61. }
  62. #define INVOKE_SERVICE(TYPE) \
  63. UA_##TYPE##Request p; \
  64. UA_##TYPE##Response r; \
  65. UA_##TYPE##Request_decodeBinary(msg, &pos, &p); \
  66. init_response_header((UA_RequestHeader*)&p, (UA_ResponseHeader*)&r); \
  67. Service_##TYPE(channel, &p, &r); \
  68. UA_ByteString_newMembers(&response_msg, UA_##TYPE##Response_calcSize(&r)+pos); \
  69. UA_##TYPE##Response_encodeBinary(&r, &pos, &response_msg); \
  70. /** this function manages all the generic stuff for the request-response game */
  71. UA_Int32 SL_handleRequest(SL_Channel *channel, UA_ByteString* msg) {
  72. UA_Int32 retval = UA_SUCCESS;
  73. UA_Int32 pos = 0;
  74. // Every Message starts with a NodeID which names the serviceRequestType
  75. UA_NodeId serviceRequestType;
  76. UA_NodeId_decodeBinary(msg, &pos, &serviceRequestType);
  77. UA_NodeId_printf("SL_processMessage - serviceRequestType=", &serviceRequestType);
  78. UA_ByteString response_msg;
  79. UA_NodeId responseType;
  80. responseType.encodingByte = UA_NODEIDTYPE_FOURBYTE;
  81. responseType.namespace = 0;
  82. pos = UA_NodeId_calcSize(&responseType); // skip nodeid
  83. int serviceid = serviceRequestType.identifier.numeric-2; // binary encoding has 2 added to the id
  84. if(serviceid == UA_GETENDPOINTSREQUEST_NS0) {
  85. INVOKE_SERVICE(GetEndpoints);
  86. responseType.identifier.numeric = UA_GETENDPOINTSRESPONSE_NS0;
  87. }
  88. else if(serviceid == UA_OPENSECURECHANNELREQUEST_NS0) {
  89. INVOKE_SERVICE(OpenSecureChannel);
  90. responseType.identifier.numeric = UA_OPENSECURECHANNELRESPONSE_NS0;
  91. }
  92. else if(serviceid == UA_CLOSESECURECHANNELREQUEST_NS0) {
  93. INVOKE_SERVICE(CloseSecureChannel);
  94. responseType.identifier.numeric = UA_CLOSESECURECHANNELRESPONSE_NS0;
  95. }
  96. else if(serviceid == UA_CREATESESSIONREQUEST_NS0) {
  97. INVOKE_SERVICE(CreateSession);
  98. responseType.identifier.numeric = UA_CREATESESSIONRESPONSE_NS0;
  99. }
  100. else if(serviceid == UA_ACTIVATESESSIONREQUEST_NS0) {
  101. INVOKE_SERVICE(ActivateSession);
  102. responseType.identifier.numeric = UA_ACTIVATESESSIONRESPONSE_NS0;
  103. }
  104. else if(serviceid == UA_CLOSESESSIONREQUEST_NS0) {
  105. INVOKE_SERVICE(CloseSession);
  106. responseType.identifier.numeric = UA_CLOSESESSIONRESPONSE_NS0;
  107. }
  108. else if(serviceid == UA_READREQUEST_NS0) {
  109. INVOKE_SERVICE(Read);
  110. responseType.identifier.numeric = UA_READRESPONSE_NS0;
  111. }
  112. else {
  113. printf("SL_processMessage - unknown request, namespace=%d, request=%d\n", serviceRequestType.namespace,serviceRequestType.identifier.numeric);
  114. retval = UA_ERROR;
  115. responseType.identifier.numeric = 0; //FIXME
  116. }
  117. pos = 0; // reset
  118. UA_NodeId_encodeBinary(&responseType, &pos, &response_msg);
  119. SL_send(channel, &response_msg, responseType.identifier.numeric);
  120. return retval;
  121. }
  122. /* inits a connection object for secure channel layer */
  123. UA_Int32 SL_Channel_init(SL_Channel *channel) {
  124. UA_AsymmetricAlgorithmSecurityHeader_init(&(channel->localAsymAlgSettings));
  125. UA_ByteString_copy(&UA_ByteString_securityPoliceNone, &(channel->localAsymAlgSettings.securityPolicyUri));
  126. UA_alloc((void**)&(channel->localNonce.data), sizeof(UA_Byte));
  127. channel->localNonce.length = 1;
  128. channel->connectionState = connectionState_CLOSED;
  129. channel->sequenceHeader.requestId = 0;
  130. channel->sequenceHeader.sequenceNumber = 1;
  131. UA_String_init(&(channel->secureChannelId));
  132. channel->securityMode = UA_SECURITYMODE_INVALID;
  133. //TODO set a valid start secureChannelId number
  134. channel->securityToken.secureChannelId = 25;
  135. //TODO set a valid start TokenId
  136. channel->securityToken.tokenId = 1;
  137. return UA_SUCCESS;
  138. }
  139. UA_Int32 SL_Channel_new(TL_connection *connection, UA_ByteString* msg, UA_Int32* pos) {
  140. UA_Int32 retval = UA_SUCCESS;
  141. UA_SecureConversationMessageHeader secureConvHeader;
  142. DBG_VERBOSE(printf("SL_Channel_new - entered\n"));
  143. // FIXME: generate new secure channel
  144. SL_Channel_init(&slc);
  145. connection->secureChannel = &slc;
  146. connection->secureChannel->tlConnection = connection;
  147. UA_SecureConversationMessageHeader_decodeBinary(msg, pos, &secureConvHeader);
  148. // connection->secureChannel->secureChannelId = secureConvHeader.secureChannelId;
  149. UA_AsymmetricAlgorithmSecurityHeader_decodeBinary(msg, pos, &(connection->secureChannel->remoteAsymAlgSettings));
  150. //TODO check that the sequence number is smaller than MaxUInt32 - 1024
  151. UA_SequenceHeader_decodeBinary(msg, pos, &(connection->secureChannel->sequenceHeader));
  152. connection->secureChannel->securityToken.tokenId = 4711;
  153. UA_ByteString_printf("SL_receive - AAS_Header.ReceiverThumbprint=", &(connection->secureChannel->remoteAsymAlgSettings.receiverCertificateThumbprint));
  154. UA_ByteString_printf("SL_receive - AAS_Header.SecurityPolicyUri=", &(connection->secureChannel->remoteAsymAlgSettings.securityPolicyUri));
  155. UA_ByteString_printf("SL_receive - AAS_Header.SenderCertificate=", &(connection->secureChannel->remoteAsymAlgSettings.senderCertificate));
  156. printf("SL_Channel_new - SequenceHeader.RequestId=%d\n",connection->secureChannel->sequenceHeader.requestId);
  157. printf("SL_Channel_new - SequenceHeader.SequenceNr=%d\n",connection->secureChannel->sequenceHeader.sequenceNumber);
  158. printf("SL_Channel_new - SecurityToken.tokenID=%d\n",connection->secureChannel->securityToken.tokenId);
  159. // FIXME: reject
  160. // if (secureConvHeader.secureChannelId != 0) {
  161. // UA_Int32 iTmp = UA_ByteString_compare(
  162. // &(connection->secureLayer.remoteAsymAlgSettings.senderCertificate),
  163. // &(asymAlgSecHeader.senderCertificate));
  164. // if (iTmp != UA_EQUAL) {
  165. // printf("SL_receive - UA_ERROR_BadSecureChannelUnknown \n");
  166. // //TODO return UA_ERROR_BadSecureChannelUnknown
  167. // }
  168. // } else {
  169. // //TODO invalid securechannelId
  170. // }
  171. UA_ByteString slMessage;
  172. slMessage.data = &(msg->data[*pos]);
  173. slMessage.length = msg->length - *pos;
  174. retval |= SL_handleRequest(connection->secureChannel, &slMessage);
  175. return retval;
  176. }
  177. /**
  178. * process the rest of the header. TL already processed MessageType
  179. * (OPN,MSG,...), isFinal and MessageSize. SL_process cares for
  180. * secureChannelId, XASHeader and sequenceHeader
  181. * */
  182. UA_Int32 SL_process(SL_Channel* connection, UA_ByteString* msg, UA_Int32* pos) {
  183. DBG_VERBOSE(printf("SL_process - entered \n"));
  184. UA_UInt32 secureChannelId;
  185. if (connection->connectionState == connectionState_ESTABLISHED) {
  186. UA_UInt32_decodeBinary(msg,pos,&secureChannelId);
  187. //FIXME: we assume SAS, need to check if AAS or SAS
  188. UA_SymmetricAlgorithmSecurityHeader symAlgSecHeader;
  189. // if (connection->securityMode == UA_MESSAGESECURITYMODE_NONE) {
  190. UA_SymmetricAlgorithmSecurityHeader_decodeBinary(msg, pos, &symAlgSecHeader);
  191. // } else {
  192. // // FIXME:
  193. // }
  194. printf("SL_process - securityToken received=%d, expected=%d\n",secureChannelId,connection->securityToken.secureChannelId);
  195. if (secureChannelId == connection->securityToken.secureChannelId) {
  196. UA_SequenceHeader_decodeBinary(msg, pos, &(connection->sequenceHeader));
  197. // process message
  198. UA_ByteString slMessage;
  199. slMessage.data = &(msg->data[*pos]);
  200. slMessage.length = msg->length - *pos;
  201. SL_handleRequest(&slc, &slMessage);
  202. } else {
  203. //TODO generate ERROR_Bad_SecureChannelUnkown
  204. }
  205. }
  206. return UA_SUCCESS;
  207. }