ua_securechannel.c 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016
  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_util.h"
  5. #include "ua_securechannel.h"
  6. #include "ua_session.h"
  7. #include "ua_types_encoding_binary.h"
  8. #include "ua_types_generated_encoding_binary.h"
  9. #include "ua_transport_generated_encoding_binary.h"
  10. #include "ua_types_generated_handling.h"
  11. #include "ua_transport_generated_handling.h"
  12. #include "ua_plugin_securitypolicy.h"
  13. #define UA_BITMASK_MESSAGETYPE 0x00ffffff
  14. #define UA_BITMASK_CHUNKTYPE 0xff000000
  15. #define UA_SECURE_MESSAGE_HEADER_LENGTH 24
  16. #define UA_ASYMMETRIC_ALG_SECURITY_HEADER_FIXED_LENGTH 12
  17. #define UA_SYMMETRIC_ALG_SECURITY_HEADER_LENGTH 4
  18. #define UA_SEQUENCE_HEADER_LENGTH 8
  19. #define UA_SECUREMH_AND_SYMALGH_LENGTH \
  20. (UA_SECURE_CONVERSATION_MESSAGE_HEADER_LENGTH + \
  21. UA_SYMMETRIC_ALG_SECURITY_HEADER_LENGTH)
  22. const UA_ByteString
  23. UA_SECURITY_POLICY_NONE_URI = {47, (UA_Byte *) "http://opcfoundation.org/UA/SecurityPolicy#None"};
  24. #ifdef UA_ENABLE_UNIT_TEST_FAILURE_HOOKS
  25. UA_THREAD_LOCAL UA_StatusCode decrypt_verifySignatureFailure;
  26. UA_THREAD_LOCAL UA_StatusCode sendAsym_sendFailure;
  27. UA_THREAD_LOCAL UA_StatusCode processSym_seqNumberFailure;
  28. #endif
  29. /* Callback data for sending responses in multiple chunks */
  30. typedef struct {
  31. UA_SecureChannel *channel;
  32. UA_UInt32 requestId;
  33. UA_UInt32 messageType;
  34. UA_UInt16 chunksSoFar;
  35. size_t messageSizeSoFar;
  36. UA_ByteString messageBuffer;
  37. UA_Boolean final;
  38. } UA_ChunkInfo;
  39. UA_StatusCode
  40. UA_SecureChannel_init(UA_SecureChannel *channel,
  41. const UA_SecurityPolicy *securityPolicy,
  42. const UA_ByteString *remoteCertificate) {
  43. if(channel == NULL || securityPolicy == NULL || remoteCertificate == NULL) {
  44. return UA_STATUSCODE_BADINTERNALERROR;
  45. }
  46. memset(channel, 0, sizeof(UA_SecureChannel));
  47. channel->state = UA_SECURECHANNELSTATE_FRESH;
  48. channel->securityPolicy = securityPolicy;
  49. UA_StatusCode retval = securityPolicy->channelModule.newContext(securityPolicy, remoteCertificate,
  50. &channel->channelContext);
  51. if(retval != UA_STATUSCODE_GOOD)
  52. return retval;
  53. retval = UA_ByteString_copy(remoteCertificate, &channel->remoteCertificate);
  54. if(retval != UA_STATUSCODE_GOOD)
  55. return retval;
  56. UA_ByteString remoteCertificateThumbprint = {20, channel->remoteCertificateThumbprint};
  57. retval = securityPolicy->asymmetricModule.
  58. makeCertificateThumbprint(securityPolicy, &channel->remoteCertificate,
  59. &remoteCertificateThumbprint);
  60. return retval;
  61. /* Linked lists are also initialized by zeroing out */
  62. /* LIST_INIT(&channel->sessions); */
  63. /* LIST_INIT(&channel->chunks); */
  64. }
  65. void
  66. UA_SecureChannel_deleteMembersCleanup(UA_SecureChannel *channel) {
  67. if(channel == NULL)
  68. return;
  69. /* Delete members */
  70. UA_ByteString_deleteMembers(&channel->remoteCertificate);
  71. UA_ByteString_deleteMembers(&channel->localNonce);
  72. UA_ByteString_deleteMembers(&channel->remoteNonce);
  73. UA_ChannelSecurityToken_deleteMembers(&channel->securityToken);
  74. UA_ChannelSecurityToken_deleteMembers(&channel->nextSecurityToken);
  75. /* Delete the channel context for the security policy */
  76. if(channel->securityPolicy)
  77. channel->securityPolicy->channelModule.deleteContext(channel->channelContext);
  78. /* Detach from the connection */
  79. if(channel->connection)
  80. UA_Connection_detachSecureChannel(channel->connection);
  81. /* Remove session pointers (not the sessions) */
  82. struct SessionEntry *se, *temp;
  83. LIST_FOREACH_SAFE(se, &channel->sessions, pointers, temp) {
  84. if(se->session)
  85. se->session->channel = NULL;
  86. LIST_REMOVE(se, pointers);
  87. UA_free(se);
  88. }
  89. /* Remove the buffered chunks */
  90. struct ChunkEntry *ch, *temp_ch;
  91. LIST_FOREACH_SAFE(ch, &channel->chunks, pointers, temp_ch) {
  92. UA_ByteString_deleteMembers(&ch->bytes);
  93. LIST_REMOVE(ch, pointers);
  94. UA_free(ch);
  95. }
  96. }
  97. UA_StatusCode
  98. UA_SecureChannel_generateNonce(const UA_SecureChannel *const channel,
  99. const size_t nonceLength,
  100. UA_ByteString *const nonce) {
  101. UA_ByteString_allocBuffer(nonce, nonceLength);
  102. if(!nonce->data)
  103. return UA_STATUSCODE_BADOUTOFMEMORY;
  104. return channel->securityPolicy->symmetricModule.generateNonce(channel->securityPolicy,
  105. nonce);
  106. }
  107. UA_StatusCode
  108. UA_SecureChannel_generateNewKeys(UA_SecureChannel *const channel) {
  109. if(channel == NULL)
  110. return UA_STATUSCODE_BADINTERNALERROR;
  111. const UA_SecurityPolicy *const securityPolicy = channel->securityPolicy;
  112. const UA_SecurityPolicyChannelModule *channelModule =
  113. &securityPolicy->channelModule;
  114. const UA_SecurityPolicySymmetricModule *symmetricModule =
  115. &securityPolicy->symmetricModule;
  116. /* Symmetric key length */
  117. size_t encryptionKeyLength = symmetricModule->cryptoModule.
  118. getLocalEncryptionKeyLength(securityPolicy, channel->channelContext);
  119. const size_t buffSize = symmetricModule->encryptionBlockSize +
  120. symmetricModule->signingKeyLength + encryptionKeyLength;
  121. UA_ByteString buffer = {buffSize, (UA_Byte *) UA_alloca(buffSize)};
  122. /* Remote keys */
  123. UA_StatusCode retval = symmetricModule->generateKey(securityPolicy, &channel->localNonce,
  124. &channel->remoteNonce, &buffer);
  125. if(retval != UA_STATUSCODE_GOOD)
  126. return retval;
  127. const UA_ByteString remoteSigningKey = {symmetricModule->signingKeyLength, buffer.data};
  128. const UA_ByteString remoteEncryptingKey = {encryptionKeyLength,
  129. buffer.data + symmetricModule->signingKeyLength};
  130. const UA_ByteString remoteIv = {symmetricModule->encryptionBlockSize,
  131. buffer.data + symmetricModule->signingKeyLength +
  132. encryptionKeyLength};
  133. retval = channelModule->setRemoteSymSigningKey(channel->channelContext, &remoteSigningKey);
  134. retval |= channelModule->setRemoteSymEncryptingKey(channel->channelContext, &remoteEncryptingKey);
  135. retval |= channelModule->setRemoteSymIv(channel->channelContext, &remoteIv);
  136. if(retval != UA_STATUSCODE_GOOD)
  137. return retval;
  138. /* Local keys */
  139. retval = symmetricModule->generateKey(securityPolicy, &channel->remoteNonce,
  140. &channel->localNonce, &buffer);
  141. if(retval != UA_STATUSCODE_GOOD)
  142. return retval;
  143. const UA_ByteString localSigningKey = {symmetricModule->signingKeyLength, buffer.data};
  144. const UA_ByteString localEncryptingKey = {encryptionKeyLength,
  145. buffer.data + symmetricModule->signingKeyLength};
  146. const UA_ByteString localIv = {symmetricModule->encryptionBlockSize,
  147. buffer.data + symmetricModule->signingKeyLength +
  148. encryptionKeyLength};
  149. retval = channelModule->setLocalSymSigningKey(channel->channelContext, &localSigningKey);
  150. retval |= channelModule->setLocalSymEncryptingKey(channel->channelContext, &localEncryptingKey);
  151. retval |= channelModule->setLocalSymIv(channel->channelContext, &localIv);
  152. return retval;
  153. }
  154. void
  155. UA_SecureChannel_attachSession(UA_SecureChannel *channel, UA_Session *session) {
  156. struct SessionEntry *se = (struct SessionEntry *) UA_malloc(sizeof(struct SessionEntry));
  157. if(!se)
  158. return;
  159. se->session = session;
  160. if(UA_atomic_cmpxchg((void **) &session->channel, NULL, channel) != NULL) {
  161. UA_free(se);
  162. return;
  163. }
  164. LIST_INSERT_HEAD(&channel->sessions, se, pointers);
  165. }
  166. void
  167. UA_SecureChannel_detachSession(UA_SecureChannel *channel, UA_Session *session) {
  168. if(session)
  169. session->channel = NULL;
  170. struct SessionEntry *se;
  171. LIST_FOREACH(se, &channel->sessions, pointers) {
  172. if(se->session == session)
  173. break;
  174. }
  175. if(!se)
  176. return;
  177. LIST_REMOVE(se, pointers);
  178. UA_free(se);
  179. }
  180. UA_Session *
  181. UA_SecureChannel_getSession(UA_SecureChannel *channel, UA_NodeId *token) {
  182. struct SessionEntry *se;
  183. LIST_FOREACH(se, &channel->sessions, pointers) {
  184. if(UA_NodeId_equal(&se->session->authenticationToken, token))
  185. break;
  186. }
  187. if(!se)
  188. return NULL;
  189. return se->session;
  190. }
  191. UA_StatusCode
  192. UA_SecureChannel_revolveTokens(UA_SecureChannel *channel) {
  193. if(channel->nextSecurityToken.tokenId == 0) // no security token issued
  194. return UA_STATUSCODE_BADSECURECHANNELTOKENUNKNOWN;
  195. //FIXME: not thread-safe
  196. memcpy(&channel->securityToken, &channel->nextSecurityToken,
  197. sizeof(UA_ChannelSecurityToken));
  198. UA_ChannelSecurityToken_init(&channel->nextSecurityToken);
  199. return UA_SecureChannel_generateNewKeys(channel);
  200. }
  201. /***************************/
  202. /* Send Asymmetric Message */
  203. /***************************/
  204. static UA_UInt16
  205. calculatePaddingAsym(const UA_SecurityPolicy *securityPolicy, const void *channelContext,
  206. size_t bytesToWrite, UA_Byte *paddingSize, UA_Byte *extraPaddingSize) {
  207. size_t plainTextBlockSize = securityPolicy->channelModule.
  208. getRemoteAsymPlainTextBlockSize(channelContext);
  209. size_t signatureSize = securityPolicy->asymmetricModule.cryptoModule.
  210. getLocalSignatureSize(securityPolicy, channelContext);
  211. size_t padding = (plainTextBlockSize - ((bytesToWrite + signatureSize + 1) % plainTextBlockSize));
  212. *paddingSize = (UA_Byte) padding;
  213. *extraPaddingSize = (UA_Byte) (padding >> 8);
  214. return (UA_UInt16) padding;
  215. }
  216. static size_t
  217. calculateAsymAlgSecurityHeaderLength(const UA_SecureChannel *channel) {
  218. size_t asymHeaderLength = UA_ASYMMETRIC_ALG_SECURITY_HEADER_FIXED_LENGTH +
  219. channel->securityPolicy->policyUri.length;
  220. if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN ||
  221. channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) {
  222. // OPN is always encrypted even if mode sign only
  223. asymHeaderLength += 20; /* Thumbprints are always 20 byte long */
  224. asymHeaderLength += channel->securityPolicy->localCertificate.length;
  225. }
  226. return asymHeaderLength;
  227. }
  228. static void
  229. hideBytesAsym(UA_SecureChannel *const channel, UA_Byte **const buf_start,
  230. const UA_Byte **const buf_end) {
  231. const UA_SecurityPolicy *const securityPolicy = channel->securityPolicy;
  232. *buf_start += UA_SECURE_CONVERSATION_MESSAGE_HEADER_LENGTH + UA_SEQUENCE_HEADER_LENGTH;
  233. /* Add the SecurityHeaderLength */
  234. *buf_start += calculateAsymAlgSecurityHeaderLength(channel);
  235. size_t potentialEncryptionMaxSize = (size_t) (*buf_end - *buf_start) + UA_SEQUENCE_HEADER_LENGTH;
  236. /* Hide bytes for signature and padding */
  237. if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN ||
  238. channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) {
  239. *buf_end -= securityPolicy->asymmetricModule.cryptoModule.
  240. getLocalSignatureSize(securityPolicy, channel->channelContext);
  241. *buf_end -= 2; // padding byte and extraPadding byte
  242. /* Add some overhead length due to RSA implementations adding a signature themselves */
  243. *buf_end -= securityPolicy->channelModule
  244. .getRemoteAsymEncryptionBufferLengthOverhead(channel->channelContext,
  245. potentialEncryptionMaxSize);
  246. }
  247. }
  248. /* Sends an OPN message using asymmetric encryption if defined */
  249. UA_StatusCode
  250. UA_SecureChannel_sendAsymmetricOPNMessage(UA_SecureChannel *channel, UA_UInt32 requestId,
  251. const void *content, const UA_DataType *contentType) {
  252. const UA_SecurityPolicy *const securityPolicy = channel->securityPolicy;
  253. UA_Connection *connection = channel->connection;
  254. if(!connection)
  255. return UA_STATUSCODE_BADINTERNALERROR;
  256. /* Allocate the message buffer */
  257. UA_ByteString buf = UA_BYTESTRING_NULL;
  258. UA_StatusCode retval =
  259. connection->getSendBuffer(connection, connection->localConf.sendBufferSize, &buf);
  260. if(retval != UA_STATUSCODE_GOOD)
  261. return retval;
  262. /* Restrict buffer to the available space for the payload */
  263. UA_Byte *buf_pos = buf.data;
  264. const UA_Byte *buf_end = &buf.data[buf.length];
  265. hideBytesAsym(channel, &buf_pos, &buf_end);
  266. /* Encode the message type and content */
  267. UA_NodeId typeId = UA_NODEID_NUMERIC(0, contentType->binaryEncodingId);
  268. retval = UA_encodeBinary(&typeId, &UA_TYPES[UA_TYPES_NODEID],
  269. &buf_pos, &buf_end, NULL, NULL);
  270. retval |= UA_encodeBinary(content, contentType, &buf_pos, &buf_end, NULL, NULL);
  271. if(retval != UA_STATUSCODE_GOOD) {
  272. connection->releaseSendBuffer(connection, &buf);
  273. return retval;
  274. }
  275. /* Compute the length of the asym header */
  276. const size_t securityHeaderLength = calculateAsymAlgSecurityHeaderLength(channel);
  277. /* Pad the message. Also if securitymode is only sign, since we are using
  278. * asymmetric communication to exchange keys and thus need to encrypt. */
  279. if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN ||
  280. channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) {
  281. const UA_Byte *buf_body_start =
  282. &buf.data[UA_SECURE_CONVERSATION_MESSAGE_HEADER_LENGTH +
  283. UA_SEQUENCE_HEADER_LENGTH + securityHeaderLength];
  284. const size_t bytesToWrite =
  285. (uintptr_t) buf_pos - (uintptr_t) buf_body_start + UA_SEQUENCE_HEADER_LENGTH;
  286. UA_Byte paddingSize = 0;
  287. UA_Byte extraPaddingSize = 0;
  288. UA_UInt16 totalPaddingSize =
  289. calculatePaddingAsym(securityPolicy, channel->channelContext,
  290. bytesToWrite, &paddingSize, &extraPaddingSize);
  291. // This is <= because the paddingSize byte also has to be written.
  292. for(UA_UInt16 i = 0; i <= totalPaddingSize; ++i) {
  293. *buf_pos = paddingSize;
  294. ++buf_pos;
  295. }
  296. if(extraPaddingSize > 0) {
  297. *buf_pos = extraPaddingSize;
  298. ++buf_pos;
  299. }
  300. }
  301. /* The total message length */
  302. size_t pre_sig_length = (uintptr_t) buf_pos - (uintptr_t) buf.data;
  303. size_t total_length = pre_sig_length;
  304. if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN ||
  305. channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT)
  306. total_length += securityPolicy->asymmetricModule.cryptoModule.
  307. getLocalSignatureSize(securityPolicy, channel->channelContext);
  308. /* Encode the headers at the beginning of the message */
  309. UA_Byte *header_pos = buf.data;
  310. size_t dataToEncryptLength =
  311. total_length - (UA_SECURE_CONVERSATION_MESSAGE_HEADER_LENGTH + securityHeaderLength);
  312. UA_SecureConversationMessageHeader respHeader;
  313. respHeader.messageHeader.messageTypeAndChunkType = UA_MESSAGETYPE_OPN + UA_CHUNKTYPE_FINAL;
  314. respHeader.messageHeader.messageSize = (UA_UInt32)
  315. (total_length + securityPolicy->channelModule.
  316. getRemoteAsymEncryptionBufferLengthOverhead(channel->channelContext, dataToEncryptLength));
  317. respHeader.secureChannelId = channel->securityToken.channelId;
  318. retval = UA_encodeBinary(&respHeader, &UA_TRANSPORT[UA_TRANSPORT_SECURECONVERSATIONMESSAGEHEADER],
  319. &header_pos, &buf_end, NULL, NULL);
  320. UA_AsymmetricAlgorithmSecurityHeader asymHeader;
  321. UA_AsymmetricAlgorithmSecurityHeader_init(&asymHeader);
  322. asymHeader.securityPolicyUri = channel->securityPolicy->policyUri;
  323. if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN ||
  324. channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) {
  325. asymHeader.senderCertificate = channel->securityPolicy->localCertificate;
  326. asymHeader.receiverCertificateThumbprint.length = 20;
  327. asymHeader.receiverCertificateThumbprint.data = channel->remoteCertificateThumbprint;
  328. }
  329. retval |= UA_encodeBinary(&asymHeader, &UA_TRANSPORT[UA_TRANSPORT_ASYMMETRICALGORITHMSECURITYHEADER],
  330. &header_pos, &buf_end, NULL, NULL);
  331. UA_SequenceHeader seqHeader;
  332. seqHeader.requestId = requestId;
  333. seqHeader.sequenceNumber = UA_atomic_add(&channel->sendSequenceNumber, 1);
  334. retval |= UA_encodeBinary(&seqHeader, &UA_TRANSPORT[UA_TRANSPORT_SEQUENCEHEADER],
  335. &header_pos, &buf_end, NULL, NULL);
  336. /* Did encoding the header succeed? */
  337. if(retval != UA_STATUSCODE_GOOD) {
  338. connection->releaseSendBuffer(connection, &buf);
  339. return retval;
  340. }
  341. if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN ||
  342. channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) {
  343. /* Sign message */
  344. const UA_ByteString dataToSign = {pre_sig_length, buf.data};
  345. size_t sigsize = securityPolicy->asymmetricModule.cryptoModule.
  346. getLocalSignatureSize(securityPolicy, channel->channelContext);
  347. UA_ByteString signature = {sigsize, buf.data + pre_sig_length};
  348. retval = securityPolicy->asymmetricModule.cryptoModule.
  349. sign(securityPolicy, channel->channelContext, &dataToSign, &signature);
  350. if(retval != UA_STATUSCODE_GOOD) {
  351. connection->releaseSendBuffer(connection, &buf);
  352. return retval;
  353. }
  354. /* Specification part 6, 6.7.4: The OpenSecureChannel Messages are
  355. * signed and encrypted if the SecurityMode is not None (even if the
  356. * SecurityMode is SignOnly). */
  357. size_t unencrypted_length =
  358. UA_SECURE_CONVERSATION_MESSAGE_HEADER_LENGTH + securityHeaderLength;
  359. UA_ByteString dataToEncrypt = {total_length - unencrypted_length,
  360. &buf.data[unencrypted_length]};
  361. retval = securityPolicy->asymmetricModule.cryptoModule.
  362. encrypt(securityPolicy, channel->channelContext, &dataToEncrypt);
  363. if(retval != UA_STATUSCODE_GOOD) {
  364. connection->releaseSendBuffer(connection, &buf);
  365. return retval;
  366. }
  367. }
  368. /* Send the message, the buffer is freed in the network layer */
  369. buf.length = respHeader.messageHeader.messageSize;
  370. retval = connection->send(connection, &buf);
  371. #ifdef UA_ENABLE_UNIT_TEST_FAILURE_HOOKS
  372. retval |= sendAsym_sendFailure
  373. #endif
  374. return retval;
  375. }
  376. /**************************/
  377. /* Send Symmetric Message */
  378. /**************************/
  379. static UA_UInt16
  380. calculatePaddingSym(const UA_SecurityPolicy *securityPolicy, const void *channelContext,
  381. size_t bytesToWrite, UA_Byte *paddingSize, UA_Byte *extraPaddingSize) {
  382. UA_UInt16 padding = (UA_UInt16) (securityPolicy->symmetricModule.encryptionBlockSize -
  383. ((bytesToWrite + securityPolicy->symmetricModule.cryptoModule.
  384. getLocalSignatureSize(securityPolicy, channelContext) + 1) %
  385. securityPolicy->symmetricModule.encryptionBlockSize));
  386. *paddingSize = (UA_Byte) padding;
  387. *extraPaddingSize = (UA_Byte) (padding >> 8);
  388. return padding;
  389. }
  390. /* Sends a message using symmetric encryption if defined
  391. *
  392. * @param ci the chunk information that is used to send the chunk.
  393. * @param buf_pos the position in the send buffer after the body was encoded.
  394. * Should be less than or equal to buf_end.
  395. * @param buf_end the maximum position of the body. */
  396. static UA_StatusCode
  397. sendChunkSymmetric(UA_ChunkInfo *ci, UA_Byte **buf_pos, const UA_Byte **buf_end) {
  398. UA_StatusCode res = UA_STATUSCODE_GOOD;
  399. UA_SecureChannel *const channel = ci->channel;
  400. const UA_SecurityPolicy *securityPolicy = channel->securityPolicy;
  401. UA_Connection *const connection = channel->connection;
  402. if(!connection)
  403. return UA_STATUSCODE_BADINTERNALERROR;
  404. /* Will this chunk surpass the capacity of the SecureChannel for the message? */
  405. UA_Byte *buf_body_start = ci->messageBuffer.data + UA_SECURE_MESSAGE_HEADER_LENGTH;
  406. UA_Byte *buf_body_end = *buf_pos;
  407. size_t bodyLength = (uintptr_t) buf_body_end - (uintptr_t) buf_body_start;
  408. ci->messageSizeSoFar += bodyLength;
  409. ci->chunksSoFar++;
  410. if(ci->messageSizeSoFar > connection->remoteConf.maxMessageSize &&
  411. connection->remoteConf.maxMessageSize != 0)
  412. res = UA_STATUSCODE_BADRESPONSETOOLARGE;
  413. if(ci->chunksSoFar > connection->remoteConf.maxChunkCount &&
  414. connection->remoteConf.maxChunkCount != 0)
  415. res = UA_STATUSCODE_BADRESPONSETOOLARGE;
  416. if(res != UA_STATUSCODE_GOOD) {
  417. connection->releaseSendBuffer(channel->connection, &ci->messageBuffer);
  418. return res;
  419. }
  420. /* Pad the message. The bytes for the padding and signature were removed
  421. * from buf_end before encoding the payload. So we don't check here. */
  422. if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) {
  423. size_t bytesToWrite = bodyLength + UA_SEQUENCE_HEADER_LENGTH;
  424. UA_Byte paddingSize = 0;
  425. UA_Byte extraPaddingSize = 0;
  426. UA_UInt16 totalPaddingSize =
  427. calculatePaddingSym(securityPolicy, channel->channelContext,
  428. bytesToWrite, &paddingSize, &extraPaddingSize);
  429. // This is <= because the paddingSize byte also has to be written.
  430. for(UA_UInt16 i = 0; i <= totalPaddingSize; ++i) {
  431. **buf_pos = paddingSize;
  432. ++(*buf_pos);
  433. }
  434. if(extraPaddingSize > 0) {
  435. **buf_pos = extraPaddingSize;
  436. ++(*buf_pos);
  437. }
  438. }
  439. /* The total message length */
  440. size_t pre_sig_length = (uintptr_t) (*buf_pos) - (uintptr_t) ci->messageBuffer.data;
  441. size_t total_length = pre_sig_length;
  442. if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN ||
  443. channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT)
  444. total_length += securityPolicy->symmetricModule.cryptoModule.
  445. getLocalSignatureSize(securityPolicy, channel->channelContext);
  446. /* Encode the chunk headers at the beginning of the buffer */
  447. UA_assert(res == UA_STATUSCODE_GOOD);
  448. UA_Byte *header_pos = ci->messageBuffer.data;
  449. UA_SecureConversationMessageHeader respHeader;
  450. respHeader.secureChannelId = channel->securityToken.channelId;
  451. respHeader.messageHeader.messageTypeAndChunkType = ci->messageType;
  452. respHeader.messageHeader.messageSize = (UA_UInt32) total_length;
  453. if(ci->final)
  454. respHeader.messageHeader.messageTypeAndChunkType += UA_CHUNKTYPE_FINAL;
  455. else
  456. respHeader.messageHeader.messageTypeAndChunkType += UA_CHUNKTYPE_INTERMEDIATE;
  457. res = UA_encodeBinary(&respHeader, &UA_TRANSPORT[UA_TRANSPORT_SECURECONVERSATIONMESSAGEHEADER],
  458. &header_pos, buf_end, NULL, NULL);
  459. UA_SymmetricAlgorithmSecurityHeader symSecHeader;
  460. symSecHeader.tokenId = channel->securityToken.tokenId;
  461. res |= UA_encodeBinary(&symSecHeader.tokenId,
  462. &UA_TRANSPORT[UA_TRANSPORT_SYMMETRICALGORITHMSECURITYHEADER],
  463. &header_pos, buf_end, NULL, NULL);
  464. UA_SequenceHeader seqHeader;
  465. seqHeader.requestId = ci->requestId;
  466. seqHeader.sequenceNumber = UA_atomic_add(&channel->sendSequenceNumber, 1);
  467. res |= UA_encodeBinary(&seqHeader, &UA_TRANSPORT[UA_TRANSPORT_SEQUENCEHEADER],
  468. &header_pos, buf_end, NULL, NULL);
  469. /* Sign message */
  470. if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN ||
  471. channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) {
  472. UA_ByteString dataToSign = ci->messageBuffer;
  473. dataToSign.length = pre_sig_length;
  474. UA_ByteString signature;
  475. signature.length = securityPolicy->symmetricModule.cryptoModule.
  476. getLocalSignatureSize(securityPolicy, channel->channelContext);
  477. signature.data = *buf_pos;
  478. res |= securityPolicy->symmetricModule.cryptoModule.
  479. sign(securityPolicy, channel->channelContext, &dataToSign, &signature);
  480. }
  481. /* Encrypt message */
  482. if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) {
  483. UA_ByteString dataToEncrypt;
  484. dataToEncrypt.data = ci->messageBuffer.data + UA_SECUREMH_AND_SYMALGH_LENGTH;
  485. dataToEncrypt.length = total_length - UA_SECUREMH_AND_SYMALGH_LENGTH;
  486. res |= securityPolicy->symmetricModule.cryptoModule.
  487. encrypt(securityPolicy, channel->channelContext, &dataToEncrypt);
  488. }
  489. if(res != UA_STATUSCODE_GOOD) {
  490. connection->releaseSendBuffer(channel->connection, &ci->messageBuffer);
  491. return res;
  492. }
  493. /* Send the chunk, the buffer is freed in the network layer */
  494. ci->messageBuffer.length = respHeader.messageHeader.messageSize;
  495. res = connection->send(channel->connection, &ci->messageBuffer);
  496. if(res != UA_STATUSCODE_GOOD)
  497. return res;
  498. /* Replace with the buffer for the next chunk */
  499. if(!ci->final) {
  500. res = connection->getSendBuffer(connection, connection->localConf.sendBufferSize,
  501. &ci->messageBuffer);
  502. if(res != UA_STATUSCODE_GOOD)
  503. return res;
  504. /* Forward the data pointer so that the payload is encoded after the
  505. * message header */
  506. *buf_pos = &ci->messageBuffer.data[UA_SECURE_MESSAGE_HEADER_LENGTH];
  507. *buf_end = &ci->messageBuffer.data[ci->messageBuffer.length];
  508. if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN ||
  509. channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT)
  510. *buf_end -= securityPolicy->symmetricModule.cryptoModule.
  511. getLocalSignatureSize(securityPolicy, channel->channelContext);
  512. /* Hide a byte needed for padding */
  513. if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT)
  514. *buf_end -= 2;
  515. }
  516. return res;
  517. }
  518. UA_StatusCode
  519. UA_SecureChannel_sendSymmetricMessage(UA_SecureChannel *channel, UA_UInt32 requestId,
  520. UA_MessageType messageType, const void *content,
  521. const UA_DataType *contentType) {
  522. const UA_SecurityPolicy *const securityPolicy = channel->securityPolicy;
  523. UA_Connection *connection = channel->connection;
  524. if(!connection)
  525. return UA_STATUSCODE_BADINTERNALERROR;
  526. /* Minimum required size */
  527. if(connection->localConf.sendBufferSize <= UA_SECURE_MESSAGE_HEADER_LENGTH)
  528. return UA_STATUSCODE_BADRESPONSETOOLARGE;
  529. /* Create the chunking info structure */
  530. UA_ChunkInfo ci;
  531. ci.channel = channel;
  532. ci.requestId = requestId;
  533. ci.chunksSoFar = 0;
  534. ci.messageSizeSoFar = 0;
  535. ci.final = false;
  536. ci.messageBuffer = UA_BYTESTRING_NULL;
  537. ci.messageType = messageType;
  538. /* Allocate the message buffer */
  539. UA_StatusCode retval =
  540. connection->getSendBuffer(connection, connection->localConf.sendBufferSize,
  541. &ci.messageBuffer);
  542. if(retval != UA_STATUSCODE_GOOD)
  543. return retval;
  544. /* Hide the message beginning where the header will be encoded */
  545. UA_Byte *buf_start = &ci.messageBuffer.data[UA_SECURE_MESSAGE_HEADER_LENGTH];
  546. const UA_Byte *buf_end = &ci.messageBuffer.data[ci.messageBuffer.length];
  547. /* Hide bytes for signature */
  548. if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN ||
  549. channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT)
  550. buf_end -= securityPolicy->symmetricModule.cryptoModule.
  551. getLocalSignatureSize(securityPolicy, channel->channelContext);
  552. /* Hide one byte for padding */
  553. if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT)
  554. buf_end -= 2;
  555. /* Encode the message type */
  556. UA_NodeId typeId = UA_NODEID_NUMERIC(0, contentType->binaryEncodingId);
  557. retval = UA_encodeBinary(&typeId, &UA_TYPES[UA_TYPES_NODEID],
  558. &buf_start, &buf_end, NULL, NULL);
  559. /* Encode with the chunking callback */
  560. retval |= UA_encodeBinary(content, contentType, &buf_start, &buf_end,
  561. (UA_exchangeEncodeBuffer) sendChunkSymmetric, &ci);
  562. /* TODO: Error handling. Send out an abort chunk if this is not the first chunk.
  563. * If this is the first chunk of the message:
  564. * - Client: Do nothing, maybe revert the sequence number?
  565. * - Server: Send a ServiceFault response? Depending on which error codes? */
  566. if(retval != UA_STATUSCODE_GOOD) {
  567. /* the abort message was not sent */
  568. if(!ci.final)
  569. sendChunkSymmetric(&ci, &buf_start, &buf_end);
  570. connection->releaseSendBuffer(connection, &ci.messageBuffer);
  571. return retval;
  572. }
  573. /* Encoding finished, send the final chunk */
  574. ci.final = UA_TRUE;
  575. return sendChunkSymmetric(&ci, &buf_start, &buf_end);
  576. }
  577. /*****************************/
  578. /* Assemble Complete Message */
  579. /*****************************/
  580. static void
  581. UA_SecureChannel_removeChunks(UA_SecureChannel *channel, UA_UInt32 requestId) {
  582. struct ChunkEntry *ch;
  583. LIST_FOREACH(ch, &channel->chunks, pointers) {
  584. if(ch->requestId == requestId) {
  585. UA_ByteString_deleteMembers(&ch->bytes);
  586. LIST_REMOVE(ch, pointers);
  587. UA_free(ch);
  588. return;
  589. }
  590. }
  591. }
  592. static UA_StatusCode
  593. appendChunk(struct ChunkEntry *const chunkEntry, const UA_ByteString *const chunkBody) {
  594. UA_Byte *new_bytes = (UA_Byte *)
  595. UA_realloc(chunkEntry->bytes.data, chunkEntry->bytes.length + chunkBody->length);
  596. if(!new_bytes) {
  597. UA_ByteString_deleteMembers(&chunkEntry->bytes);
  598. return UA_STATUSCODE_BADOUTOFMEMORY;
  599. }
  600. chunkEntry->bytes.data = new_bytes;
  601. memcpy(&chunkEntry->bytes.data[chunkEntry->bytes.length], chunkBody->data, chunkBody->length);
  602. chunkEntry->bytes.length += chunkBody->length;
  603. return UA_STATUSCODE_GOOD;
  604. }
  605. static UA_StatusCode
  606. UA_SecureChannel_appendChunk(UA_SecureChannel *channel, UA_UInt32 requestId,
  607. const UA_ByteString *chunkBody) {
  608. struct ChunkEntry *ch;
  609. LIST_FOREACH(ch, &channel->chunks, pointers) {
  610. if(ch->requestId == requestId)
  611. break;
  612. }
  613. /* No chunkentry on the channel, create one */
  614. if(!ch) {
  615. ch = (struct ChunkEntry *) UA_malloc(sizeof(struct ChunkEntry));
  616. if(!ch)
  617. return UA_STATUSCODE_BADOUTOFMEMORY;
  618. ch->requestId = requestId;
  619. UA_ByteString_init(&ch->bytes);
  620. LIST_INSERT_HEAD(&channel->chunks, ch, pointers);
  621. }
  622. return appendChunk(ch, chunkBody);
  623. }
  624. static UA_StatusCode
  625. UA_SecureChannel_finalizeChunk(UA_SecureChannel *channel, UA_UInt32 requestId,
  626. const UA_ByteString *const chunkBody, UA_MessageType messageType,
  627. UA_ProcessMessageCallback callback, void *application) {
  628. struct ChunkEntry *chunkEntry;
  629. LIST_FOREACH(chunkEntry, &channel->chunks, pointers) {
  630. if(chunkEntry->requestId == requestId)
  631. break;
  632. }
  633. UA_ByteString bytes;
  634. if(!chunkEntry) {
  635. bytes = *chunkBody;
  636. } else {
  637. UA_StatusCode retval = appendChunk(chunkEntry, chunkBody);
  638. if(retval != UA_STATUSCODE_GOOD)
  639. return retval;
  640. bytes = chunkEntry->bytes;
  641. LIST_REMOVE(chunkEntry, pointers);
  642. UA_free(chunkEntry);
  643. }
  644. UA_StatusCode retval = callback(application, channel, messageType, requestId, &bytes);
  645. if(chunkEntry)
  646. UA_ByteString_deleteMembers(&bytes);
  647. return retval;
  648. }
  649. /****************************/
  650. /* Process a received Chunk */
  651. /****************************/
  652. static UA_StatusCode
  653. decryptChunk(UA_SecureChannel *channel, const UA_SecurityPolicyCryptoModule *cryptoModule,
  654. UA_ByteString *chunk, size_t offset, UA_UInt32 *requestId,
  655. UA_UInt32 *sequenceNumber, UA_ByteString *payload,
  656. UA_MessageType messageType) {
  657. UA_StatusCode retval = UA_STATUSCODE_GOOD;
  658. const UA_SecurityPolicy *securityPolicy = channel->securityPolicy;
  659. size_t chunkSizeAfterDecryption = chunk->length;
  660. if(cryptoModule == NULL)
  661. return UA_STATUSCODE_BADINTERNALERROR;
  662. /* Decrypt the chunk. Always decrypt opn messages if mode not none */
  663. if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT ||
  664. messageType == UA_MESSAGETYPE_OPN) {
  665. UA_ByteString cipherText = {chunk->length - offset, chunk->data + offset};
  666. size_t sizeBeforeDecryption = cipherText.length;
  667. retval = cryptoModule->decrypt(securityPolicy, channel->channelContext, &cipherText);
  668. chunkSizeAfterDecryption -= (sizeBeforeDecryption - cipherText.length);
  669. if(retval != UA_STATUSCODE_GOOD)
  670. return retval;
  671. }
  672. /* Verify the chunk signature */
  673. size_t sigsize = 0;
  674. size_t paddingSize = 0;
  675. if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN ||
  676. channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT ||
  677. messageType == UA_MESSAGETYPE_OPN) {
  678. /* Compute the padding size */
  679. sigsize = cryptoModule->
  680. getRemoteSignatureSize(securityPolicy, channel->channelContext);
  681. if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT ||
  682. (messageType == UA_MESSAGETYPE_OPN &&
  683. channel->securityMode != UA_MESSAGESECURITYMODE_NONE)) {
  684. paddingSize = chunk->data[chunkSizeAfterDecryption - sigsize - 1];
  685. size_t keyLength = cryptoModule->
  686. getRemoteEncryptionKeyLength(securityPolicy, channel->channelContext);
  687. if(keyLength > 2048) {
  688. paddingSize <<= 8; /* Extra padding size */
  689. paddingSize += chunk->data[chunkSizeAfterDecryption - sigsize - 2];
  690. }
  691. }
  692. if(offset + paddingSize + sigsize >= chunkSizeAfterDecryption)
  693. return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
  694. /* Verify the signature */
  695. const UA_ByteString chunkDataToVerify = {chunkSizeAfterDecryption - sigsize, chunk->data};
  696. const UA_ByteString signature = {sigsize, chunk->data + chunkSizeAfterDecryption - sigsize};
  697. retval = cryptoModule->verify(securityPolicy, channel->channelContext,
  698. &chunkDataToVerify, &signature);
  699. #ifdef UA_ENABLE_UNIT_TEST_FAILURE_HOOKS
  700. retval |= decrypt_verifySignatureFailure;
  701. #endif
  702. if(retval != UA_STATUSCODE_GOOD)
  703. return retval;
  704. }
  705. /* Decode the sequence header */
  706. UA_SequenceHeader sequenceHeader;
  707. retval = UA_SequenceHeader_decodeBinary(chunk, &offset, &sequenceHeader);
  708. if(retval != UA_STATUSCODE_GOOD)
  709. return retval;
  710. if(offset + paddingSize + sigsize >= chunk->length)
  711. return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
  712. *requestId = sequenceHeader.requestId;
  713. *sequenceNumber = sequenceHeader.sequenceNumber;
  714. payload->data = chunk->data + offset;
  715. payload->length = chunkSizeAfterDecryption - offset - sigsize - paddingSize;
  716. return UA_STATUSCODE_GOOD;
  717. }
  718. typedef UA_StatusCode(*UA_SequenceNumberCallback)(UA_SecureChannel *channel,
  719. UA_UInt32 sequenceNumber);
  720. static UA_StatusCode
  721. processSequenceNumberAsym(UA_SecureChannel *const channel, UA_UInt32 sequenceNumber) {
  722. channel->receiveSequenceNumber = sequenceNumber;
  723. return UA_STATUSCODE_GOOD;
  724. }
  725. // TODO: We somehow need to make sure that a sequence number is never reused for the same tokenId
  726. static UA_StatusCode
  727. processSequenceNumberSym(UA_SecureChannel *const channel, UA_UInt32 sequenceNumber) {
  728. /* Failure mode hook for unit tests */
  729. #ifdef UA_ENABLE_UNIT_TEST_FAILURE_HOOKS
  730. if(processSym_seqNumberFailure != UA_STATUSCODE_GOOD)
  731. return processSym_seqNumberFailure;
  732. #endif
  733. /* Does the sequence number match? */
  734. if(sequenceNumber != channel->receiveSequenceNumber + 1) {
  735. if(channel->receiveSequenceNumber + 1 > 4294966271 && sequenceNumber < 1024) // FIXME: Remove magic numbers :(
  736. channel->receiveSequenceNumber = sequenceNumber - 1; /* Roll over */
  737. else
  738. return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
  739. }
  740. ++channel->receiveSequenceNumber;
  741. return UA_STATUSCODE_GOOD;
  742. }
  743. static UA_StatusCode
  744. checkAsymHeader(UA_SecureChannel *const channel,
  745. UA_AsymmetricAlgorithmSecurityHeader *const asymHeader) {
  746. UA_StatusCode retval = UA_STATUSCODE_GOOD;
  747. const UA_SecurityPolicy *const securityPolicy = channel->securityPolicy;
  748. if(!UA_ByteString_equal(&securityPolicy->policyUri, &asymHeader->securityPolicyUri)) {
  749. return UA_STATUSCODE_BADSECURITYPOLICYREJECTED;
  750. }
  751. // TODO: Verify certificate using certificate plugin. This will come with a new PR
  752. /* Something like this
  753. retval = certificateManager->verify(certificateStore??, &asymHeader->senderCertificate);
  754. if(retval != UA_STATUSCODE_GOOD)
  755. return retval;
  756. */
  757. retval = securityPolicy->asymmetricModule.
  758. compareCertificateThumbprint(securityPolicy, &asymHeader->receiverCertificateThumbprint);
  759. if(retval != UA_STATUSCODE_GOOD) {
  760. return retval;
  761. }
  762. return UA_STATUSCODE_GOOD;
  763. }
  764. static UA_StatusCode
  765. checkSymHeader(UA_SecureChannel *const channel,
  766. const UA_UInt32 tokenId) {
  767. if(tokenId != channel->securityToken.tokenId) {
  768. if(tokenId != channel->nextSecurityToken.tokenId)
  769. return UA_STATUSCODE_BADSECURECHANNELTOKENUNKNOWN;
  770. return UA_SecureChannel_revolveTokens(channel);
  771. }
  772. return UA_STATUSCODE_GOOD;
  773. }
  774. UA_StatusCode
  775. UA_SecureChannel_processChunk(UA_SecureChannel *channel, UA_ByteString *chunk,
  776. UA_ProcessMessageCallback callback,
  777. void *application) {
  778. /* Decode message header */
  779. size_t offset = 0;
  780. UA_SecureConversationMessageHeader messageHeader;
  781. UA_StatusCode retval =
  782. UA_SecureConversationMessageHeader_decodeBinary(chunk, &offset, &messageHeader);
  783. if(retval != UA_STATUSCODE_GOOD)
  784. return retval;
  785. #if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
  786. /* The wrong ChannelId. Non-opened channels have the id zero. */
  787. if(messageHeader.secureChannelId != channel->securityToken.channelId &&
  788. channel->state != UA_SECURECHANNELSTATE_FRESH)
  789. return UA_STATUSCODE_BADSECURECHANNELIDINVALID;
  790. #endif
  791. UA_MessageType messageType = (UA_MessageType)
  792. (messageHeader.messageHeader.messageTypeAndChunkType & UA_BITMASK_MESSAGETYPE);
  793. UA_ChunkType chunkType = (UA_ChunkType)
  794. (messageHeader.messageHeader.messageTypeAndChunkType & UA_BITMASK_CHUNKTYPE);
  795. /* ERR message (not encrypted) */
  796. UA_UInt32 requestId = 0;
  797. UA_UInt32 sequenceNumber = 0;
  798. UA_ByteString chunkPayload;
  799. const UA_SecurityPolicyCryptoModule *cryptoModule = NULL;
  800. UA_SequenceNumberCallback sequenceNumberCallback = NULL;
  801. switch(messageType) {
  802. case UA_MESSAGETYPE_ERR: {
  803. if(chunkType != UA_CHUNKTYPE_FINAL)
  804. return UA_STATUSCODE_BADTCPMESSAGETYPEINVALID;
  805. chunkPayload.length = chunk->length - offset;
  806. chunkPayload.data = chunk->data + offset;
  807. return callback(application, channel, messageType, requestId, &chunkPayload);
  808. }
  809. case UA_MESSAGETYPE_MSG:
  810. case UA_MESSAGETYPE_CLO: {
  811. /* Decode and check the symmetric security header (tokenId) */
  812. UA_SymmetricAlgorithmSecurityHeader symmetricSecurityHeader;
  813. UA_SymmetricAlgorithmSecurityHeader_init(&symmetricSecurityHeader);
  814. retval = UA_SymmetricAlgorithmSecurityHeader_decodeBinary(chunk, &offset,
  815. &symmetricSecurityHeader);
  816. if(retval != UA_STATUSCODE_GOOD)
  817. return retval;
  818. #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
  819. // let's help fuzzing by setting the correct tokenId
  820. symmetricSecurityHeader.tokenId = channel->securityToken.tokenId;
  821. #endif
  822. retval = checkSymHeader(channel, symmetricSecurityHeader.tokenId);
  823. if(retval != UA_STATUSCODE_GOOD)
  824. return retval;
  825. cryptoModule = &channel->securityPolicy->symmetricModule.cryptoModule;
  826. sequenceNumberCallback = processSequenceNumberSym;
  827. break;
  828. }
  829. case UA_MESSAGETYPE_OPN: {
  830. /* Chunking not allowed for OPN */
  831. if(chunkType != UA_CHUNKTYPE_FINAL)
  832. return UA_STATUSCODE_BADTCPMESSAGETYPEINVALID;
  833. // Decode the asymmetric algorithm security header and
  834. // call the callback to perform checks.
  835. UA_AsymmetricAlgorithmSecurityHeader asymHeader;
  836. UA_AsymmetricAlgorithmSecurityHeader_init(&asymHeader);
  837. offset = UA_SECURE_CONVERSATION_MESSAGE_HEADER_LENGTH;
  838. retval = UA_AsymmetricAlgorithmSecurityHeader_decodeBinary(chunk,
  839. &offset,
  840. &asymHeader);
  841. if(retval != UA_STATUSCODE_GOOD)
  842. break;
  843. retval = checkAsymHeader(channel, &asymHeader);
  844. UA_AsymmetricAlgorithmSecurityHeader_deleteMembers(&asymHeader);
  845. if(retval != UA_STATUSCODE_GOOD)
  846. break;
  847. cryptoModule = &channel->securityPolicy->asymmetricModule.cryptoModule;
  848. sequenceNumberCallback = processSequenceNumberAsym;
  849. break;
  850. }
  851. default:
  852. return UA_STATUSCODE_BADTCPMESSAGETYPEINVALID;
  853. }
  854. /* Decrypt message */
  855. retval = decryptChunk(channel, cryptoModule, chunk, offset, &requestId,
  856. &sequenceNumber, &chunkPayload, messageType);
  857. if(retval != UA_STATUSCODE_GOOD)
  858. return retval;
  859. /* Check the sequence number */
  860. if(sequenceNumberCallback == NULL)
  861. return UA_STATUSCODE_BADINTERNALERROR;
  862. retval = sequenceNumberCallback(channel, sequenceNumber);
  863. /* Skip sequence number checking for fuzzer to improve coverage */
  864. if(retval != UA_STATUSCODE_GOOD)
  865. #if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
  866. return retval;
  867. #else
  868. retval = UA_STATUSCODE_GOOD;
  869. #endif
  870. /* Process the payload */
  871. if(chunkType == UA_CHUNKTYPE_FINAL) {
  872. retval = UA_SecureChannel_finalizeChunk(channel, requestId, &chunkPayload,
  873. messageType, callback, application);
  874. } else if(chunkType == UA_CHUNKTYPE_INTERMEDIATE) {
  875. retval = UA_SecureChannel_appendChunk(channel, requestId, &chunkPayload);
  876. } else if(chunkType == UA_CHUNKTYPE_ABORT) {
  877. UA_SecureChannel_removeChunks(channel, requestId);
  878. } else {
  879. retval = UA_STATUSCODE_BADTCPMESSAGETYPEINVALID;
  880. }
  881. return retval;
  882. }