123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- /* vim: set expandtab ts=4 sw=4: */
- /*
- * You may redistribute this program and/or modify it under the terms of
- * the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
- #include "crypto/Sign_admin.h"
- #include "admin/Admin.h"
- #include "benc/String.h"
- #include "crypto/Key.h"
- #include "crypto/Sign.h"
- #include "dht/Address.h"
- #include "memory/Allocator.h"
- #include "util/Base32.h"
- #include "util/Identity.h"
- #include "wire/Message.h"
- struct Context {
- uint8_t signingKeypair[64];
- uint8_t pubSigningKey[64];
- struct Random* rand;
- struct Allocator* alloc;
- struct Admin* admin;
- Identity
- };
- static void checkSig(Dict* args, void* vctx, String* txid, struct Allocator* requestAlloc)
- {
- struct Context* ctx = Identity_check((struct Context*) vctx);
- String* msgHash = Dict_getStringC(args, "msgHash");
- String* signature = Dict_getStringC(args, "signature");
- Dict* out = Dict_new(requestAlloc);
- uint8_t publicSigningKey[32];
- uint8_t sigBytes[64];
- char* underscore = CString_strchr(signature->bytes, '_');
- if (msgHash->len > 64) {
- Dict_putStringCC(out, "error", "msgHash too long, max 64 bytes", requestAlloc);
- } else if (underscore == NULL) {
- Dict_putStringCC(out, "error",
- "malformed signature, missing separator", requestAlloc);
- } else if (Base32_decode(
- publicSigningKey, 32, signature->bytes, (int)(underscore - signature->bytes)) != 32)
- {
- Dict_putStringCC(out, "error",
- "malformed signature, failed to decode pubkey", requestAlloc);
- } else if (Base32_decode(
- sigBytes, 64, &underscore[1], CString_strlen(&underscore[1])) != 64)
- {
- Dict_putStringCC(out, "error",
- "malformed signature, failed to decode signature", requestAlloc);
- } else {
- Message_t* msg = Message_new(0, msgHash->len + 64, requestAlloc);
- Err_assert(Message_epush(msg, msgHash->bytes, msgHash->len));
- Err_assert(Message_epush(msg, sigBytes, 64));
- uint8_t curve25519key[32];
- if (Sign_verifyMsg(publicSigningKey, msg)) {
- Dict_putStringCC(out, "error", "invalid signature", requestAlloc);
- } else if (Sign_publicSigningKeyToCurve25519(curve25519key, publicSigningKey)) {
- Dict_putStringCC(out, "error", "not a valid curve25519 key", requestAlloc);
- } else {
- struct Address addr = {0};
- Address_forKey(&addr, curve25519key);
- uint8_t ipv6[40];
- Address_printIp(ipv6, &addr);
- String* k = Key_stringify(curve25519key, requestAlloc);
- Dict_putStringC(out, "pubkey", k, requestAlloc);
- Dict_putStringCC(out, "ipv6", ipv6, requestAlloc);
- Dict_putStringCC(out, "error", "none", requestAlloc);
- }
- }
- Admin_sendMessage(out, txid, ctx->admin);
- }
- static void sign(Dict* args, void* vctx, String* txid, struct Allocator* requestAlloc)
- {
- struct Context* ctx = Identity_check((struct Context*) vctx);
- String* msgHash = Dict_getStringC(args, "msgHash");
- Dict* out = Dict_new(requestAlloc);
- if (msgHash->len > 64) {
- Dict_putStringCC(out, "error", "msgHash too long, max 64 bytes", requestAlloc);
- } else {
- Message_t* msg = Message_new(0, msgHash->len + 64, requestAlloc);
- Err_assert(Message_epush(msg, msgHash->bytes, msgHash->len));
- Sign_signMsg(ctx->signingKeypair, msg, ctx->rand);
- uint8_t signB64[128];
- Assert_true(Base32_encode(signB64, 128, Message_bytes(msg), 64) > 0);
- String* sig = String_printf(requestAlloc, "%s_%s", ctx->pubSigningKey, signB64);
- Dict_putStringC(out, "signature", sig, requestAlloc);
- Dict_putStringCC(out, "error", "none", requestAlloc);
- }
- Admin_sendMessage(out, txid, ctx->admin);
- }
- void Sign_admin_register(uint8_t* privateKey,
- struct Admin* admin,
- struct Random* rand,
- struct Allocator* alloc)
- {
- struct Context* ctx = Allocator_calloc(alloc, sizeof(struct Context), 1);
- Sign_signingKeyPairFromCurve25519(ctx->signingKeypair, privateKey);
- uint8_t sPubKey[32];
- Sign_publicKeyFromKeyPair(sPubKey, ctx->signingKeypair);
- Assert_true(Base32_encode(ctx->pubSigningKey, 64, sPubKey, 32) > 0);
- ctx->alloc = alloc;
- ctx->rand = rand;
- ctx->admin = admin;
- Identity_set(ctx);
- Admin_registerFunction("Sign_checkSig", checkSig, ctx, false,
- ((struct Admin_FunctionArg[]) {
- { .name = "msgHash", .required = true, .type = "String" },
- { .name = "signature", .required = true, .type = "String" },
- }), admin);
- Admin_registerFunction("Sign_sign", sign, ctx, true,
- ((struct Admin_FunctionArg[]) {
- { .name = "msgHash", .required = true, .type = "String" },
- }), admin);
- }
|