*
* secnet is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version d of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* secnet is distributed in the hope that it will be useful, but
return safe_realloc_ary(0,size,count,message);
}
-/* Convert a buffer into its MP_INT representation */
-void read_mpbin(MP_INT *a, uint8_t *bin, int binsize)
+void hex_encode(const uint8_t *bin, int binsize, char *buff)
{
- char *buff;
int i;
- buff=safe_malloc(binsize*2 + 1,"read_mpbin");
-
for (i=0; i<binsize; i++) {
buff[i*2]=hexdigits[(bin[i] & 0xf0) >> 4];
buff[i*2+1]=hexdigits[(bin[i] & 0xf)];
}
buff[binsize*2]=0;
-
- mpz_set_str(a, buff, 16);
- free(buff);
}
-/* Convert a MP_INT into a hex string */
-char *write_mpstring(MP_INT *a)
+string_t hex_encode_alloc(const uint8_t *bin, int binsize)
{
char *buff;
- buff=safe_malloc(mpz_sizeinbase(a,16)+2,"write_mpstring");
- mpz_get_str(buff, 16, a);
+ buff=safe_malloc(hex_encode_size(binsize),"hex_encode");
+ hex_encode(bin,binsize,buff);
return buff;
}
return -1;
}
-/* Convert a MP_INT into a buffer; return length; truncate if necessary */
-int32_t write_mpbin(MP_INT *a, uint8_t *buffer, int32_t buflen)
+bool_t hex_decode(uint8_t *buffer, int32_t buflen, int32_t *outlen,
+ cstring_t hb, bool_t allow_odd_nibble)
{
- char *hb;
- int i,j,l;
-
- if (buflen==0) return 0;
- hb=write_mpstring(a);
-
- l=strlen(hb);
- i=0; j=0;
+ int i = 0, j = 0, l = strlen(hb), hi, lo;
+ bool_t ok = False;
+
+ if (!l || !buflen) { ok = !l; goto done; }
if (l&1) {
/* The number starts with a half-byte */
- buffer[i++]=hexval(hb[j++]);
+ if (!allow_odd_nibble) goto done;
+ lo = hexval(hb[j++]); if (lo < 0) goto done;
+ buffer[i++] = lo;
}
- for (; hb[j] && i<buflen; i++) {
- buffer[i]=(hexval(hb[j])<<4)|hexval(hb[j+1]);
- j+=2;
+ for (; hb[j] && i < buflen; i++) {
+ hi = hexval(hb[j++]);
+ lo = hexval(hb[j++]);
+ if (hi < 0 || lo < 0) goto done;
+ buffer[i] = (hi << 4) | lo;
}
+ ok = !hb[j];
+done:
+ *outlen = i;
+ return ok;
+}
+
+void read_mpbin(MP_INT *a, uint8_t *bin, int binsize)
+{
+ char *buff = hex_encode_alloc(bin, binsize);
+ mpz_set_str(a, buff, 16);
+ free(buff);
+}
+
+char *write_mpstring(MP_INT *a)
+{
+ char *buff;
+
+ buff=safe_malloc(mpz_sizeinbase(a,16)+2,"write_mpstring");
+ mpz_get_str(buff, 16, a);
+ return buff;
+}
+
+int32_t write_mpbin(MP_INT *a, uint8_t *buffer, int32_t buflen)
+{
+ char *hb = write_mpstring(a);
+ int32_t len;
+ hex_decode(buffer, buflen, &len, hb, True);
free(hb);
- return i;
+ return len;
}
#define DEFINE_SETFDFLAG(fn,FL,FLAG) \
return p;
}
-/* Append a two-byte length and the string to the buffer. Length is in
- network byte order. */
void buf_append_string(struct buffer_if *buf, cstring_t s)
{
size_t len;
" %s; sending NAK\n",
comm_addr_to_string(dest),
our_index, their_index, msgtype, logwhy);
- dest->comm->sendmsg(dest->comm->st, buf, dest);
+ dest->comm->sendmsg(dest->comm->st, buf, dest, 0);
}
int consttime_memeq(const void *s1in, const void *s2in, size_t n)
#ifndef CONFIG_IPV6
ia->sin.sin_family=AF_INET;
- ia->sin.sin_addr.s_addr=string_item_to_ipaddr(item,desc);
+ ia->sin.sin_addr.s_addr=htonl(string_item_to_ipaddr(item,desc));
ia->sin.sin_port=htons(port);
#else /* CONFIG_IPV6 => we have adns_text2addr */