ua_securechannel_manager.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. #include "ua_securechannel_manager.h"
  5. #include "ua_session.h"
  6. #include "ua_server_internal.h"
  7. #include "ua_transport_generated_handling.h"
  8. #define STARTCHANNELID 1
  9. #define STARTTOKENID 1
  10. UA_StatusCode
  11. UA_SecureChannelManager_init(UA_SecureChannelManager* cm, UA_Server* server) {
  12. LIST_INIT(&cm->channels);
  13. // TODO: use an ID that is likely to be unique after a restart
  14. cm->lastChannelId = STARTCHANNELID;
  15. cm->lastTokenId = STARTTOKENID;
  16. cm->currentChannelCount = 0;
  17. cm->server = server;
  18. return UA_STATUSCODE_GOOD;
  19. }
  20. void UA_SecureChannelManager_deleteMembers(UA_SecureChannelManager* cm) {
  21. channel_list_entry *entry, *temp;
  22. LIST_FOREACH_SAFE(entry, &cm->channels, pointers, temp) {
  23. LIST_REMOVE(entry, pointers);
  24. UA_SecureChannel_deleteMembersCleanup(&entry->channel);
  25. UA_free(entry);
  26. }
  27. }
  28. static void
  29. removeSecureChannelCallback(UA_Server *server, void *entry) {
  30. channel_list_entry *centry = (channel_list_entry*)entry;
  31. UA_SecureChannel_deleteMembersCleanup(&centry->channel);
  32. UA_free(entry);
  33. }
  34. static UA_StatusCode
  35. removeSecureChannel(UA_SecureChannelManager *cm, channel_list_entry *entry) {
  36. /* Add a delayed callback to remove the channel when the currently
  37. * scheduled jobs have completed */
  38. UA_StatusCode retval = UA_Server_delayedCallback(cm->server, removeSecureChannelCallback, entry);
  39. if(retval != UA_STATUSCODE_GOOD) {
  40. UA_LOG_WARNING(cm->server->config.logger, UA_LOGCATEGORY_SESSION,
  41. "Could not remove the secure channel with error code %s",
  42. UA_StatusCode_name(retval));
  43. return retval; /* Try again next time */
  44. }
  45. /* Detach the channel and make the capacity available */
  46. LIST_REMOVE(entry, pointers);
  47. UA_atomic_add(&cm->currentChannelCount, (UA_UInt32)-1);
  48. return UA_STATUSCODE_GOOD;
  49. }
  50. /* remove channels that were not renewed or who have no connection attached */
  51. void
  52. UA_SecureChannelManager_cleanupTimedOut(UA_SecureChannelManager *cm, UA_DateTime nowMonotonic) {
  53. channel_list_entry *entry, *temp;
  54. LIST_FOREACH_SAFE(entry, &cm->channels, pointers, temp) {
  55. UA_DateTime timeout = entry->channel.securityToken.createdAt +
  56. (UA_DateTime)(entry->channel.securityToken.revisedLifetime * UA_MSEC_TO_DATETIME);
  57. if(timeout < nowMonotonic || !entry->channel.connection) {
  58. UA_LOG_INFO_CHANNEL(cm->server->config.logger, &entry->channel,
  59. "SecureChannel has timed out");
  60. removeSecureChannel(cm, entry);
  61. }
  62. else if(entry->channel.nextSecurityToken.tokenId > 0) {
  63. UA_SecureChannel_revolveTokens(&entry->channel);
  64. }
  65. }
  66. }
  67. /* remove the first channel that has no session attached */
  68. static UA_Boolean purgeFirstChannelWithoutSession(UA_SecureChannelManager* cm) {
  69. channel_list_entry* entry;
  70. LIST_FOREACH(entry, &cm->channels, pointers) {
  71. if(LIST_EMPTY(&(entry->channel.sessions))) {
  72. UA_LOG_DEBUG_CHANNEL(cm->server->config.logger, &entry->channel,
  73. "Channel was purged since maxSecureChannels was "
  74. "reached and channel had no session attached");
  75. removeSecureChannel(cm, entry);
  76. UA_assert(entry != LIST_FIRST(&cm->channels));
  77. return true;
  78. }
  79. }
  80. return false;
  81. }
  82. UA_StatusCode
  83. UA_SecureChannelManager_create(UA_SecureChannelManager *const cm, UA_Connection *const connection,
  84. const UA_SecurityPolicy *const securityPolicy,
  85. const UA_AsymmetricAlgorithmSecurityHeader *const asymHeader) {
  86. /* connection already has a channel attached. */
  87. if(connection->channel != NULL)
  88. return UA_STATUSCODE_BADINTERNALERROR;
  89. /* Check if there exists a free SC, otherwise try to purge one SC without a
  90. * session the purge has been introduced to pass CTT, it is not clear what
  91. * strategy is expected here */
  92. if(cm->currentChannelCount >= cm->server->config.maxSecureChannels &&
  93. !purgeFirstChannelWithoutSession(cm))
  94. return UA_STATUSCODE_BADOUTOFMEMORY;
  95. UA_LOG_INFO(cm->server->config.logger, UA_LOGCATEGORY_SECURECHANNEL,
  96. "Creating a new SecureChannel");
  97. channel_list_entry* entry = (channel_list_entry*)UA_malloc(sizeof(channel_list_entry));
  98. if(!entry)
  99. return UA_STATUSCODE_BADOUTOFMEMORY;
  100. /* Create the channel context and parse the sender (remote) certificate used for the
  101. * secureChannel. */
  102. UA_StatusCode retval = UA_SecureChannel_init(&entry->channel, securityPolicy,
  103. &asymHeader->senderCertificate);
  104. if(retval != UA_STATUSCODE_GOOD) {
  105. UA_free(entry);
  106. return retval;
  107. }
  108. /* Channel state is fresh (0) */
  109. entry->channel.securityToken.channelId = 0;
  110. entry->channel.securityToken.tokenId = cm->lastTokenId++;
  111. entry->channel.securityToken.createdAt = UA_DateTime_now();
  112. entry->channel.securityToken.revisedLifetime = cm->server->config.maxSecurityTokenLifetime;
  113. LIST_INSERT_HEAD(&cm->channels, entry, pointers);
  114. UA_atomic_add(&cm->currentChannelCount, 1);
  115. UA_Connection_attachSecureChannel(connection, &entry->channel);
  116. return UA_STATUSCODE_GOOD;
  117. }
  118. UA_StatusCode
  119. UA_SecureChannelManager_open(UA_SecureChannelManager* cm, UA_SecureChannel *channel,
  120. const UA_OpenSecureChannelRequest* request,
  121. UA_OpenSecureChannelResponse* response) {
  122. if(channel->state != UA_SECURECHANNELSTATE_FRESH) {
  123. UA_LOG_ERROR_CHANNEL(cm->server->config.logger, channel,
  124. "Called open on already open or closed channel");
  125. return UA_STATUSCODE_BADINTERNALERROR;
  126. }
  127. if(request->securityMode != UA_MESSAGESECURITYMODE_NONE &&
  128. UA_ByteString_equal(&channel->securityPolicy->policyUri, &UA_SECURITY_POLICY_NONE_URI)) {
  129. return UA_STATUSCODE_BADSECURITYMODEREJECTED;
  130. }
  131. channel->securityToken.channelId = cm->lastChannelId++;
  132. channel->securityToken.createdAt = UA_DateTime_now();
  133. channel->securityToken.revisedLifetime =
  134. (request->requestedLifetime > cm->server->config.maxSecurityTokenLifetime) ?
  135. cm->server->config.maxSecurityTokenLifetime : request->requestedLifetime;
  136. if(channel->securityToken.revisedLifetime == 0) // lifetime 0 -> set the maximum possible
  137. channel->securityToken.revisedLifetime = cm->server->config.maxSecurityTokenLifetime;
  138. UA_ByteString_copy(&request->clientNonce, &channel->remoteNonce);
  139. channel->securityMode = request->securityMode;
  140. const size_t keyLength = channel->securityPolicy->symmetricModule.cryptoModule.
  141. getLocalEncryptionKeyLength(channel->securityPolicy, channel->channelContext);
  142. UA_SecureChannel_generateNonce(channel,
  143. keyLength,
  144. &channel->localNonce);
  145. UA_SecureChannel_generateNewKeys(channel);
  146. // Set the response
  147. UA_ByteString_copy(&channel->localNonce, &response->serverNonce);
  148. UA_ChannelSecurityToken_copy(&channel->securityToken, &response->securityToken);
  149. response->responseHeader.timestamp = UA_DateTime_now();
  150. response->responseHeader.requestHandle = request->requestHeader.requestHandle;
  151. // Now overwrite the creation date with the internal monotonic clock
  152. channel->securityToken.createdAt = UA_DateTime_nowMonotonic();
  153. channel->state = UA_SECURECHANNELSTATE_OPEN;
  154. return UA_STATUSCODE_GOOD;
  155. }
  156. UA_StatusCode
  157. UA_SecureChannelManager_renew(UA_SecureChannelManager* cm, UA_SecureChannel *channel,
  158. const UA_OpenSecureChannelRequest* request,
  159. UA_OpenSecureChannelResponse* response) {
  160. if(channel->state != UA_SECURECHANNELSTATE_OPEN) {
  161. UA_LOG_ERROR_CHANNEL(cm->server->config.logger, channel,
  162. "Called renew on channel which is not open");
  163. return UA_STATUSCODE_BADINTERNALERROR;
  164. }
  165. /* If no security token is already issued */
  166. if(channel->nextSecurityToken.tokenId == 0) {
  167. channel->nextSecurityToken.channelId = channel->securityToken.channelId;
  168. channel->nextSecurityToken.tokenId = cm->lastTokenId++;
  169. channel->nextSecurityToken.createdAt = UA_DateTime_now();
  170. channel->nextSecurityToken.revisedLifetime =
  171. (request->requestedLifetime > cm->server->config.maxSecurityTokenLifetime) ?
  172. cm->server->config.maxSecurityTokenLifetime : request->requestedLifetime;
  173. if(channel->nextSecurityToken.revisedLifetime == 0) /* lifetime 0 -> return the max lifetime */
  174. channel->nextSecurityToken.revisedLifetime = cm->server->config.maxSecurityTokenLifetime;
  175. }
  176. /* invalidate the old nonce */
  177. if(channel->remoteNonce.data)
  178. UA_ByteString_deleteMembers(&channel->remoteNonce);
  179. if(channel->localNonce.data)
  180. UA_ByteString_deleteMembers(&channel->localNonce);
  181. /* set the response */
  182. UA_ByteString_copy(&request->clientNonce, &channel->remoteNonce);
  183. const size_t keyLength = channel->securityPolicy->symmetricModule.cryptoModule.
  184. getLocalEncryptionKeyLength(channel->securityPolicy, channel->channelContext);
  185. UA_SecureChannel_generateNonce(channel,
  186. keyLength,
  187. &channel->localNonce);
  188. UA_ByteString_copy(&channel->localNonce, &response->serverNonce);
  189. UA_ChannelSecurityToken_copy(&channel->nextSecurityToken, &response->securityToken);
  190. response->responseHeader.requestHandle = request->requestHeader.requestHandle;
  191. /* reset the creation date to the monotonic clock */
  192. channel->nextSecurityToken.createdAt = UA_DateTime_nowMonotonic();
  193. return UA_STATUSCODE_GOOD;
  194. }
  195. UA_SecureChannel*
  196. UA_SecureChannelManager_get(UA_SecureChannelManager* cm, UA_UInt32 channelId) {
  197. channel_list_entry* entry;
  198. LIST_FOREACH(entry, &cm->channels, pointers) {
  199. if(entry->channel.securityToken.channelId == channelId)
  200. return &entry->channel;
  201. }
  202. return NULL;
  203. }
  204. UA_StatusCode
  205. UA_SecureChannelManager_close(UA_SecureChannelManager* cm, UA_UInt32 channelId) {
  206. channel_list_entry* entry;
  207. LIST_FOREACH(entry, &cm->channels, pointers) {
  208. if(entry->channel.securityToken.channelId == channelId)
  209. break;
  210. }
  211. if(!entry)
  212. return UA_STATUSCODE_BADINTERNALERROR;
  213. return removeSecureChannel(cm, entry);
  214. }