mavlink_secure_command.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /*
  2. mavlink class for handling SECURE_COMMAND messages
  3. */
  4. #include <Arduino.h>
  5. #include "mavlink.h"
  6. #include "board_config.h"
  7. #include "version.h"
  8. #include "parameters.h"
  9. /*
  10. handle a SECURE_COMMAND
  11. */
  12. void MAVLinkSerial::handle_secure_command(const mavlink_secure_command_t &pkt)
  13. {
  14. mavlink_secure_command_reply_t reply {};
  15. reply.result = MAV_RESULT_UNSUPPORTED;
  16. reply.sequence = pkt.sequence;
  17. reply.operation = pkt.operation;
  18. if (uint16_t(pkt.data_length) + uint16_t(pkt.sig_length) > sizeof(pkt.data)) {
  19. reply.result = MAV_RESULT_DENIED;
  20. goto send_reply;
  21. }
  22. if (!check_signature(pkt.sig_length, pkt.data_length, pkt.sequence, pkt.operation, pkt.data)) {
  23. reply.result = MAV_RESULT_DENIED;
  24. goto send_reply;
  25. }
  26. switch (pkt.operation) {
  27. case SECURE_COMMAND_GET_SESSION_KEY:
  28. case SECURE_COMMAND_GET_REMOTEID_SESSION_KEY: {
  29. make_session_key(session_key);
  30. reply.data_length = sizeof(session_key);
  31. memcpy(reply.data, session_key, reply.data_length);
  32. reply.result = MAV_RESULT_ACCEPTED;
  33. break;
  34. }
  35. case SECURE_COMMAND_GET_PUBLIC_KEYS: {
  36. if (pkt.data_length != 2) {
  37. reply.result = MAV_RESULT_UNSUPPORTED;
  38. goto send_reply;
  39. }
  40. const uint8_t key_idx = pkt.data[0];
  41. uint8_t num_keys = pkt.data[1];
  42. const uint8_t max_fetch = (sizeof(reply.data)-1) / PUBLIC_KEY_LEN;
  43. if (key_idx >= MAX_PUBLIC_KEYS ||
  44. num_keys > max_fetch ||
  45. key_idx+num_keys > MAX_PUBLIC_KEYS ||
  46. g.no_public_keys()) {
  47. reply.result = MAV_RESULT_FAILED;
  48. goto send_reply;
  49. }
  50. for (uint8_t i=0;i<num_keys;i++) {
  51. g.get_public_key(i+key_idx, &reply.data[1+i*PUBLIC_KEY_LEN]);
  52. }
  53. reply.data_length = 1+num_keys*PUBLIC_KEY_LEN;
  54. reply.data[0] = key_idx;
  55. reply.result = MAV_RESULT_ACCEPTED;
  56. break;
  57. }
  58. case SECURE_COMMAND_SET_PUBLIC_KEYS: {
  59. if (pkt.data_length < PUBLIC_KEY_LEN+1) {
  60. reply.result = MAV_RESULT_FAILED;
  61. goto send_reply;
  62. }
  63. const uint8_t key_idx = pkt.data[0];
  64. const uint8_t num_keys = (pkt.data_length-1) / PUBLIC_KEY_LEN;
  65. if (num_keys == 0) {
  66. reply.result = MAV_RESULT_FAILED;
  67. goto send_reply;
  68. }
  69. if (key_idx >= MAX_PUBLIC_KEYS ||
  70. key_idx+num_keys > MAX_PUBLIC_KEYS) {
  71. reply.result = MAV_RESULT_FAILED;
  72. goto send_reply;
  73. }
  74. bool failed = false;
  75. for (uint8_t i=0; i<num_keys; i++) {
  76. failed |= !g.set_public_key(key_idx+i, &pkt.data[1+i*PUBLIC_KEY_LEN]);
  77. }
  78. reply.result = failed? MAV_RESULT_FAILED : MAV_RESULT_ACCEPTED;
  79. break;
  80. }
  81. case SECURE_COMMAND_REMOVE_PUBLIC_KEYS: {
  82. if (pkt.data_length != 2) {
  83. reply.result = MAV_RESULT_FAILED;
  84. goto send_reply;
  85. }
  86. const uint8_t key_idx = pkt.data[0];
  87. const uint8_t num_keys = pkt.data[1];
  88. if (num_keys == 0) {
  89. reply.result = MAV_RESULT_FAILED;
  90. goto send_reply;
  91. }
  92. if (key_idx >= MAX_PUBLIC_KEYS ||
  93. key_idx+num_keys > MAX_PUBLIC_KEYS) {
  94. reply.result = MAV_RESULT_FAILED;
  95. goto send_reply;
  96. }
  97. for (uint8_t i=0; i<num_keys; i++) {
  98. g.remove_public_key(key_idx+i);
  99. }
  100. reply.result = MAV_RESULT_ACCEPTED;
  101. break;
  102. }
  103. case SECURE_COMMAND_SET_REMOTEID_CONFIG: {
  104. int16_t data_len = pkt.data_length;
  105. char data[pkt.data_length+1];
  106. memcpy(data, pkt.data, pkt.data_length);
  107. data[pkt.data_length] = 0;
  108. /*
  109. command buffer is nul separated set of NAME=VALUE pairs
  110. */
  111. reply.result = MAV_RESULT_ACCEPTED;
  112. char *command = (char *)data;
  113. while (data_len > 0) {
  114. uint8_t cmdlen = strlen(command);
  115. char *eq = strchr(command, '=');
  116. if (eq != nullptr) {
  117. *eq = 0;
  118. if (!g.set_by_name_string(command, eq+1)) {
  119. mav_printf(MAV_SEVERITY_INFO, "set %s failed", command);
  120. reply.result = MAV_RESULT_FAILED;
  121. } else {
  122. mav_printf(MAV_SEVERITY_INFO, "set %s OK", command);
  123. }
  124. }
  125. command += cmdlen+1;
  126. data_len -= cmdlen+1;
  127. }
  128. break;
  129. }
  130. }
  131. send_reply:
  132. // send reply
  133. mavlink_msg_secure_command_reply_send_struct(chan, &reply);
  134. }