cstring *base58_decode_check(unsigned char *addrtype, const char *s_in) { /* decode base58 string */ cstring *s = base58_decode(s_in); if (!s) return NULL; if (s->len < 4) goto err_out; /* validate with trailing hash, then remove hash */ unsigned char md32[4]; bu_Hash4(md32, s->str, s->len - 4); if (memcmp(md32, &s->str[s->len - 4], 4)) goto err_out; cstr_resize(s, s->len - 4); /* if addrtype requested, remove from front of data string */ if (addrtype) { *addrtype = (unsigned char) s->str[0]; cstr_erase(s, 0, 1); } return s; err_out: cstr_free(s, true); return NULL; }
cstring *message_str(const unsigned char netmagic[4], const char *command_, const void *data, uint32_t data_len) { cstring *s = cstr_new_sz(P2P_HDR_SZ + data_len); /* network identifier (magic number) */ cstr_append_buf(s, netmagic, 4); /* command string */ char command[12] = {}; strncpy(command, command_, 12); cstr_append_buf(s, command, 12); /* data length */ uint32_t data_len_le = htole32(data_len); cstr_append_buf(s, &data_len_le, 4); /* data checksum */ unsigned char md32[4]; bu_Hash4(md32, data, data_len); cstr_append_buf(s, &md32[0], 4); /* data payload */ if (data_len > 0) cstr_append_buf(s, data, data_len); return s; }
GString *message_str(const unsigned char netmagic[4], const char *command_, const void *data, uint32_t data_len) { GString *s = g_string_sized_new(P2P_HDR_SZ + data_len); /* network identifier (magic number) */ g_string_append_len(s, (gchar *) netmagic, 4); /* command string */ char command[12] = {}; strncpy(command, command_, 12); g_string_append_len(s, command, 12); /* data length */ uint32_t data_len_le = GUINT32_TO_LE(data_len); g_string_append_len(s, (gchar *) &data_len_le, 4); /* data checksum */ unsigned char md32[4]; bu_Hash4(md32, data, data_len); g_string_append_len(s, (gchar *) &md32[0], 4); /* data payload */ if (data_len > 0) g_string_append_len(s, data, data_len); return s; }
bool message_valid(const struct p2p_message *msg) { if (!msg) return false; /* data checksum */ unsigned char md32[4]; if (msg->hdr.data_len) bu_Hash4(md32, msg->data, msg->hdr.data_len); else bu_Hash4(md32, "", 0); if (memcmp(msg->hdr.hash, md32, sizeof(md32))) return false; return true; }
cstring *base58_encode_check(unsigned char addrtype, bool have_addrtype, const void *data, size_t data_len) { cstring *s = cstr_new_sz(data_len + 1 + 4); if (have_addrtype) cstr_append_c(s, addrtype); cstr_append_buf(s, data, data_len); unsigned char md32[4]; bu_Hash4(md32, s->str, s->len); cstr_append_buf(s, md32, 4); cstring *s_enc = base58_encode(s->str, s->len); cstr_free(s, true); return s_enc; }