ua_securechannel.h 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  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. #ifndef UA_SECURECHANNEL_H_
  5. #define UA_SECURECHANNEL_H_
  6. #ifdef __cplusplus
  7. extern "C" {
  8. #endif
  9. #include "queue.h"
  10. #include "ua_types.h"
  11. #include "ua_transport_generated.h"
  12. #include "ua_connection_internal.h"
  13. #include "ua_plugin_securitypolicy.h"
  14. #include "ua_plugin_log.h"
  15. #include "ua_util.h"
  16. #define UA_SECURE_CONVERSATION_MESSAGE_HEADER_LENGTH 12
  17. struct UA_Session;
  18. typedef struct UA_Session UA_Session;
  19. struct SessionEntry {
  20. LIST_ENTRY(SessionEntry) pointers;
  21. UA_Session *session; // Just a pointer. The session is held in the session manager or the client
  22. };
  23. /* For chunked requests */
  24. struct ChunkEntry {
  25. LIST_ENTRY(ChunkEntry) pointers;
  26. UA_UInt32 requestId;
  27. UA_ByteString bytes;
  28. };
  29. typedef enum {
  30. UA_SECURECHANNELSTATE_FRESH,
  31. UA_SECURECHANNELSTATE_OPEN,
  32. UA_SECURECHANNELSTATE_CLOSED
  33. } UA_SecureChannelState;
  34. struct UA_SecureChannel {
  35. UA_SecureChannelState state;
  36. UA_MessageSecurityMode securityMode;
  37. UA_ChannelSecurityToken securityToken; /* the channelId is contained in the securityToken */
  38. UA_ChannelSecurityToken nextSecurityToken;
  39. /* The endpoint and context of the channel */
  40. const UA_SecurityPolicy *securityPolicy;
  41. void *channelContext; /* For interaction with the security policy */
  42. UA_Connection *connection;
  43. /* Asymmetric encryption info */
  44. UA_ByteString remoteCertificate;
  45. UA_Byte remoteCertificateThumbprint[20]; /* The thumprint of the remote certificate */
  46. /* Symmetric encryption info */
  47. UA_ByteString remoteNonce;
  48. UA_ByteString localNonce;
  49. UA_UInt32 receiveSequenceNumber;
  50. UA_UInt32 sendSequenceNumber;
  51. LIST_HEAD(session_pointerlist, SessionEntry) sessions;
  52. LIST_HEAD(chunk_pointerlist, ChunkEntry) chunks;
  53. };
  54. UA_StatusCode
  55. UA_SecureChannel_init(UA_SecureChannel *channel,
  56. const UA_SecurityPolicy *securityPolicy,
  57. const UA_ByteString *remoteCertificate);
  58. void UA_SecureChannel_deleteMembersCleanup(UA_SecureChannel *channel);
  59. /* Generates new keys and sets them in the channel context */
  60. UA_StatusCode UA_SecureChannel_generateNewKeys(UA_SecureChannel* const channel);
  61. /* Wrapper function for generating nonces for the supplied channel.
  62. *
  63. * Uses the random generator of the channels security policy to allocate
  64. * and generate a nonce with the specified length.
  65. *
  66. * \param channel the channel to use.
  67. * \param nonceLength the length of the nonce to be generated.
  68. * \param nonce will contain the nonce after being successfully called.
  69. */
  70. UA_StatusCode UA_SecureChannel_generateNonce(const UA_SecureChannel *const channel,
  71. const size_t nonceLength,
  72. UA_ByteString *const nonce);
  73. void UA_SecureChannel_attachSession(UA_SecureChannel *channel, UA_Session *session);
  74. void UA_SecureChannel_detachSession(UA_SecureChannel *channel, UA_Session *session);
  75. UA_Session * UA_SecureChannel_getSession(UA_SecureChannel *channel, UA_NodeId *token);
  76. UA_StatusCode UA_SecureChannel_revolveTokens(UA_SecureChannel *channel);
  77. UA_StatusCode
  78. UA_SecureChannel_sendSymmetricMessage(UA_SecureChannel *channel, UA_UInt32 requestId,
  79. UA_MessageType messageType, const void *content,
  80. const UA_DataType *contentType);
  81. UA_StatusCode
  82. UA_SecureChannel_sendAsymmetricOPNMessage(UA_SecureChannel *channel, UA_UInt32 requestId,
  83. const void *content, const UA_DataType *contentType);
  84. /**
  85. * Chunking
  86. * -------- */
  87. /* For sending responses in multiple chunks */
  88. typedef struct {
  89. UA_SecureChannel *channel;
  90. UA_UInt32 requestId;
  91. UA_UInt32 messageType;
  92. UA_UInt16 chunksSoFar;
  93. size_t messageSizeSoFar;
  94. UA_ByteString messageBuffer;
  95. UA_StatusCode errorCode;
  96. UA_Boolean final;
  97. } UA_ChunkInfo;
  98. typedef UA_StatusCode
  99. (UA_ProcessMessageCallback)(void *application, UA_SecureChannel *channel,
  100. UA_MessageType messageType, UA_UInt32 requestId,
  101. const UA_ByteString *message);
  102. typedef UA_StatusCode
  103. (UA_AsymHeaderCallback)(void *application, UA_SecureChannel *channel,
  104. UA_AsymmetricAlgorithmSecurityHeader *asymHeader);
  105. typedef UA_StatusCode
  106. (UA_SymHeaderCallback)(void *application, UA_SecureChannel *channel,
  107. UA_UInt32 tokenId);
  108. /* Process a single chunk. This also decrypts the chunk if required. The
  109. * callback function is called with the complete message body if the message is
  110. * complete.
  111. *
  112. * Symmetric calback is ERR, MSG, CLO only
  113. * Asymmetric callback is OPN only
  114. *
  115. * @param channel the channel the chunks were recieved on.
  116. * @param chunks the memory region where the chunks are stored.
  117. * @param callback the callback function that gets called with the complete
  118. * message body, once a final chunk is processed.
  119. * @param application data pointer to application specific data that gets passed
  120. * on to the callback function. */
  121. UA_StatusCode
  122. UA_SecureChannel_processChunk(UA_SecureChannel *channel, UA_ByteString *chunk,
  123. UA_ProcessMessageCallback callback,
  124. void *application);
  125. /**
  126. * Log Helper
  127. * ----------
  128. * C99 requires at least one element for the variadic argument. If the log
  129. * statement has no variable arguments, supply an additional NULL. It will be
  130. * ignored by printf.
  131. *
  132. * We have to jump through some hoops to enable the use of format strings
  133. * without arguments since (pedantic) C99 does not allow variadic macros with
  134. * zero arguments. So we add a dummy argument that is not printed (%.0s is
  135. * string of length zero). */
  136. #define UA_LOG_TRACE_CHANNEL_INTERNAL(LOGGER, CHANNEL, MSG, ...) \
  137. UA_LOG_TRACE(LOGGER, UA_LOGCATEGORY_SECURECHANNEL, \
  138. "Connection %i | SecureChannel %i | " MSG "%.0s", \
  139. ((CHANNEL)->connection ? (CHANNEL)->connection->sockfd : 0), \
  140. (CHANNEL)->securityToken.channelId, __VA_ARGS__)
  141. #define UA_LOG_TRACE_CHANNEL(LOGGER, CHANNEL, ...) \
  142. UA_MACRO_EXPAND(UA_LOG_TRACE_CHANNEL_INTERNAL(LOGGER, CHANNEL, __VA_ARGS__, ""))
  143. #define UA_LOG_DEBUG_CHANNEL_INTERNAL(LOGGER, CHANNEL, MSG, ...) \
  144. UA_LOG_DEBUG(LOGGER, UA_LOGCATEGORY_SECURECHANNEL, \
  145. "Connection %i | SecureChannel %i | " MSG "%.0s", \
  146. ((CHANNEL)->connection ? (CHANNEL)->connection->sockfd : 0), \
  147. (CHANNEL)->securityToken.channelId, __VA_ARGS__)
  148. #define UA_LOG_DEBUG_CHANNEL(LOGGER, CHANNEL, ...) \
  149. UA_MACRO_EXPAND(UA_LOG_DEBUG_CHANNEL_INTERNAL(LOGGER, CHANNEL, __VA_ARGS__, ""))
  150. #define UA_LOG_INFO_CHANNEL_INTERNAL(LOGGER, CHANNEL, MSG, ...) \
  151. UA_LOG_INFO(LOGGER, UA_LOGCATEGORY_SECURECHANNEL, \
  152. "Connection %i | SecureChannel %i | " MSG "%.0s", \
  153. ((CHANNEL)->connection ? (CHANNEL)->connection->sockfd : 0), \
  154. (CHANNEL)->securityToken.channelId, __VA_ARGS__)
  155. #define UA_LOG_INFO_CHANNEL(LOGGER, CHANNEL, ...) \
  156. UA_MACRO_EXPAND(UA_LOG_INFO_CHANNEL_INTERNAL(LOGGER, CHANNEL, __VA_ARGS__, ""))
  157. #define UA_LOG_WARNING_CHANNEL_INTERNAL(LOGGER, CHANNEL, MSG, ...) \
  158. UA_LOG_WARNING(LOGGER, UA_LOGCATEGORY_SECURECHANNEL, \
  159. "Connection %i | SecureChannel %i | " MSG "%.0s", \
  160. ((CHANNEL)->connection ? (CHANNEL)->connection->sockfd : 0), \
  161. (CHANNEL)->securityToken.channelId, __VA_ARGS__)
  162. #define UA_LOG_WARNING_CHANNEL(LOGGER, CHANNEL, ...) \
  163. UA_MACRO_EXPAND(UA_LOG_WARNING_CHANNEL_INTERNAL(LOGGER, CHANNEL, __VA_ARGS__, ""))
  164. #define UA_LOG_ERROR_CHANNEL_INTERNAL(LOGGER, CHANNEL, MSG, ...) \
  165. UA_LOG_ERROR(LOGGER, UA_LOGCATEGORY_SECURECHANNEL, \
  166. "Connection %i | SecureChannel %i | " MSG "%.0s", \
  167. ((CHANNEL)->connection ? (CHANNEL)->connection->sockfd : 0), \
  168. (CHANNEL)->securityToken.channelId, __VA_ARGS__)
  169. #define UA_LOG_ERROR_CHANNEL(LOGGER, CHANNEL, ...) \
  170. UA_MACRO_EXPAND(UA_LOG_ERROR_CHANNEL_INTERNAL(LOGGER, CHANNEL, __VA_ARGS__, ""))
  171. #define UA_LOG_FATAL_CHANNEL_INTERNAL(LOGGER, CHANNEL, MSG, ...) \
  172. UA_LOG_FATAL(LOGGER, UA_LOGCATEGORY_SECURECHANNEL, \
  173. "Connection %i | SecureChannel %i | " MSG "%.0s", \
  174. ((CHANNEL)->connection ? (CHANNEL)->connection->sockfd : 0), \
  175. (CHANNEL)->securityToken.channelId, __VA_ARGS__)
  176. #define UA_LOG_FATAL_CHANNEL(LOGGER, CHANNEL, ...) \
  177. UA_MACRO_EXPAND(UA_LOG_FATAL_CHANNEL_INTERNAL(LOGGER, CHANNEL, __VA_ARGS__, ""))
  178. #ifdef __cplusplus
  179. } // extern "C"
  180. #endif
  181. #endif /* UA_SECURECHANNEL_H_ */