ua_securechannel.c 41 KB

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