ua_services_session.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  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_services.h"
  5. #include "ua_server_internal.h"
  6. #include "ua_session_manager.h"
  7. #include "ua_types_generated_handling.h"
  8. /* Create a signed nonce */
  9. static UA_StatusCode
  10. nonceAndSignCreateSessionResponse(UA_Server *server, UA_SecureChannel *channel,
  11. UA_Session *session,
  12. const UA_CreateSessionRequest *request,
  13. UA_CreateSessionResponse *response) {
  14. if(channel->securityMode != UA_MESSAGESECURITYMODE_SIGN &&
  15. channel->securityMode != UA_MESSAGESECURITYMODE_SIGNANDENCRYPT)
  16. return UA_STATUSCODE_GOOD;
  17. const UA_SecurityPolicy *const securityPolicy = channel->securityPolicy;
  18. UA_SignatureData *signatureData = &response->serverSignature;
  19. /* Generate Nonce
  20. * FIXME: remove magic number??? */
  21. UA_StatusCode retval = UA_SecureChannel_generateNonce(channel, 32, &response->serverNonce);
  22. UA_ByteString_deleteMembers(&session->serverNonce);
  23. retval |= UA_ByteString_copy(&response->serverNonce, &session->serverNonce);
  24. if(retval != UA_STATUSCODE_GOOD) {
  25. UA_SessionManager_removeSession(&server->sessionManager, &session->authenticationToken);
  26. return retval;
  27. }
  28. size_t signatureSize = securityPolicy->asymmetricModule.cryptoModule.
  29. getLocalSignatureSize(securityPolicy, channel->channelContext);
  30. retval |= UA_ByteString_allocBuffer(&signatureData->signature, signatureSize);
  31. if(retval != UA_STATUSCODE_GOOD) {
  32. UA_SessionManager_removeSession(&server->sessionManager, &session->authenticationToken);
  33. return retval;
  34. }
  35. UA_ByteString dataToSign;
  36. retval |= UA_ByteString_allocBuffer(&dataToSign,
  37. request->clientCertificate.length +
  38. request->clientNonce.length);
  39. if(retval != UA_STATUSCODE_GOOD) {
  40. UA_SignatureData_deleteMembers(signatureData);
  41. UA_SessionManager_removeSession(&server->sessionManager, &session->authenticationToken);
  42. return retval;
  43. }
  44. memcpy(dataToSign.data, request->clientCertificate.data, request->clientCertificate.length);
  45. memcpy(dataToSign.data + request->clientCertificate.length,
  46. request->clientNonce.data, request->clientNonce.length);
  47. retval |= UA_String_copy(&securityPolicy->asymmetricModule.cryptoModule.
  48. signatureAlgorithmUri, &signatureData->algorithm);
  49. retval |= securityPolicy->asymmetricModule.cryptoModule.
  50. sign(securityPolicy, channel->channelContext, &dataToSign, &signatureData->signature);
  51. UA_ByteString_deleteMembers(&dataToSign);
  52. if(retval != UA_STATUSCODE_GOOD) {
  53. UA_SignatureData_deleteMembers(signatureData);
  54. UA_SessionManager_removeSession(&server->sessionManager, &session->authenticationToken);
  55. }
  56. return retval;
  57. }
  58. void Service_CreateSession(UA_Server *server, UA_SecureChannel *channel,
  59. const UA_CreateSessionRequest *request,
  60. UA_CreateSessionResponse *response) {
  61. if(channel == NULL) {
  62. response->responseHeader.serviceResult = UA_STATUSCODE_BADINTERNALERROR;
  63. return;
  64. }
  65. if(channel->connection == NULL) {
  66. response->responseHeader.serviceResult = UA_STATUSCODE_BADINTERNALERROR;
  67. return;
  68. }
  69. UA_LOG_DEBUG_CHANNEL(server->config.logger, channel, "Trying to create session");
  70. if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN ||
  71. channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) {
  72. if(!UA_ByteString_equal(&request->clientCertificate,
  73. &channel->remoteCertificate)) {
  74. response->responseHeader.serviceResult = UA_STATUSCODE_BADCERTIFICATEINVALID;
  75. return;
  76. }
  77. }
  78. if(channel->securityToken.channelId == 0) {
  79. response->responseHeader.serviceResult =
  80. UA_STATUSCODE_BADSECURECHANNELIDINVALID;
  81. return;
  82. }
  83. if(!UA_ByteString_equal(&channel->securityPolicy->policyUri,
  84. &UA_SECURITY_POLICY_NONE_URI) &&
  85. request->clientNonce.length < 32) {
  86. response->responseHeader.serviceResult = UA_STATUSCODE_BADNONCEINVALID;
  87. return;
  88. }
  89. ////////////////////// TODO: Compare application URI with certificate uri (decode certificate)
  90. /* Allocate the response */
  91. response->serverEndpoints = (UA_EndpointDescription*)
  92. UA_Array_new(server->config.endpointsSize,
  93. &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]);
  94. if(!response->serverEndpoints) {
  95. response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
  96. return;
  97. }
  98. response->serverEndpointsSize = server->config.endpointsSize;
  99. /* Copy the server's endpointdescriptions into the response */
  100. for(size_t i = 0; i < server->config.endpointsSize; ++i)
  101. response->responseHeader.serviceResult |=
  102. UA_EndpointDescription_copy(&server->config.endpoints[i].endpointDescription,
  103. &response->serverEndpoints[i]);
  104. if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD)
  105. return;
  106. /* Mirror back the endpointUrl */
  107. for(size_t i = 0; i < response->serverEndpointsSize; ++i) {
  108. UA_String_deleteMembers(&response->serverEndpoints[i].endpointUrl);
  109. UA_String_copy(&request->endpointUrl,
  110. &response->serverEndpoints[i].endpointUrl);
  111. }
  112. UA_Session *newSession;
  113. response->responseHeader.serviceResult =
  114. UA_SessionManager_createSession(&server->sessionManager,
  115. channel, request, &newSession);
  116. if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
  117. UA_LOG_DEBUG_CHANNEL(server->config.logger, channel,
  118. "Processing CreateSessionRequest failed");
  119. return;
  120. }
  121. /* Fill the session with more information */
  122. newSession->maxResponseMessageSize = request->maxResponseMessageSize;
  123. newSession->maxRequestMessageSize =
  124. channel->connection->localConf.maxMessageSize;
  125. response->responseHeader.serviceResult |=
  126. UA_ApplicationDescription_copy(&request->clientDescription,
  127. &newSession->clientDescription);
  128. /* Prepare the response */
  129. response->sessionId = newSession->sessionId;
  130. response->revisedSessionTimeout = (UA_Double)newSession->timeout;
  131. response->authenticationToken = newSession->authenticationToken;
  132. response->responseHeader.serviceResult =
  133. UA_String_copy(&request->sessionName, &newSession->sessionName);
  134. if(server->config.endpointsSize > 0)
  135. response->responseHeader.serviceResult |=
  136. UA_ByteString_copy(&channel->securityPolicy->localCertificate,
  137. &response->serverCertificate);
  138. /* Create a signed nonce */
  139. response->responseHeader.serviceResult =
  140. nonceAndSignCreateSessionResponse(server, channel, newSession, request, response);
  141. /* Failure -> remove the session */
  142. if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
  143. UA_SessionManager_removeSession(&server->sessionManager, &newSession->authenticationToken);
  144. return;
  145. }
  146. UA_LOG_DEBUG_CHANNEL(server->config.logger, channel,
  147. "Session " UA_PRINTF_GUID_FORMAT " created",
  148. UA_PRINTF_GUID_DATA(newSession->sessionId.identifier.guid));
  149. }
  150. static void
  151. checkSignature(const UA_Server *server,
  152. const UA_SecureChannel *channel,
  153. UA_Session *session,
  154. const UA_ActivateSessionRequest *request,
  155. UA_ActivateSessionResponse *response) {
  156. if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN ||
  157. channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) {
  158. const UA_SecurityPolicy *const securityPolicy = channel->securityPolicy;
  159. const UA_ByteString *const localCertificate = &securityPolicy->localCertificate;
  160. UA_ByteString dataToVerify;
  161. UA_StatusCode retval = UA_ByteString_allocBuffer(&dataToVerify,
  162. localCertificate->length + session->serverNonce.length);
  163. if(retval != UA_STATUSCODE_GOOD) {
  164. response->responseHeader.serviceResult = retval;
  165. UA_LOG_DEBUG_SESSION(server->config.logger, session,
  166. "Failed to allocate buffer for signature verification! %#10x", retval);
  167. return;
  168. }
  169. memcpy(dataToVerify.data, localCertificate->data, localCertificate->length);
  170. memcpy(dataToVerify.data + localCertificate->length,
  171. session->serverNonce.data, session->serverNonce.length);
  172. retval = securityPolicy->asymmetricModule.cryptoModule.
  173. verify(securityPolicy, channel->channelContext, &dataToVerify,
  174. &request->clientSignature.signature);
  175. if(retval != UA_STATUSCODE_GOOD) {
  176. response->responseHeader.serviceResult = retval;
  177. UA_LOG_DEBUG_SESSION(server->config.logger, session,
  178. "Failed to verify the client signature! %#10x", retval);
  179. UA_ByteString_deleteMembers(&dataToVerify);
  180. return;
  181. }
  182. retval = UA_SecureChannel_generateNonce(channel, 32, &response->serverNonce);
  183. UA_ByteString_deleteMembers(&session->serverNonce);
  184. retval |= UA_ByteString_copy(&response->serverNonce, &session->serverNonce);
  185. if(retval != UA_STATUSCODE_GOOD) {
  186. response->responseHeader.serviceResult = retval;
  187. UA_LOG_DEBUG_SESSION(server->config.logger, session,
  188. "Failed to generate a new nonce! %#10x", retval);
  189. UA_ByteString_deleteMembers(&dataToVerify);
  190. return;
  191. }
  192. UA_ByteString_deleteMembers(&dataToVerify);
  193. }
  194. }
  195. void
  196. Service_ActivateSession(UA_Server *server, UA_SecureChannel *channel,
  197. UA_Session *session, const UA_ActivateSessionRequest *request,
  198. UA_ActivateSessionResponse *response) {
  199. if(session->validTill < UA_DateTime_nowMonotonic()) {
  200. UA_LOG_INFO_SESSION(server->config.logger, session,
  201. "ActivateSession: SecureChannel %i wants "
  202. "to activate, but the session has timed out",
  203. channel->securityToken.channelId);
  204. response->responseHeader.serviceResult =
  205. UA_STATUSCODE_BADSESSIONIDINVALID;
  206. return;
  207. }
  208. checkSignature(server, channel, session, request, response);
  209. if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD)
  210. return;
  211. /* Callback into userland access control */
  212. response->responseHeader.serviceResult =
  213. server->config.accessControl.activateSession(&session->sessionId,
  214. &request->userIdentityToken,
  215. &session->sessionHandle);
  216. if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD)
  217. return;
  218. /* Detach the old SecureChannel */
  219. if(session->channel && session->channel != channel) {
  220. UA_LOG_INFO_SESSION(server->config.logger, session,
  221. "ActivateSession: Detach from old channel");
  222. UA_SecureChannel_detachSession(session->channel, session);
  223. }
  224. /* Attach to the SecureChannel and activate */
  225. UA_SecureChannel_attachSession(channel, session);
  226. session->activated = true;
  227. UA_Session_updateLifetime(session);
  228. UA_LOG_INFO_SESSION(server->config.logger, session,
  229. "ActivateSession: Session activated");
  230. }
  231. void
  232. Service_CloseSession(UA_Server *server, UA_Session *session,
  233. const UA_CloseSessionRequest *request,
  234. UA_CloseSessionResponse *response) {
  235. UA_LOG_INFO_SESSION(server->config.logger, session, "CloseSession");
  236. /* Callback into userland access control */
  237. server->config.accessControl.closeSession(&session->sessionId,
  238. session->sessionHandle);
  239. response->responseHeader.serviceResult =
  240. UA_SessionManager_removeSession(&server->sessionManager,
  241. &session->authenticationToken);
  242. }