Sign_admin.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /* vim: set expandtab ts=4 sw=4: */
  2. /*
  3. * You may redistribute this program and/or modify it under the terms of
  4. * the GNU General Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. */
  15. #include "crypto/Sign_admin.h"
  16. #include "admin/Admin.h"
  17. #include "benc/String.h"
  18. #include "crypto/Key.h"
  19. #include "crypto/Sign.h"
  20. #include "dht/Address.h"
  21. #include "exception/Er.h"
  22. #include "memory/Allocator.h"
  23. #include "util/Base32.h"
  24. #include "util/Identity.h"
  25. #include "wire/Message.h"
  26. struct Context {
  27. uint8_t signingKeypair[64];
  28. uint8_t pubSigningKey[64];
  29. struct Random* rand;
  30. struct Allocator* alloc;
  31. struct Admin* admin;
  32. Identity
  33. };
  34. static void checkSig(Dict* args, void* vctx, String* txid, struct Allocator* requestAlloc)
  35. {
  36. struct Context* ctx = Identity_check((struct Context*) vctx);
  37. String* msgHash = Dict_getStringC(args, "msgHash");
  38. String* signature = Dict_getStringC(args, "signature");
  39. Dict* out = Dict_new(requestAlloc);
  40. uint8_t publicSigningKey[32];
  41. uint8_t sigBytes[64];
  42. char* underscore = CString_strchr(signature->bytes, '_');
  43. if (msgHash->len > 64) {
  44. Dict_putStringCC(out, "error", "msgHash too long, max 64 bytes", requestAlloc);
  45. } else if (underscore == NULL) {
  46. Dict_putStringCC(out, "error",
  47. "malformed signature, missing separator", requestAlloc);
  48. } else if (Base32_decode(
  49. publicSigningKey, 32, signature->bytes, (int)(underscore - signature->bytes)) != 32)
  50. {
  51. Dict_putStringCC(out, "error",
  52. "malformed signature, failed to decode pubkey", requestAlloc);
  53. } else if (Base32_decode(
  54. sigBytes, 64, &underscore[1], CString_strlen(&underscore[1])) != 64)
  55. {
  56. Dict_putStringCC(out, "error",
  57. "malformed signature, failed to decode signature", requestAlloc);
  58. } else {
  59. struct Message* msg = Message_new(0, msgHash->len + 64, requestAlloc);
  60. Er_assert(Message_epush(msg, msgHash->bytes, msgHash->len));
  61. Er_assert(Message_epush(msg, sigBytes, 64));
  62. uint8_t curve25519key[32];
  63. if (Sign_verifyMsg(publicSigningKey, msg)) {
  64. Dict_putStringCC(out, "error", "invalid signature", requestAlloc);
  65. } else if (Sign_publicSigningKeyToCurve25519(curve25519key, publicSigningKey)) {
  66. Dict_putStringCC(out, "error", "not a valid curve25519 key", requestAlloc);
  67. } else {
  68. struct Address addr = {0};
  69. Address_forKey(&addr, curve25519key);
  70. uint8_t ipv6[40];
  71. Address_printIp(ipv6, &addr);
  72. String* k = Key_stringify(curve25519key, requestAlloc);
  73. Dict_putStringC(out, "pubkey", k, requestAlloc);
  74. Dict_putStringCC(out, "ipv6", ipv6, requestAlloc);
  75. Dict_putStringCC(out, "error", "none", requestAlloc);
  76. }
  77. }
  78. Admin_sendMessage(out, txid, ctx->admin);
  79. }
  80. static void sign(Dict* args, void* vctx, String* txid, struct Allocator* requestAlloc)
  81. {
  82. struct Context* ctx = Identity_check((struct Context*) vctx);
  83. String* msgHash = Dict_getStringC(args, "msgHash");
  84. Dict* out = Dict_new(requestAlloc);
  85. if (msgHash->len > 64) {
  86. Dict_putStringCC(out, "error", "msgHash too long, max 64 bytes", requestAlloc);
  87. } else {
  88. struct Message* msg = Message_new(0, msgHash->len + 64, requestAlloc);
  89. Er_assert(Message_epush(msg, msgHash->bytes, msgHash->len));
  90. Sign_signMsg(ctx->signingKeypair, msg, ctx->rand);
  91. uint8_t signB64[128];
  92. Assert_true(Base32_encode(signB64, 128, msg->msgbytes, 64) > 0);
  93. String* sig = String_printf(requestAlloc, "%s_%s", ctx->pubSigningKey, signB64);
  94. Dict_putStringC(out, "signature", sig, requestAlloc);
  95. Dict_putStringCC(out, "error", "none", requestAlloc);
  96. }
  97. Admin_sendMessage(out, txid, ctx->admin);
  98. }
  99. void Sign_admin_register(uint8_t* privateKey,
  100. struct Admin* admin,
  101. struct Random* rand,
  102. struct Allocator* alloc)
  103. {
  104. struct Context* ctx = Allocator_calloc(alloc, sizeof(struct Context), 1);
  105. Sign_signingKeyPairFromCurve25519(ctx->signingKeypair, privateKey);
  106. uint8_t sPubKey[32];
  107. Sign_publicKeyFromKeyPair(sPubKey, ctx->signingKeypair);
  108. Assert_true(Base32_encode(ctx->pubSigningKey, 64, sPubKey, 32) > 0);
  109. ctx->alloc = alloc;
  110. ctx->rand = rand;
  111. ctx->admin = admin;
  112. Identity_set(ctx);
  113. Admin_registerFunction("Sign_checkSig", checkSig, ctx, false,
  114. ((struct Admin_FunctionArg[]) {
  115. { .name = "msgHash", .required = true, .type = "String" },
  116. { .name = "signature", .required = true, .type = "String" },
  117. }), admin);
  118. Admin_registerFunction("Sign_sign", sign, ctx, true,
  119. ((struct Admin_FunctionArg[]) {
  120. { .name = "msgHash", .required = true, .type = "String" },
  121. }), admin);
  122. }