mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2026-09-22 15:29:03 -07:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b3dd5c0e3a | ||
|
|
ee7ee22555 | ||
|
|
cf49e511a5 | ||
|
|
505b9c7f56 | ||
|
|
8c30b2b9f5 | ||
|
|
b9c1407013 | ||
|
|
d905607353 | ||
|
|
e5e90b1f71 | ||
|
|
d5ed025871 | ||
|
|
b55422a528 | ||
|
|
909a14fb48 | ||
|
|
107e3e4106 | ||
|
|
6ef247fb93 | ||
|
|
b8e46b835b | ||
|
|
0900fee5d9 | ||
|
|
1f26cb98de | ||
|
|
ceeb8ee0bc | ||
|
|
54c47a1e03 | ||
|
|
6bb855873d | ||
|
|
39db45e144 | ||
|
|
41c187ba12 | ||
|
|
d7c99728bc | ||
|
|
8e19188f49 | ||
|
|
625e3e8e25 | ||
|
|
fde99e2fcf | ||
|
|
132643cd4a | ||
|
|
faf7b81c01 | ||
|
|
bcc6799902 | ||
|
|
718e1d6c08 | ||
|
|
a9ce773584 | ||
|
|
d69bc4fb5e | ||
|
|
1b68d6dbdc | ||
|
|
62578a2162 | ||
|
|
9e80db0fd1 | ||
|
|
e8ab6adf89 | ||
|
|
7c184cf991 | ||
|
|
72def658d0 | ||
|
|
e7cd888c7d | ||
|
|
1205578935 | ||
|
|
4e77365e8d | ||
|
|
4f2a779769 | ||
|
|
cafbe44dde | ||
|
|
6234bfd8bf | ||
|
|
77796caba6 | ||
|
|
97f1d7ae2e | ||
|
|
487e89d4d0 |
No files matched your search
+37
@@ -0,0 +1,37 @@
|
||||
ZeroTier One - Network Virtualization Everywhere
|
||||
Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
||||
|
||||
This program 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 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
See LICENSE.GPL-3 for the full GNU GPL v3 license.
|
||||
|
||||
--
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial closed-source software that incorporates or links
|
||||
directly against ZeroTier software without disclosing the source code
|
||||
of your own application.
|
||||
|
||||
--
|
||||
|
||||
The above license does not apply to third party code included with or
|
||||
linked against by ZeroTier software. See the third party code section
|
||||
of the AUTHORS.md for an index of third party software included in
|
||||
this software repository.
|
||||
|
||||
Licenses for third party code are all relatively permissive: MIT,
|
||||
BSD, and public domain. The only exception is the tap-windows driver
|
||||
which is under the GPLv2, but this is only needed to produce the
|
||||
binary tap device driver used by the ZeroTier service on Windows.
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,17 @@
|
||||
CC=gcc
|
||||
CXX=g++
|
||||
|
||||
#ARCH_FLAGS=-arch x86_64 -arch i386 -arch ppc
|
||||
|
||||
DEFS=-DHAS_DEV_URANDOM
|
||||
CXXDEFS=-DBOOST_DISABLE_ASSERTS -DBOOST_NO_TYPEID -DNDEBUG
|
||||
|
||||
CFLAGS=-mmacosx-version-min=10.4 -std=c99 -O6 -ftree-vectorize -Wall $(DEFS) $(ARCH_FLAGS)
|
||||
CXXFLAGS=-mmacosx-version-min=10.4 -Drestrict=__restrict__ -O6 -ftree-vectorize -Wall $(DEFS) $(CXXDEFS) $(ARCH_FLAGS)
|
||||
|
||||
LDFLAGS=-mmacosx-version-min=10.4 $(ARCH_FLAGS)
|
||||
DLLFLAGS=$(ARCH_FLAGS) -shared
|
||||
DLLEXT=dylib
|
||||
|
||||
LIBANODE_LIBS=-lcrypto -lpthread -lresolv
|
||||
LIBSPARK_LIBS=-lz
|
||||
@@ -0,0 +1,17 @@
|
||||
CC=gcc
|
||||
CXX=g++
|
||||
|
||||
DEFS=-DHAS_DEV_URANDOM
|
||||
|
||||
CFLAGS=-std=c99 -O6 -fPIC -Wall $(DEFS)
|
||||
CXXFLAGS=-Drestrict=__restrict__ -O6 -Wall $(DEFS) -I..
|
||||
|
||||
#CFLAGS=-g -Wall $(DEFS)
|
||||
#CXXFLAGS=-g -Wall $(DEFS)
|
||||
|
||||
LDFLAGS=
|
||||
DLLFLAGS=-shared
|
||||
DLLEXT=so
|
||||
|
||||
LIBANODE_LIBS=-lcrypto -lresolv -pthread
|
||||
LIBSPARK_LIBS=-lz
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,33 @@
|
||||
SYSNAME:=${shell uname}
|
||||
SYSNAME!=uname
|
||||
include ../config.mk.${SYSNAME}
|
||||
|
||||
LIBANODE_OBJS= \
|
||||
impl/aes.o \
|
||||
impl/dictionary.o \
|
||||
impl/dns_txt.o \
|
||||
impl/ec.o \
|
||||
impl/environment.o \
|
||||
impl/misc.o \
|
||||
impl/thread.o \
|
||||
address.o \
|
||||
aes_digest.o \
|
||||
errors.o \
|
||||
identity.o \
|
||||
network_address.o \
|
||||
secure_random.o \
|
||||
system_transport.o \
|
||||
uri.o
|
||||
# zone.o
|
||||
|
||||
all: $(LIBANODE_OBJS)
|
||||
ar rcs libanode.a $(LIBANODE_OBJS)
|
||||
ranlib libanode.a
|
||||
$(CC) $(CFLAGS) -o utils/anode-make-identity utils/anode-make-identity.c $(LIBANODE_OBJS) $(LIBANODE_LIBS)
|
||||
|
||||
clean: force
|
||||
rm -f $(LIBANODE_OBJS)
|
||||
rm -f libanode.$(DLLEXT) libanode.a
|
||||
rm -f utils/anode-make-identity
|
||||
|
||||
force: ;
|
||||
@@ -0,0 +1,98 @@
|
||||
/* libanode: the Anode C reference implementation
|
||||
* Copyright (C) 2009-2010 Adam Ierymenko <adam.ierymenko@gmail.com>
|
||||
*
|
||||
* This program 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 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 <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "impl/aes.h"
|
||||
#include "impl/ec.h"
|
||||
#include "impl/misc.h"
|
||||
#include "impl/types.h"
|
||||
#include "anode.h"
|
||||
|
||||
int AnodeAddress_calc_short_id(
|
||||
const AnodeAddress *address,
|
||||
AnodeAddressId *short_address_id)
|
||||
{
|
||||
unsigned char digest[16];
|
||||
|
||||
switch(AnodeAddress_get_type(address)) {
|
||||
case ANODE_ADDRESS_ANODE_256_40:
|
||||
Anode_aes_digest(address->bits,ANODE_ADDRESS_LENGTH_ANODE_256_40,digest);
|
||||
break;
|
||||
default:
|
||||
return ANODE_ERR_ADDRESS_INVALID;
|
||||
}
|
||||
|
||||
*((uint64_t *)short_address_id->bits) = ((uint64_t *)digest)[0] ^ ((uint64_t *)digest)[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int AnodeAddress_get_zone(const AnodeAddress *address,AnodeZone *zone)
|
||||
{
|
||||
switch(AnodeAddress_get_type(address)) {
|
||||
case ANODE_ADDRESS_ANODE_256_40:
|
||||
*((uint32_t *)&(zone->bits[0])) = *((uint32_t *)&(address->bits[1]));
|
||||
return 0;
|
||||
}
|
||||
return ANODE_ERR_ADDRESS_INVALID;
|
||||
}
|
||||
|
||||
int AnodeAddress_to_string(const AnodeAddress *address,char *buf,int len)
|
||||
{
|
||||
const unsigned char *inptr;
|
||||
char *outptr;
|
||||
unsigned int i;
|
||||
|
||||
switch(AnodeAddress_get_type(address)) {
|
||||
case ANODE_ADDRESS_ANODE_256_40:
|
||||
if (len < (((ANODE_ADDRESS_LENGTH_ANODE_256_40 / 5) * 8) + 1))
|
||||
return ANODE_ERR_BUFFER_TOO_SMALL;
|
||||
inptr = (const unsigned char *)address->bits;
|
||||
outptr = buf;
|
||||
for(i=0;i<(ANODE_ADDRESS_LENGTH_ANODE_256_40 / 5);++i) {
|
||||
Anode_base32_5_to_8(inptr,outptr);
|
||||
inptr += 5;
|
||||
outptr += 8;
|
||||
}
|
||||
*outptr = (char)0;
|
||||
return ((ANODE_ADDRESS_LENGTH_ANODE_256_40 / 5) * 8);
|
||||
}
|
||||
return ANODE_ERR_ADDRESS_INVALID;
|
||||
}
|
||||
|
||||
int AnodeAddress_from_string(const char *str,AnodeAddress *address)
|
||||
{
|
||||
const char *blk_start = str;
|
||||
const char *ptr = str;
|
||||
unsigned int address_len = 0;
|
||||
|
||||
while (*ptr) {
|
||||
if ((unsigned long)(ptr - blk_start) == 8) {
|
||||
if ((address_len + 5) > sizeof(address->bits))
|
||||
return ANODE_ERR_ADDRESS_INVALID;
|
||||
Anode_base32_8_to_5(blk_start,(unsigned char *)&(address->bits[address_len]));
|
||||
address_len += 5;
|
||||
blk_start = ptr;
|
||||
}
|
||||
++ptr;
|
||||
}
|
||||
|
||||
if (ptr != blk_start)
|
||||
return ANODE_ERR_ADDRESS_INVALID;
|
||||
if (AnodeAddress_get_type(address) != ANODE_ADDRESS_ANODE_256_40)
|
||||
return ANODE_ERR_ADDRESS_INVALID;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/* libanode: the Anode C reference implementation
|
||||
* Copyright (C) 2009-2010 Adam Ierymenko <adam.ierymenko@gmail.com>
|
||||
*
|
||||
* This program 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 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 <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "anode.h"
|
||||
#include "impl/aes.h"
|
||||
#include "impl/misc.h"
|
||||
#include "impl/types.h"
|
||||
|
||||
void Anode_aes_digest(const void *const message,unsigned long message_len,void *const hash)
|
||||
{
|
||||
unsigned char previous_digest[16];
|
||||
unsigned char digest[16];
|
||||
unsigned char block[32];
|
||||
const unsigned char *in = (const unsigned char *)message;
|
||||
const unsigned char *end = in + message_len;
|
||||
unsigned long block_counter;
|
||||
AnodeAesExpandedKey expkey;
|
||||
|
||||
((uint64_t *)digest)[0] = 0ULL;
|
||||
((uint64_t *)digest)[1] = 0ULL;
|
||||
((uint64_t *)block)[0] = 0ULL;
|
||||
((uint64_t *)block)[1] = 0ULL;
|
||||
((uint64_t *)block)[2] = 0ULL;
|
||||
((uint64_t *)block)[3] = 0ULL;
|
||||
|
||||
/* Davis-Meyer hash function built from block cipher */
|
||||
block_counter = 0;
|
||||
while (in != end) {
|
||||
block[block_counter++] = *(in++);
|
||||
if (block_counter == 32) {
|
||||
block_counter = 0;
|
||||
((uint64_t *)previous_digest)[0] = ((uint64_t *)digest)[0];
|
||||
((uint64_t *)previous_digest)[1] = ((uint64_t *)digest)[1];
|
||||
Anode_aes256_expand_key(block,&expkey);
|
||||
Anode_aes256_encrypt(&expkey,digest,digest);
|
||||
((uint64_t *)digest)[0] ^= ((uint64_t *)previous_digest)[0];
|
||||
((uint64_t *)digest)[1] ^= ((uint64_t *)previous_digest)[1];
|
||||
}
|
||||
}
|
||||
|
||||
/* Davis-Meyer end marker */
|
||||
block[block_counter++] = 0x80;
|
||||
while (block_counter != 32) block[block_counter++] = 0;
|
||||
((uint64_t *)previous_digest)[0] = ((uint64_t *)digest)[0];
|
||||
((uint64_t *)previous_digest)[1] = ((uint64_t *)digest)[1];
|
||||
Anode_aes256_expand_key(block,&expkey);
|
||||
Anode_aes256_encrypt(&expkey,digest,digest);
|
||||
((uint64_t *)digest)[0] ^= ((uint64_t *)previous_digest)[0];
|
||||
((uint64_t *)digest)[1] ^= ((uint64_t *)previous_digest)[1];
|
||||
|
||||
/* Merkle-DamgĂĄrd length padding */
|
||||
((uint64_t *)block)[0] = 0ULL;
|
||||
if (sizeof(message_len) >= 8) { /* 32/64 bit? this will get optimized out */
|
||||
block[8] = (uint8_t)((uint64_t)message_len >> 56);
|
||||
block[9] = (uint8_t)((uint64_t)message_len >> 48);
|
||||
block[10] = (uint8_t)((uint64_t)message_len >> 40);
|
||||
block[11] = (uint8_t)((uint64_t)message_len >> 32);
|
||||
} else ((uint32_t *)block)[2] = 0;
|
||||
block[12] = (uint8_t)(message_len >> 24);
|
||||
block[13] = (uint8_t)(message_len >> 16);
|
||||
block[14] = (uint8_t)(message_len >> 8);
|
||||
block[15] = (uint8_t)message_len;
|
||||
((uint64_t *)previous_digest)[0] = ((uint64_t *)digest)[0];
|
||||
((uint64_t *)previous_digest)[1] = ((uint64_t *)digest)[1];
|
||||
Anode_aes256_expand_key(block,&expkey);
|
||||
Anode_aes256_encrypt(&expkey,digest,digest);
|
||||
((uint64_t *)digest)[0] ^= ((uint64_t *)previous_digest)[0];
|
||||
((uint64_t *)digest)[1] ^= ((uint64_t *)previous_digest)[1];
|
||||
|
||||
((uint64_t *)hash)[0] = ((uint64_t *)digest)[0];
|
||||
((uint64_t *)hash)[1] = ((uint64_t *)digest)[1];
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,52 @@
|
||||
/* libanode: the Anode C reference implementation
|
||||
* Copyright (C) 2009-2010 Adam Ierymenko <adam.ierymenko@gmail.com>
|
||||
*
|
||||
* This program 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 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 <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "anode.h"
|
||||
|
||||
struct AnodeErrDesc
|
||||
{
|
||||
int code;
|
||||
const char *desc;
|
||||
};
|
||||
|
||||
#define TOTAL_ERRORS 12
|
||||
static const struct AnodeErrDesc ANODE_ERRORS[TOTAL_ERRORS] = {
|
||||
{ ANODE_ERR_NONE, "No error (success)" },
|
||||
{ ANODE_ERR_INVALID_ARGUMENT, "Invalid argument" },
|
||||
{ ANODE_ERR_OUT_OF_MEMORY, "Out of memory" },
|
||||
{ ANODE_ERR_INVALID_URI, "Invalid URI" },
|
||||
{ ANODE_ERR_BUFFER_TOO_SMALL, "Supplied buffer too small" },
|
||||
{ ANODE_ERR_ADDRESS_INVALID, "Address invalid" },
|
||||
{ ANODE_ERR_ADDRESS_TYPE_NOT_SUPPORTED, "Address type not supported"},
|
||||
{ ANODE_ERR_CONNECTION_CLOSED, "Connection closed"},
|
||||
{ ANODE_ERR_CONNECT_FAILED, "Connect failed"},
|
||||
{ ANODE_ERR_UNABLE_TO_BIND, "Unable to bind to address"},
|
||||
{ ANODE_ERR_TOO_MANY_OPEN_SOCKETS, "Too many open sockets"},
|
||||
{ ANODE_ERR_DNS_NAME_NOT_FOUND_OR_TIMED_OUT, "DNS name not found or timed out"}
|
||||
};
|
||||
|
||||
extern const char *Anode_strerror(int err)
|
||||
{
|
||||
int i;
|
||||
int negerr = -err;
|
||||
|
||||
for(i=0;i<TOTAL_ERRORS;++i) {
|
||||
if ((ANODE_ERRORS[i].code == err)||(ANODE_ERRORS[i].code == negerr))
|
||||
return ANODE_ERRORS[i].desc;
|
||||
}
|
||||
|
||||
return "Unknown error";
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/* libanode: the Anode C reference implementation
|
||||
* Copyright (C) 2009-2010 Adam Ierymenko <adam.ierymenko@gmail.com>
|
||||
*
|
||||
* This program 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 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 <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "impl/types.h"
|
||||
#include "impl/ec.h"
|
||||
#include "impl/misc.h"
|
||||
#include "anode.h"
|
||||
|
||||
int AnodeIdentity_generate(AnodeIdentity *identity,const AnodeZone *zone,enum AnodeAddressType type)
|
||||
{
|
||||
struct AnodeECKeyPair kp;
|
||||
|
||||
switch(type) {
|
||||
case ANODE_ADDRESS_ANODE_256_40:
|
||||
if (!AnodeECKeyPair_generate(&kp))
|
||||
return ANODE_ERR_OUT_OF_MEMORY;
|
||||
|
||||
identity->address.bits[0] = (unsigned char)ANODE_ADDRESS_ANODE_256_40;
|
||||
|
||||
identity->address.bits[1] = zone->bits[0];
|
||||
identity->address.bits[2] = zone->bits[1];
|
||||
identity->address.bits[3] = zone->bits[2];
|
||||
identity->address.bits[4] = zone->bits[3];
|
||||
|
||||
identity->address.bits[5] = 0;
|
||||
identity->address.bits[6] = 0;
|
||||
|
||||
Anode_memcpy((void *)&(identity->address.bits[7]),(const void *)kp.pub.key,ANODE_EC_PUBLIC_KEY_BYTES);
|
||||
Anode_memcpy((void *)identity->secret,(const void *)kp.priv.key,kp.priv.bytes);
|
||||
|
||||
AnodeAddress_calc_short_id(&identity->address,&identity->address_id);
|
||||
|
||||
AnodeECKeyPair_destroy(&kp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ANODE_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
int AnodeIdentity_to_string(const AnodeIdentity *identity,char *dest,int dest_len)
|
||||
{
|
||||
char hexbuf[128];
|
||||
char strbuf[128];
|
||||
int n;
|
||||
|
||||
if ((n = AnodeAddress_to_string(&identity->address,strbuf,sizeof(strbuf))) <= 0)
|
||||
return n;
|
||||
|
||||
switch(AnodeAddress_get_type(&identity->address)) {
|
||||
case ANODE_ADDRESS_ANODE_256_40:
|
||||
Anode_to_hex((const unsigned char *)identity->secret,ANODE_ADDRESS_SECRET_LENGTH_ANODE_256_40,hexbuf,sizeof(hexbuf));
|
||||
n = snprintf(dest,dest_len,"ANODE-256-40:%s:%s",strbuf,hexbuf);
|
||||
if (n >= dest_len)
|
||||
return ANODE_ERR_BUFFER_TOO_SMALL;
|
||||
return n;
|
||||
}
|
||||
|
||||
return ANODE_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
int AnodeIdentity_from_string(AnodeIdentity *identity,const char *str)
|
||||
{
|
||||
char buf[1024];
|
||||
char *id_name;
|
||||
char *address;
|
||||
char *secret;
|
||||
int ec;
|
||||
|
||||
Anode_str_copy(buf,str,sizeof(buf));
|
||||
|
||||
id_name = buf;
|
||||
if (!id_name) return 0;
|
||||
if (!*id_name) return 0;
|
||||
address = (char *)Anode_strchr(id_name,':');
|
||||
if (!address) return 0;
|
||||
if (!*address) return 0;
|
||||
*(address++) = (char)0;
|
||||
secret = (char *)Anode_strchr(address,':');
|
||||
if (!secret) return 0;
|
||||
if (!*secret) return 0;
|
||||
*(secret++) = (char)0;
|
||||
|
||||
if (Anode_strcaseeq("ANODE-256-40",id_name)) {
|
||||
if ((ec = AnodeAddress_from_string(address,&identity->address)))
|
||||
return ec;
|
||||
if (Anode_strlen(secret) != (ANODE_ADDRESS_SECRET_LENGTH_ANODE_256_40 * 2))
|
||||
return ANODE_ERR_INVALID_ARGUMENT;
|
||||
Anode_from_hex(secret,(unsigned char *)identity->secret,sizeof(identity->secret));
|
||||
AnodeAddress_calc_short_id(&identity->address,&identity->address_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ANODE_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/* libanode: the Anode C reference implementation
|
||||
* Copyright (C) 2009-2010 Adam Ierymenko <adam.ierymenko@gmail.com>
|
||||
*
|
||||
* This program 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 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 <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "aes.h"
|
||||
|
||||
void Anode_cmac_aes256(
|
||||
const AnodeAesExpandedKey *expkey,
|
||||
const unsigned char *restrict data,
|
||||
unsigned long data_len,
|
||||
unsigned char *restrict mac)
|
||||
{
|
||||
unsigned char cbc[16];
|
||||
unsigned char pad[16];
|
||||
const unsigned char *restrict pos = data;
|
||||
unsigned long i;
|
||||
unsigned long remaining = data_len;
|
||||
unsigned char c;
|
||||
|
||||
((uint64_t *)((void *)cbc))[0] = 0ULL;
|
||||
((uint64_t *)((void *)cbc))[1] = 0ULL;
|
||||
|
||||
while (remaining >= 16) {
|
||||
((uint64_t *)((void *)cbc))[0] ^= ((uint64_t *)((void *)pos))[0];
|
||||
((uint64_t *)((void *)cbc))[1] ^= ((uint64_t *)((void *)pos))[1];
|
||||
pos += 16;
|
||||
if (remaining > 16)
|
||||
Anode_aes256_encrypt(expkey,cbc,cbc);
|
||||
remaining -= 16;
|
||||
}
|
||||
|
||||
((uint64_t *)((void *)pad))[0] = 0ULL;
|
||||
((uint64_t *)((void *)pad))[1] = 0ULL;
|
||||
Anode_aes256_encrypt(expkey,pad,pad);
|
||||
|
||||
c = pad[0] & 0x80;
|
||||
for(i=0;i<15;++i)
|
||||
pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7);
|
||||
pad[15] <<= 1;
|
||||
if (c)
|
||||
pad[15] ^= 0x87;
|
||||
|
||||
if (remaining||(!data_len)) {
|
||||
for(i=0;i<remaining;++i)
|
||||
cbc[i] ^= *(pos++);
|
||||
cbc[remaining] ^= 0x80;
|
||||
|
||||
c = pad[0] & 0x80;
|
||||
for(i=0;i<15;++i)
|
||||
pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7);
|
||||
pad[15] <<= 1;
|
||||
if (c)
|
||||
pad[15] ^= 0x87;
|
||||
}
|
||||
|
||||
((uint64_t *)((void *)mac))[0] = ((uint64_t *)((void *)pad))[0] ^ ((uint64_t *)((void *)cbc))[0];
|
||||
((uint64_t *)((void *)mac))[1] = ((uint64_t *)((void *)pad))[1] ^ ((uint64_t *)((void *)cbc))[1];
|
||||
|
||||
Anode_aes256_encrypt(expkey,mac,mac);
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/* libanode: the Anode C reference implementation
|
||||
* Copyright (C) 2009 Adam Ierymenko <adam.ierymenko@gmail.com>
|
||||
*
|
||||
* This program 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 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 <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _ANODE_AES_H
|
||||
#define _ANODE_AES_H
|
||||
|
||||
#include <openssl/aes.h>
|
||||
#include "types.h"
|
||||
|
||||
/* This just glues us to OpenSSL's built-in AES-256 implementation */
|
||||
|
||||
#define ANODE_AES_BLOCK_SIZE 16
|
||||
#define ANODE_AES_KEY_SIZE 32
|
||||
|
||||
typedef AES_KEY AnodeAesExpandedKey;
|
||||
|
||||
#define Anode_aes256_expand_key(k,ek) AES_set_encrypt_key((const unsigned char *)(k),256,(AES_KEY *)(ek))
|
||||
|
||||
/* Note: in and out can be the same thing */
|
||||
#define Anode_aes256_encrypt(ek,in,out) AES_encrypt((const unsigned char *)(in),(unsigned char *)(out),(const AES_KEY *)(ek))
|
||||
|
||||
/* Note: iv is modified */
|
||||
static inline void Anode_aes256_cfb_encrypt(
|
||||
const AnodeAesExpandedKey *expkey,
|
||||
const unsigned char *in,
|
||||
unsigned char *out,
|
||||
unsigned char *iv,
|
||||
unsigned long len)
|
||||
{
|
||||
int tmp = 0;
|
||||
AES_cfb128_encrypt(in,out,len,(const AES_KEY *)expkey,iv,&tmp,AES_ENCRYPT);
|
||||
}
|
||||
static inline void Anode_aes256_cfb_decrypt(
|
||||
const AnodeAesExpandedKey *expkey,
|
||||
const unsigned char *in,
|
||||
unsigned char *out,
|
||||
unsigned char *iv,
|
||||
unsigned long len)
|
||||
{
|
||||
int tmp = 0;
|
||||
AES_cfb128_encrypt(in,out,len,(const AES_KEY *)expkey,iv,&tmp,AES_DECRYPT);
|
||||
}
|
||||
|
||||
/* CMAC message authentication code */
|
||||
void Anode_cmac_aes256(
|
||||
const AnodeAesExpandedKey *expkey,
|
||||
const unsigned char *restrict data,
|
||||
unsigned long data_len,
|
||||
unsigned char *restrict mac);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,239 @@
|
||||
/* libanode: the Anode C reference implementation
|
||||
* Copyright (C) 2009-2010 Adam Ierymenko <adam.ierymenko@gmail.com>
|
||||
*
|
||||
* This program 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 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 <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "dictionary.h"
|
||||
|
||||
static const char *EMPTY_STR = "";
|
||||
|
||||
void AnodeDictionary_clear(struct AnodeDictionary *d)
|
||||
{
|
||||
struct AnodeDictionaryEntry *e,*ne;
|
||||
int oldcs;
|
||||
unsigned int i;
|
||||
|
||||
oldcs = d->case_sensitive;
|
||||
|
||||
for(i=0;i<ANODE_DICTIONARY_FIXED_HASH_TABLE_SIZE;++i) {
|
||||
e = d->ht[i];
|
||||
while (e) {
|
||||
ne = e->next;
|
||||
if ((e->key)&&(e->key != EMPTY_STR)) free((void *)e->key);
|
||||
if ((e->value)&&(e->value != EMPTY_STR)) free((void *)e->value);
|
||||
free((void *)e);
|
||||
e = ne;
|
||||
}
|
||||
}
|
||||
|
||||
Anode_zero((void *)d,sizeof(struct AnodeDictionary));
|
||||
|
||||
d->case_sensitive = oldcs;
|
||||
}
|
||||
|
||||
void AnodeDictionary_put(struct AnodeDictionary *d,const char *key,const char *value)
|
||||
{
|
||||
struct AnodeDictionaryEntry *e;
|
||||
char *p1;
|
||||
const char *p2;
|
||||
unsigned int bucket = (d->case_sensitive) ? AnodeDictionary__get_bucket(key) : AnodeDictionary__get_bucket_ci(key);
|
||||
unsigned int len,i;
|
||||
|
||||
e = d->ht[bucket];
|
||||
while (e) {
|
||||
if (((d->case_sensitive) ? Anode_streq(key,e->key) : Anode_strcaseeq(key,e->key))) {
|
||||
if (!d->case_sensitive) {
|
||||
p1 = e->key;
|
||||
p2 = key;
|
||||
while (*p2) *(p1++) = *(p2++);
|
||||
}
|
||||
|
||||
len = 0;
|
||||
while (value[len]) ++len;
|
||||
if (len) {
|
||||
if ((e->value)&&(e->value != EMPTY_STR))
|
||||
e->value = (char *)realloc((void *)e->value,len + 1);
|
||||
else e->value = (char *)malloc(len + 1);
|
||||
for(i=0;i<len;++i) e->value[i] = value[i];
|
||||
e->value[i] = (char)0;
|
||||
} else {
|
||||
if ((e->value)&&(e->value != EMPTY_STR)) free((void *)e->value);
|
||||
e->value = (char *)EMPTY_STR;
|
||||
}
|
||||
return;
|
||||
}
|
||||
e = e->next;
|
||||
}
|
||||
|
||||
e = (struct AnodeDictionaryEntry *)malloc(sizeof(struct AnodeDictionaryEntry));
|
||||
|
||||
len = 0;
|
||||
while (key[len]) ++len;
|
||||
if (len) {
|
||||
e->key = (char *)malloc(len + 1);
|
||||
for(i=0;i<len;++i) e->key[i] = key[i];
|
||||
e->key[i] = (char)0;
|
||||
} else e->key = (char *)EMPTY_STR;
|
||||
|
||||
len = 0;
|
||||
while (value[len]) ++len;
|
||||
if (len) {
|
||||
e->value = (char *)malloc(len + 1);
|
||||
for(i=0;i<len;++i) e->value[i] = value[i];
|
||||
e->value[i] = (char)0;
|
||||
} else e->value = (char *)EMPTY_STR;
|
||||
|
||||
e->next = d->ht[bucket];
|
||||
d->ht[bucket] = e;
|
||||
|
||||
++d->size;
|
||||
}
|
||||
|
||||
void AnodeDictionary_read(
|
||||
struct AnodeDictionary *d,
|
||||
char *in,
|
||||
const char *line_breaks,
|
||||
const char *kv_breaks,
|
||||
const char *comment_chars,
|
||||
char escape_char,
|
||||
int trim_whitespace_from_keys,
|
||||
int trim_whitespace_from_values)
|
||||
{
|
||||
char *line = in;
|
||||
char *key;
|
||||
char *value;
|
||||
char *p1,*p2,*p3;
|
||||
char last = ~escape_char;
|
||||
int eof_state = 0;
|
||||
|
||||
for(;;) {
|
||||
if ((!*in)||((Anode_strchr(line_breaks,*in))&&((last != escape_char)||(!escape_char)))) {
|
||||
if (!*in)
|
||||
eof_state = 1;
|
||||
else *in = (char)0;
|
||||
|
||||
if ((*line)&&((comment_chars)&&(!Anode_strchr(comment_chars,*line)))) {
|
||||
key = line;
|
||||
|
||||
while (*line) {
|
||||
if ((Anode_strchr(kv_breaks,*line))&&((last != escape_char)||(!escape_char))) {
|
||||
*(line++) = (char)0;
|
||||
break;
|
||||
} else last = *(line++);
|
||||
}
|
||||
while ((*line)&&(Anode_strchr(kv_breaks,*line))&&((last != escape_char)||(!escape_char)))
|
||||
last = *(line++);
|
||||
value = line;
|
||||
|
||||
if (escape_char) {
|
||||
p1 = key;
|
||||
while (*p1) {
|
||||
if (*p1 == escape_char) {
|
||||
p2 = p1;
|
||||
p3 = p1 + 1;
|
||||
while (*p3)
|
||||
*(p2++) = *(p3++);
|
||||
*p2 = (char)0;
|
||||
}
|
||||
++p1;
|
||||
}
|
||||
p1 = value;
|
||||
while (*p1) {
|
||||
if (*p1 == escape_char) {
|
||||
p2 = p1;
|
||||
p3 = p1 + 1;
|
||||
while (*p3)
|
||||
*(p2++) = *(p3++);
|
||||
*p2 = (char)0;
|
||||
}
|
||||
++p1;
|
||||
}
|
||||
}
|
||||
|
||||
if (trim_whitespace_from_keys)
|
||||
Anode_trim(key);
|
||||
if (trim_whitespace_from_values)
|
||||
Anode_trim(value);
|
||||
|
||||
AnodeDictionary_put(d,key,value);
|
||||
}
|
||||
|
||||
if (eof_state)
|
||||
break;
|
||||
else line = in + 1;
|
||||
}
|
||||
last = *(in++);
|
||||
}
|
||||
}
|
||||
|
||||
long AnodeDictionary_write(
|
||||
struct AnodeDictionary *d,
|
||||
char *out,
|
||||
long out_size,
|
||||
const char *line_break,
|
||||
const char *kv_break)
|
||||
{
|
||||
struct AnodeDictionaryEntry *e;
|
||||
const char *tmp;
|
||||
long ptr = 0;
|
||||
unsigned int bucket;
|
||||
|
||||
if (out_size <= 0)
|
||||
return -1;
|
||||
|
||||
for(bucket=0;bucket<ANODE_DICTIONARY_FIXED_HASH_TABLE_SIZE;++bucket) {
|
||||
e = d->ht[bucket];
|
||||
while (e) {
|
||||
tmp = e->key;
|
||||
if (tmp) {
|
||||
while (*tmp) {
|
||||
out[ptr++] = *tmp++;
|
||||
if (ptr >= (out_size - 1)) return -1;
|
||||
}
|
||||
}
|
||||
|
||||
tmp = kv_break;
|
||||
if (tmp) {
|
||||
while (*tmp) {
|
||||
out[ptr++] = *tmp++;
|
||||
if (ptr >= (out_size - 1)) return -1;
|
||||
}
|
||||
}
|
||||
|
||||
tmp = e->value;
|
||||
if (tmp) {
|
||||
while (*tmp) {
|
||||
out[ptr++] = *tmp++;
|
||||
if (ptr >= (out_size - 1)) return -1;
|
||||
}
|
||||
}
|
||||
|
||||
tmp = line_break;
|
||||
if (tmp) {
|
||||
while (*tmp) {
|
||||
out[ptr++] = *tmp++;
|
||||
if (ptr >= (out_size - 1)) return -1;
|
||||
}
|
||||
}
|
||||
|
||||
e = e->next;
|
||||
}
|
||||
}
|
||||
|
||||
out[ptr] = (char)0;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/* libanode: the Anode C reference implementation
|
||||
* Copyright (C) 2009-2010 Adam Ierymenko <adam.ierymenko@gmail.com>
|
||||
*
|
||||
* This program 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 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 <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* This is a simple string hash table suitable for small tables such as zone
|
||||
* files or HTTP header lists. */
|
||||
|
||||
#ifndef _ANODE_DICTIONARY_H
|
||||
#define _ANODE_DICTIONARY_H
|
||||
|
||||
#include "misc.h"
|
||||
|
||||
/* This is a fixed hash table and is designed for relatively small numbers
|
||||
* of keys for things like zone files. */
|
||||
#define ANODE_DICTIONARY_FIXED_HASH_TABLE_SIZE 16
|
||||
#define ANODE_DICTIONARY_FIXED_HASH_TABLE_MASK 15
|
||||
|
||||
/* Computes a hash code for a string and returns the hash bucket */
|
||||
static inline unsigned int AnodeDictionary__get_bucket(const char *s)
|
||||
{
|
||||
unsigned int hc = 3;
|
||||
while (*s)
|
||||
hc = ((hc << 4) + hc) + (unsigned int)*(s++);
|
||||
return ((hc ^ (hc >> 4)) & ANODE_DICTIONARY_FIXED_HASH_TABLE_MASK);
|
||||
}
|
||||
/* Case insensitive version of get_bucket */
|
||||
static inline unsigned int AnodeDictionary__get_bucket_ci(const char *s)
|
||||
{
|
||||
unsigned int hc = 3;
|
||||
while (*s)
|
||||
hc = ((hc << 4) + hc) + (unsigned int)Anode_tolower(*(s++));
|
||||
return ((hc ^ (hc >> 4)) & ANODE_DICTIONARY_FIXED_HASH_TABLE_MASK);
|
||||
}
|
||||
|
||||
struct AnodeDictionaryEntry
|
||||
{
|
||||
char *key;
|
||||
char *value;
|
||||
struct AnodeDictionaryEntry *next;
|
||||
};
|
||||
|
||||
struct AnodeDictionary
|
||||
{
|
||||
struct AnodeDictionaryEntry *ht[ANODE_DICTIONARY_FIXED_HASH_TABLE_SIZE];
|
||||
unsigned int size;
|
||||
int case_sensitive;
|
||||
};
|
||||
|
||||
static inline void AnodeDictionary_init(struct AnodeDictionary *d,int case_sensitive)
|
||||
{
|
||||
Anode_zero((void *)d,sizeof(struct AnodeDictionary));
|
||||
d->case_sensitive = case_sensitive;
|
||||
}
|
||||
|
||||
void AnodeDictionary_clear(struct AnodeDictionary *d);
|
||||
|
||||
static inline void AnodeDictionary_destroy(struct AnodeDictionary *d)
|
||||
{
|
||||
AnodeDictionary_clear(d);
|
||||
}
|
||||
|
||||
void AnodeDictionary_put(struct AnodeDictionary *d,const char *key,const char *value);
|
||||
|
||||
static inline const char *AnodeDictionary_get(struct AnodeDictionary *d,const char *key)
|
||||
{
|
||||
struct AnodeDictionaryEntry *e;
|
||||
unsigned int bucket = (d->case_sensitive) ? AnodeDictionary__get_bucket(key) : AnodeDictionary__get_bucket_ci(key);
|
||||
|
||||
e = d->ht[bucket];
|
||||
while (e) {
|
||||
if ((d->case_sensitive ? Anode_streq(key,e->key) : Anode_strcaseeq(key,e->key)))
|
||||
return e->value;
|
||||
e = e->next;
|
||||
}
|
||||
|
||||
return (const char *)0;
|
||||
}
|
||||
|
||||
static inline void AnodeDictionary_iterate(
|
||||
struct AnodeDictionary *d,
|
||||
void *arg,
|
||||
int (*func)(void *,const char *,const char *))
|
||||
{
|
||||
struct AnodeDictionaryEntry *e;
|
||||
unsigned int bucket;
|
||||
|
||||
for(bucket=0;bucket<ANODE_DICTIONARY_FIXED_HASH_TABLE_SIZE;++bucket) {
|
||||
e = d->ht[bucket];
|
||||
while (e) {
|
||||
if (!func(arg,e->key,e->value))
|
||||
return;
|
||||
e = e->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AnodeDictionary_read(
|
||||
struct AnodeDictionary *d,
|
||||
char *in,
|
||||
const char *line_breaks,
|
||||
const char *kv_breaks,
|
||||
const char *comment_chars,
|
||||
char escape_char,
|
||||
int trim_whitespace_from_keys,
|
||||
int trim_whitespace_from_values);
|
||||
|
||||
long AnodeDictionary_write(
|
||||
struct AnodeDictionary *d,
|
||||
char *out,
|
||||
long out_size,
|
||||
const char *line_break,
|
||||
const char *kv_break);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,93 @@
|
||||
/* libanode: the Anode C reference implementation
|
||||
* Copyright (C) 2009-2010 Adam Ierymenko <adam.ierymenko@gmail.com>
|
||||
*
|
||||
* This program 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 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 <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
#include <netdb.h>
|
||||
#include "dns_txt.h"
|
||||
|
||||
#ifndef C_IN
|
||||
#define C_IN ns_c_in
|
||||
#endif
|
||||
#ifndef T_TXT
|
||||
#define T_TXT ns_t_txt
|
||||
#endif
|
||||
|
||||
static volatile int Anode_resolver_initialized = 0;
|
||||
|
||||
int Anode_sync_resolve_txt(const char *host,char *txt,unsigned int txt_len)
|
||||
{
|
||||
unsigned char answer[16384],*pptr,*end;
|
||||
char name[16384];
|
||||
int len,explen,i;
|
||||
|
||||
if (!Anode_resolver_initialized) {
|
||||
Anode_resolver_initialized = 1;
|
||||
res_init();
|
||||
}
|
||||
|
||||
/* Do not taunt happy fun ball. */
|
||||
|
||||
len = res_search(host,C_IN,T_TXT,answer,sizeof(answer));
|
||||
if (len > 12) {
|
||||
pptr = answer + 12;
|
||||
end = answer + len;
|
||||
|
||||
explen = dn_expand(answer,end,pptr,name,sizeof(name));
|
||||
if (explen > 0) {
|
||||
pptr += explen;
|
||||
|
||||
if ((pptr + 2) >= end) return 2;
|
||||
if (ntohs(*((uint16_t *)pptr)) == T_TXT) {
|
||||
pptr += 4;
|
||||
if (pptr >= end) return 2;
|
||||
|
||||
explen = dn_expand(answer,end,pptr,name,sizeof(name));
|
||||
if (explen > 0) {
|
||||
pptr += explen;
|
||||
|
||||
if ((pptr + 2) >= end) return 2;
|
||||
if (ntohs(*((uint16_t *)pptr)) == T_TXT) {
|
||||
pptr += 10;
|
||||
if (pptr >= end) return 2;
|
||||
|
||||
len = *(pptr++);
|
||||
if (len <= 0) return 2;
|
||||
if ((pptr + len) > end) return 2;
|
||||
|
||||
if (txt_len < (len + 1))
|
||||
return 4;
|
||||
else {
|
||||
for(i=0;i<len;++i)
|
||||
txt[i] = pptr[i];
|
||||
txt[len] = (char)0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/* libanode: the Anode C reference implementation
|
||||
* Copyright (C) 2009-2010 Adam Ierymenko <adam.ierymenko@gmail.com>
|
||||
*
|
||||
* This program 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 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 <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _ANODE_DNS_TXT_H
|
||||
#define _ANODE_DNS_TXT_H
|
||||
|
||||
/**
|
||||
* Synchronous TXT resolver routine
|
||||
*
|
||||
* Error codes:
|
||||
* 1 - I/O error
|
||||
* 2 - Invalid response
|
||||
* 3 - TXT record not found
|
||||
* 4 - Destination buffer too small for result
|
||||
*
|
||||
* @param host Host name
|
||||
* @param txt Buffer to store TXT result
|
||||
* @param txt_len Size of buffer
|
||||
* @return Zero on success, special error code on failure
|
||||
*/
|
||||
int Anode_sync_resolve_txt(const char *host,char *txt,unsigned int txt_len);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,219 @@
|
||||
/* libanode: the Anode C reference implementation
|
||||
* Copyright (C) 2009-2010 Adam Ierymenko <adam.ierymenko@gmail.com>
|
||||
*
|
||||
* This program 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 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 <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/obj_mac.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/ecdh.h>
|
||||
#include <openssl/ecdsa.h>
|
||||
#include "types.h"
|
||||
#include "misc.h"
|
||||
#include "ec.h"
|
||||
|
||||
static EC_GROUP *AnodeEC_group = (EC_GROUP *)0;
|
||||
|
||||
static void *AnodeEC_KDF(const void *in,size_t inlen,void *out,size_t *outlen)
|
||||
{
|
||||
unsigned long i,longest_length;
|
||||
|
||||
if (!*outlen)
|
||||
return out;
|
||||
|
||||
for(i=0;i<(unsigned long)*outlen;++i)
|
||||
((unsigned char *)out)[i] = (unsigned char)0;
|
||||
|
||||
longest_length = inlen;
|
||||
if (longest_length < *outlen)
|
||||
longest_length = *outlen;
|
||||
for(i=0;i<longest_length;++i)
|
||||
((unsigned char *)out)[i % (unsigned long)*outlen] ^= ((const unsigned char *)in)[i % (unsigned long)inlen];
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
int AnodeECKeyPair_generate(struct AnodeECKeyPair *pair)
|
||||
{
|
||||
EC_KEY *key;
|
||||
int len;
|
||||
|
||||
#ifdef HAS_DEV_URANDOM
|
||||
char buf[128];
|
||||
FILE *f = fopen("/dev/urandom","r");
|
||||
if (f) {
|
||||
if (fread(buf,1,sizeof(buf),f) == sizeof(buf))
|
||||
RAND_add(buf,sizeof(buf),sizeof(buf)/2);
|
||||
fclose(f);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!AnodeEC_group) {
|
||||
AnodeEC_group = EC_GROUP_new_by_curve_name(ANODE_EC_GROUP);
|
||||
if (!AnodeEC_group) return 0;
|
||||
}
|
||||
|
||||
key = EC_KEY_new();
|
||||
if (!key) return 0;
|
||||
|
||||
if (!EC_KEY_set_group(key,AnodeEC_group)) {
|
||||
EC_KEY_free(key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!EC_KEY_generate_key(key)) {
|
||||
EC_KEY_free(key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Anode_zero(pair,sizeof(struct AnodeECKeyPair));
|
||||
|
||||
/* Stuff the private key into priv.key */
|
||||
len = BN_num_bytes(EC_KEY_get0_private_key(key));
|
||||
if ((len > ANODE_EC_PRIME_BYTES)||(len < 0)) {
|
||||
EC_KEY_free(key);
|
||||
return 0;
|
||||
}
|
||||
BN_bn2bin(EC_KEY_get0_private_key(key),&(pair->priv.key[ANODE_EC_PRIME_BYTES - len]));
|
||||
pair->priv.bytes = ANODE_EC_PRIME_BYTES;
|
||||
|
||||
len = EC_POINT_point2oct(AnodeEC_group,EC_KEY_get0_public_key(key),POINT_CONVERSION_COMPRESSED,pair->pub.key,sizeof(pair->pub.key),0);
|
||||
if (len != ANODE_EC_PUBLIC_KEY_BYTES) {
|
||||
EC_KEY_free(key);
|
||||
return 0;
|
||||
}
|
||||
pair->pub.bytes = ANODE_EC_PUBLIC_KEY_BYTES;
|
||||
|
||||
/* Keep a copy of OpenSSL's structure around so we don't have to re-init
|
||||
* it every time we use our key pair structure. */
|
||||
pair->internal_key = key;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int AnodeECKeyPair_init(struct AnodeECKeyPair *pair,const struct AnodeECKey *pub,const struct AnodeECKey *priv)
|
||||
{
|
||||
EC_KEY *key;
|
||||
EC_POINT *kxy;
|
||||
BIGNUM *pn;
|
||||
|
||||
if (!AnodeEC_group) {
|
||||
AnodeEC_group = EC_GROUP_new_by_curve_name(ANODE_EC_GROUP);
|
||||
if (!AnodeEC_group) return 0;
|
||||
}
|
||||
|
||||
key = EC_KEY_new();
|
||||
if (!key)
|
||||
return 0;
|
||||
|
||||
if (!EC_KEY_set_group(key,AnodeEC_group)) {
|
||||
EC_KEY_free(key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Grab the private key */
|
||||
if (priv->bytes != ANODE_EC_PRIME_BYTES) {
|
||||
EC_KEY_free(key);
|
||||
return 0;
|
||||
}
|
||||
pn = BN_new();
|
||||
if (!pn) {
|
||||
EC_KEY_free(key);
|
||||
return 0;
|
||||
}
|
||||
if (!BN_bin2bn(priv->key,ANODE_EC_PRIME_BYTES,pn)) {
|
||||
BN_free(pn);
|
||||
EC_KEY_free(key);
|
||||
return 0;
|
||||
}
|
||||
if (!EC_KEY_set_private_key(key,pn)) {
|
||||
BN_free(pn);
|
||||
EC_KEY_free(key);
|
||||
return 0;
|
||||
}
|
||||
BN_free(pn);
|
||||
|
||||
/* Set the public key */
|
||||
if (pub->bytes != ANODE_EC_PUBLIC_KEY_BYTES) {
|
||||
EC_KEY_free(key);
|
||||
return 0;
|
||||
}
|
||||
kxy = EC_POINT_new(AnodeEC_group);
|
||||
if (!kxy) {
|
||||
EC_KEY_free(key);
|
||||
return 0;
|
||||
}
|
||||
EC_POINT_oct2point(AnodeEC_group,kxy,pub->key,ANODE_EC_PUBLIC_KEY_BYTES,0);
|
||||
if (!EC_KEY_set_public_key(key,kxy)) {
|
||||
EC_POINT_free(kxy);
|
||||
EC_KEY_free(key);
|
||||
return 0;
|
||||
}
|
||||
EC_POINT_free(kxy);
|
||||
|
||||
Anode_zero(pair,sizeof(struct AnodeECKeyPair));
|
||||
Anode_memcpy((void *)&(pair->pub),(const void *)pub,sizeof(struct AnodeECKey));
|
||||
Anode_memcpy((void *)&(pair->priv),(const void *)priv,sizeof(struct AnodeECKey));
|
||||
pair->internal_key = key;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void AnodeECKeyPair_destroy(struct AnodeECKeyPair *pair)
|
||||
{
|
||||
if (pair) {
|
||||
if (pair->internal_key)
|
||||
EC_KEY_free((EC_KEY *)pair->internal_key);
|
||||
}
|
||||
}
|
||||
|
||||
int AnodeECKeyPair_agree(const struct AnodeECKeyPair *my_key_pair,const struct AnodeECKey *their_pub_key,unsigned char *key_buf,unsigned int key_len)
|
||||
{
|
||||
EC_POINT *pub;
|
||||
int i;
|
||||
|
||||
if (!AnodeEC_group) {
|
||||
AnodeEC_group = EC_GROUP_new_by_curve_name(ANODE_EC_GROUP);
|
||||
if (!AnodeEC_group) return 0;
|
||||
}
|
||||
|
||||
if (!my_key_pair->internal_key)
|
||||
return 0;
|
||||
|
||||
if (their_pub_key->bytes != ANODE_EC_PUBLIC_KEY_BYTES)
|
||||
return 0;
|
||||
pub = EC_POINT_new(AnodeEC_group);
|
||||
if (!pub)
|
||||
return 0;
|
||||
EC_POINT_oct2point(AnodeEC_group,pub,their_pub_key->key,ANODE_EC_PUBLIC_KEY_BYTES,0);
|
||||
|
||||
i = ECDH_compute_key(key_buf,key_len,pub,(EC_KEY *)my_key_pair->internal_key,&AnodeEC_KDF);
|
||||
if (i != (int)key_len) {
|
||||
EC_POINT_free(pub);
|
||||
return 0;
|
||||
}
|
||||
|
||||
EC_POINT_free(pub);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void AnodeEC_random(unsigned char *buf,unsigned int len)
|
||||
{
|
||||
RAND_pseudo_bytes(buf,len);
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/* libanode: the Anode C reference implementation
|
||||
* Copyright (C) 2009-2010 Adam Ierymenko <adam.ierymenko@gmail.com>
|
||||
*
|
||||
* This program 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 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 <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Elliptic curve glue -- hides OpenSSL code behind this source module */
|
||||
|
||||
#ifndef _ANODE_EC_H
|
||||
#define _ANODE_EC_H
|
||||
|
||||
#include "misc.h"
|
||||
|
||||
/* Right now, only one mode is supported: NIST-P-256. This is the only mode
|
||||
* supported in the spec as well, and should be good for quite some time.
|
||||
* If other modes are needed this code will need to be refactored. */
|
||||
|
||||
/* NIST-P-256 prime size in bytes */
|
||||
#define ANODE_EC_PRIME_BYTES 32
|
||||
|
||||
/* Sizes of key fields */
|
||||
#define ANODE_EC_GROUP NID_X9_62_prime256v1
|
||||
#define ANODE_EC_PUBLIC_KEY_BYTES (ANODE_EC_PRIME_BYTES + 1)
|
||||
#define ANODE_EC_PRIVATE_KEY_BYTES ANODE_EC_PRIME_BYTES
|
||||
|
||||
/* Larger of public or private key bytes, used for buffers */
|
||||
#define ANODE_EC_MAX_BYTES ANODE_EC_PUBLIC_KEY_BYTES
|
||||
|
||||
struct AnodeECKey
|
||||
{
|
||||
unsigned char key[ANODE_EC_MAX_BYTES];
|
||||
unsigned int bytes;
|
||||
};
|
||||
|
||||
struct AnodeECKeyPair
|
||||
{
|
||||
struct AnodeECKey pub;
|
||||
struct AnodeECKey priv;
|
||||
void *internal_key;
|
||||
};
|
||||
|
||||
/* Key management functions */
|
||||
int AnodeECKeyPair_generate(struct AnodeECKeyPair *pair);
|
||||
int AnodeECKeyPair_init(struct AnodeECKeyPair *pair,const struct AnodeECKey *pub,const struct AnodeECKey *priv);
|
||||
void AnodeECKeyPair_destroy(struct AnodeECKeyPair *pair);
|
||||
int AnodeECKeyPair_agree(const struct AnodeECKeyPair *my_key_pair,const struct AnodeECKey *their_pub_key,unsigned char *key_buf,unsigned int key_len);
|
||||
|
||||
/* Provides access to the secure PRNG used to generate keys */
|
||||
void AnodeEC_random(unsigned char *buf,unsigned int len);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,118 @@
|
||||
/* libanode: the Anode C reference implementation
|
||||
* Copyright (C) 2009-2010 Adam Ierymenko <adam.ierymenko@gmail.com>
|
||||
*
|
||||
* This program 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 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 <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "environment.h"
|
||||
|
||||
#ifdef WINDOWS
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
static char Anode_cache_base[1024] = { 0 };
|
||||
|
||||
const char *Anode_get_cache()
|
||||
{
|
||||
if (Anode_cache_base[0])
|
||||
return Anode_cache_base;
|
||||
|
||||
#ifdef WINDOWS
|
||||
#else
|
||||
char tmp[1024];
|
||||
char home[1024];
|
||||
unsigned int i;
|
||||
struct stat st;
|
||||
const char *_home = getenv("HOME");
|
||||
|
||||
if (!_home)
|
||||
return (const char *)0;
|
||||
for(i=0;i<sizeof(home);++i) {
|
||||
home[i] = _home[i];
|
||||
if (!home[i]) {
|
||||
if (i == 0)
|
||||
return (const char *)0;
|
||||
else if (home[i-1] == ANODE_PATH_SEPARATOR)
|
||||
home[i-1] = (char)0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == sizeof(home))
|
||||
return (const char *)0;
|
||||
|
||||
#ifdef __APPLE__
|
||||
snprintf(tmp,sizeof(tmp),"%s%cLibrary",home,ANODE_PATH_SEPARATOR);
|
||||
tmp[sizeof(tmp)-1] = (char)0;
|
||||
if (!stat(tmp,&st)) {
|
||||
sprintf(tmp,"%s%cLibrary%cCaches",home,ANODE_PATH_SEPARATOR,ANODE_PATH_SEPARATOR);
|
||||
if (stat(tmp,&st)) {
|
||||
if (mkdir(tmp,0700))
|
||||
return (const char *)0;
|
||||
}
|
||||
snprintf(Anode_cache_base,sizeof(Anode_cache_base),"%s%ccom.zerotier.anode",tmp,ANODE_PATH_SEPARATOR);
|
||||
Anode_cache_base[sizeof(Anode_cache_base)-1] = (char)0;
|
||||
if (stat(Anode_cache_base,&st)) {
|
||||
if (mkdir(Anode_cache_base,0700)) {
|
||||
Anode_cache_base[0] = (char)0;
|
||||
return (const char *)0;
|
||||
}
|
||||
}
|
||||
return Anode_cache_base;
|
||||
}
|
||||
#endif
|
||||
|
||||
snprintf(tmp,sizeof(tmp),"%s%c.anode",home,ANODE_PATH_SEPARATOR);
|
||||
tmp[sizeof(tmp)-1] = (char)0;
|
||||
if (stat(tmp,&st)) {
|
||||
if (mkdir(tmp,0700)) {
|
||||
Anode_cache_base[0] = (char)0;
|
||||
return (const char *)0;
|
||||
}
|
||||
}
|
||||
snprintf(Anode_cache_base,sizeof(Anode_cache_base),"%s%ccaches",tmp,ANODE_PATH_SEPARATOR);
|
||||
Anode_cache_base[sizeof(Anode_cache_base)-1] = (char)0;
|
||||
if (stat(Anode_cache_base,&st)) {
|
||||
if (mkdir(Anode_cache_base,0700)) {
|
||||
Anode_cache_base[0] = (char)0;
|
||||
return (const char *)0;
|
||||
}
|
||||
}
|
||||
|
||||
return Anode_cache_base;
|
||||
#endif
|
||||
}
|
||||
|
||||
char *Anode_get_cache_sub(const char *cache_subdir,char *buf,unsigned int len)
|
||||
{
|
||||
struct stat st;
|
||||
const char *cache_base = Anode_get_cache();
|
||||
|
||||
if (!len)
|
||||
return (char *)0;
|
||||
if (!cache_base)
|
||||
return (char *)0;
|
||||
|
||||
snprintf(buf,len,"%s%c%s",cache_base,ANODE_PATH_SEPARATOR,cache_subdir);
|
||||
buf[len-1] = (char)0;
|
||||
if (stat(buf,&st)) {
|
||||
if (mkdir(buf,0700))
|
||||
return (char *)0;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
Loaded 20 of 173 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user