ua_securechannel.c 47 KB

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