ua_securechannel.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #include "ua_util.h"
  2. #include "ua_securechannel.h"
  3. #include "ua_session.h"
  4. #include "ua_statuscodes.h"
  5. #include "ua_types_encoding_binary.h"
  6. void UA_SecureChannel_init(UA_SecureChannel *channel) {
  7. UA_MessageSecurityMode_init(&channel->securityMode);
  8. UA_ChannelSecurityToken_init(&channel->securityToken);
  9. UA_AsymmetricAlgorithmSecurityHeader_init(&channel->clientAsymAlgSettings);
  10. UA_AsymmetricAlgorithmSecurityHeader_init(&channel->serverAsymAlgSettings);
  11. UA_ByteString_init(&channel->clientNonce);
  12. UA_ByteString_init(&channel->serverNonce);
  13. channel->sequenceNumber = 0;
  14. channel->connection = UA_NULL;
  15. LIST_INIT(&channel->sessions);
  16. }
  17. void UA_SecureChannel_deleteMembersCleanup(UA_SecureChannel *channel) {
  18. UA_AsymmetricAlgorithmSecurityHeader_deleteMembers(&channel->serverAsymAlgSettings);
  19. UA_ByteString_deleteMembers(&channel->serverNonce);
  20. UA_AsymmetricAlgorithmSecurityHeader_deleteMembers(&channel->clientAsymAlgSettings);
  21. UA_ByteString_deleteMembers(&channel->clientNonce);
  22. UA_ChannelSecurityToken_deleteMembers(&channel->securityToken);
  23. UA_Connection *c = channel->connection;
  24. if(c) {
  25. UA_Connection_detachSecureChannel(c);
  26. if(c->close)
  27. c->close(c);
  28. }
  29. /* just remove the pointers and free the linked list (not the sessions) */
  30. struct SessionEntry *se;
  31. while((se = LIST_FIRST(&channel->sessions))) {
  32. UA_SecureChannel_detachSession(channel, se->session); /* the se is deleted inside */
  33. }
  34. }
  35. //TODO implement real nonce generator - DUMMY function
  36. UA_StatusCode UA_SecureChannel_generateNonce(UA_ByteString *nonce) {
  37. if(!(nonce->data = UA_malloc(1)))
  38. return UA_STATUSCODE_BADOUTOFMEMORY;
  39. nonce->length = 1;
  40. nonce->data[0] = 'a';
  41. return UA_STATUSCODE_GOOD;
  42. }
  43. void UA_SecureChannel_attachSession(UA_SecureChannel *channel, UA_Session *session) {
  44. struct SessionEntry *se = UA_malloc(sizeof(struct SessionEntry));
  45. if(!se)
  46. return;
  47. se->session = session;
  48. #ifdef UA_MULTITHREADING
  49. if(uatomic_cmpxchg(&session->channel, UA_NULL, channel) != UA_NULL) {
  50. UA_free(se);
  51. return;
  52. }
  53. #else
  54. if(session->channel != UA_NULL) {
  55. UA_free(se);
  56. return;
  57. }
  58. session->channel = channel;
  59. #endif
  60. LIST_INSERT_HEAD(&channel->sessions, se, pointers);
  61. }
  62. void UA_SecureChannel_detachSession(UA_SecureChannel *channel, UA_Session *session) {
  63. if(session)
  64. session->channel = UA_NULL;
  65. struct SessionEntry *se;
  66. LIST_FOREACH(se, &channel->sessions, pointers) {
  67. if(se->session != session)
  68. continue;
  69. LIST_REMOVE(se, pointers);
  70. UA_free(se);
  71. break;
  72. }
  73. }
  74. UA_Session * UA_SecureChannel_getSession(UA_SecureChannel *channel, UA_NodeId *token) {
  75. struct SessionEntry *se;
  76. LIST_FOREACH(se, &channel->sessions, pointers) {
  77. if(UA_NodeId_equal(&se->session->authenticationToken, token))
  78. break;
  79. }
  80. if(!se)
  81. return UA_NULL;
  82. return se->session;
  83. }
  84. UA_StatusCode UA_SecureChannel_sendBinaryMessage(UA_SecureChannel *channel, UA_UInt32 requestId,
  85. const void *content,
  86. const UA_DataType *contentType) {
  87. UA_Connection *connection = channel->connection;
  88. if(!connection)
  89. return UA_STATUSCODE_BADINTERNALERROR;
  90. UA_NodeId typeId = contentType->typeId;
  91. if(typeId.identifierType != UA_NODEIDTYPE_NUMERIC)
  92. return UA_STATUSCODE_BADINTERNALERROR;
  93. typeId.identifier.numeric += UA_ENCODINGOFFSET_BINARY;
  94. UA_SecureConversationMessageHeader respHeader;
  95. respHeader.messageHeader.messageTypeAndFinal = UA_MESSAGETYPEANDFINAL_MSGF;
  96. respHeader.messageHeader.messageSize = 0;
  97. respHeader.secureChannelId = channel->securityToken.channelId;
  98. UA_SymmetricAlgorithmSecurityHeader symSecHeader;
  99. symSecHeader.tokenId = channel->securityToken.tokenId;
  100. UA_SequenceHeader seqHeader;
  101. seqHeader.requestId = requestId;
  102. respHeader.messageHeader.messageSize =
  103. UA_SecureConversationMessageHeader_calcSizeBinary(&respHeader)
  104. + UA_SymmetricAlgorithmSecurityHeader_calcSizeBinary(&symSecHeader)
  105. + UA_SequenceHeader_calcSizeBinary(&seqHeader)
  106. + UA_NodeId_calcSizeBinary(&typeId)
  107. + UA_calcSizeBinary(content, contentType);
  108. UA_ByteString message;
  109. UA_StatusCode retval = connection->getBuffer(connection, &message, respHeader.messageHeader.messageSize);
  110. if(retval)
  111. return retval;
  112. /* do this only now, so the sequence number does not increase if sth fails */
  113. #ifndef UA_MULTITHREADING
  114. seqHeader.sequenceNumber = ++channel->sequenceNumber;
  115. #else
  116. seqHeader.sequenceNumber = uatomic_add_return(&channel->sequenceNumber, 1);
  117. #endif
  118. size_t messagePos = 0;
  119. UA_SecureConversationMessageHeader_encodeBinary(&respHeader, &message, &messagePos);
  120. UA_SymmetricAlgorithmSecurityHeader_encodeBinary(&symSecHeader, &message, &messagePos);
  121. UA_SequenceHeader_encodeBinary(&seqHeader, &message, &messagePos);
  122. UA_NodeId_encodeBinary(&typeId, &message, &messagePos);
  123. UA_encodeBinary(content, contentType, &message, &messagePos);
  124. if(connection->write(connection, &message, respHeader.messageHeader.messageSize) != UA_STATUSCODE_GOOD)
  125. connection->releaseBuffer(connection, &message);
  126. return UA_STATUSCODE_GOOD;
  127. }