├── README.md ├── include ├── libp2p │ ├── utils │ │ ├── urlencode.h │ │ ├── string_list.h │ │ ├── linked_list.h │ │ ├── vector.h │ │ ├── threadsafe_buffer.h │ │ └── logger.h │ ├── os │ │ ├── timespec.h │ │ ├── memstream.h │ │ └── utils.h │ ├── crypto │ │ ├── sha512.h │ │ ├── sha1.h │ │ ├── encoding │ │ │ ├── x509.h │ │ │ ├── base16.h │ │ │ ├── base58.h │ │ │ ├── base32.h │ │ │ └── base64.h │ │ ├── aes.h │ │ ├── sha256.h │ │ ├── key.h │ │ ├── ephemeral.h │ │ └── rsa.h │ ├── yamux │ │ ├── config.h │ │ ├── frame.h │ │ └── stream.h │ ├── net │ │ ├── server.h │ │ ├── p2pnet.h │ │ ├── protocol.h │ │ └── connectionstream.h │ ├── conn │ │ ├── transport_dialer.h │ │ ├── connection.h │ │ ├── session.h │ │ └── dialer.h │ ├── nodeio │ │ └── nodeio.h │ ├── routing │ │ ├── kademlia.h │ │ ├── dht_protocol.h │ │ └── dht.h │ ├── peer │ │ └── providerstore.h │ ├── db │ │ ├── filestore.h │ │ └── datastore.h │ ├── swarm │ │ └── swarm.h │ ├── secio │ │ ├── exchange.h │ │ ├── propose.h │ │ └── secio.h │ ├── hashmap │ │ └── hashmap.h │ ├── record │ │ ├── message.h │ │ └── record.h │ └── identify │ │ └── identify.h └── mbedtls │ ├── net.h │ ├── havege.h │ ├── platform_time.h │ ├── arc4.h │ ├── base64.h │ ├── pkcs5.h │ ├── md_internal.h │ ├── padlock.h │ ├── ssl_cookie.h │ ├── error.h │ ├── cipher_internal.h │ ├── entropy_poll.h │ ├── certs.h │ ├── version.h │ └── aesni.h ├── .gitignore ├── thirdparty ├── Makefile └── mbedtls │ └── version.c ├── hashmap └── Makefile ├── test ├── test_net.h ├── crypto │ ├── test_base32.h │ ├── test_mac.h │ ├── test_aes.h │ └── test_base58.h ├── Makefile ├── test_multistream.h ├── test_mbedtls.h ├── mock_stream.h ├── test_helper.h ├── multihash │ └── test_multihash.h └── test_peer.h ├── nodeio ├── Makefile └── nodeio.c ├── identify └── Makefile ├── os ├── Makefile └── timespec.c ├── db ├── Makefile ├── filestore.c └── datastore.c ├── net ├── udp.c ├── sctp.c ├── Makefile ├── tcp.c ├── TODO └── stream.c ├── record ├── Makefile └── message_handler.c ├── peer └── Makefile ├── swarm ├── Makefile ├── HowConnectionsWork.txt └── SwarmConnectionFlow.txt ├── secio ├── Makefile └── char_vector.c ├── conn ├── Makefile ├── connection.c ├── tcp_transport_dialer.c └── transport_dialer.c ├── crypto ├── Makefile ├── sha512.c ├── encoding │ ├── Makefile │ ├── base64.c │ ├── base16.c │ └── x509.c ├── sha256.c ├── peerutils.c └── aes.c ├── utils ├── Makefile ├── string_list.c ├── linked_list.c ├── urlencode.c └── vector.c ├── yamux ├── Makefile └── frame.c ├── routing └── Makefile ├── .project ├── LICENSE └── Makefile /README.md: -------------------------------------------------------------------------------- 1 | # c-libp2p 2 | Implementation of libp2p in C. 3 | -------------------------------------------------------------------------------- /include/libp2p/utils/urlencode.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | char *libp2p_utils_url_encode(char *src); 4 | char *libp2p_utils_url_decode(char *src); 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | 3 | !.gitignore 4 | !Makefile 5 | !**/ 6 | 7 | *.o 8 | .settings/language.settings.xml 9 | *.a 10 | test/testit_libp2p 11 | -------------------------------------------------------------------------------- /thirdparty/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | cd mbedtls; make all; 3 | 4 | clean: 5 | # this is a waste of time. Uncomment if you make changes to mbedtls 6 | #cd mbedtls; make clean; -------------------------------------------------------------------------------- /hashmap/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -O0 -I../include -g3 3 | LFLAGS = 4 | DEPS = 5 | OBJS = hashmap.o 6 | 7 | %.o: %.c $(DEPS) 8 | $(CC) -c -o $@ $< $(CFLAGS) 9 | 10 | 11 | all: $(OBJS) 12 | 13 | clean: 14 | rm -f *.o 15 | -------------------------------------------------------------------------------- /include/libp2p/utils/string_list.h: -------------------------------------------------------------------------------- 1 | struct StringList { 2 | char* string; 3 | struct StringList* next; 4 | }; 5 | 6 | struct StringList* libp2p_utils_string_list_new(); 7 | 8 | void libp2p_utils_string_list_free(struct StringList* in); 9 | -------------------------------------------------------------------------------- /include/libp2p/os/timespec.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /** 4 | * mac doesn't have timespec_get 5 | */ 6 | 7 | #ifdef __MACH__ 8 | #include 9 | #define TIME_UTC 1 10 | int timespec_get(struct timespec *ts, int base); 11 | #endif 12 | -------------------------------------------------------------------------------- /test/test_net.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include "libp2p/net/server.h" 3 | 4 | int test_net_server_startup_shutdown() { 5 | 6 | libp2p_net_server_start("127.0.0.1", 1234, NULL); 7 | sleep(5); 8 | libp2p_net_server_stop(); 9 | return 1; 10 | } 11 | -------------------------------------------------------------------------------- /include/libp2p/os/memstream.h: -------------------------------------------------------------------------------- 1 | #if defined(__linux__) 2 | # include 3 | #endif 4 | 5 | #include 6 | 7 | #if _POSIX_C_SOURCE < 200809L 8 | 9 | FILE *open_memstream(char **ptr, size_t *sizeloc); 10 | 11 | #endif /* _POSIX_C_SOURCE < 200809L */ 12 | -------------------------------------------------------------------------------- /nodeio/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -O0 -Wall -I../include -I../../c-protobuf 3 | 4 | ifdef DEBUG 5 | CFLAGS += -g3 6 | endif 7 | 8 | LFLAGS = 9 | DEPS = 10 | OBJS = nodeio.o 11 | 12 | %.o: %.c $(DEPS) 13 | $(CC) -c -o $@ $< $(CFLAGS) 14 | 15 | all: $(OBJS) 16 | 17 | clean: 18 | rm -f *.o 19 | -------------------------------------------------------------------------------- /identify/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -O0 -Wall -Werror -I../include -I../../c-protobuf -std=c11 3 | 4 | ifdef DEBUG 5 | CFLAGS += -g3 6 | endif 7 | 8 | LFLAGS = 9 | DEPS = 10 | OBJS = identify.o 11 | 12 | %.o: %.c 13 | $(CC) -c -o $@ $< $(CFLAGS) 14 | 15 | all: $(OBJS) 16 | 17 | clean: 18 | rm -f *.o 19 | -------------------------------------------------------------------------------- /os/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -O0 -I../include -I../../c-protobuf -I../../c-multihash/include -I../../c-multiaddr/include -g3 3 | LFLAGS = 4 | DEPS = 5 | OBJS = utils.o memstream.o 6 | 7 | %.o: %.c $(DEPS) 8 | $(CC) -c -o $@ $< $(CFLAGS) 9 | 10 | 11 | all: $(OBJS) 12 | 13 | clean: 14 | rm -f $(OBJS) 15 | -------------------------------------------------------------------------------- /db/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -O0 -I../include -I../../c-protobuf -I../../c-multihash/include -I../../c-multiaddr/include -g3 -std=c99 3 | LFLAGS = 4 | DEPS = 5 | OBJS = datastore.o filestore.o 6 | 7 | %.o: %.c $(DEPS) 8 | $(CC) -c -o $@ $< $(CFLAGS) 9 | 10 | 11 | all: $(OBJS) 12 | 13 | clean: 14 | rm -f $(OBJS) 15 | -------------------------------------------------------------------------------- /net/udp.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "libp2p/net/p2pnet.h" 5 | 6 | /* Create a UDP socket. 7 | */ 8 | int socket_udp4(void) 9 | { 10 | int s; 11 | 12 | s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); 13 | 14 | if (s == -1) return -1; 15 | return s; 16 | } 17 | -------------------------------------------------------------------------------- /record/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -O0 -I../include -I../../c-protobuf -I../../c-multihash/include -I../../c-multiaddr/include -g3 3 | LFLAGS = 4 | DEPS = 5 | OBJS = record.o message.o message_handler.o 6 | 7 | %.o: %.c $(DEPS) 8 | $(CC) -c -o $@ $< $(CFLAGS) 9 | 10 | 11 | all: $(OBJS) 12 | 13 | clean: 14 | rm -f $(OBJS) 15 | -------------------------------------------------------------------------------- /net/sctp.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "libp2p/net/p2pnet.h" 5 | 6 | /* Create a SCTP socket. 7 | */ 8 | int socket_stream_sctp4(void) 9 | { 10 | int s; 11 | 12 | s = socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP); 13 | if (s == -1) return -1; 14 | return s; 15 | } 16 | -------------------------------------------------------------------------------- /peer/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -O0 -I../include -I../../c-protobuf -I../../c-multihash/include -I../../c-multiaddr/include -g3 -std=c11 3 | LFLAGS = 4 | DEPS = 5 | OBJS = peer.o peerstore.o providerstore.o 6 | 7 | %.o: %.c $(DEPS) 8 | $(CC) -c -o $@ $< $(CFLAGS) 9 | 10 | 11 | all: $(OBJS) 12 | 13 | clean: 14 | rm -f $(OBJS) 15 | -------------------------------------------------------------------------------- /swarm/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -O0 -Wall -I../include -I../../c-protobuf -I../../c-multiaddr/include -std=c99 3 | 4 | ifdef DEBUG 5 | CFLAGS += -g3 6 | endif 7 | 8 | LFLAGS = 9 | DEPS = 10 | OBJS = swarm.o 11 | 12 | %.o: %.c $(DEPS) 13 | $(CC) -c -o $@ $< $(CFLAGS) 14 | 15 | all: $(OBJS) 16 | 17 | clean: 18 | rm -f *.o 19 | -------------------------------------------------------------------------------- /secio/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -O0 -Wall -I../include -I../../c-protobuf -I../../c-multiaddr/include -std=c99 3 | 4 | ifdef DEBUG 5 | CFLAGS += -g3 6 | endif 7 | 8 | LFLAGS = 9 | DEPS = 10 | OBJS = exchange.o propose.o secio.o 11 | 12 | %.o: %.c $(DEPS) 13 | $(CC) -c -o $@ $< $(CFLAGS) 14 | 15 | all: $(OBJS) 16 | 17 | clean: 18 | rm -f *.o 19 | -------------------------------------------------------------------------------- /conn/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -O0 -I../include -I../../c-protobuf -I../../c-multihash/include -I../../c-multiaddr/include -g3 3 | LFLAGS = 4 | DEPS = 5 | OBJS = dialer.o transport_dialer.o connection.o tcp_transport_dialer.o session.o 6 | 7 | %.o: %.c $(DEPS) 8 | $(CC) -c -o $@ $< $(CFLAGS) 9 | 10 | 11 | all: $(OBJS) 12 | 13 | clean: 14 | rm -f *.o 15 | -------------------------------------------------------------------------------- /crypto/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -O0 -I../include -I../../c-protobuf -I../../c-multihash/include -g3 3 | LFLAGS = 4 | DEPS = 5 | OBJS = rsa.o sha256.o sha512.o sha1.o key.o peerutils.o ephemeral.o aes.o 6 | 7 | %.o: %.c $(DEPS) 8 | $(CC) -c -o $@ $< $(CFLAGS) 9 | 10 | 11 | all: $(OBJS) 12 | cd encoding; make all; 13 | 14 | clean: 15 | rm -f *.o 16 | cd encoding; make clean; 17 | -------------------------------------------------------------------------------- /utils/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -O0 -Wall -I../include -I../../c-multiaddr/include -std=c99 3 | 4 | ifdef DEBUG 5 | CFLAGS += -g3 6 | endif 7 | 8 | LFLAGS = 9 | DEPS = 10 | OBJS = string_list.o vector.o linked_list.o logger.o urlencode.o thread_pool.o threadsafe_buffer.o 11 | 12 | %.o: %.c $(DEPS) 13 | $(CC) -c -o $@ $< $(CFLAGS) 14 | 15 | all: $(OBJS) 16 | 17 | clean: 18 | rm -f *.o 19 | -------------------------------------------------------------------------------- /net/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -O0 -Wall -I../include -I../../c-protobuf -I../../c-multiaddr/include 3 | 4 | ifdef DEBUG 5 | CFLAGS += -g3 6 | endif 7 | 8 | LFLAGS = 9 | DEPS = 10 | OBJS = sctp.o socket.o tcp.o udp.o multistream.o protocol.o connectionstream.o stream.o server.o 11 | 12 | %.o: %.c $(DEPS) 13 | $(CC) -c -o $@ $< $(CFLAGS) 14 | 15 | all: $(OBJS) 16 | 17 | clean: 18 | rm -f *.o 19 | -------------------------------------------------------------------------------- /net/tcp.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "libp2p/net/p2pnet.h" 5 | 6 | /** 7 | * Methods for tcp sockets 8 | */ 9 | 10 | /** 11 | * Create a TCP socket. 12 | * @returns the socket descriptor returned by socket() 13 | */ 14 | int socket_tcp4(void) 15 | { 16 | int s; 17 | s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); 18 | return s; 19 | } 20 | -------------------------------------------------------------------------------- /include/libp2p/crypto/sha512.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /*** 4 | * hash a string using SHA512 5 | * @param input the input string 6 | * @param input_length the length of the input string 7 | * @param output where to place the results, should be 64 bytes 8 | * @returns number of bytes written, or 0 9 | */ 10 | int libp2p_crypto_hashing_sha512(const unsigned char* input, size_t input_length, unsigned char* output); 11 | 12 | -------------------------------------------------------------------------------- /yamux/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -O0 -Wall -Werror -I../include -I../../c-protobuf -std=c11 3 | 4 | ifdef DEBUG 5 | CFLAGS += -g3 6 | endif 7 | 8 | LFLAGS = 9 | DEPS = 10 | OBJS = frame.o session.o stream.o yamux.o ../os/timespec.o 11 | 12 | %.o: %.c 13 | $(CC) -c -o $@ $< $(CFLAGS) 14 | 15 | all: $(OBJS) 16 | 17 | clean: 18 | rm -f *.o 19 | rm -f test 20 | 21 | test: all test.o 22 | $(CC) -o test test.o $(OBJS) $(CFLAGS) -------------------------------------------------------------------------------- /net/TODO: -------------------------------------------------------------------------------- 1 | - SCTP datagram and sequenced packets implementations, just stream for now. 2 | 3 | - UDP implementation, incomplete. 4 | 5 | - Implement some kind of network events such as libutp does, so libutp can 6 | be added and a more robust implementation for already implemented protocols, 7 | it may also be easier to switch protocols or use multiples at once from 8 | high-level calls. 9 | 10 | - Implement UDT 11 | 12 | - IPv6. 13 | -------------------------------------------------------------------------------- /crypto/sha512.c: -------------------------------------------------------------------------------- 1 | #include "mbedtls/sha512.h" 2 | 3 | /*** 4 | * hash a string using SHA512 5 | * @param input the input string 6 | * @param input_length the length of the input string 7 | * @param output where to place the results 8 | * @returns 1 9 | */ 10 | int libp2p_crypto_hashing_sha512(const unsigned char* input, size_t input_length, unsigned char* output) { 11 | mbedtls_sha512(input, input_length, output, 0); 12 | return 64; 13 | } 14 | -------------------------------------------------------------------------------- /include/libp2p/yamux/config.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | struct yamux_config 8 | { 9 | size_t accept_backlog ; 10 | uint32_t max_stream_window_size; 11 | }; 12 | 13 | #define YAMUX_DEFAULT_WINDOW (0x100*0x400) 14 | 15 | #define YAMUX_DEFAULT_CONFIG ((struct yamux_config)\ 16 | {\ 17 | .accept_backlog=0x100,\ 18 | .max_stream_window_size=YAMUX_DEFAULT_WINDOW\ 19 | }) 20 | -------------------------------------------------------------------------------- /crypto/encoding/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -O0 -I../../include -g3 -std=c99 3 | LFLAGS = 4 | DEPS = ../../include/libp2p/crypto/encoding/base58.h ../../include/libp2p/crypto/encoding/base64.h \ 5 | ../../include/libp2p/crypto/encoding/x509.h ../../include/libp2p/crypto/encoding/base16.h \ 6 | ../../include/libp2p/crypto/encoding/base32.h 7 | OBJS = base58.o base64.o x509.o base16.o base32.o 8 | 9 | %.o: %.c $(DEPS) 10 | $(CC) -c -o $@ $< $(CFLAGS) 11 | 12 | 13 | all: $(OBJS) 14 | 15 | clean: 16 | rm -f *.o 17 | -------------------------------------------------------------------------------- /record/message_handler.c: -------------------------------------------------------------------------------- 1 | #include "libp2p/record/message.h" 2 | #include "libp2p/peer/peer.h" 3 | 4 | /** 5 | * A generic handler for different types of messages 6 | */ 7 | 8 | 9 | int libp2p_record_handler_ping(struct Libp2pPeer* peer, struct KademliaMessage* message) { 10 | return 0; 11 | } 12 | 13 | int libp2p_record_message_handle(struct Libp2pPeer* peer, struct KademliaMessage* message) { 14 | switch (message->message_type) { 15 | case (MESSAGE_TYPE_PING): 16 | return libp2p_record_handler_ping(peer, message); 17 | default: 18 | break; 19 | } 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /include/libp2p/net/server.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Header for libp2p/net/server 3 | */ 4 | 5 | /*** 6 | * Start a server given the information 7 | * NOTE: This spins off a thread. 8 | * @param ip the ip address to attach to 9 | * @param port the port to use 10 | * @param protocol_handlers the protocol handlers 11 | * @returns true(1) on success, false(0) otherwise 12 | */ 13 | int libp2p_net_server_start(const char* ip, int port, struct Libp2pVector* protocol_handlers); 14 | 15 | /*** 16 | * Shut down the server started by libp2p_net_start_server 17 | * @returns true(1) on success, false(0) otherwise 18 | */ 19 | int libp2p_net_server_stop(); 20 | -------------------------------------------------------------------------------- /os/timespec.c: -------------------------------------------------------------------------------- 1 | #ifdef __MACH__ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "libp2p/os/timespec.h" 9 | 10 | int timespec_get(struct timespec *ts, int base) { 11 | switch (base) { 12 | case TIME_UTC: { 13 | clock_serv_t cclock; 14 | mach_timespec_t mts; 15 | host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); 16 | clock_get_time(cclock, &mts); 17 | mach_port_deallocate(mach_task_self(), cclock); 18 | ts->tv_sec = mts.tv_sec; 19 | ts->tv_nsec = mts.tv_nsec; 20 | return base; 21 | } 22 | } 23 | return 0; 24 | } 25 | #endif 26 | -------------------------------------------------------------------------------- /conn/connection.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "libp2p/conn/connection.h" 4 | 5 | struct Connection* libp2p_conn_connection_new(struct TransportDialer* transport_dialer, struct MultiAddress* multiaddress) { 6 | struct Connection* out = NULL; 7 | 8 | if (transport_dialer != NULL) { 9 | out = (struct Connection*)malloc(sizeof(struct Connection)); 10 | if (out != NULL) { 11 | //TODO implement this 12 | } 13 | } 14 | return out; 15 | } 16 | 17 | void libp2p_conn_connection_free(struct Connection* connection) { 18 | if (connection != NULL) { 19 | //close(connection->socket_handle); 20 | free(connection); 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /include/libp2p/utils/linked_list.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct Libp2pLinkedList { 4 | void* item; 5 | struct Libp2pLinkedList* next; 6 | }; 7 | 8 | /*** 9 | * Create a new linked list struct 10 | * @returns a new linked list struct 11 | */ 12 | struct Libp2pLinkedList* libp2p_utils_linked_list_new(); 13 | 14 | /** 15 | * Free resources from a linked list 16 | * NOTE: if the item is a complex object, free the item before 17 | * you call this method, and set item to NULL. Otherwise, this 18 | * method will call a simple free() 19 | * @param head the top of the linked list 20 | */ 21 | void libp2p_utils_linked_list_free(struct Libp2pLinkedList* head); 22 | -------------------------------------------------------------------------------- /routing/Makefile: -------------------------------------------------------------------------------- 1 | DHT_DIR = dht 2 | CC = gcc 3 | CFLAGS = -O0 -I../include -I../../c-multiaddr/include -I$(DHT_DIR) -g3 4 | LFLAGS = 5 | DEPS = # $(DHT_DIR)/dht.h 6 | OBJS = kademlia.o dht.o dht_protocol.o 7 | 8 | %.o: %.c $(DEPS) 9 | $(CC) -c -o $@ $< $(CFLAGS) 10 | 11 | all: $(OBJS) 12 | 13 | $(DHT_DIR)/dht.h: 14 | git clone https://github.com/jech/dht.git $(DHT_DIR) 15 | 16 | #dht.c: $(DEPS) 17 | # ln -s $(DHT_DIR)/dht.c . 18 | 19 | kademlia_test: $(OBJS) 20 | $(CC) -o kademlia_test kademlia_test.c kademlia.o dht.o $(CFLAGS) -pthread ../libp2p.a ../../c-multiaddr/libmultiaddr.a -lm 21 | 22 | clean: 23 | rm -f kademlia_test $(OBJS) 24 | #dht.c 25 | #rm -rf $(DHT_DIR) 26 | -------------------------------------------------------------------------------- /test/crypto/test_base32.h: -------------------------------------------------------------------------------- 1 | #include "libp2p/crypto/encoding/base32.h" 2 | 3 | int test_crypto_encoding_base32_encode() { 4 | size_t input_size = 1000; 5 | unsigned char input[input_size]; 6 | int minus = 0; 7 | for(int i = 0; i < input_size; i++) { 8 | if (input_size > 0 && input_size % 255 == 0) { 9 | minus += 255; 10 | } 11 | input[i] = input_size - minus; 12 | } 13 | 14 | size_t results_size = libp2p_crypto_encoding_base32_encode_size(input_size); 15 | unsigned char results[results_size]; 16 | int retVal = libp2p_crypto_encoding_base32_encode(input, input_size, &results[0], &results_size); 17 | if (retVal == 0) 18 | return 0; 19 | return 1; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /test/crypto/test_mac.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "libp2p/crypto/sha256.h" 4 | 5 | int test_crypto_hashing_sha256() { 6 | int array_length = 255; 7 | char test_array[array_length]; 8 | 9 | for(int i = 0; i < array_length; i++) { 10 | int j = i % 255; 11 | test_array[i] = i; 12 | } 13 | 14 | char result_mac1[32]; 15 | char result_mac2[32]; 16 | 17 | libp2p_crypto_hashing_sha256((unsigned char*)&test_array[0], array_length, (unsigned char*)&result_mac1[0]); 18 | libp2p_crypto_hashing_sha256((unsigned char*)&test_array[0], array_length, (unsigned char*)&result_mac2[0]); 19 | 20 | if (memcmp(result_mac1, result_mac2, 32) != 0) 21 | return 0; 22 | return 1; 23 | } 24 | -------------------------------------------------------------------------------- /utils/string_list.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "libp2p/utils/string_list.h" 4 | 5 | struct StringList* libp2p_utils_string_list_new() { 6 | struct StringList* list = (struct StringList*)malloc(sizeof(struct StringList)); 7 | if (list != NULL) 8 | { 9 | list->next = NULL; 10 | list->string = NULL; 11 | } 12 | return list; 13 | } 14 | 15 | void libp2p_utils_string_list_free(struct StringList* list) { 16 | struct StringList* current = list; 17 | struct StringList* temp = NULL; 18 | 19 | while(current != NULL) { 20 | if (current->string != NULL) 21 | free(current->string); 22 | temp = current->next; 23 | free(current); 24 | current = temp; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /utils/linked_list.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "libp2p/utils/linked_list.h" 4 | 5 | struct Libp2pLinkedList* libp2p_utils_linked_list_new() { 6 | struct Libp2pLinkedList* out = (struct Libp2pLinkedList*)malloc(sizeof(struct Libp2pLinkedList)); 7 | if (out != NULL) { 8 | out->item = NULL; 9 | out->next = NULL; 10 | } 11 | return out; 12 | } 13 | 14 | void libp2p_utils_linked_list_free(struct Libp2pLinkedList* head) { 15 | struct Libp2pLinkedList* current = head; 16 | struct Libp2pLinkedList* next = NULL; 17 | while (current != NULL) { 18 | next = current->next; 19 | if (current->item != NULL) { 20 | free(current->item); 21 | current->item = NULL; 22 | } 23 | free(current); 24 | current = next; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /include/libp2p/conn/transport_dialer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "multiaddr/multiaddr.h" 4 | #include "libp2p/net/stream.h" 5 | #include "libp2p/utils/linked_list.h" 6 | 7 | struct TransportDialer { 8 | char* peer_id; 9 | struct RsaPrivateKey* private_key; 10 | int (*can_handle)(const struct MultiAddress* multiaddr); 11 | struct Stream* (*dial)(const struct TransportDialer* transport_dialer, const struct MultiAddress* multiaddr); 12 | }; 13 | 14 | struct TransportDialer* libp2p_conn_transport_dialer_new(char* peer_id, struct RsaPrivateKey* private_key); 15 | void libp2p_conn_transport_dialer_free(struct TransportDialer* in); 16 | 17 | struct Stream* libp2p_conn_transport_dialer_get(const struct Libp2pLinkedList* transport_dialers, const struct MultiAddress* multiaddr); 18 | -------------------------------------------------------------------------------- /test/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -O0 -I../include -I. -I../../c-multihash/include -I../../c-multiaddr/include -std=c11 3 | 4 | ifdef DEBUG 5 | CFLAGS += -g3 6 | endif 7 | 8 | LFLAGS = -L../ -L../../c-multihash -L../../c-multiaddr 9 | DEPS = crypto/test_base58.h crypto/test_rsa.h test_mbedtls.h 10 | OBJS = testit.o ../../c-protobuf/protobuf.o ../../c-protobuf/varint.o ../libp2p.a 11 | 12 | %.o: %.c $(DEPS) 13 | $(CC) -c -o $@ $< $(CFLAGS) 14 | 15 | testit_libp2p: $(OBJS) $(DEPS) 16 | $(CC) -o $@ $(OBJS) $(LFLAGS) -lp2p -lm -lmultihash -lmultiaddr -lpthread 17 | 18 | all_others: 19 | cd ../crypto; make all; 20 | cd ../thirdparty; make all; 21 | 22 | all: all_others testit_libp2p 23 | 24 | clean: 25 | rm -f *.o 26 | rm -f testit_libp2p 27 | 28 | test: clean testit_libp2p 29 | -------------------------------------------------------------------------------- /include/libp2p/nodeio/nodeio.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "libp2p/net/stream.h" 4 | #include "libp2p/conn/session.h" 5 | 6 | int libp2p_nodeio_upgrade_stream(struct SessionContext* context); 7 | int libp2p_nodeio_handshake(struct SessionContext* context); 8 | int libp2p_nodeio_handle(struct SessionContext* context); 9 | /** 10 | * Called by requestor to get a protobuf'd node from a hash 11 | * @param context the session context 12 | * @param hash the hash 13 | * @param hash_size the length of the hash 14 | * @param results where to put the buffer 15 | * @param results_size the size of the results 16 | * @returns true(1) on success, otherwise false(0) 17 | */ 18 | int libp2p_nodeio_get(struct SessionContext* context, unsigned char* hash, int hash_size, unsigned char** results, size_t* results_length); 19 | -------------------------------------------------------------------------------- /include/libp2p/routing/kademlia.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "libp2p/utils/vector.h" 4 | #include "multiaddr/multiaddr.h" 5 | 6 | int start_kademlia(int sock, int family, char* peer_id, int timeout, struct Libp2pVector* bootstrap_addresses); 7 | int start_kademlia_multiaddress(struct MultiAddress* multiaddress, char* peer_id, int timeout, struct Libp2pVector* bootstrap_addresses); 8 | void stop_kademlia (void); 9 | 10 | void *kademlia_thread (void *ptr); 11 | void *announce_thread (void *ptr); 12 | 13 | int announce_kademlia (char* peer_id, uint16_t port); 14 | 15 | /*** 16 | * Search for a hash 17 | * @param peer_id the hash to search for 18 | * @param timeout timeout in seconds 19 | * @returns an array of MultiAddress 20 | */ 21 | struct MultiAddress** search_kademlia(char* peer_id, int timeout); 22 | 23 | int ping_kademlia (char *ip, uint16_t port); 24 | -------------------------------------------------------------------------------- /include/libp2p/crypto/sha1.h: -------------------------------------------------------------------------------- 1 | #ifndef _SHA1_H 2 | #define _SHA1_H 3 | 4 | #include 5 | #include 6 | 7 | typedef struct { 8 | uint32_t state[5]; 9 | uint32_t count[2]; 10 | uint8_t buffer[64]; 11 | } SHA1_CTX; 12 | 13 | #define SHA1_DIGEST_SIZE 20 14 | 15 | void SHA1_Init(SHA1_CTX* context); 16 | void SHA1_Update(SHA1_CTX* context, const uint8_t* data, const size_t len); 17 | void SHA1_Final(SHA1_CTX* context, uint8_t digest[SHA1_DIGEST_SIZE]); 18 | 19 | /*** 20 | * Hash the input using SHA1 21 | * @param input the input to hash 22 | * @param input_length the length of the input 23 | * @param output where the output is placed, should be 40 bytes in width 24 | * @returns the number of bytes written, or 0 on error 25 | */ 26 | int libp2p_crypto_hashing_sha1(const unsigned char* input, size_t input_length, unsigned char* output); 27 | 28 | #endif /* _SHA1_H */ 29 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | c-libp2p 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | 14 | 15 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 16 | full,incremental, 17 | 18 | 19 | 20 | 21 | 22 | org.eclipse.cdt.core.cnature 23 | org.eclipse.cdt.core.ccnature 24 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 25 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 26 | 27 | 28 | -------------------------------------------------------------------------------- /db/filestore.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "libp2p/db/filestore.h" 5 | #include "libp2p/os/utils.h" 6 | 7 | /*** 8 | * initialize the structure of the filestore 9 | * @param filestore the struct to initialize 10 | * @returns true(1) on success 11 | */ 12 | int libp2p_filestore_init(struct Filestore* datastore, const char* config_root) { 13 | return 1; 14 | } 15 | 16 | /*** 17 | * initialize the structure of the filestore 18 | * @param filestore the struct to initialize 19 | * @returns true(1) on success 20 | */ 21 | struct Filestore* libp2p_filestore_new() { 22 | struct Filestore* f = malloc(sizeof(struct Filestore)); 23 | if (f == NULL) 24 | return 0; 25 | f->handle = NULL; 26 | f->node_get = NULL; 27 | return f; 28 | } 29 | 30 | /*** 31 | * deallocate the memory and clear resources from a filestore_init 32 | * @param filestore the struct to deallocate 33 | * @returns true(1) 34 | */ 35 | int libp2p_filestore_free(struct Filestore* filestore) { 36 | if (filestore != NULL) 37 | { 38 | free(filestore); 39 | } 40 | return 1; 41 | } 42 | -------------------------------------------------------------------------------- /include/libp2p/crypto/encoding/x509.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Wrappers around the x509 stuff 3 | */ 4 | 5 | #ifndef __LIBP2P_CRYPTO_ENCODING_X509_H__ 6 | #define __LIBP2P_CRYPTO_ENCODING_X509_H__ 7 | 8 | #include "libp2p/crypto/rsa.h" 9 | 10 | /** 11 | * Turn an RsaPrivateKey struct into a DER formatted array of bytes 12 | * @param private_key the RsaPrivateKey struct 13 | * @param bytes an array of 1600 bytes to hold the DER formatted data 14 | * @returns true(1) on success 15 | */ 16 | int libp2p_crypto_encoding_x509_private_key_to_der(struct RsaPrivateKey* private_key, unsigned char* bytes[1600]); 17 | 18 | /** 19 | * Take a DER formatted char array and turn it into an RsaPrivateKey 20 | * @param der the DER formatted char array 21 | * @param der_length the number of bytes in the char array 22 | * @param private_key the struct to put the data in. Memory should have already been allocated for the struct. 23 | * @returns true(1) on success 24 | */ 25 | int libp2p_crypto_encoding_x509_der_to_private_key(unsigned char* der, size_t der_length, struct RsaPrivateKey* private_key); 26 | 27 | #endif /* x509_h */ 28 | -------------------------------------------------------------------------------- /utils/urlencode.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | char *libp2p_utils_url_encode(char *src) 6 | { 7 | const char *hex = "0123456789abcdef"; 8 | char *p, *dst = malloc (strlen(src) * 3); 9 | 10 | if (!dst) return NULL; 11 | 12 | for(p = dst ; *src ; src++ ) { 13 | if( isalnum(*src)){ 14 | *p++ = *src; 15 | } else { 16 | *p++ = '%'; 17 | *p++ = hex[*src >> 4]; 18 | *p++ = hex[*src & 15]; 19 | } 20 | } 21 | *p++ = '\0'; 22 | return realloc(dst, (size_t) (p - dst)); 23 | } 24 | 25 | int h2b(int c) 26 | { 27 | if (c >= '0' && c <= '9') { 28 | return c - '0'; 29 | } else if (c >= 'a' && c <= 'f') { 30 | return c - 'a' + 10; 31 | } else if (c >= 'A' && c <= 'F') { 32 | return c - 'A' + 10; 33 | } 34 | return 0; // ? 35 | } 36 | 37 | char *libp2p_utils_url_decode(char *src) 38 | { 39 | char *p, *dst = malloc (strlen(src) + 1); 40 | 41 | for(p = dst ; *src ; src++ ) { 42 | if(*src != '%'){ 43 | *p++ = *src; 44 | } else { 45 | *p = h2b(*(++src)) << 4; 46 | *p++ |= h2b(*(++src)) & 15; 47 | } 48 | } 49 | *p++ = '\0'; 50 | return realloc(dst, (size_t) (p - dst)); 51 | } 52 | -------------------------------------------------------------------------------- /test/crypto/test_aes.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "libp2p/crypto/aes.h" 7 | 8 | int test_aes() { 9 | char key[32]; 10 | char iv[17] = "ae287j789wcqe46a"; 11 | char iv_original[17] = "ae287j789wcqe46a"; 12 | unsigned char* encrypted = NULL; 13 | size_t output_size = 0; 14 | char* input = "inc the null, this is 40 bytes of data"; 15 | unsigned char* unencrypted = NULL; 16 | size_t input_size = 40; 17 | int retVal = 0; 18 | 19 | if (libp2p_crypto_aes_key_generate(key) != 1) 20 | goto exit; 21 | 22 | if (libp2p_crypto_aes_encrypt(key, iv, input, input_size, &encrypted, &output_size) != 1) 23 | goto exit; 24 | 25 | if (output_size != 48) 26 | goto exit; 27 | 28 | if (encrypted == NULL) 29 | goto exit; 30 | 31 | if (libp2p_crypto_aes_decrypt(key, iv_original, (char*)encrypted, output_size, &unencrypted, &output_size) != 1) 32 | goto exit; 33 | 34 | if (output_size != 48) 35 | goto exit; 36 | 37 | if (strncmp(input, (char*)unencrypted, input_size) != 0) 38 | goto exit; 39 | 40 | retVal = 1; 41 | exit: 42 | if (encrypted != NULL) 43 | free(encrypted); 44 | if (unencrypted != NULL) 45 | free(unencrypted); 46 | return retVal; 47 | } 48 | -------------------------------------------------------------------------------- /secio/char_vector.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "libp2p/secio/char_vector.h" 4 | 5 | struct UnsignedCharVector* char_vector_new() { 6 | struct UnsignedCharVector* vector = (struct UnsignedCharVector*)malloc(sizeof(struct UnsignedCharVector)); 7 | vector->buffer = NULL; 8 | vector->buffer_size = 0; 9 | return vector; 10 | } 11 | 12 | void char_vector_free(struct UnsignedCharVector* vector) { 13 | if (vector != NULL) { 14 | if (vector->buffer != NULL) 15 | free(vector->buffer); 16 | vector->buffer = NULL; 17 | vector->buffer_size = 0; 18 | free(vector); 19 | vector = NULL; 20 | } 21 | } 22 | 23 | int char_vector_add(struct UnsignedCharVector* vector, unsigned char* in_bytes, size_t in_size) { 24 | // make new memory 25 | if (vector->buffer == NULL) { 26 | vector->buffer = (unsigned char*)malloc(in_size); 27 | if (vector->buffer == NULL) 28 | return 0; 29 | vector->buffer_size = in_size; 30 | } else { 31 | vector->buffer = (unsigned char*)realloc(vector->buffer_size + in_size); 32 | if (vector->buffer == NULL) 33 | return 0; 34 | memcpy(&vector->buffer[vector->buffer_size], in_bytes, in_size); 35 | vector->buffer_size = in_size + vector->buffer_size; 36 | } 37 | return 1; 38 | } 39 | -------------------------------------------------------------------------------- /yamux/frame.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "libp2p/yamux/frame.h" 5 | 6 | enum eness 7 | { 8 | unk, 9 | little, 10 | big 11 | }; 12 | 13 | static enum eness eness = unk; 14 | 15 | static void set_eness() 16 | { 17 | uint16_t x = 1; 18 | 19 | if (*(char*)&x == 1) 20 | eness = little; 21 | else 22 | eness = big; 23 | } 24 | 25 | /*** 26 | * convert the frame so it can be sent over the network (makes the endienness correct) 27 | * @param frame the frame to encode 28 | */ 29 | void encode_frame(struct yamux_frame* frame) 30 | { 31 | if (eness == unk) 32 | set_eness(); 33 | 34 | frame->flags = htons(frame->flags ); 35 | frame->streamid = htonl(frame->streamid); 36 | frame->length = htonl(frame->length ); 37 | } 38 | 39 | /*** 40 | * Convert the frame from the network format to the local format (corrects endienness) 41 | * @param frame the frame to decode 42 | */ 43 | void decode_frame(struct yamux_frame* frame) 44 | { 45 | if (eness == unk) 46 | set_eness(); 47 | 48 | frame->flags = ntohs(frame->flags ); 49 | frame->streamid = ntohl(frame->streamid); 50 | frame->length = ntohl(frame->length ); 51 | } 52 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 AGORISE, LTD. 4 | An International Business Company, Cyprus Reg# ΗΕ375959 5 | 6 | Contains works from BitShares Munich IVS 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in all 16 | copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | SOFTWARE. 25 | -------------------------------------------------------------------------------- /include/mbedtls/net.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file net.h 3 | * 4 | * \brief Deprecated header file that includes mbedtls/net_sockets.h 5 | * 6 | * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved 7 | * SPDX-License-Identifier: Apache-2.0 8 | * 9 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 10 | * not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 17 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | * 21 | * This file is part of mbed TLS (https://tls.mbed.org) 22 | * 23 | * \deprecated Superseded by mbedtls/net_sockets.h 24 | */ 25 | 26 | #if !defined(MBEDTLS_DEPRECATED_REMOVED) 27 | #include "mbedtls/net_sockets.h" 28 | #if defined(MBEDTLS_DEPRECATED_WARNING) 29 | #warning "Deprecated header file: Superseded by mbedtls/net_sockets.h" 30 | #endif /* MBEDTLS_DEPRECATED_WARNING */ 31 | #endif /* !MBEDTLS_DEPRECATED_REMOVED */ 32 | -------------------------------------------------------------------------------- /conn/tcp_transport_dialer.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "multiaddr/multiaddr.h" 6 | #include "libp2p/net/p2pnet.h" 7 | #include "libp2p/net/connectionstream.h" 8 | #include "libp2p/conn/connection.h" 9 | #include "libp2p/conn/transport_dialer.h" 10 | #include "multiaddr/multiaddr.h" 11 | 12 | /** 13 | * An implementation of a tcp transport dialer 14 | */ 15 | 16 | int libp2p_conn_tcp_can_handle(const struct MultiAddress* addr) { 17 | return multiaddress_is_ip(addr); 18 | } 19 | 20 | struct Stream* libp2p_conn_tcp_dial(const struct TransportDialer* transport_dialer, const struct MultiAddress* addr) { 21 | int socket_descriptor = socket_open4(); 22 | char* ip; 23 | int port = multiaddress_get_ip_port(addr); 24 | if (!multiaddress_get_ip_address(addr, &ip)) 25 | return NULL; 26 | 27 | struct Stream* stream = libp2p_net_connection_new(socket_descriptor, ip, port, NULL); 28 | free(ip); 29 | 30 | return stream; 31 | } 32 | 33 | struct TransportDialer* libp2p_conn_tcp_transport_dialer_new(char* peer_id, struct RsaPrivateKey* private_key) { 34 | struct TransportDialer* out = libp2p_conn_transport_dialer_new(peer_id, private_key); 35 | out->can_handle = libp2p_conn_tcp_can_handle; 36 | out->dial = libp2p_conn_tcp_dial; 37 | return out; 38 | } 39 | -------------------------------------------------------------------------------- /include/libp2p/crypto/aes.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /** 4 | * Generate a new AES key 5 | * @param key where to store the 32 byte key 6 | * @returns true(1) on success 7 | */ 8 | int libp2p_crypto_aes_key_generate(char* key); 9 | 10 | /** 11 | * Encrypt a block of text 12 | * @param key the aes key (32 bytes) 13 | * @param iv the random part of encryption (16 bytes) 14 | * @param input the text to encrypt 15 | * @param input_size the length of the array 16 | * @param output where the output will be placed 17 | * @param output_size the length of the memory allocated for output 18 | * @returns true(1) on success, otherwise false(0) 19 | */ 20 | int libp2p_crypto_aes_encrypt(char* key, char* iv, char* input, size_t input_size, unsigned char** output, size_t* output_size); 21 | 22 | /** 23 | * Decrypt a block of text 24 | * @param key the aes key (32 bytes) 25 | * @param iv the random part of encryption (16 bytes) 26 | * @param input the text to encrypt 27 | * @param input_size the length of the array 28 | * @param output where the output will be placed 29 | * @param output_size the length of the memory allocated for output 30 | * @returns true(1) on success, otherwise false(0) 31 | */ 32 | int libp2p_crypto_aes_decrypt(char* key, char* iv, char* input, size_t input_size, unsigned char** output, size_t* output_size); 33 | -------------------------------------------------------------------------------- /include/libp2p/yamux/frame.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | typedef uint8_t yamux_version ; 7 | typedef uint32_t yamux_streamid; 8 | 9 | #define YAMUX_VERSION (0x00) 10 | #define YAMUX_STREAMID_SESSION (0) 11 | 12 | enum yamux_frame_type 13 | { 14 | yamux_frame_data = 0x00, 15 | yamux_frame_window_update = 0x01, 16 | yamux_frame_ping = 0x02, 17 | yamux_frame_go_away = 0x03 18 | }; 19 | enum yamux_frame_flags 20 | { 21 | yamux_frame_nil = 0x0000, 22 | 23 | yamux_frame_syn = 0x0001, 24 | yamux_frame_ack = 0x0002, 25 | yamux_frame_fin = 0x0004, 26 | yamux_frame_rst = 0x0008 27 | }; 28 | 29 | #pragma pack(push,1) 30 | struct yamux_frame 31 | { 32 | yamux_version version ; 33 | uint8_t type ; 34 | uint16_t flags ; 35 | yamux_streamid streamid; 36 | uint32_t length ; 37 | }; 38 | #pragma pack(pop) 39 | 40 | /*** 41 | * convert the frame so it can be sent over the network (makes the endienness correct) 42 | * @param frame the frame to encode 43 | */ 44 | void encode_frame(struct yamux_frame* frame); 45 | 46 | /*** 47 | * Convert the frame from the network format to the local format (corrects endienness) 48 | * @param frame the frame to decode 49 | */ 50 | void decode_frame(struct yamux_frame* frame); 51 | 52 | 53 | -------------------------------------------------------------------------------- /include/libp2p/peer/providerstore.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "libp2p/db/datastore.h" 4 | #include "libp2p/peer/peer.h" 5 | 6 | /** 7 | * Contains a hash and the peer id of 8 | * who can provide it 9 | */ 10 | struct ProviderEntry { 11 | unsigned char* hash; 12 | int hash_size; 13 | unsigned char* peer_id; 14 | int peer_id_size; 15 | }; 16 | 17 | /*** 18 | * A structure to store providers. The implementation 19 | * is a vector of ProviderEntry structures, which contain 20 | * the hash and peer id. 21 | */ 22 | struct ProviderStore { 23 | struct Libp2pVector* provider_entries; 24 | // this is requred so we can look locally for requests 25 | const struct Datastore* datastore; 26 | const struct Libp2pPeer* local_peer; 27 | }; 28 | 29 | /** 30 | * Create a new ProviderStore 31 | * @returns a ProviderStore struct 32 | */ 33 | struct ProviderStore* libp2p_providerstore_new(const struct Datastore* datastore, const struct Libp2pPeer* local_peer); 34 | 35 | /*** 36 | * Clean resources used by a ProviderStore 37 | * @param in the ProviderStore to clean up 38 | */ 39 | void libp2p_providerstore_free(struct ProviderStore* in); 40 | 41 | int libp2p_providerstore_add(struct ProviderStore* store, const unsigned char* hash, int hash_size, const unsigned char* peer_id, int peer_id_size); 42 | 43 | int libp2p_providerstore_get(struct ProviderStore* store, const unsigned char* hash, int hash_size, unsigned char** peer_id, int *peer_id_size); 44 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | DEBUG = true 3 | export DEBUG 4 | 5 | LINKER_FLAGS= 6 | 7 | OBJS = \ 8 | conn/*.o \ 9 | crypto/*.o \ 10 | crypto/encoding/*.o \ 11 | db/*.o \ 12 | thirdparty/mbedtls/*.o \ 13 | hashmap/hashmap.o \ 14 | identify/*.o \ 15 | net/*.o \ 16 | os/*.o \ 17 | peer/*.o \ 18 | record/*.o \ 19 | routing/*.o \ 20 | secio/*.o \ 21 | utils/*.o \ 22 | swarm/*.o \ 23 | yamux/*.o 24 | 25 | link: 26 | ar rcs libp2p.a $(OBJS) $(LINKER_FLAGS) 27 | 28 | compile: 29 | cd conn; make all; 30 | cd crypto; make all; 31 | cd db; make all; 32 | cd thirdparty; make all; 33 | cd hashmap; make all; 34 | cd identify; make all; 35 | cd net; make all; 36 | cd os; make all; 37 | cd peer; make all; 38 | cd record; make all; 39 | cd routing; make all; 40 | cd secio; make all; 41 | cd swarm; make all; 42 | cd utils; make all; 43 | cd yamux; make all; 44 | 45 | test: compile link 46 | cd test; make all; 47 | 48 | rebuild: clean all 49 | 50 | all: test 51 | 52 | clean: 53 | cd conn; make clean; 54 | cd crypto; make clean; 55 | cd db; make clean; 56 | cd hashmap; make clean; 57 | cd identify; make clean; 58 | cd net; make clean; 59 | cd os; make clean; 60 | cd peer; make clean; 61 | cd thirdparty; make clean 62 | cd record; make clean; 63 | cd routing; make clean; 64 | cd secio; make clean; 65 | cd swarm; make clean; 66 | cd utils; make clean; 67 | cd test; make clean; 68 | cd yamux; make clean; 69 | rm -rf libp2p.a 70 | 71 | -------------------------------------------------------------------------------- /include/libp2p/crypto/sha256.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "mbedtls/sha256.h" 4 | 5 | /*** 6 | * hash a string using SHA256 7 | * @param input the input string 8 | * @param input_length the length of the input string 9 | * @param output where to place the results 10 | * @returns 1 11 | */ 12 | int libp2p_crypto_hashing_sha256(const unsigned char* input, size_t input_length, unsigned char* output); 13 | 14 | /** 15 | * Initialize a sha256 hmac process 16 | * @param ctx the context 17 | * @returns true(1) on success, otherwise false(0) 18 | */ 19 | int libp2p_crypto_hashing_sha256_init(mbedtls_sha256_context* ctx); 20 | 21 | /** 22 | * Update a sha256 hmac process 23 | * @param ctx the context 24 | * @param input the data to add 25 | * @param input_size the size of input 26 | * @returns true(1) on success, otherwise false(0) 27 | */ 28 | int libp2p_crypto_hashing_sha256_update(mbedtls_sha256_context* ctx, const unsigned char* input, size_t input_size); 29 | 30 | /** 31 | * finalize a sha256 hmac process 32 | * @param ctx the context 33 | * @param hash where to put the results (for SHA256, should be 32 bytes long) 34 | * @returns true(1) on success, otherwise false(0) 35 | */ 36 | int libp2p_crypto_hashing_sha256_finish(mbedtls_sha256_context* ctx, unsigned char* hash); 37 | 38 | /** 39 | * Clean up allocated memory 40 | * @param ctx the context 41 | * @returns true(1) on success, otherwise false(0) 42 | */ 43 | int libp2p_crypto_hashing_sha256_free(mbedtls_sha256_context* ctx); 44 | -------------------------------------------------------------------------------- /include/libp2p/db/filestore.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | /*** 6 | * Interface to data storage 7 | */ 8 | 9 | 10 | struct Filestore { 11 | 12 | // generic connection and status variables for the datastore 13 | void* handle; // a handle to the filesstore (a FSRepo struct) 14 | 15 | // function pointers for datastore operations 16 | /** 17 | * Retrieves a protobuf'd node from the disk 18 | * @param key the key 19 | * @param key_size the key size 20 | * @param data the protobuf'd results 21 | * @param data_size the size of the results 22 | * @param filestore a reference to the filestore struct 23 | */ 24 | int (*node_get)(const unsigned char* key, size_t key_size, 25 | void** data, size_t *data_size, const struct Filestore* filestore); 26 | }; 27 | 28 | /*** 29 | * Initialize the structure of the filestore to default settings. Used for 30 | * creating a new filestore on the disk. 31 | * @param filestore the struct to initialize 32 | * @param config_root the path to the root of IPFS 33 | * @returns true(1) on success 34 | */ 35 | int libp2p_filestore_init(struct Filestore* filestore, const char* config_root); 36 | 37 | /*** 38 | * initialize the structure of the filestore 39 | * @param filestore the struct to initialize 40 | * @returns true(1) on success 41 | */ 42 | struct Filestore* libp2p_filestore_new(); 43 | 44 | 45 | /*** 46 | * deallocate the memory and clear resources from a filestore_init 47 | * @param filestore the struct to deallocate 48 | * @returns true(1) 49 | */ 50 | int libp2p_filestore_free(struct Filestore* datastore); 51 | -------------------------------------------------------------------------------- /include/libp2p/swarm/swarm.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /*** 4 | * This listens for requests from the connected peers 5 | */ 6 | #include "libp2p/utils/thread_pool.h" 7 | #include "libp2p/db/datastore.h" 8 | #include "libp2p/db/filestore.h" 9 | #include "libp2p/peer/peer.h" 10 | 11 | struct SwarmContext { 12 | threadpool thread_pool; 13 | struct Libp2pVector* protocol_handlers; 14 | struct Datastore* datastore; 15 | struct Filestore* filestore; 16 | }; 17 | 18 | /*** 19 | * Add a connected peer to the swarm 20 | * NOTE: We should already have a connection to the peer 21 | * @param context the SwarmContext 22 | * @param peer the connected peer 23 | * @returns true(1) on success, false(0) otherwise 24 | */ 25 | int libp2p_swarm_add_peer(struct SwarmContext* context, struct Libp2pPeer* peer); 26 | 27 | /** 28 | * add an incoming connection 29 | * @param context the SwarmContext 30 | * @param file_descriptor the incoming file descriptor of the connection 31 | * @param ip the incoming ip (ipv4 format) 32 | * @param port the incoming port 33 | * @return true(1) on success, false(0) otherwise 34 | */ 35 | int libp2p_swarm_add_connection(struct SwarmContext* context, int file_descriptor, int ip, int port ); 36 | 37 | /** 38 | * Fire up the swarm engine, and return its context 39 | * @param protocol_handlers the protocol handlers 40 | * @param datastore the datastore 41 | * @param filestore the file store 42 | * @returns the SwarmContext 43 | */ 44 | struct SwarmContext* libp2p_swarm_new(struct Libp2pVector* protocol_handlers, struct Datastore* datastore, struct Filestore* filestore); 45 | -------------------------------------------------------------------------------- /include/libp2p/conn/connection.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /** 3 | * Implements an interface to connect and talk to different nodes. 4 | * A Dialer will connect, and return a Connection structure 5 | */ 6 | 7 | #include "libp2p/conn/transport_dialer.h" 8 | #include "multiaddr/multiaddr.h" 9 | 10 | struct Connection { 11 | int socket_handle; 12 | /** 13 | * Read from the stream 14 | * @param socket_handle the socket to read from 15 | * @param in what was read in NOTE: this allocates memory 16 | * @param in_size the number of bytes read in 17 | * @returns number of bytes written or negative number on error 18 | */ 19 | int (*read)(const struct Connection* conn, char** in, size_t* in_size); 20 | /** 21 | * Write to the stream 22 | * @param socket_handle the socket to write to 23 | * @param out the bytes to write to the stream 24 | * @param out_size the number of bytes to write 25 | * @returns 0 on success, otherwise an error code 26 | */ 27 | int (*write)(const struct Connection* conn, const char* out, size_t out_size); 28 | }; 29 | 30 | /** 31 | * creates a new connection 32 | * @param transport_dialer the TransportDialer to use 33 | * @param multiaddress the destination 34 | * @returns a connection that is ready to be read from / written to 35 | */ 36 | struct Connection* libp2p_conn_connection_new(struct TransportDialer* transport_dialer, struct MultiAddress* multiaddress); 37 | 38 | /*** 39 | * close a connection and dispose of struct 40 | * @param connection the resource to clean up 41 | */ 42 | void libp2p_conn_connection_free(struct Connection* connection); 43 | 44 | 45 | -------------------------------------------------------------------------------- /thirdparty/mbedtls/version.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Version information 3 | * 4 | * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 5 | * SPDX-License-Identifier: Apache-2.0 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | * not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * 19 | * This file is part of mbed TLS (https://tls.mbed.org) 20 | */ 21 | 22 | #if !defined(MBEDTLS_CONFIG_FILE) 23 | #include "mbedtls/config.h" 24 | #else 25 | #include MBEDTLS_CONFIG_FILE 26 | #endif 27 | 28 | #if defined(MBEDTLS_VERSION_C) 29 | 30 | #include "mbedtls/version.h" 31 | #include 32 | 33 | unsigned int mbedtls_version_get_number() 34 | { 35 | return( MBEDTLS_VERSION_NUMBER ); 36 | } 37 | 38 | void mbedtls_version_get_string( char *string ) 39 | { 40 | memcpy( string, MBEDTLS_VERSION_STRING, 41 | sizeof( MBEDTLS_VERSION_STRING ) ); 42 | } 43 | 44 | void mbedtls_version_get_string_full( char *string ) 45 | { 46 | memcpy( string, MBEDTLS_VERSION_STRING_FULL, 47 | sizeof( MBEDTLS_VERSION_STRING_FULL ) ); 48 | } 49 | 50 | #endif /* MBEDTLS_VERSION_C */ 51 | -------------------------------------------------------------------------------- /include/libp2p/crypto/encoding/base16.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /** 4 | * Encode in Base16 format 5 | * @param incoming the incoming bytes 6 | * @param incoming_length the length of the incoming bytes 7 | * @param results where to put the results 8 | * @param results_length the size of the buffer, and returns the actual length used 9 | * @returns true(1) on success 10 | */ 11 | int libp2p_crypto_encoding_base16_encode(const unsigned char* incoming, size_t incoming_length, unsigned char* results, size_t* results_length); 12 | 13 | /** 14 | * Calculate the size of the buffer necessary to encode 15 | * @param incoming_length the length of the incoming value 16 | * @returns the size of the buffer necessary to hold the encoded bytes 17 | */ 18 | int libp2p_crypto_encoding_base16_encode_size(size_t incoming_length); 19 | 20 | /** 21 | * Decode from Base16 format 22 | * @param incoming the incoming base16 encoded string 23 | * @param incoming_length the length of the incoming string (no need to include null) 24 | * @param results where to put the results 25 | * @param results_length the size of the buffer, and returns the actual length used 26 | * @returns true(1) on success 27 | */ 28 | int libp2p_crypto_encoding_base16_decode(const unsigned char* incoming, size_t incoming_length, unsigned char* results, size_t* results_length); 29 | 30 | /** 31 | * Calculate the size of the buffer necessary to decode 32 | * @param incoming_length the length of the incoming value 33 | * @returns the size of the buffer necessary to hold the decoded bytes 34 | */ 35 | int libp2p_crypto_encoding_base16_decode_size(size_t incoming_length); 36 | -------------------------------------------------------------------------------- /include/libp2p/crypto/encoding/base58.h: -------------------------------------------------------------------------------- 1 | #ifndef base58_h 2 | #define base58_h 3 | 4 | #include 5 | /** 6 | * convert a base58 encoded string into a binary array 7 | * @param base58 the base58 encoded string 8 | * @param base58_size the size of the encoded string 9 | * @param binary_data the results buffer 10 | * @param binary_data_size the size of the results buffer 11 | * @returns true(1) on success 12 | */ 13 | int libp2p_crypto_encoding_base58_decode(const unsigned char* base58, size_t base58_size, unsigned char** binary_data, size_t *binary_data_size); 14 | 15 | /** 16 | * encode an array of bytes into a base58 string 17 | * @param binary_data the data to be encoded 18 | * @param binary_data_size the size of the data to be encoded 19 | * @param base58 the results buffer 20 | * @param base58_size the size of the results buffer 21 | * @returns true(1) on success 22 | */ 23 | int libp2p_crypto_encoding_base58_encode(const unsigned char* binary_data, size_t binary_data_size, unsigned char** base58, size_t* base58_size); 24 | 25 | /*** 26 | * calculate the size of the results based on an incoming string 27 | * @param decoded_length the length of the string to be encoded 28 | * @returns the size in bytes had the string been encoded 29 | */ 30 | size_t libp2p_crypto_encoding_base58_encode_size(size_t decoded_length); 31 | 32 | /** 33 | * calculate the max length in bytes of an encoding of n source bytes 34 | * @param encoded_length the length of the string to be decoded 35 | * @returns the maximum size in bytes had the string been decoded 36 | */ 37 | size_t libp2p_crypto_encoding_base58_decode_size(size_t encoded_length); 38 | 39 | 40 | #endif /* base58_h */ 41 | -------------------------------------------------------------------------------- /include/libp2p/utils/vector.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define VECTOR_INIT_CAPACITY 4 4 | 5 | //#define VECTOR_INIT(vec) vector vec; vector_init(&vec) 6 | //#define VECTOR_ADD(vec, item) vector_add(&vec, (void *) item) 7 | //#define VECTOR_SET(vec, id, item) vector_set(&vec, id, (void *) item) 8 | //#define VECTOR_GET(vec, type, id) (type) vector_get(&vec, id) 9 | //#define VECTOR_DELETE(vec, id) vector_delete(&vec, id) 10 | //#define VECTOR_TOTAL(vec) vector_total(&vec) 11 | //#define VECTOR_FREE(vec) vector_free(&vec) 12 | 13 | /** 14 | * This is an implementation of a simple vector. 15 | * 16 | * NOTE: that items are stored as pointers. So if you free the item 17 | * after insertion, you will be unable to retrieve it. 18 | */ 19 | 20 | struct Libp2pVector { 21 | void const** items; 22 | int capacity; 23 | int total; 24 | }; 25 | 26 | struct Libp2pVector* libp2p_utils_vector_new(int initial_size); 27 | int libp2p_utils_vector_total(struct Libp2pVector* in); 28 | //static void libp2p_utils_vector_resize(struct Libp2pVector *vector, int new_size); 29 | /** 30 | * Add a value to the vector 31 | * @param vector the vector to add the item to. 32 | * @param value the value to be added NOTE: this only saves the pointer, it does not copy. 33 | * @returns the index of the item in the vector 34 | */ 35 | int libp2p_utils_vector_add(struct Libp2pVector *vector, const void * value); 36 | void libp2p_utils_vector_set(struct Libp2pVector *vector, int pos, void *value); 37 | const void *libp2p_utils_vector_get(struct Libp2pVector *vector, int); 38 | void libp2p_utils_vector_delete(struct Libp2pVector *vector, int pos); 39 | void libp2p_utils_vector_free(struct Libp2pVector *vector); 40 | -------------------------------------------------------------------------------- /nodeio/nodeio.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "libp2p/net/stream.h" 5 | #include "libp2p/conn/session.h" 6 | 7 | int libp2p_nodeio_upgrade_stream(struct SessionContext* context) { 8 | int retVal = 0; 9 | char* protocol = "/nodeio/1.0.0\n"; 10 | unsigned char* results = NULL; 11 | size_t results_size = 0; 12 | if (!context->default_stream->write(context, (unsigned char*)protocol, strlen(protocol))) 13 | goto exit; 14 | if (!context->default_stream->read(context, &results, &results_size, 5)) 15 | goto exit; 16 | if (results_size != strlen(protocol)) 17 | goto exit; 18 | if (strncmp((char*)results, protocol, results_size) != 0) 19 | goto exit; 20 | retVal = 1; 21 | exit: 22 | if (results != NULL) { 23 | free(results); 24 | results = NULL; 25 | } 26 | return retVal; 27 | } 28 | 29 | /** 30 | * Called by requestor to get a protobuf'd node from a hash 31 | * @param context the session context 32 | * @param hash the hash 33 | * @param hash_size the length of the hash 34 | * @param results where to put the buffer 35 | * @param results_size the size of the results 36 | * @returns true(1) on success, otherwise false(0) 37 | */ 38 | int libp2p_nodeio_get(struct SessionContext* context, unsigned char* hash, int hash_length, unsigned char** results, size_t* results_size) { 39 | if (!context->default_stream->write(context, hash, hash_length)) 40 | return 0; 41 | if (!context->default_stream->read(context, results, results_size, 5)) 42 | return 0; 43 | return 1; 44 | } 45 | 46 | int libp2p_nodeio_handshake(struct SessionContext* context) { 47 | char* protocol = "/nodeio/1.0.0\n"; 48 | return context->default_stream->write(context, (unsigned char*)protocol, strlen(protocol)); 49 | } 50 | -------------------------------------------------------------------------------- /include/libp2p/crypto/encoding/base32.h: -------------------------------------------------------------------------------- 1 | #ifndef __LIBP2P_CRYPTO_ENCODING_BASE32_H__ 2 | #define __LIBP2P_CRYPTO_ENCODING_BASE32_H__ 3 | 4 | #include 5 | 6 | /** 7 | * Encode in Base32 format 8 | * @param incoming the incoming bytes 9 | * @param incoming_length the length of the incoming bytes 10 | * @param results where to put the results 11 | * @param results_length the size of the buffer, and returns the actual length used 12 | * @returns true(1) on success 13 | */ 14 | int libp2p_crypto_encoding_base32_encode(const unsigned char* incoming, size_t incoming_length, 15 | unsigned char* results, size_t* results_length); 16 | 17 | /** 18 | * Calculate the size of the buffer necessary to encode 19 | * @param incoming_length the length of the incoming value 20 | * @returns the size of the buffer necessary to hold the encoded bytes 21 | */ 22 | size_t libp2p_crypto_encoding_base32_encode_size(size_t incoming_length); 23 | 24 | /** 25 | * Decode from Base16 format 26 | * @param incoming the incoming base16 encoded string 27 | * @param incoming_length the length of the incoming string (no need to include null) 28 | * @param results where to put the results 29 | * @param results_length the size of the buffer, and returns the actual length used 30 | * @returns true(1) on success 31 | */ 32 | int libp2p_crypto_encoding_base32_decode(const unsigned char* incoming, size_t incoming_length, 33 | unsigned char* results, size_t* results_length); 34 | 35 | /** 36 | * Calculate the size of the buffer necessary to decode 37 | * @param incoming_length the length of the incoming value 38 | * @returns the size of the buffer necessary to hold the decoded bytes 39 | */ 40 | size_t libp2p_crypto_encoding_base32_decode_size(size_t incoming_length); 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /crypto/sha256.c: -------------------------------------------------------------------------------- 1 | #include "mbedtls/sha256.h" 2 | 3 | /*** 4 | * hash a string using SHA256 5 | * @param input the input string 6 | * @param input_length the length of the input string 7 | * @param output where to place the results, should be 32 bytes 8 | * @returns 1 9 | */ 10 | int libp2p_crypto_hashing_sha256(const unsigned char* input, size_t input_length, unsigned char* output) { 11 | mbedtls_sha256(input, input_length, output, 0); 12 | return 32; 13 | } 14 | 15 | 16 | /** 17 | * Initialize a sha256 hmac process 18 | * @param ctx the context 19 | * @returns true(1) on success, otherwise false(0) 20 | */ 21 | int libp2p_crypto_hashing_sha256_init(mbedtls_sha256_context* ctx) { 22 | mbedtls_sha256_init(ctx); 23 | return 1; 24 | } 25 | 26 | /** 27 | * Update a sha256 hmac process 28 | * @param ctx the context 29 | * @param input the data to add 30 | * @param input_size the size of input 31 | * @returns true(1) on success, otherwise false(0) 32 | */ 33 | int libp2p_crypto_hashing_sha256_update(mbedtls_sha256_context* ctx, const unsigned char* input, size_t input_size) { 34 | mbedtls_sha256_update(ctx, input, input_size); 35 | return 1; 36 | } 37 | 38 | /** 39 | * finalize a sha256 hmac process 40 | * @param ctx the context 41 | * @param hash where to put the results (for SHA256, should be 32 bytes long) 42 | * @returns true(1) on success, otherwise false(0) 43 | */ 44 | int libp2p_crypto_hashing_sha256_finish(mbedtls_sha256_context* ctx, unsigned char* hash) { 45 | mbedtls_sha256_finish(ctx, hash); 46 | return 1; 47 | } 48 | 49 | /** 50 | * Clean up allocated memory 51 | * @param ctx the context 52 | * @returns true(1) on success, otherwise false(0) 53 | */ 54 | int libp2p_crypto_hashing_sha256_free(mbedtls_sha256_context* ctx) { 55 | mbedtls_sha256_free(ctx); 56 | return 1; 57 | } 58 | -------------------------------------------------------------------------------- /conn/transport_dialer.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "libp2p/crypto/rsa.h" 4 | #include "libp2p/conn/transport_dialer.h" 5 | 6 | struct TransportDialer* libp2p_conn_transport_dialer_new(char* peer_id, struct RsaPrivateKey* private_key) { 7 | struct TransportDialer* out = (struct TransportDialer*)malloc(sizeof(struct TransportDialer)); 8 | if (out != NULL) { 9 | out->peer_id = NULL; 10 | out->private_key = NULL; 11 | if (peer_id != NULL) { 12 | out->peer_id = malloc(strlen(peer_id) + 1); 13 | strcpy(out->peer_id, peer_id); 14 | } 15 | if (private_key != NULL) { 16 | out->private_key = private_key; 17 | } 18 | } 19 | return out; 20 | } 21 | 22 | /** 23 | * free resources from a TransportDialer struct 24 | * @param in the struct to be freed 25 | */ 26 | void libp2p_conn_transport_dialer_free(struct TransportDialer* in) { 27 | if (in != NULL) { 28 | if (in->peer_id != NULL) 29 | free(in->peer_id); 30 | //libp2p_crypto_private_key_free(in->private_key); 31 | free(in); 32 | } 33 | } 34 | 35 | /** 36 | * Given a list of dialers, find the appropriate dialer for this multiaddress 37 | * @param transport_dialers a list of dialers 38 | * @param multiaddr the address 39 | * @returns a connection, or NULL if no appropriate dialer was found 40 | */ 41 | struct Stream* libp2p_conn_transport_dialer_get(const struct Libp2pLinkedList* transport_dialers, const struct MultiAddress* multiaddr) { 42 | const struct Libp2pLinkedList* current = transport_dialers; 43 | struct TransportDialer* t_dialer = NULL; 44 | while (current != NULL) { 45 | t_dialer = (struct TransportDialer*)current->item; 46 | if (t_dialer->can_handle(multiaddr)) 47 | break; 48 | current = current->next; 49 | t_dialer = NULL; 50 | } 51 | 52 | if (t_dialer != NULL) { 53 | return t_dialer->dial(t_dialer, multiaddr); 54 | } 55 | 56 | return NULL; 57 | } 58 | -------------------------------------------------------------------------------- /include/libp2p/crypto/key.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | /** 6 | * Utilities for public keys 7 | */ 8 | 9 | enum KeyType { KEYTYPE_RSA, KEYTYPE_ED25519, KEYTYPE_INVALID }; 10 | 11 | struct PublicKey { 12 | enum KeyType type; 13 | unsigned char* data; 14 | size_t data_size; 15 | }; 16 | 17 | struct PrivateKey { 18 | enum KeyType type; 19 | unsigned char* data; 20 | size_t data_size; 21 | }; 22 | 23 | struct PublicKey* libp2p_crypto_public_key_new(); 24 | void libp2p_crypto_public_key_free(struct PublicKey* in); 25 | 26 | struct PrivateKey* libp2p_crypto_private_key_new(); 27 | void libp2p_crypto_private_key_free(struct PrivateKey* in); 28 | int libp2p_crypto_private_key_copy(const struct PrivateKey* source, struct PrivateKey* destination); 29 | 30 | /** 31 | * Unmarshal a public key from a protobuf 32 | */ 33 | int libp2p_crypto_public_key_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct PublicKey** out); 34 | size_t libp2p_crypto_public_key_protobuf_encode_size(const struct PublicKey* in); 35 | int libp2p_crypto_public_key_protobuf_encode(const struct PublicKey* in, unsigned char* buffer, size_t max_buffer_length, size_t* bytes_written); 36 | // private key 37 | int libp2p_crypto_private_key_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct PrivateKey** out); 38 | size_t libp2p_crypto_private_key_protobuf_encode_size(const struct PrivateKey* in); 39 | int libp2p_crypto_private_key_protobuf_encode(const struct PrivateKey* in, unsigned char* buffer, size_t max_buffer_length, size_t* bytes_written); 40 | 41 | /** 42 | * convert a public key into a peer id 43 | * @param public_key the public key struct 44 | * @param peer_id the results, in a null-terminated string 45 | * @returns true(1) on success, otherwise false(0) 46 | */ 47 | int libp2p_crypto_public_key_to_peer_id(struct PublicKey* public_key, char** peer_id); 48 | -------------------------------------------------------------------------------- /include/libp2p/crypto/encoding/base64.h: -------------------------------------------------------------------------------- 1 | #ifndef base64_h 2 | #define base64_h 3 | 4 | #include 5 | 6 | /** 7 | * encode using base64 8 | * @param input_data the data to be encoded 9 | * @param input_length the length of the input data 10 | * @param output_data where the data is to be stored 11 | * @param max_output_length the max size of the output_data 12 | * @param bytes_written the number of bytes written to output_data 13 | * @returns true(1) on success, otherwise false 14 | */ 15 | int libp2p_crypto_encoding_base64_encode(const unsigned char* input_data, size_t input_length, unsigned char* output_data, size_t max_output_length, size_t* bytes_written); 16 | 17 | /** 18 | * calculate the max length in bytes of an encoding of n source bytes 19 | * @param encoded_size the size of the encoded string 20 | * @returns the maximum size in bytes had the string been decoded 21 | */ 22 | size_t libp2p_crypto_encoding_base64_encode_size(size_t input_length); 23 | 24 | /** 25 | * decode something that was encoded as base64 26 | * @param input_data the data to decode 27 | * @param input_length the length of the input data 28 | * @param output_data the buffer to store the output 29 | * @param max_output_length the length of the output buffer 30 | * @param bytes_written the number of bytes written to output_data 31 | * @returns a pointer to the decoded data 32 | */ 33 | int libp2p_crypto_encoding_base64_decode(const unsigned char* input_data, size_t input_length, unsigned char* output_data, size_t max_output_length, size_t* bytes_written); 34 | 35 | /** 36 | * calculate the max length in bytes of a decoding of n source bytes 37 | * @param decoded_size the size of the incoming string to be encoded 38 | * @returns the maximum size in bytes had the string been encoded 39 | */ 40 | size_t libp2p_crypto_encoding_base64_decode_size(size_t input_length); 41 | 42 | #endif /* base64_h */ 43 | -------------------------------------------------------------------------------- /include/libp2p/utils/threadsafe_buffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /** 4 | * A thredsafe buffer 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | /*** 12 | * Holds the information about the buffer 13 | */ 14 | struct ThreadsafeBufferContext { 15 | size_t buffer_size; 16 | uint8_t* buffer; 17 | pthread_mutex_t lock; 18 | }; 19 | 20 | /*** 21 | * Allocate a new context 22 | * @returns a newly allocated context, or NULL on error (out of memory?) 23 | */ 24 | struct ThreadsafeBufferContext* threadsafe_buffer_context_new(); 25 | 26 | /*** 27 | * Free resources of a buffer context 28 | * @param context the context 29 | */ 30 | void threadsafe_buffer_context_free(struct ThreadsafeBufferContext* context); 31 | 32 | /*** 33 | * Read from the buffer without destroying its contents or moving its read pointer 34 | * @param context the context 35 | * @param results where to put the results 36 | * @param results_size the size of the results 37 | * @returns number of bytes read 38 | */ 39 | size_t threadsafe_buffer_peek(struct ThreadsafeBufferContext* context, uint8_t* results, size_t results_size); 40 | 41 | /*** 42 | * Read from the buffer. 43 | * NOTE: If results_size is more than what is left in the buffer, this will read everything. 44 | * @param context the context 45 | * @param results where to put the results 46 | * @param results_size the size of the buffer 47 | * @returns number of bytes read 48 | */ 49 | size_t threadsafe_buffer_read(struct ThreadsafeBufferContext* context, uint8_t* results, size_t results_size); 50 | 51 | /**** 52 | * Add bytes to the end of the buffer 53 | * @param context the context 54 | * @param bytes the bytes to add 55 | * @param bytes_size the size of bytes 56 | * @returns the size added to the buffer (0 on error) 57 | */ 58 | size_t threadsafe_buffer_write(struct ThreadsafeBufferContext* context, const uint8_t* bytes, size_t bytes_size); 59 | -------------------------------------------------------------------------------- /include/libp2p/net/p2pnet.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | int socket_open4(); 7 | int socket_bind4(int s, uint32_t ip, uint16_t port); 8 | int socket_bind4_reuse(int s, uint32_t ip, uint16_t port); 9 | int socket_read_select4(int socket_fd, int num_seconds); 10 | int socket_accept4(int s, uint32_t *ip, uint16_t *port); 11 | int socket_local4(int s, uint32_t *ip, uint16_t *port); 12 | int socket_connect4(int s, uint32_t ip, uint16_t port); 13 | int socket_connect4_with_timeout(int s, uint32_t ip, uint16_t port, int timeout_secs); 14 | int socket_listen(int s, uint32_t *localip, uint16_t *localport); 15 | 16 | /*** 17 | * Reads data from a socket, used instead of recv so if a protocol needs 18 | * to use something else before or after it can be done here instead of 19 | * outside the lib. 20 | * 21 | * @param s the socket 22 | * @param buf what to send 23 | * @param len the length of buf 24 | * @param flags network flags 25 | * @param num_secs the number of seconds before a timeout 26 | * @returns number of bytes, 0, or negative number on error (i.e. EAGAIN or EWOULDBLOCK) 27 | */ 28 | ssize_t socket_read(int s, char *buf, size_t len, int flags, int timeout_secs); 29 | ssize_t socket_write(int s, const char *buf, size_t len, int flags); 30 | /** 31 | * Used to send the size of the next transmission for "framed" transmissions. NOTE: This will send in big endian format 32 | * @param s the socket descriptor 33 | * @param size the size to send 34 | * @param flags socket flags 35 | * @returns number of bytes sent 36 | */ 37 | ssize_t socket_write_size(int s, unsigned long size, int flags); 38 | 39 | int socket_tcp4(void); 40 | 41 | int socket_stream_sctp4(void); 42 | 43 | int socket_udp4(void); 44 | 45 | /** 46 | * convert a hostname into an ip address 47 | * @param hostname the name of the host. i.e. www.jmjatlanta.com 48 | * @returns the ip address as an uint32_t 49 | */ 50 | uint32_t hostname_to_ip(const char* hostname); 51 | -------------------------------------------------------------------------------- /test/test_multistream.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "libp2p/net/multistream.h" 8 | 9 | int test_multistream_connect() { 10 | int retVal = 0; 11 | char* response; 12 | size_t response_size; 13 | 14 | struct Stream* stream = libp2p_net_multistream_connect("www.jmjatlanta.com", 4001); 15 | if (stream == NULL) 16 | goto exit; 17 | 18 | retVal = 1; 19 | 20 | exit: 21 | if (stream != NULL) { 22 | struct SessionContext ctx; 23 | ctx.insecure_stream = stream; 24 | stream->close(stream); 25 | libp2p_net_multistream_stream_free(stream); 26 | } 27 | 28 | return retVal; 29 | } 30 | 31 | int test_multistream_get_list() { 32 | int retVal = 0; 33 | struct StreamMessage* response; 34 | char* filtered = NULL; 35 | 36 | struct SessionContext session; 37 | session.insecure_stream = libp2p_net_multistream_connect("10.211.55.2", 4001); 38 | 39 | if (session.insecure_stream == NULL) 40 | goto exit; 41 | 42 | // try to respond something, ls command 43 | struct StreamMessage outgoing; 44 | outgoing.data = (uint8_t*)"ls\n"; 45 | outgoing.data_size = 3; 46 | if (libp2p_net_multistream_write(&session, &outgoing) <= 0) 47 | goto exit; 48 | 49 | // retrieve response 50 | retVal = libp2p_net_multistream_read(&session, &response, 5); 51 | if (retVal <= 0) 52 | goto exit; 53 | 54 | filtered = malloc(response->data_size + 1); 55 | strncpy(filtered, (char*)response->data, response->data_size); 56 | filtered[response->data_size] = 0; 57 | 58 | fprintf(stdout, "Response from multistream ls: %s", (char*)filtered); 59 | 60 | retVal = 1; 61 | 62 | exit: 63 | if (session.insecure_stream != NULL) { 64 | session.insecure_stream->close(session.insecure_stream); 65 | libp2p_net_multistream_stream_free(session.insecure_stream); 66 | } 67 | libp2p_stream_message_free(response); 68 | if (filtered != NULL) 69 | free(filtered); 70 | 71 | return retVal > 0; 72 | } 73 | -------------------------------------------------------------------------------- /include/libp2p/utils/logger.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define LOGLEVEL_NONE 0 4 | #define LOGLEVEL_CRITICAL 1 5 | #define LOGLEVEL_ERROR 2 6 | #define LOGLEVEL_INFO 3 7 | #define LOGLEVEL_DEBUG 4 8 | #define LOGLEVEL_VERBOSE 5 9 | 10 | #define CURRENT_LOGLEVEL LOGLEVEL_DEBUG 11 | 12 | 13 | /*** 14 | * Add a class to watch for logging messages 15 | * @param str the class name to watch 16 | */ 17 | void libp2p_logger_add_class(const char* str); 18 | 19 | /** 20 | * Initialize the logger. This should be done only once. 21 | */ 22 | void libp2p_logger_init(); 23 | 24 | /*** 25 | * Checks to see if the logger has been initialized 26 | */ 27 | int libp2p_logger_initialized(); 28 | 29 | int libp2p_logger_free(); 30 | 31 | /*** 32 | * Checks to see if we're watching for a particular class 33 | * @param area the "class" to look for 34 | * @returns true(1) if found, false(0) otherwise 35 | */ 36 | int libp2p_logger_watching_class(const char* area); 37 | 38 | /** 39 | * Log a message to the console 40 | * @param area the class it is coming from 41 | * @param log_level logger level 42 | * @param format the logging string 43 | * @param ... params 44 | */ 45 | void libp2p_logger_log(const char* area, int log_level, const char* format, ...); 46 | 47 | /** 48 | * Log a debug message to the console 49 | * @param area the class it is coming from 50 | * @param format the logging string 51 | * @param ... params 52 | */ 53 | void libp2p_logger_debug(const char* area, const char* format, ...); 54 | 55 | /** 56 | * Log an error message to the console 57 | * @param area the class it is coming from 58 | * @param format the logging string 59 | * @param ... params 60 | */ 61 | void libp2p_logger_error(const char* area, const char* format, ...); 62 | 63 | /** 64 | * Log an info message to the console 65 | * @param area the class it is coming from 66 | * @param format the logging string 67 | * @param ... params 68 | */ 69 | void libp2p_logger_info(const char* area, const char* format, ...); 70 | 71 | -------------------------------------------------------------------------------- /include/libp2p/secio/exchange.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "libp2p/crypto/rsa.h" 4 | #include "libp2p/conn/session.h" 5 | 6 | struct Exchange { 7 | unsigned char* epubkey; 8 | size_t epubkey_size; 9 | unsigned char* signature; 10 | size_t signature_size; 11 | }; 12 | 13 | struct Exchange* libp2p_secio_exchange_new(); 14 | void libp2p_secio_exchange_free(struct Exchange* in); 15 | 16 | /** 17 | * retrieves the approximate size of an encoded version of the passed in struct 18 | * @param in the struct to look at 19 | * @reutrns the size of buffer needed 20 | */ 21 | size_t libp2p_secio_exchange_protobuf_encode_size(struct Exchange* in); 22 | 23 | /** 24 | * Encode the struct Exchange in protobuf format 25 | * @param in the struct to be encoded 26 | * @param buffer where to put the results 27 | * @param max_buffer_length the max to write 28 | * @param bytes_written how many bytes were written to the buffer 29 | * @returns true(1) on success, otherwise false(0) 30 | */ 31 | int libp2p_secio_exchange_protobuf_encode(struct Exchange* in, unsigned char* buffer, size_t max_buffer_length, size_t* bytes_written); 32 | 33 | /** 34 | * Turns a protobuf array into an Exchange struct 35 | * @param buffer the protobuf array 36 | * @param max_buffer_length the length of the buffer 37 | * @param out a pointer to the new struct Exchange NOTE: this method allocates memory 38 | * @returns true(1) on success, otherwise false(0) 39 | */ 40 | int libp2p_secio_exchange_protobuf_decode(unsigned char* buffer, size_t max_buffer_length, struct Exchange** out); 41 | 42 | /*** 43 | * Build an exchange object based on passed in values 44 | * @param local_session the SessionContext 45 | * @param private_key the local RsaPrivateKey 46 | * @param bytes_to_be_signed the bytes that should be signed 47 | * @param bytes_size the length of bytes_to_be_signed 48 | * @returns an Exchange object or NULL 49 | */ 50 | struct Exchange* libp2p_secio_exchange_build(struct SessionContext* local_session, struct RsaPrivateKey* private_key, const char* bytes_to_be_signed, size_t bytes_size); 51 | -------------------------------------------------------------------------------- /include/libp2p/crypto/ephemeral.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "mbedtls/ecdh.h" 5 | 6 | /** 7 | * General helpers for ephemeral keys 8 | */ 9 | 10 | struct StretchedKey { 11 | unsigned char* iv; 12 | size_t iv_size; 13 | unsigned char* cipher_key; 14 | size_t cipher_size; 15 | unsigned char* mac_key; 16 | size_t mac_size; 17 | }; 18 | 19 | struct EphemeralPublicKey { 20 | size_t num_bits; 21 | uint64_t x; 22 | uint64_t y; 23 | unsigned char* bytes; // a public key in bytes (the combination of X and Y) 24 | size_t bytes_size; 25 | unsigned char* shared_key; 26 | size_t shared_key_size; 27 | }; 28 | 29 | struct EphemeralPrivateKey { 30 | size_t num_bits; 31 | uint64_t secret_key; 32 | mbedtls_ecdh_context ctx; 33 | struct EphemeralPublicKey* public_key; 34 | }; 35 | 36 | /** 37 | * Generate a Ephemeral Public Key as well as a shared key 38 | * @param curve the curve to use (P-256, P-384, or P-521) 39 | * @param private_key where to store the private key 40 | * @reutrns true(1) on success, otherwise false(0) 41 | */ 42 | int libp2p_crypto_ephemeral_keypair_generate(char* curve, struct EphemeralPrivateKey** private_key); 43 | 44 | /** 45 | * Generate a shared secret 46 | * @param private_key the context, also where it puts the shared secret 47 | * @param remote_public_key the key the remote gave us 48 | * @param remote_public_key_size the size of the remote public key 49 | * @reutrns true(1) on success, otherwise false(0) 50 | */ 51 | int libp2p_crypto_ephemeral_generate_shared_secret(struct EphemeralPrivateKey* private_key, const unsigned char* remote_public_key, size_t remote_public_key_size); 52 | 53 | /*** 54 | * Remove resources used by generation of ephemeral private key 55 | * @param in the key to destroy 56 | */ 57 | void libp2p_crypto_ephemeral_key_free( struct EphemeralPrivateKey* in); 58 | 59 | /** 60 | * Routines to help with the StretchedKey struct 61 | */ 62 | struct StretchedKey* libp2p_crypto_ephemeral_stretched_key_new(); 63 | void libp2p_crypto_ephemeral_stretched_key_free(struct StretchedKey* in); 64 | -------------------------------------------------------------------------------- /include/mbedtls/havege.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file havege.h 3 | * 4 | * \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion 5 | * 6 | * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 7 | * SPDX-License-Identifier: Apache-2.0 8 | * 9 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 10 | * not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 17 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | * 21 | * This file is part of mbed TLS (https://tls.mbed.org) 22 | */ 23 | #ifndef MBEDTLS_HAVEGE_H 24 | #define MBEDTLS_HAVEGE_H 25 | 26 | #include 27 | 28 | #define MBEDTLS_HAVEGE_COLLECT_SIZE 1024 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | /** 35 | * \brief HAVEGE state structure 36 | */ 37 | typedef struct 38 | { 39 | int PT1, PT2, offset[2]; 40 | int pool[MBEDTLS_HAVEGE_COLLECT_SIZE]; 41 | int WALK[8192]; 42 | } 43 | mbedtls_havege_state; 44 | 45 | /** 46 | * \brief HAVEGE initialization 47 | * 48 | * \param hs HAVEGE state to be initialized 49 | */ 50 | void mbedtls_havege_init( mbedtls_havege_state *hs ); 51 | 52 | /** 53 | * \brief Clear HAVEGE state 54 | * 55 | * \param hs HAVEGE state to be cleared 56 | */ 57 | void mbedtls_havege_free( mbedtls_havege_state *hs ); 58 | 59 | /** 60 | * \brief HAVEGE rand function 61 | * 62 | * \param p_rng A HAVEGE state 63 | * \param output Buffer to fill 64 | * \param len Length of buffer 65 | * 66 | * \return 0 67 | */ 68 | int mbedtls_havege_random( void *p_rng, unsigned char *output, size_t len ); 69 | 70 | #ifdef __cplusplus 71 | } 72 | #endif 73 | 74 | #endif /* havege.h */ 75 | -------------------------------------------------------------------------------- /crypto/peerutils.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "mh/multihash.h" 5 | #include "mh/hashes.h" 6 | #include "libp2p/crypto/encoding/base58.h" 7 | #include "libp2p/crypto/sha256.h" 8 | //#include "libp2p/crypto/key.h" 9 | 10 | /** 11 | * base58 encode a string NOTE: this also puts the prefix 'Qm' in front as the ID is a multihash 12 | * @param pointyaddr where the results will go 13 | * @param rezbuflen the length of the results buffer. It will also put how much was used here 14 | * @param ID_BUF the input text (usually a SHA256 hash) 15 | * @param ID_BUF_SIZE the input size (normally a SHA256, therefore 32 bytes) 16 | * @returns true(1) on success 17 | */ 18 | int PrettyID(unsigned char * pointyaddr, size_t* rezbuflen,unsigned char * ID_BUF, size_t ID_BUF_SIZE)//b58 encoded ID buf 19 | { 20 | int returnstatus = 0; 21 | 22 | unsigned char temp_buffer[*rezbuflen]; 23 | 24 | memset(temp_buffer, 0, *rezbuflen); 25 | 26 | // wrap the base58 into a multihash 27 | int retVal = mh_new(temp_buffer, MH_H_SHA2_256, ID_BUF, ID_BUF_SIZE); 28 | if (retVal < 0) 29 | return 0; 30 | 31 | // base58 the multihash 32 | returnstatus = libp2p_crypto_encoding_base58_encode(temp_buffer, strlen((char*)temp_buffer), &pointyaddr, rezbuflen); 33 | if(returnstatus == 0) 34 | return 0; 35 | 36 | return 1; 37 | } 38 | 39 | 40 | /**** 41 | * Make a SHA256 hash of what is usually the DER formatted private key. 42 | * @param result where to store the result. Should be 32 chars long 43 | * @param texttohash the text to hash. A DER formatted public key 44 | * @param text_size the size of the text 45 | */ 46 | /* 47 | void ID_FromPK_non_null_terminated(char * result,unsigned char * texttohash, size_t text_size) 48 | { 49 | 50 | libp2p_crypto_hashing_sha256(texttohash, text_size, (unsigned char*)result); 51 | } 52 | */ 53 | 54 | /**** 55 | * Make a SHA256 hash of what is usually the DER formatted private key. 56 | * @param result where to store the result. Should be 32 chars long 57 | * @param texttohash a null terminated string of the text to hash 58 | */ 59 | /* 60 | void ID_FromPK(char * result,unsigned char * texttohash) 61 | { 62 | ID_FromPK_non_null_terminated(result,texttohash,strlen((char*)texttohash)); 63 | } 64 | */ 65 | -------------------------------------------------------------------------------- /utils/vector.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "libp2p/utils/vector.h" 5 | 6 | struct Libp2pVector* libp2p_utils_vector_new(int initial_size) 7 | { 8 | struct Libp2pVector* v = (struct Libp2pVector*)malloc(sizeof(struct Libp2pVector)); 9 | v->capacity = initial_size; 10 | v->total = 0; 11 | v->items = malloc(sizeof(void *) * v->capacity); 12 | return v; 13 | } 14 | 15 | int libp2p_utils_vector_total(struct Libp2pVector *v) 16 | { 17 | return v->total; 18 | } 19 | 20 | static void libp2p_utils_vector_resize(struct Libp2pVector *v, int capacity) 21 | { 22 | #ifdef DEBUG_ON 23 | printf("vector_resize: %d to %d\n", v->capacity, capacity); 24 | #endif 25 | 26 | void const** items = realloc(v->items, sizeof(void *) * capacity); 27 | if (items) { 28 | v->items = items; 29 | v->capacity = capacity; 30 | } 31 | } 32 | 33 | /**** 34 | * Add an item to the vector. NOTE: This does not copy the item 35 | * @param v the vector to add to 36 | * @param item the item to add 37 | */ 38 | int libp2p_utils_vector_add(struct Libp2pVector *v, const void *item) 39 | { 40 | if (v->capacity == v->total) 41 | libp2p_utils_vector_resize(v, v->capacity * 2); 42 | v->items[v->total++] = item; 43 | return v->total; 44 | } 45 | 46 | void libp2p_utils_vector_set(struct Libp2pVector *v, int index, void *item) 47 | { 48 | if (index >= 0 && index < v->total) 49 | v->items[index] = item; 50 | } 51 | 52 | const void *libp2p_utils_vector_get(struct Libp2pVector *v, int index) 53 | { 54 | if (index >= 0 && index < v->total) 55 | return v->items[index]; 56 | return NULL; 57 | } 58 | 59 | void libp2p_utils_vector_delete(struct Libp2pVector *v, int index) 60 | { 61 | if (index < 0 || index >= v->total) 62 | return; 63 | 64 | v->items[index] = NULL; 65 | 66 | for (int i = 0; i < v->total - 1; i++) { 67 | v->items[i] = v->items[i + 1]; 68 | v->items[i + 1] = NULL; 69 | } 70 | 71 | v->total--; 72 | 73 | if (v->total > 0 && v->total == v->capacity / 4) 74 | libp2p_utils_vector_resize(v, v->capacity / 2); 75 | } 76 | 77 | void libp2p_utils_vector_free(struct Libp2pVector *v) 78 | { 79 | free(v->items); 80 | free(v); 81 | } 82 | -------------------------------------------------------------------------------- /test/test_mbedtls.h: -------------------------------------------------------------------------------- 1 | /** 2 | * A playground for testing mbedtls functions 3 | */ 4 | 5 | #include "mbedtls/bignum.h" 6 | 7 | int convertToString(unsigned char* string, int len) { 8 | // load up the mpi 9 | mbedtls_mpi mpi; 10 | mbedtls_mpi_init(&mpi); 11 | int retVal = mbedtls_mpi_read_binary(&mpi, string, len); 12 | if (retVal < 0) { 13 | mbedtls_mpi_free(&mpi); 14 | return 0; 15 | } 16 | 17 | // put it in string form so we can see it 18 | size_t buffer_len = 50; 19 | size_t output_len = 0; 20 | char buffer[buffer_len]; 21 | retVal = mbedtls_mpi_write_string(&mpi, 10, buffer, buffer_len, &output_len); 22 | if (retVal < 0) { 23 | mbedtls_mpi_free(&mpi); 24 | return 0; 25 | } 26 | for(int i = 0; i < output_len; i++) { 27 | printf("%02x", buffer[i]); 28 | } 29 | printf("\n"); 30 | mbedtls_mpi_free(&mpi); 31 | return 1; 32 | } 33 | 34 | int test_mbedtls_varint_128_binary() { 35 | // the values I'm working with 0x08, 0x00, 0x18, 0xa7, 0x09 36 | unsigned char starting_val[5] = { 0x08, 0x00, 0x18, 0x87, 0x09 }; 37 | size_t starting_len = 5; 38 | 39 | for(int i = 0; i < 5; i++) { 40 | if (convertToString(&starting_val[i], 5 - i) != 1) 41 | return 0; 42 | } 43 | 44 | printf(" 3 and 4\n"); 45 | if (convertToString(&starting_val[2], 2) != 1) { 46 | return 0; 47 | } 48 | 49 | printf("And now the other way...\n"); 50 | 51 | for(int i = 1; i <= 5; i--) { 52 | if (convertToString(starting_val, i) != 1) 53 | return 0; 54 | } 55 | 56 | 57 | return 1; 58 | } 59 | 60 | int test_mbedtls_varint_128_string() { 61 | // go from string to uint_128 and back again 62 | char* bigint_string = "47942806932686753431"; 63 | 64 | mbedtls_mpi mpi; 65 | 66 | mbedtls_mpi_init(&mpi); 67 | 68 | int retVal = mbedtls_mpi_read_string( &mpi, 10, bigint_string ); 69 | if (retVal < 0) { 70 | mbedtls_mpi_free(&mpi); 71 | return 0; 72 | } 73 | 74 | // now go back again 75 | size_t buffer_len = 50; 76 | size_t output_len = 0; 77 | char buffer[buffer_len]; 78 | retVal = mbedtls_mpi_write_string(&mpi, 10, buffer, buffer_len, &output_len); 79 | if (retVal < 0) { 80 | mbedtls_mpi_free(&mpi); 81 | return 0; 82 | } 83 | if (strcmp(buffer, bigint_string) != 0) { 84 | mbedtls_mpi_free(&mpi); 85 | return 0; 86 | } 87 | mbedtls_mpi_free(&mpi); 88 | return 1; 89 | } 90 | -------------------------------------------------------------------------------- /test/mock_stream.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "libp2p/net/stream.h" 5 | 6 | struct StreamMessage* mock_message = NULL; 7 | int mock_message_position = 0; 8 | 9 | void mock_stream_free(struct Stream* stream); 10 | 11 | int mock_stream_close(struct Stream* stream) { 12 | if (stream == NULL) 13 | return 0; 14 | struct ConnectionContext* ctx = (struct ConnectionContext*)stream->stream_context; 15 | mock_stream_free(stream); 16 | return 1; 17 | } 18 | 19 | int mock_stream_peek(void* context) { 20 | if (mock_message == NULL) 21 | return 0; 22 | return mock_message->data_size; 23 | } 24 | 25 | int mock_stream_read(void* context, struct StreamMessage** msg, int timeout_secs) { 26 | *msg = libp2p_stream_message_copy(mock_message); 27 | return 1; 28 | } 29 | 30 | int mock_stream_read_raw(void* context, uint8_t* buffer, int buffer_size, int timeout_secs) { 31 | if (mock_message == NULL) 32 | return 0; 33 | int min = buffer_size > mock_message->data_size - mock_message_position ? mock_message->data_size - mock_message_position : buffer_size; 34 | memcpy(buffer, mock_message->data, min); 35 | mock_message_position += min; 36 | return min; 37 | } 38 | 39 | int mock_stream_write(void* context, struct StreamMessage* msg) { 40 | return msg->data_size; 41 | } 42 | 43 | struct Stream* mock_stream_new() { 44 | struct Stream* out = libp2p_stream_new(); 45 | if (out != NULL) { 46 | out->close = mock_stream_close; 47 | out->peek = mock_stream_peek; 48 | out->read = mock_stream_read; 49 | out->read_raw = mock_stream_read_raw; 50 | out->write = mock_stream_write; 51 | struct ConnectionContext* ctx = malloc(sizeof(struct ConnectionContext)); 52 | ctx->session_context = (struct SessionContext*)malloc(sizeof(struct SessionContext)); 53 | ctx->session_context->default_stream = out; 54 | out->stream_context = ctx; 55 | } 56 | return out; 57 | } 58 | 59 | void mock_stream_free(struct Stream* stream) { 60 | if (stream == NULL) 61 | return; 62 | if (stream->stream_context != NULL) { 63 | struct ConnectionContext* ctx = (struct ConnectionContext*)stream->stream_context; 64 | // this will close the session, which will be a loop, so don't 65 | //libp2p_session_context_free(ctx->session_context); 66 | free(ctx->session_context); 67 | free(stream->stream_context); 68 | } 69 | free(stream); 70 | } 71 | -------------------------------------------------------------------------------- /include/mbedtls/platform_time.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file platform_time.h 3 | * 4 | * \brief mbed TLS Platform time abstraction 5 | * 6 | * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved 7 | * SPDX-License-Identifier: Apache-2.0 8 | * 9 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 10 | * not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 17 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | * 21 | * This file is part of mbed TLS (https://tls.mbed.org) 22 | */ 23 | #ifndef MBEDTLS_PLATFORM_TIME_H 24 | #define MBEDTLS_PLATFORM_TIME_H 25 | 26 | #if !defined(MBEDTLS_CONFIG_FILE) 27 | #include "config.h" 28 | #else 29 | #include MBEDTLS_CONFIG_FILE 30 | #endif 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | /** 37 | * \name SECTION: Module settings 38 | * 39 | * The configuration options you can set for this module are in this section. 40 | * Either change them in config.h or define them on the compiler command line. 41 | * \{ 42 | */ 43 | 44 | /* 45 | * The time_t datatype 46 | */ 47 | #if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) 48 | typedef MBEDTLS_PLATFORM_TIME_TYPE_MACRO mbedtls_time_t; 49 | #else 50 | /* For time_t */ 51 | #include 52 | typedef time_t mbedtls_time_t; 53 | #endif /* MBEDTLS_PLATFORM_TIME_TYPE_MACRO */ 54 | 55 | /* 56 | * The function pointers for time 57 | */ 58 | #if defined(MBEDTLS_PLATFORM_TIME_ALT) 59 | extern mbedtls_time_t (*mbedtls_time)( mbedtls_time_t* time ); 60 | 61 | /** 62 | * \brief Set your own time function pointer 63 | * 64 | * \param time_func the time function implementation 65 | * 66 | * \return 0 67 | */ 68 | int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* time ) ); 69 | #else 70 | #if defined(MBEDTLS_PLATFORM_TIME_MACRO) 71 | #define mbedtls_time MBEDTLS_PLATFORM_TIME_MACRO 72 | #else 73 | #define mbedtls_time time 74 | #endif /* MBEDTLS_PLATFORM_TIME_MACRO */ 75 | #endif /* MBEDTLS_PLATFORM_TIME_ALT */ 76 | 77 | #ifdef __cplusplus 78 | } 79 | #endif 80 | 81 | #endif /* platform_time.h */ 82 | -------------------------------------------------------------------------------- /crypto/encoding/base64.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "mbedtls/base64.h" 5 | 6 | /** 7 | * encode using base64 8 | * @param input_data the data to be encoded 9 | * @param input_length the length of the input data 10 | * @param output_data where the data is to be stored 11 | * @param max_output_length the max size of the output_data 12 | * @param bytes_written the number of bytes written to output_data 13 | * @returns true(1) on success, otherwise false 14 | */ 15 | int libp2p_crypto_encoding_base64_encode(const unsigned char* input_data, size_t input_length, unsigned char* output_data, size_t max_output_length, size_t* bytes_written) { 16 | int retVal = mbedtls_base64_encode(output_data, max_output_length, bytes_written, input_data, input_length); 17 | return retVal == 0; 18 | } 19 | 20 | /** 21 | * decode something that was encoded as base64 22 | * @param input_data the data to decode 23 | * @param input_length the length of the input data 24 | * @param output_data the buffer to store the output 25 | * @param max_output_length the length of the output buffer 26 | * @param bytes_written the number of bytes written to output_data 27 | * @returns true(1) on success, otherwise 0 28 | */ 29 | int libp2p_crypto_encoding_base64_decode(const unsigned char* input_data, size_t input_length, unsigned char* output_data, size_t max_output_length, size_t* bytes_written) { 30 | int retVal = mbedtls_base64_decode(output_data, max_output_length, bytes_written, input_data, input_length); 31 | return retVal == 0; 32 | } 33 | 34 | /** 35 | * calculate the max length in bytes of an encoding of n source bytes 36 | * @param encoded_size the size of the encoded string 37 | * @returns the maximum size in bytes had the string been decoded 38 | */ 39 | size_t libp2p_crypto_encoding_base64_decode_size(size_t encoded_size) { 40 | size_t radix = 64; 41 | double bits_per_digit = log2(radix); // each char represents about 6 bits 42 | 43 | return ceil(encoded_size * bits_per_digit / 8); 44 | } 45 | 46 | /** 47 | * calculate the max length in bytes of a decoding of n source bytes 48 | * @param decoded_size the size of the incoming string to be encoded 49 | * @returns the maximum size in bytes had the string been encoded 50 | */ 51 | size_t libp2p_crypto_encoding_base64_encode_size(size_t decoded_size) { 52 | /* 53 | size_t radix = 64; 54 | double bits_per_digit = log2(radix); 55 | 56 | return ceil( (8 / bits_per_digit * decoded_size) + 1); 57 | */ 58 | return (decoded_size / 3 + (decoded_size % 3 != 0)) * 4 + 1; 59 | } 60 | 61 | -------------------------------------------------------------------------------- /include/libp2p/hashmap/hashmap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Generic hashmap manipulation functions 3 | * 4 | * Originally by Elliot C Back - http://elliottback.com/wp/hashmap-implementation-in-c/ 5 | * 6 | * Modified by Pete Warden to fix a serious performance problem, support strings as keys 7 | * and removed thread synchronization - http://petewarden.typepad.com 8 | */ 9 | #ifndef __HASHMAP_H__ 10 | #define __HASHMAP_H__ 11 | 12 | #define MAP_MISSING -3 /* No such element */ 13 | #define MAP_FULL -2 /* Hashmap is full */ 14 | #define MAP_OMEM -1 /* Out of Memory */ 15 | #define MAP_OK 0 /* OK */ 16 | 17 | /* 18 | * any_t is a pointer. This allows you to put arbitrary structures in 19 | * the hashmap. 20 | */ 21 | typedef void *any_t; 22 | 23 | /* 24 | * PFany is a pointer to a function that can take two any_t arguments 25 | * and return an integer. Returns status code.. 26 | */ 27 | typedef int (*PFany)(any_t, any_t); 28 | 29 | /* 30 | * map_t is a pointer to an internally maintained data structure. 31 | * Clients of this package do not need to know how hashmaps are 32 | * represented. They see and manipulate only map_t's. 33 | */ 34 | typedef any_t map_t; 35 | 36 | /* 37 | * Return an empty hashmap. Returns NULL if empty. 38 | */ 39 | extern map_t libp2p_hashmap_new(); 40 | 41 | /* 42 | * Iteratively call f with argument (item, data) for 43 | * each element data in the hashmap. The function must 44 | * return a map status code. If it returns anything other 45 | * than MAP_OK the traversal is terminated. f must 46 | * not reenter any hashmap functions, or deadlock may arise. 47 | */ 48 | extern int libp2p_hashmap_iterate(map_t in, PFany f, any_t item); 49 | 50 | /* 51 | * Add an element to the hashmap. Return MAP_OK or MAP_OMEM. 52 | */ 53 | extern int libp2p_hashmap_put(map_t in, char* key, any_t value); 54 | 55 | /* 56 | * Get an element from the hashmap. Return MAP_OK or MAP_MISSING. 57 | */ 58 | extern int libp2p_hashmap_get(map_t in, char* key, any_t *arg); 59 | 60 | /* 61 | * Remove an element from the hashmap. Return MAP_OK or MAP_MISSING. 62 | */ 63 | extern int libp2p_hashmap_remove(map_t in, char* key); 64 | 65 | /* 66 | * Get any element. Return MAP_OK or MAP_MISSING. 67 | * remove - should the element be removed from the hashmap 68 | */ 69 | extern int libp2p_hashmap_get_one(map_t in, any_t *arg, int remove); 70 | 71 | /* 72 | * Free the hashmap 73 | */ 74 | extern void libp2p_hashmap_free(map_t in); 75 | 76 | /* 77 | * Get the current size of a hashmap 78 | */ 79 | extern int libp2p_hashmap_length(map_t in); 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /test/test_helper.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "libp2p/crypto/key.h" 5 | 6 | void read_file(char* path, char** contents) { 7 | FILE* fd = fopen(path, "r"); 8 | fseek(fd, 0L, SEEK_END); 9 | size_t num_bytes = ftell(fd); 10 | rewind(fd); 11 | *contents = malloc(num_bytes); 12 | fread(*contents, 1, num_bytes, fd); 13 | fclose(fd); 14 | return; 15 | } 16 | 17 | struct PrivateKey* base64ToPrivateKey(char* base64) { 18 | int retVal = 0; 19 | size_t decode_base64_size = 0; 20 | unsigned char* decode_base64 = NULL; 21 | struct PrivateKey* out = NULL; 22 | 23 | // 1) take the private key and turn it back into bytes (decode base 64) 24 | decode_base64_size = libp2p_crypto_encoding_base64_decode_size(strlen(base64)); 25 | decode_base64 = (unsigned char*)malloc(decode_base64_size); 26 | if (decode_base64 == NULL) 27 | goto exit; 28 | memset(decode_base64, 0, decode_base64_size); 29 | 30 | if (!libp2p_crypto_encoding_base64_decode((unsigned char*)base64, strlen(base64), &decode_base64[0], decode_base64_size, &decode_base64_size)) 31 | goto exit; 32 | 33 | if (!libp2p_crypto_private_key_protobuf_decode(decode_base64, decode_base64_size, &out)) 34 | goto exit; 35 | 36 | retVal = 1; 37 | exit: 38 | if (retVal != 1) { 39 | libp2p_crypto_private_key_free(out); 40 | out = NULL; 41 | } 42 | if (decode_base64 != NULL) 43 | free(decode_base64); 44 | return out; 45 | } 46 | 47 | int test_helper_get_id_from_config(char* path, struct PrivateKey** private_ptr, char** peer_ptr) { 48 | int retVal = 0; 49 | char* contents = NULL; 50 | char* ptr = NULL; 51 | char* end = NULL; 52 | int length = 0; 53 | read_file(path, &contents); 54 | if (contents == NULL) 55 | goto exit; 56 | 57 | // peer id 58 | ptr = strstr(contents, "PeerID"); 59 | if (ptr == NULL) 60 | goto exit; 61 | 62 | ptr = strstr(ptr, "Qm"); 63 | if (ptr == NULL) 64 | goto exit; 65 | 66 | end = strstr(ptr, "\""); 67 | 68 | length = end - ptr; 69 | *peer_ptr = malloc(length + 1); 70 | if (*peer_ptr == NULL) 71 | goto exit; 72 | memcpy(*peer_ptr, ptr, length); 73 | (*peer_ptr)[length] = 0; 74 | 75 | if (private_ptr != NULL) { 76 | // private key 77 | ptr = strstr(contents, "PrivKey\":"); 78 | if (ptr == NULL) 79 | goto exit; 80 | ptr += 9; 81 | ptr = strstr(ptr, "\""); 82 | ptr++; 83 | 84 | end = strstr(ptr, "\""); 85 | end[0] = 0; 86 | 87 | // turn the encoded private key into a struct 88 | *private_ptr = base64ToPrivateKey(ptr); 89 | } 90 | 91 | retVal = 1; 92 | exit: 93 | if (contents != NULL) 94 | free(contents); 95 | return retVal; 96 | } 97 | -------------------------------------------------------------------------------- /crypto/encoding/base16.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "libp2p/crypto/encoding/base16.h" 5 | 6 | /** 7 | * Encode in Base16 format 8 | * @param incoming the incoming bytes 9 | * @param incoming_length the length of the incoming bytes 10 | * @param results where to put the results 11 | * @param results_length the size of the buffer, and returns the actual length used 12 | * @returns true(1) on success 13 | */ 14 | int libp2p_crypto_encoding_base16_encode(const unsigned char* incoming, size_t incoming_length, unsigned char* results, size_t* results_length) { 15 | // the size will be 2x the size of incoming, so check that 16 | if (*results_length < incoming_length * 2) 17 | return 0; 18 | 19 | // clear out the results variable 20 | memset(results, 0, *results_length); 21 | 22 | *results_length = 0; 23 | for(int i = 0; i < incoming_length; i++) { 24 | unsigned char buf[3]; 25 | sprintf((char*)buf, "%02x", incoming[i]); 26 | results[i * 2] = buf[0]; 27 | results[i * 2 + 1] = buf[1]; 28 | *results_length += 2; 29 | } 30 | 31 | return 1; 32 | } 33 | 34 | /** 35 | * Calculate the size of the buffer necessary to encode 36 | * @param incoming_length the length of the incoming value 37 | * @returns the size of the buffer necessary to hold the encoded bytes 38 | */ 39 | int libp2p_crypto_encoding_base16_encode_size(size_t incoming_length) { 40 | return incoming_length * 2; 41 | } 42 | 43 | /** 44 | * Decode from Base16 format 45 | * @param incoming the incoming base16 encoded string 46 | * @param incoming_length the length of the incoming string (no need to include null) 47 | * @param results where to put the results 48 | * @param results_length the size of the buffer, and returns the actual length used 49 | * @returns true(1) on success 50 | */ 51 | int libp2p_crypto_encoding_base16_decode(const unsigned char* incoming, size_t incoming_length, unsigned char* results, size_t* results_length) { 52 | 53 | // buffer too small 54 | if (*results_length < incoming_length / 2) 55 | return 0; 56 | 57 | memset(results, 0, *results_length); 58 | 59 | char* pos = (char*)incoming; 60 | 61 | for(int i = 0; i < incoming_length / 2; i++) { 62 | sscanf(pos, "%2hhx", &results[i]); 63 | pos += 2; 64 | } 65 | return 1; 66 | } 67 | 68 | /** 69 | * Calculate the size of the buffer necessary to decode 70 | * @param incoming_length the length of the incoming value 71 | * @returns the size of the buffer necessary to hold the decoded bytes 72 | */ 73 | int libp2p_crypto_encoding_base16_decode_size(size_t incoming_length) { 74 | return incoming_length / 2; 75 | } 76 | 77 | -------------------------------------------------------------------------------- /include/libp2p/db/datastore.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | /*** 6 | * Interface to data storage 7 | */ 8 | 9 | enum DatastoreCursorOp { CURSOR_FIRST, CURSOR_NEXT, CURSOR_LAST, CURSOR_PREVIOUS }; 10 | 11 | struct DatastoreRecord { 12 | uint8_t *key; 13 | size_t key_size; 14 | uint8_t *value; 15 | size_t value_size; 16 | unsigned long long timestamp; 17 | }; 18 | 19 | struct Datastore { 20 | char* type; 21 | char* path; 22 | char* storage_max; 23 | int storage_gc_watermark; 24 | char* gc_period; 25 | char* params; 26 | int no_sync; 27 | int hash_on_read; 28 | int bloom_filter_size; 29 | 30 | // function pointers for datastore operations 31 | int (*datastore_open)(int argc, char** argv, struct Datastore* datastore); 32 | int (*datastore_close)(struct Datastore* datastore); 33 | int (*datastore_put)(struct DatastoreRecord* record, const struct Datastore* datastore); 34 | int (*datastore_get)(const unsigned char* key, size_t key_size, struct DatastoreRecord** record, const struct Datastore* datastore); 35 | int (*datastore_cursor_open)(struct Datastore* datastore); 36 | int (*datastore_cursor_close)(struct Datastore* datastore); 37 | int (*datastore_cursor_get)(unsigned char** key, int* key_length, unsigned char** value, int* value_length, enum DatastoreCursorOp op, struct Datastore* datastore); 38 | // generic connection and status variables for the datastore 39 | void* datastore_context; // a handle to a context that holds connectivity information 40 | }; 41 | 42 | /*** 43 | * Initialize the structure of the datastore to default settings. Used for 44 | * creating a new datastore on the disk. 45 | * @param datastore the struct to initialize 46 | * @param config_root the path to the root of IPFS 47 | * @returns true(1) on success 48 | */ 49 | int libp2p_datastore_init(struct Datastore* datastore, const char* config_root); 50 | 51 | /*** 52 | * initialize the structure of the datastore 53 | * @param datastore the struct to initialize 54 | * @returns true(1) on success 55 | */ 56 | int libp2p_datastore_new(struct Datastore** datastore); 57 | 58 | 59 | /*** 60 | * deallocate the memory and clear resources from a datastore_init 61 | * @param datastore the struct to deallocate 62 | * @returns true(1) 63 | */ 64 | int libp2p_datastore_free(struct Datastore* datastore); 65 | 66 | /*** 67 | * Create a new DatastoreRecord struct 68 | * @returns a newly allocated DatastoreRecord struct 69 | */ 70 | struct DatastoreRecord* libp2p_datastore_record_new(); 71 | 72 | /*** 73 | * Free resources of a DatastoreRecord 74 | */ 75 | int libp2p_datastore_record_free(struct DatastoreRecord* record); 76 | -------------------------------------------------------------------------------- /net/stream.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "multiaddr/multiaddr.h" 4 | #include "libp2p/net/stream.h" 5 | #include "libp2p/net/connectionstream.h" 6 | #include "libp2p/yamux/yamux.h" 7 | 8 | int libp2p_stream_default_handle_upgrade(struct Stream* parent_stream, struct Stream* new_stream) { 9 | return libp2p_net_connection_upgrade(parent_stream, new_stream); 10 | } 11 | 12 | struct Stream* libp2p_stream_new() { 13 | struct Stream* stream = (struct Stream*) malloc(sizeof(struct Stream)); 14 | if (stream != NULL) { 15 | stream->address = NULL; 16 | stream->close = NULL; 17 | stream->parent_stream = NULL; 18 | stream->peek = NULL; 19 | stream->read = NULL; 20 | stream->read_raw = NULL; 21 | stream->socket_mutex = NULL; 22 | stream->stream_context = NULL; 23 | stream->write = NULL; 24 | stream->handle_upgrade = libp2p_stream_default_handle_upgrade; 25 | stream->channel = -1; 26 | } 27 | return stream; 28 | } 29 | 30 | void libp2p_stream_free(struct Stream* stream) { 31 | if (stream != NULL) { 32 | if (stream->socket_mutex != NULL) { 33 | free(stream->socket_mutex); 34 | stream->socket_mutex = NULL; 35 | } 36 | if (stream->address != NULL) { 37 | multiaddress_free(stream->address); 38 | stream->address = NULL; 39 | } 40 | free(stream); 41 | } 42 | } 43 | 44 | int libp2p_stream_is_open(struct Stream* stream) { 45 | if (stream == NULL) 46 | return 0; 47 | 48 | struct Stream* base_stream = stream; 49 | while (base_stream->parent_stream != NULL) 50 | base_stream = base_stream->parent_stream; 51 | if (base_stream->stream_type == STREAM_TYPE_RAW) { 52 | struct ConnectionContext* ctx = (struct ConnectionContext*)base_stream->stream_context; 53 | if (ctx->socket_descriptor > 0) 54 | return 1; 55 | } 56 | return 0; 57 | } 58 | 59 | // forward declaration 60 | struct YamuxChannelContext* libp2p_yamux_get_channel_context(void* stream_context); 61 | 62 | /** 63 | * Look for the latest stream 64 | * (properly handles both raw streams and yamux streams) 65 | * @param in the incoming stream 66 | * @returns the latest child stream 67 | */ 68 | struct Stream* libp2p_stream_get_latest_stream(struct Stream* in) { 69 | if (in == NULL) 70 | return NULL; 71 | if (in->stream_type == STREAM_TYPE_RAW) { 72 | struct ConnectionContext* ctx = (struct ConnectionContext*)in->stream_context; 73 | return ctx->session_context->default_stream; 74 | } else if (in->stream_type == STREAM_TYPE_YAMUX) { 75 | struct YamuxChannelContext* ctx = libp2p_yamux_get_channel_context(in->stream_context); 76 | if (ctx != NULL) 77 | return ctx->child_stream; 78 | } 79 | return libp2p_stream_get_latest_stream(in->parent_stream); 80 | } 81 | -------------------------------------------------------------------------------- /include/libp2p/crypto/rsa.h: -------------------------------------------------------------------------------- 1 | #ifndef rsa_h 2 | #define rsa_h 3 | 4 | #include 5 | 6 | struct RsaPublicKey { 7 | char* der; 8 | size_t der_length; 9 | }; 10 | 11 | struct RsaPrivateKey { 12 | // the basics of a key pair 13 | unsigned long long QP; 14 | unsigned long long DQ; 15 | unsigned long long DP; 16 | unsigned long long Q; 17 | unsigned long long P; 18 | unsigned long long D; 19 | unsigned long long E; 20 | unsigned long long N; 21 | // the keys in DER format 22 | // private 23 | char* der; 24 | size_t der_length; 25 | // public 26 | char* public_key_der; 27 | size_t public_key_length; 28 | }; 29 | 30 | /** 31 | * Convert a struct RsaPrivateKey to a struct PrivateKey 32 | * @param in the RsaPrivateKey 33 | * @returns a struct PrivateKey 34 | */ 35 | struct PrivateKey* libp2p_crypto_rsa_to_private_key(struct RsaPrivateKey* in); 36 | 37 | /*** 38 | * Convert a PrivateKey struct to an RsaPrivateKey struct 39 | * @param in the PrivateKey (NOTE: Must be of type KEYTYPE_RSA 40 | * @returns the RsaPrivateKey or NULL on error 41 | */ 42 | struct RsaPrivateKey* libp2p_crypto_private_key_to_rsa(struct PrivateKey* in); 43 | 44 | /** 45 | * generate a new private key 46 | * @param private_key the new private key 47 | * @param num_bits_for_keypair the size of the key (1024 minimum) 48 | * @returns true(1) on success 49 | */ 50 | int libp2p_crypto_rsa_generate_keypair(struct RsaPrivateKey* private_key, unsigned long num_bits_for_keypair); 51 | 52 | /** 53 | * Use the private key DER to fill in the public key DER 54 | * @param private_key the private key to use 55 | * @reutrns true(1) on success 56 | */ 57 | int libp2p_crypto_rsa_private_key_fill_public_key(struct RsaPrivateKey* private_key); 58 | 59 | 60 | /*** 61 | * Free resources used by RsaPrivateKey 62 | * @param private_key the resources 63 | * @returns 0 64 | */ 65 | int libp2p_crypto_rsa_rsa_private_key_free(struct RsaPrivateKey* private_key); 66 | struct RsaPrivateKey* libp2p_crypto_rsa_rsa_private_key_new(); 67 | /** 68 | * sign a message 69 | * @param private_key the private key 70 | * @param message the message to be signed 71 | * @param message_length the length of message 72 | * @param result the resultant signature. Note: should be pre-allocated and be the size of the private key (i.e. 2048) 73 | * @returns true(1) on successs, otherwise false(0) 74 | */ 75 | int libp2p_crypto_rsa_sign(struct RsaPrivateKey* private_key, const char* message, size_t message_length, unsigned char** result, size_t* result_size); 76 | 77 | int libp2p_crypto_rsa_verify(struct RsaPublicKey* public_key, const unsigned char* message, size_t message_length, const unsigned char* signature); 78 | 79 | #endif /* rsa_h */ 80 | -------------------------------------------------------------------------------- /include/libp2p/secio/propose.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "libp2p/crypto/rsa.h" 4 | 5 | struct Propose { 6 | unsigned char* rand; 7 | size_t rand_size; 8 | // a protobuf'd struct PublicKey (defined in crypto/key.h) 9 | unsigned char* public_key; 10 | size_t public_key_size; 11 | char* exchanges; 12 | size_t exchanges_size; 13 | char* ciphers; 14 | size_t ciphers_size; 15 | char* hashes; 16 | size_t hashes_size; 17 | }; 18 | 19 | struct Propose* libp2p_secio_propose_new(); 20 | void libp2p_secio_propose_free(struct Propose* in); 21 | /** 22 | * Helper to set the property to a value 23 | * @param to the property 24 | * @param to_size the size that matches the property 25 | * @param from the value to be set in the property 26 | * @param from_size the size of from 27 | * @returns true(1) on success, otherwise false(0) 28 | */ 29 | int libp2p_secio_propose_set_property(void** to, size_t* to_size, const void* from, size_t from_size); 30 | 31 | /** 32 | * retrieves the approximate size of an encoded version of the passed in struct 33 | * @param in the struct to look at 34 | * @reutrns the size of buffer needed 35 | */ 36 | size_t libp2p_secio_propose_protobuf_encode_size(struct Propose* in); 37 | 38 | /** 39 | * Encode the struct Propose in protobuf format 40 | * @param in the struct to be encoded 41 | * @param buffer where to put the results 42 | * @param max_buffer_length the max to write 43 | * @param bytes_written how many bytes were written to the buffer 44 | * @returns true(1) on success, otherwise false(0) 45 | */ 46 | int libp2p_secio_propose_protobuf_encode(struct Propose* in, unsigned char* buffer, size_t max_buffer_length, size_t* bytes_written); 47 | 48 | /** 49 | * Turns a protobuf array into a Propose struct 50 | * @param buffer the protobuf array 51 | * @param max_buffer_length the length of the buffer 52 | * @param out a pointer to the new struct Propose NOTE: this method allocates memory 53 | * @returns true(1) on success, otherwise false(0) 54 | */ 55 | int libp2p_secio_propose_protobuf_decode(const unsigned char* buffer, size_t max_buffer_length, struct Propose** out); 56 | 57 | /*** 58 | * Build a propose structure for sending to the remote client 59 | * @param nonce a 16 byte nonce, previously defined 60 | * @param rsa_key the local RSA key 61 | * @param supportedExchanges a comma separated list of supported exchange protocols 62 | * @param supportedCiphers a comma separated list of supported ciphers 63 | * @param supportedHashes a comma separated list of supported hashes 64 | * @returns an initialized Propose struct, or NULL 65 | */ 66 | struct Propose* libp2p_secio_propose_build(unsigned char nonce[16], struct RsaPrivateKey* rsa_key, 67 | const char* supportedExchanges, const char* supportedCiphers, const char* supportedHashes); 68 | -------------------------------------------------------------------------------- /include/libp2p/record/message.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "libp2p/record/record.h" 5 | 6 | /** 7 | * protobuf stuff for Message 8 | * This is used for the KAD / DHT stuff 9 | */ 10 | 11 | enum MessageType { 12 | MESSAGE_TYPE_PUT_VALUE = 0, 13 | MESSAGE_TYPE_GET_VALUE = 1, 14 | MESSAGE_TYPE_ADD_PROVIDER = 2, 15 | MESSAGE_TYPE_GET_PROVIDERS = 3, 16 | MESSAGE_TYPE_FIND_NODE = 4, 17 | MESSAGE_TYPE_PING = 5 18 | }; 19 | 20 | struct KademliaMessage { 21 | enum MessageType message_type; // protobuf field 1 (a varint) 22 | char* key; // protobuf field 2 23 | size_t key_size; 24 | struct Libp2pRecord* record; // protobuf field 3 25 | struct Libp2pLinkedList* closer_peer_head; // protobuf field 8 linked list of Libp2pPeers 26 | struct Libp2pLinkedList* provider_peer_head; // protobuf field 9 linked list of Libp2pPeers 27 | int32_t cluster_level_raw; // protobuf field 10 28 | }; 29 | 30 | /** 31 | * create a new Libp2pMessage struct 32 | * @returns a new Libp2pMessage with default settings 33 | */ 34 | struct KademliaMessage* libp2p_message_new(); 35 | 36 | /** 37 | * Deallocate memory from a Message struct 38 | * @param in the struct 39 | */ 40 | void libp2p_message_free(struct KademliaMessage* in); 41 | 42 | /** 43 | * determine the size necessary for a message struct to be protobuf'd 44 | * @param in the struct to be protobuf'd 45 | * @returns the size required 46 | */ 47 | size_t libp2p_message_protobuf_encode_size(const struct KademliaMessage* in); 48 | 49 | /** 50 | * Encode a Message into a protobuf 51 | * @param in the message 52 | * @param buffer the byte array that will hold the protobuf 53 | * @param max_buffer_size the amount of memory previously reserved for buffer 54 | * @param bytes_written will hold the number of bytes written to buffer 55 | * @returns true(1) on success, otherwise false(0) 56 | */ 57 | int libp2p_message_protobuf_encode(const struct KademliaMessage* in, unsigned char* buffer, size_t max_buffer_size, size_t* bytes_written); 58 | 59 | /** 60 | * Convert a Libp2pMessage into protobuf format, 61 | * allocating memory as needed 62 | * @param in the Libp2pMessage to convert 63 | * @param buffer where to store the protobuf 64 | * @param buffer_size the size written into buffer 65 | * @returns true(1) on success, otherwise false(0) 66 | */ 67 | int libp2p_message_protobuf_allocate_and_encode(const struct KademliaMessage* in, unsigned char **buffer, size_t* buffer_size); 68 | 69 | /** 70 | * turn a protobuf back into a message 71 | * @param buffer the protobuf 72 | * @param buffer_size the length of the buffer 73 | * @param out the message 74 | * @returns true(1) on success, otherwise false(0) 75 | */ 76 | int libp2p_message_protobuf_decode(unsigned char* buffer, size_t buffer_size, struct KademliaMessage** out); 77 | 78 | -------------------------------------------------------------------------------- /include/libp2p/routing/dht_protocol.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "libp2p/conn/session.h" 4 | #include "libp2p/net/protocol.h" 5 | #include "libp2p/peer/peerstore.h" 6 | #include "libp2p/peer/providerstore.h" 7 | #include "libp2p/record/message.h" 8 | 9 | /*** 10 | * This is where kademlia and dht talk to the outside world 11 | */ 12 | 13 | 14 | struct DhtContext { 15 | struct Peerstore* peer_store; 16 | struct ProviderStore* provider_store; 17 | struct Datastore* datastore; 18 | struct Filestore* filestore; 19 | }; 20 | 21 | struct Libp2pProtocolHandler* libp2p_routing_dht_build_protocol_handler(struct Peerstore* peer_store, struct ProviderStore* provider_store, 22 | struct Datastore* datastore, struct Filestore* filestore); 23 | 24 | /** 25 | * Take existing stream and upgrade to the Kademlia / DHT protocol/codec 26 | * @param context the context 27 | * @returns true(1) on success, otherwise false(0) 28 | */ 29 | int libp2p_routing_dht_upgrade_stream(struct SessionContext* context); 30 | 31 | /** 32 | * Handle a client requesting an upgrade to the DHT protocol 33 | * @param stream the stream 34 | * @returns true(1) on success, otherwise false(0) 35 | */ 36 | int libp2p_routing_dht_handshake(struct Stream* stream); 37 | 38 | /*** 39 | * Handle the incoming message. Handshake should have already 40 | * been done. We should expect that the next read contains 41 | * a protobuf'd kademlia message. 42 | * @param stream the incoming stream 43 | * @param protocol_context the protocol context 44 | * @returns true(1) on success, otherwise false(0) 45 | */ 46 | int libp2p_routing_dht_handle_message(struct Stream* stream, struct DhtContext* protocol_context); 47 | 48 | /*** 49 | * Send a kademlia message 50 | * NOTE: this call upgrades the stream to /ipfs/kad/1.0.0 51 | * @param context the context 52 | * @param message the message 53 | * @returns true(1) on success, false(0) otherwise 54 | */ 55 | int libp2p_routing_dht_send_message(struct SessionContext* sessionContext, struct KademliaMessage* message); 56 | 57 | /** 58 | * Attempt to receive a kademlia message 59 | * NOTE: This call assumes that a send_message was sent 60 | * @param sessionContext the context 61 | * @param result where to put the results 62 | * @returns true(1) on success, false(0) otherwise 63 | */ 64 | int libp2p_routing_dht_receive_message(struct SessionContext* sessionContext, struct KademliaMessage** result); 65 | 66 | /** 67 | * Used to send a message to the nearest x peers 68 | * 69 | * @param private_key the private key of the local peer 70 | * @param peerstore the collection of peers 71 | * @param datastore a connection to the datastore 72 | * @param msg the message to send 73 | * @returns true(1) if we sent to at least 1, false(0) otherwise 74 | */ 75 | int libp2p_routing_dht_send_message_nearest_x(const struct Dialer* dialer, struct Peerstore* peerstore, 76 | struct Datastore* datastore, struct KademliaMessage* msg, int numToSend); 77 | -------------------------------------------------------------------------------- /include/libp2p/identify/identify.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "libp2p/utils/vector.h" 4 | 5 | #define IDENTIFY_PROTOCOL_VERSION "ipfs/0.1.0" 6 | #define IDENTIFY_AGENT_VERSION "c-ipfs/1.0" 7 | 8 | typedef struct { 9 | // publicKey is this node's public key (which also gives its node.ID) 10 | // - may not need to be sent, as secure channel implies it has been sent. 11 | // - then again, if we change / disable secure channel, may still want it. 12 | char *PublicKey; 13 | int PublicKeyLength; 14 | // listenAddrs are the multiaddrs the sender node listens for open connections on 15 | char **ListenAddrs; 16 | // protocols are the services this node is running 17 | char **Protocols; 18 | // oservedAddr is the multiaddr of the remote endpoint that the sender node perceives 19 | // this is useful information to convey to the other side, as it helps the remote endpoint 20 | // determine whether its connection to the local peer goes through NAT. 21 | char *ObservedAddr; 22 | // protocolVersion determines compatibility between peers 23 | char *ProtocolVersion; 24 | // agentVersion is like a UserAgent string in browsers, or client version in bittorrent 25 | // includes the client name and client. 26 | char *AgentVersion; 27 | char *XXX_unrecognized; 28 | } Identify; 29 | 30 | struct IdentifyContext { 31 | struct Stream* parent_stream; 32 | struct Stream* stream; 33 | }; 34 | 35 | int libp2p_identify_can_handle(const struct StreamMessage* msg); 36 | int libp2p_identify_send_protocol(struct Stream* stream, Identify* identify, int initiatedByUs); 37 | int libp2p_identify_receive_protocol(struct Stream* stream); 38 | Identify* libp2p_identify_new(); 39 | void libp2p_identify_free(Identify* in); 40 | char *libp2p_identify_new_item(char *item, size_t size); 41 | int libp2p_identify_array_add_item(char ***array, char *item); 42 | int libp2p_identify_protobuf_encode(const Identify* in, unsigned char* buffer, size_t max_buffer_size, size_t* bytes_written); 43 | int libp2p_identify_protobuf_decode(const unsigned char* in, size_t in_size, Identify** out); 44 | int libp2p_identify_handle_message(const struct StreamMessage* msg, struct Stream* stream, void* protocol_context); 45 | int libp2p_identify_shutdown(void* protocol_context); 46 | struct Libp2pProtocolHandler* libp2p_identify_build_protocol_handler(char* public_key, int publicKeyLength); 47 | 48 | /*** 49 | * Create a new stream that negotiates the identify protocol 50 | * 51 | * NOTE: This will be sent by our side (us asking them). 52 | * Incoming "Identify" requests should be handled by the 53 | * external protocol handler, not this function. 54 | * 55 | * @param parent_stream the parent stream 56 | * @returns a new Stream that can talk "identify" 57 | */ 58 | struct Stream* libp2p_identify_stream_new(struct Stream* parent_stream, Identify* identify, int initiatedByUs); 59 | 60 | -------------------------------------------------------------------------------- /include/libp2p/secio/secio.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "libp2p/crypto/key.h" 4 | #include "libp2p/crypto/rsa.h" 5 | #include "libp2p/conn/session.h" 6 | #include "libp2p/peer/peerstore.h" 7 | #include "libp2p/net/protocol.h" 8 | 9 | /** 10 | * Handling of a secure connection 11 | */ 12 | 13 | enum SecioStatus { 14 | secio_status_unknown, 15 | secio_status_initialized, 16 | secio_status_syn, 17 | secio_status_ack 18 | }; 19 | 20 | struct SecioContext { 21 | struct Stream* stream; 22 | struct SessionContext* session_context; 23 | struct RsaPrivateKey* private_key; 24 | struct Peerstore* peer_store; 25 | struct StreamMessage* buffered_message; 26 | size_t buffered_message_pos; 27 | volatile enum SecioStatus status; 28 | }; 29 | 30 | struct Libp2pProtocolHandler* libp2p_secio_build_protocol_handler(struct RsaPrivateKey* private_key, struct Peerstore* peer_store); 31 | 32 | /*** 33 | * Initiates a secio handshake. Use this method when you want to initiate a secio 34 | * session. This should not be used to respond to incoming secio requests 35 | * @param parent_stream the parent stream 36 | * @param peerstore the peerstore 37 | * @param rsa_private_key the local private key 38 | * @returns a Secio Stream 39 | */ 40 | struct Stream* libp2p_secio_stream_new(struct Stream* parent_stream, struct Peerstore* peerstore, struct RsaPrivateKey* rsa_private_key); 41 | 42 | /*** 43 | * Initiates a secio handshake. Use this method when you want to initiate a secio 44 | * session. This should not be used to respond to incoming secio requests 45 | * @param ctx the SecioContext 46 | * @returns true(1) on success, false(0) otherwise 47 | */ 48 | int libp2p_secio_initiate_handshake(struct SecioContext* ctx); 49 | 50 | /*** 51 | * Send the protocol string to the remote stream 52 | * @param stream stream 53 | * @returns true(1) on success, false(0) otherwise 54 | */ 55 | int libp2p_secio_send_protocol(struct Stream* stream); 56 | 57 | /*** 58 | * Attempt to read the secio protocol as a reply from the remote 59 | * @param session the context 60 | * @returns true(1) if we received what we think we should have, false(0) otherwise 61 | */ 62 | int libp2p_secio_receive_protocol(struct Stream* stream); 63 | 64 | /*** 65 | * performs initial communication over an insecure channel to share 66 | * keys, IDs, and initiate connection. This is a framed messaging system 67 | * NOTE: session must contain a valid socket_descriptor that is a multistream. 68 | * @param secio_stream a stream that is a Secio stream 69 | * @returns true(1) on success, false(0) otherwise 70 | */ 71 | int libp2p_secio_handshake(struct Stream* secio_stream); 72 | 73 | /*** 74 | * Wait for secio stream to become ready 75 | * @param session_context the session context to check 76 | * @param timeout_secs the number of seconds to wait for things to become ready 77 | * @returns true(1) if it becomes ready, false(0) otherwise 78 | */ 79 | int libp2p_secio_ready(struct SessionContext* session_context, int timeout_secs); 80 | 81 | -------------------------------------------------------------------------------- /crypto/encoding/x509.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "mbedtls/rsa.h" 6 | #include "mbedtls/pk.h" 7 | #include "mbedtls/ctr_drbg.h" 8 | 9 | #include "libp2p/crypto/encoding/x509.h" 10 | 11 | /** 12 | * public methods 13 | */ 14 | 15 | /** 16 | * convert a RSA Private Key to an array of bytes in DER format 17 | * @param private_key the private key 18 | * @param bytes where to put the resultant bytes 19 | * @returns true(1) on success 20 | */ 21 | int libp2p_crypto_encoding_x509_private_key_to_der(struct RsaPrivateKey* private_key, unsigned char* bytes[1600]) { 22 | 23 | // get everything setup 24 | mbedtls_pk_context ctx; 25 | mbedtls_pk_init( &ctx); 26 | 27 | mbedtls_pk_setup( &ctx, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)); 28 | 29 | mbedtls_rsa_context* rsa = mbedtls_pk_rsa( ctx ); 30 | 31 | // set the values in the context 32 | mbedtls_mpi N; 33 | mbedtls_mpi_init(&N); 34 | mbedtls_mpi_lset(&N, private_key->N); 35 | 36 | mbedtls_mpi E; 37 | mbedtls_mpi_init(&E); 38 | mbedtls_mpi_lset(&E, private_key->E); 39 | 40 | mbedtls_mpi Q; 41 | mbedtls_mpi_init(&Q); 42 | mbedtls_mpi_lset(&Q, private_key->Q); 43 | 44 | rsa->N = N; 45 | rsa->E = E; 46 | rsa->Q = Q; 47 | rsa->len = ( mbedtls_mpi_bitlen(&rsa->N ) + 7) >> 3; 48 | 49 | // now write to DER 50 | mbedtls_pk_write_key_der(&ctx, *bytes, 1600); 51 | 52 | mbedtls_mpi_free(&N); 53 | mbedtls_mpi_free(&E); 54 | mbedtls_mpi_free(&Q); 55 | mbedtls_rsa_free(rsa); 56 | mbedtls_pk_free(&ctx); 57 | 58 | return 1; 59 | } 60 | 61 | /*** 62 | * Parse a DER bytestring into a RsaPrivateKey struct 63 | * @param der the incoming bytestring 64 | * @param der_length the length of the bytestring 65 | * @param private_key the RsaPrivateKey to fill 66 | * @returns true(1) on success 67 | */ 68 | int libp2p_crypto_encoding_x509_der_to_private_key(unsigned char* der, size_t der_length, struct RsaPrivateKey* private_key) { 69 | mbedtls_pk_context ctx; 70 | mbedtls_pk_init(&ctx); 71 | 72 | int retVal = mbedtls_pk_parse_key(&ctx, der, der_length, NULL, 0); 73 | 74 | if (retVal >= 0) { 75 | // parse the results into the structure 76 | mbedtls_rsa_context* rsa = mbedtls_pk_rsa(ctx); 77 | private_key->D = *(rsa->D.p); 78 | private_key->DP = *(rsa->DP.p); 79 | private_key->DQ = *(rsa->DQ.p); 80 | private_key->E = *(rsa->E.p); 81 | private_key->N = *(rsa->N.p); 82 | private_key->P = *(rsa->P.p); 83 | private_key->Q = *(rsa->Q.p); 84 | private_key->QP = *(rsa->QP.p); 85 | 86 | // now put the public DER format in. 87 | private_key->der = malloc(sizeof(char) * der_length); 88 | if (private_key->der == NULL) 89 | return 0; 90 | memcpy(private_key->der, der, der_length); 91 | private_key->der_length = der_length; 92 | 93 | //NOTE: the public DER stuff is done in rsa.c 94 | } 95 | 96 | mbedtls_pk_free(&ctx); 97 | 98 | return retVal >= 0; 99 | } 100 | -------------------------------------------------------------------------------- /include/libp2p/net/protocol.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "libp2p/conn/session.h" 3 | #include "libp2p/utils/vector.h" 4 | #include "libp2p/net/stream.h" 5 | 6 | /*** 7 | * An "interface" for different IPFS protocols 8 | */ 9 | struct Libp2pProtocolHandler { 10 | /** 11 | * A protocol dependent context (often an IpfsNode pointer, but libp2p doesn't know about that) 12 | */ 13 | void* context; 14 | /** 15 | * Determines if this protocol can handle the incoming message 16 | * @param incoming the incoming data 17 | * @param incoming_size the size of the incoming data buffer 18 | * @returns true(1) if it can handle this message, false(0) if not 19 | */ 20 | int (*CanHandle)(const struct StreamMessage* msg); 21 | /*** 22 | * Handles the message 23 | * @param incoming the incoming data buffer 24 | * @param incoming_size the size of the incoming data buffer 25 | * @param stream the incoming stream 26 | * @param protocol_context the protocol-dependent context 27 | * @returns 0 if the caller should not continue looping, <0 on error, >0 on success 28 | */ 29 | int (*HandleMessage)(const struct StreamMessage* msg, struct Stream* stream, void* protocol_context); 30 | 31 | /** 32 | * Shutting down. Clean up any memory allocations 33 | * @param protocol_context the context 34 | * @returns true(1) 35 | */ 36 | int (*Shutdown)(void* protocol_context); 37 | }; 38 | 39 | /** 40 | * Allocate resources for a new Libp2pProtocolHandler 41 | * @returns an allocated struct 42 | */ 43 | struct Libp2pProtocolHandler* libp2p_protocol_handler_new(); 44 | 45 | /*** 46 | * Release resources of a protocol handler 47 | * @param handler the handler to free 48 | */ 49 | void libp2p_protocol_handler_free(struct Libp2pProtocolHandler* handler); 50 | 51 | /*** 52 | * Handle an incoming message 53 | * @param message the incoming message 54 | * @param stream the incoming connection 55 | * @param handlers a Vector of protocol handlers 56 | * @returns -1 on error, 0 on protocol upgrade, 1 on success 57 | */ 58 | int libp2p_protocol_marshal(struct StreamMessage* message, struct Stream* stream, struct Libp2pVector* protocol_handlers); 59 | 60 | /*** 61 | * Shut down all protocol handlers and free vector 62 | * @param handlers vector of Libp2pProtocolHandler 63 | * @returns true(1) 64 | */ 65 | int libp2p_protocol_handlers_shutdown(struct Libp2pVector* handlers); 66 | 67 | /*** 68 | * Check to see if this is a valid protocol 69 | * @param msg the message 70 | * @param handlers the vector of handlers 71 | */ 72 | int libp2p_protocol_is_valid_protocol(struct StreamMessage* msg, struct Libp2pVector* handlers); 73 | 74 | /*** 75 | * Retrieve the correct protocol handlder for a particular protocol id 76 | * @param protocol_handlers the collection of protocol handlers 77 | * @param id the protocol id 78 | * @returns a protocol handler that can handle id (or NULL if none found) 79 | */ 80 | const struct Libp2pProtocolHandler* libp2p_protocol_get_handler(struct Libp2pVector* protocol_handlers, const char* id); 81 | -------------------------------------------------------------------------------- /include/libp2p/yamux/stream.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "session.h" 7 | #include "libp2p/conn/session.h" 8 | #include "libp2p/yamux/yamux.h" 9 | 10 | // forward declarations 11 | struct YamuxChannelContext; 12 | 13 | // NOTE: 'data' is not guaranteed to be preserved when the read_fn 14 | // handler exists (read: it will be freed). 15 | struct yamux_stream; 16 | 17 | typedef void (*yamux_stream_read_fn)(struct yamux_stream* stream, uint32_t data_length, void* data); 18 | typedef void (*yamux_stream_fin_fn )(struct yamux_stream* stream); 19 | typedef void (*yamux_stream_rst_fn )(struct yamux_stream* stream); 20 | typedef void (*yamux_stream_free_fn)(struct yamux_stream* stream); 21 | 22 | enum yamux_stream_state 23 | { 24 | yamux_stream_inited, 25 | yamux_stream_syn_sent, 26 | yamux_stream_syn_recv, 27 | yamux_stream_est, 28 | yamux_stream_closing, 29 | yamux_stream_closed 30 | }; 31 | 32 | struct yamux_stream 33 | { 34 | struct yamux_session* session; 35 | 36 | yamux_stream_read_fn read_fn; 37 | yamux_stream_fin_fn fin_fn ; 38 | yamux_stream_rst_fn rst_fn ; 39 | yamux_stream_free_fn free_fn; 40 | 41 | struct Stream* stream; 42 | 43 | enum yamux_stream_state state; 44 | 45 | yamux_streamid id; 46 | 47 | uint32_t window_size; 48 | }; 49 | 50 | /** 51 | * Create a new stream that has a YamuxChannelContext 52 | * @param context the Yamux context 53 | * @param id the stream id 54 | * @param msg the incoming message 55 | * @returns a stream that is a Yamux channel 56 | */ 57 | struct Stream* yamux_channel_new(struct YamuxContext* context, yamux_streamid id, struct StreamMessage* msg); 58 | 59 | // not obligatory, SYN is sent by yamux_stream_write when the stream 60 | // isn't initialised anyway 61 | ssize_t yamux_stream_init (struct YamuxChannelContext* channel_ctx); 62 | 63 | /*** 64 | * Closes the stream 65 | * NOTE: doesn't free the stream, uses FIN 66 | * @param context the YamuxContext or YamuxChannelContext 67 | * @returns number of bytes sent 68 | */ 69 | ssize_t yamux_stream_close(void* context); 70 | // uses RST 71 | ssize_t yamux_stream_reset(struct YamuxChannelContext* stream); 72 | 73 | void yamux_stream_free(struct yamux_stream* stream); 74 | 75 | ssize_t yamux_stream_window_update(struct YamuxChannelContext* ctx, int32_t delta); 76 | ssize_t yamux_stream_write(struct YamuxChannelContext* ctx, uint32_t data_length, void* data); 77 | 78 | /*** 79 | * process stream 80 | * @param stream the stream 81 | * @param frame the frame 82 | * @param incoming the stream bytes (after the frame) 83 | * @param incoming_size the size of incoming 84 | * @returns the number of bytes processed (can be zero) or negative number on error 85 | */ 86 | ssize_t yamux_stream_process(struct yamux_stream* stream, struct yamux_frame* frame, const uint8_t* incoming, size_t incoming_size); 87 | 88 | /** 89 | * Retrieve the flags for this context 90 | * @param context the context 91 | * @returns the correct flag 92 | */ 93 | enum yamux_frame_flags get_flags(void* context); 94 | 95 | -------------------------------------------------------------------------------- /crypto/aes.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "mbedtls/entropy.h" 5 | #include "mbedtls/ctr_drbg.h" 6 | #include "mbedtls/aes.h" 7 | 8 | /** 9 | * functions for aes encryption 10 | */ 11 | 12 | /** 13 | * Generate a new AES key 14 | * @param key where to store the 32 byte key 15 | * @returns true(1) on success 16 | */ 17 | int libp2p_crypto_aes_key_generate(char* key) { 18 | mbedtls_entropy_context entropy; 19 | mbedtls_ctr_drbg_context ctr_drbg; 20 | 21 | mbedtls_entropy_init(&entropy); 22 | 23 | char* pers = "aes generate key"; 24 | 25 | mbedtls_ctr_drbg_init(&ctr_drbg); 26 | 27 | if (mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, 28 | (const unsigned char *) pers, 29 | strlen( pers )) != 0) 30 | return 0; 31 | 32 | if (mbedtls_ctr_drbg_random(&ctr_drbg, (unsigned char*)key, 32) != 0) 33 | return 0; 34 | 35 | return 1; 36 | } 37 | 38 | /** 39 | * Encrypt a block of text 40 | * @param key the aes key (32 bytes) 41 | * @param iv the random part of encryption (16 bytes) 42 | * @param input the text to encrypt 43 | * @param input_size the length of the array 44 | * @param output where the output will be placed 45 | * @param output_size the length of the memory allocated for output 46 | * @returns true(1) on success, otherwise false(0) 47 | */ 48 | int libp2p_crypto_aes_encrypt(char* key, char* iv, char* input, size_t input_size, unsigned char** output, size_t* output_size) { 49 | int new_size = 0; 50 | mbedtls_aes_context ctx; 51 | mbedtls_aes_init(&ctx); 52 | mbedtls_aes_setkey_enc(&ctx, (unsigned char*)key, 256); 53 | // turn input into a multiple of 16 54 | new_size = input_size; 55 | if (new_size % 16 != 0) { 56 | new_size += new_size % 16; 57 | } 58 | char* padded_input = malloc(new_size); 59 | memcpy(padded_input, input, input_size); 60 | if (new_size != input_size) 61 | memset(&padded_input[input_size], 0, new_size - input_size); 62 | // make room for the output 63 | *output = malloc(new_size); 64 | *output_size = new_size; 65 | int retVal = mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, new_size, (unsigned char*)iv, (unsigned char*)padded_input, *output); 66 | free(padded_input); 67 | if (retVal != 0) 68 | free(output); 69 | return retVal == 0; 70 | } 71 | 72 | /** 73 | * Decrypt a block of text 74 | * @param key the aes key (32 bytes) 75 | * @param iv the random part of encryption (16 bytes) 76 | * @param input the text to encrypt 77 | * @param input_size the length of the array 78 | * @param output where the output will be placed 79 | * @param output_size the length of the memory allocated for output 80 | * @returns true(1) on success, otherwise false(0) 81 | */ 82 | int libp2p_crypto_aes_decrypt(char* key, char* iv, char* input, size_t input_size, unsigned char** output, size_t* output_size) { 83 | mbedtls_aes_context ctx; 84 | mbedtls_aes_init(&ctx); 85 | mbedtls_aes_setkey_dec(&ctx, (unsigned char*)key, 256); 86 | // make room for the output 87 | *output = malloc(input_size); 88 | *output_size = input_size; 89 | if (mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, input_size, (unsigned char*)iv, (unsigned char*)input, *output) != 0) 90 | return 0; 91 | return 1; 92 | } 93 | -------------------------------------------------------------------------------- /test/multihash/test_multihash.h: -------------------------------------------------------------------------------- 1 | #ifndef test_multihash_h 2 | #define test_multihash_h 3 | 4 | #include "../../include/libp2p/multihash_old/multihash.h" 5 | #include "libp2p/crypto/encoding/base58.h" 6 | 7 | int test_multihash_encode() { 8 | struct MultiHash hash; 9 | hash.fn_code = MULTIHASH_SHA1; 10 | hash.size = 2; 11 | unsigned char data[] = "A"; 12 | hash.data = data; 13 | // 8 bytes plus terminating null to make it easier to debug 14 | // note: function does not clear the buffer, so we have to 15 | char buffer[9]; 16 | char* b = buffer; 17 | memset(b, 0, 9); 18 | int retVal = libp2p_multihash_hex_string(&hash, b, 9); 19 | if (retVal == 0) 20 | return 0; 21 | 22 | if (b[0] != '1' && b[1] != '1') 23 | return 0; 24 | if (b[2] != '0' && b[3] != '2') 25 | return 0; 26 | if (b[4] != '4' && b[5] != '1') 27 | return 0; 28 | if (b[6] != '0' && b[7] != '0') 29 | return 0; 30 | return 1; 31 | } 32 | 33 | int test_multihash_decode() { 34 | char in[9] = "11024100"; 35 | char* string = in; 36 | struct MultiHash hash; 37 | 38 | int retVal = libp2p_multihash_from_hex_string(string, 8, &hash); 39 | if (retVal == 0) 40 | return 0; 41 | 42 | if (hash.fn_code != 0x11) 43 | return 0; 44 | if (hash.size != 2) 45 | return 0; 46 | if (hash.data[0] != 0x41 || hash.data[1] != 0x00) 47 | return 0; 48 | return 1; 49 | } 50 | 51 | int test_multihash_base58_decode() { 52 | unsigned char original[5] = { 'S', 'D', 'Y', 'h', 'd' }; 53 | 54 | size_t buffer_len = 4; 55 | unsigned char buffer[buffer_len]; 56 | unsigned char* ptr = buffer; 57 | 58 | int retVal = libp2p_crypto_encoding_base58_decode(original, 5, &ptr, &buffer_len); 59 | if (retVal == 0) 60 | return 0; 61 | if (buffer[0] != 0x11) 62 | return 0; 63 | if (buffer[1] != 0x02) 64 | return 0; 65 | 66 | return 1; 67 | } 68 | 69 | int test_multihash_size() { 70 | unsigned char hash[6] = {'S', 'D', 'Y', 'h', 'd' ,0 }; 71 | unsigned char* ptr = hash; 72 | size_t sz = libp2p_multihash_b58_size(ptr); 73 | 74 | return sz == 2; 75 | } 76 | 77 | int test_multihash_base58_encode_decode() { 78 | // build the original MultiHash 79 | struct MultiHash original; 80 | original.fn_code = MULTIHASH_SHA1; 81 | original.size = 2; 82 | unsigned char data[] = "A"; 83 | original.data = data; 84 | 85 | // have a buffer to store the base58 encoding 86 | size_t buffer_size = 65535; 87 | unsigned char buffer[buffer_size]; 88 | unsigned char* b = buffer; 89 | 90 | // encode it 91 | libp2p_multihash_to_b58(&original, b, buffer_size); 92 | 93 | // build a place to store the new MultiHash 94 | struct MultiHash results; 95 | results.size = 2; 96 | unsigned char results_data[2]; 97 | results.data = results_data; 98 | 99 | // decode it 100 | libp2p_b58_to_multihash(b, strlen((char*)b), &results); 101 | 102 | // compare 103 | if (original.fn_code != results.fn_code) 104 | return 0; 105 | if (original.size != results.size) 106 | return 0; 107 | if (original.data[0] != results.data[0]) 108 | return 0; 109 | if (original.data[1] != results.data[1]) 110 | return 0; 111 | return 1; 112 | } 113 | 114 | #endif /* test_multihash_h */ 115 | -------------------------------------------------------------------------------- /include/libp2p/os/utils.h: -------------------------------------------------------------------------------- 1 | /** 2 | * OS specific stuff. This is going to get ugly, but at least its in one place 3 | */ 4 | #ifndef __OS_UTILS_H__ 5 | #define __OS_UTILS_H__ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | /** 12 | * a linked list to store filenames 13 | */ 14 | struct FileList { 15 | char* file_name; 16 | struct FileList* next; 17 | }; 18 | 19 | /** 20 | * Builds a list of files within a directory 21 | * @param path the path to examine 22 | * @returns a FileList struct of the first file 23 | */ 24 | struct FileList* os_utils_list_directory(const char* path); 25 | 26 | /** 27 | * Cleans up memory used by a FileList struct 28 | * @param first the struct to free 29 | * @returns true(1) 30 | */ 31 | int os_utils_free_file_list(struct FileList* first); 32 | 33 | /** 34 | * Split the filename from the path 35 | * @param in the full path and filename 36 | * @param path only the path part 37 | * @param filename only the file name 38 | * @returns true(1) 39 | */ 40 | int os_utils_split_filename(const char* in, char** path, char** filename); 41 | 42 | 43 | /** 44 | * get an environment varible from the os 45 | * @param variable the variable to look for 46 | * @returns the results 47 | */ 48 | char* os_utils_getenv(const char* variable); 49 | int os_utils_setenv(const char* variable, const char* value, int overwrite); 50 | /** 51 | * get the user's home directory 52 | * @returns the user's home directory 53 | */ 54 | char* os_utils_get_homedir(); 55 | 56 | /** 57 | * join 2 pieces of a filepath, being careful about the slashes 58 | * @param root the root part 59 | * @param extension what should be concatenated 60 | * @param results where to put the results 61 | * @param max_len throw an error if the total is longer than max_len 62 | */ 63 | int os_utils_filepath_join(const char* root, const char* extension, char* results, unsigned long max_len); 64 | 65 | int os_utils_file_exists(const char* file_name); 66 | 67 | int os_utils_file_size(const char* file_name); 68 | 69 | int os_utils_directory_writeable(const char* path); 70 | 71 | int os_utils_directory_exists(const char* path); 72 | 73 | /** 74 | * Determine if the path presented is actually a directory 75 | * @param file_name the path to examine 76 | * @returns true(1) if file_name is actually a directory 77 | */ 78 | int os_utils_is_directory(const char* file_name); 79 | 80 | /*** 81 | * Get the current time in GMT (UTC) as seconds since epoch 82 | * @returns seconds since epoch 83 | */ 84 | unsigned long long os_utils_gmtime(); 85 | 86 | /** 87 | * String search for platforms without it 88 | * @haystack where to look 89 | * @needle what you're looking for 90 | * @len when to stop looking 91 | * @returns a pointer to where the needle is found in the haystack or NULL if not found 92 | */ 93 | char *strnstr(const char *haystack, const char *needle, size_t len); 94 | 95 | /** 96 | * Make a directory, and any directories before it 97 | * @param path the path to create 98 | * @returns true(1) on success, false(0) otherwise 99 | */ 100 | int os_mkdir(char* path); 101 | 102 | #endif /* utils_h */ 103 | -------------------------------------------------------------------------------- /include/libp2p/record/record.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "libp2p/record/record.h" 4 | #include "libp2p/crypto/rsa.h" 5 | 6 | struct Libp2pRecord { 7 | // the key that references this record 8 | char* key; 9 | size_t key_size; 10 | // the actual value this record is storing 11 | unsigned char* value; 12 | size_t value_size; 13 | // hash of the author's public key 14 | char* author; 15 | size_t author_size; 16 | // a PKI signature for the key + value + author 17 | unsigned char* signature; 18 | size_t signature_size; 19 | // time the record was received, set by receiver 20 | char* time_received; 21 | size_t time_received_size; 22 | }; 23 | 24 | /** 25 | * Create a record with default settings 26 | * @returns the newly allocated record struct 27 | */ 28 | struct Libp2pRecord* libp2p_record_new(); 29 | 30 | /** 31 | * Free the resources from a record struct 32 | * @param in the struct to free 33 | */ 34 | void libp2p_record_free(struct Libp2pRecord* in); 35 | 36 | /** 37 | * Convert a Libp2pRecord into protobuf format 38 | * @param in the Libp2pRecord to convert 39 | * @param buffer where to store the protobuf 40 | * @param max_buffer_size the size of the allocated buffer 41 | * @param bytes_written the size written into buffer 42 | * @returns true(1) on success, otherwise false(0) 43 | */ 44 | int libp2p_record_protobuf_encode(const struct Libp2pRecord* in, unsigned char* buffer, size_t max_buffer_size, size_t* bytes_written); 45 | 46 | /** 47 | * Convert a Libp2pRecord into protobuf format, allocating 48 | * memory as needed 49 | * @param in the Libp2pRecord to convert 50 | * @param buffer where to store the protobuf 51 | * @param buffer_size the size of the allocated buffer 52 | * @returns true(1) on success, otherwise false(0) 53 | */ 54 | int libp2p_record_protobuf_allocate_and_encode(const struct Libp2pRecord* in, unsigned char **buffer, size_t *buffer_size); 55 | 56 | /** 57 | * Generates an estimate of the buffer size needed to encode the struct 58 | * @param in the Libp2pRecord that you want to encode 59 | * @returns the approximate number of bytes required 60 | */ 61 | size_t libp2p_record_protobuf_encode_size(const struct Libp2pRecord* in); 62 | 63 | /** 64 | * Convert a protobuf byte array into a Libp2pRecord 65 | * @param in the byte array 66 | * @param in_size the size of the byte array 67 | * @param out a pointer to the new Libp2pRecord 68 | * @returns true(1) on success, otherwise false(0) 69 | */ 70 | int libp2p_record_protobuf_decode(const unsigned char* in, size_t in_size, struct Libp2pRecord** out); 71 | 72 | /** 73 | * This method does all the hard stuff in one step. It fills a Libp2pRecord struct, and converts it into a protobuf 74 | * @param record a pointer to the protobuf results 75 | * @param rec_size the number of bytes used in the area pointed to by record 76 | * @param sk the private key used to sign 77 | * @param key the key in the Libp2pRecord 78 | * @param value the value in the Libp2pRecord 79 | * @param vlen the length of value 80 | * @param sign true if you want to sign the record 81 | * @returns 0 on success, -1 on error 82 | */ 83 | int libp2p_record_make_put_record (char** record, size_t *rec_size, const struct RsaPrivateKey* sk, const char* key, const char* value, size_t vlen, int sign); 84 | -------------------------------------------------------------------------------- /include/mbedtls/arc4.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file arc4.h 3 | * 4 | * \brief The ARCFOUR stream cipher 5 | * 6 | * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 7 | * SPDX-License-Identifier: Apache-2.0 8 | * 9 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 10 | * not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 17 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | * 21 | * This file is part of mbed TLS (https://tls.mbed.org) 22 | */ 23 | #ifndef MBEDTLS_ARC4_H 24 | #define MBEDTLS_ARC4_H 25 | 26 | #if !defined(MBEDTLS_CONFIG_FILE) 27 | #include "config.h" 28 | #else 29 | #include MBEDTLS_CONFIG_FILE 30 | #endif 31 | 32 | #include 33 | 34 | #if !defined(MBEDTLS_ARC4_ALT) 35 | // Regular implementation 36 | // 37 | 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | /** 43 | * \brief ARC4 context structure 44 | */ 45 | typedef struct 46 | { 47 | int x; /*!< permutation index */ 48 | int y; /*!< permutation index */ 49 | unsigned char m[256]; /*!< permutation table */ 50 | } 51 | mbedtls_arc4_context; 52 | 53 | /** 54 | * \brief Initialize ARC4 context 55 | * 56 | * \param ctx ARC4 context to be initialized 57 | */ 58 | void mbedtls_arc4_init( mbedtls_arc4_context *ctx ); 59 | 60 | /** 61 | * \brief Clear ARC4 context 62 | * 63 | * \param ctx ARC4 context to be cleared 64 | */ 65 | void mbedtls_arc4_free( mbedtls_arc4_context *ctx ); 66 | 67 | /** 68 | * \brief ARC4 key schedule 69 | * 70 | * \param ctx ARC4 context to be setup 71 | * \param key the secret key 72 | * \param keylen length of the key, in bytes 73 | */ 74 | void mbedtls_arc4_setup( mbedtls_arc4_context *ctx, const unsigned char *key, 75 | unsigned int keylen ); 76 | 77 | /** 78 | * \brief ARC4 cipher function 79 | * 80 | * \param ctx ARC4 context 81 | * \param length length of the input data 82 | * \param input buffer holding the input data 83 | * \param output buffer for the output data 84 | * 85 | * \return 0 if successful 86 | */ 87 | int mbedtls_arc4_crypt( mbedtls_arc4_context *ctx, size_t length, const unsigned char *input, 88 | unsigned char *output ); 89 | 90 | #ifdef __cplusplus 91 | } 92 | #endif 93 | 94 | #else /* MBEDTLS_ARC4_ALT */ 95 | #include "arc4_alt.h" 96 | #endif /* MBEDTLS_ARC4_ALT */ 97 | 98 | #ifdef __cplusplus 99 | extern "C" { 100 | #endif 101 | 102 | /** 103 | * \brief Checkup routine 104 | * 105 | * \return 0 if successful, or 1 if the test failed 106 | */ 107 | int mbedtls_arc4_self_test( int verbose ); 108 | 109 | #ifdef __cplusplus 110 | } 111 | #endif 112 | 113 | #endif /* arc4.h */ 114 | -------------------------------------------------------------------------------- /db/datastore.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "libp2p/db/datastore.h" 5 | #include "libp2p/os/utils.h" 6 | 7 | int alloc_and_assign(char** result, const char* string) { 8 | *result = malloc(strlen(string)+1); 9 | if (*result == NULL) 10 | return 0; 11 | strcpy(*result, string); 12 | return 1; 13 | } 14 | 15 | /*** 16 | * initialize the structure of the datastore 17 | * @param datastore the struct to initialize 18 | * @returns true(1) on success 19 | */ 20 | int libp2p_datastore_init(struct Datastore* datastore, const char* config_root) { 21 | unsigned long stringLength = strlen(config_root) + 12; 22 | datastore->path = malloc(sizeof(char) * stringLength); 23 | os_utils_filepath_join(config_root, "datastore", datastore->path, stringLength); 24 | alloc_and_assign(&datastore->type, "lmdb"); 25 | alloc_and_assign(&datastore->storage_max, "10GB"); 26 | datastore->storage_gc_watermark = 90; 27 | alloc_and_assign(&datastore->gc_period, "1h"); 28 | datastore->hash_on_read = 0; 29 | datastore->bloom_filter_size = 0; 30 | datastore->no_sync = 0; 31 | return 1; 32 | } 33 | 34 | /*** 35 | * initialize the structure of the datastore 36 | * @param datastore the struct to initialize 37 | * @returns true(1) on success 38 | */ 39 | int libp2p_datastore_new(struct Datastore** datastore) { 40 | *datastore = malloc(sizeof(struct Datastore)); 41 | if (*datastore == NULL) 42 | return 0; 43 | (*datastore)->path = NULL; 44 | (*datastore)->datastore_context = NULL; 45 | (*datastore)->type = NULL; 46 | (*datastore)->storage_max = NULL; 47 | (*datastore)->gc_period = NULL; 48 | (*datastore)->params = NULL; 49 | return 1; 50 | } 51 | 52 | /*** 53 | * deallocate the memory and clear resources from a datastore_init 54 | * @param datastore the struct to deallocate 55 | * @returns true(1) 56 | */ 57 | int libp2p_datastore_free(struct Datastore* datastore) { 58 | if (datastore != NULL) 59 | { 60 | if (datastore->path != NULL) 61 | free(datastore->path); 62 | if (datastore->type != NULL) 63 | free(datastore->type); 64 | if (datastore->storage_max != NULL) 65 | free(datastore->storage_max); 66 | if (datastore->gc_period != NULL) 67 | free(datastore->gc_period); 68 | if (datastore->params != NULL) 69 | free(datastore->params); 70 | if (datastore->datastore_context != NULL) 71 | datastore->datastore_close(datastore); 72 | free(datastore); 73 | } 74 | return 1; 75 | } 76 | 77 | struct DatastoreRecord* libp2p_datastore_record_new() { 78 | struct DatastoreRecord* rec = (struct DatastoreRecord*) malloc(sizeof(struct DatastoreRecord)); 79 | if (rec != NULL) { 80 | rec->key = NULL; 81 | rec->key_size = 0; 82 | rec->timestamp = 0; 83 | rec->value = NULL; 84 | rec->value_size = 0; 85 | } 86 | return rec; 87 | } 88 | 89 | int libp2p_datastore_record_free(struct DatastoreRecord* rec) { 90 | if (rec != NULL) { 91 | if (rec->key != NULL) { 92 | free(rec->key); 93 | rec->key = NULL; 94 | } 95 | rec->key_size = 0; 96 | if (rec->value != NULL) { 97 | free(rec->value); 98 | rec->value = NULL; 99 | } 100 | rec->value_size = 0; 101 | rec->timestamp = 0; 102 | free(rec); 103 | } 104 | return 1; 105 | } 106 | -------------------------------------------------------------------------------- /include/libp2p/conn/session.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "libp2p/crypto/key.h" 4 | #include "libp2p/db/datastore.h" 5 | #include "libp2p/db/filestore.h" 6 | 7 | /*** 8 | * Holds the details of communication between two hosts 9 | * 10 | * NOTE: This needs a deep cleaning. The links between c-ipfs and c-libp2p should 11 | * be clearly defined. This seems to tie the two together inappropriately. 12 | */ 13 | 14 | enum IPTrafficType { TCP, UDP }; 15 | 16 | struct SessionContext { 17 | // to get the connection started 18 | char* host; 19 | int port; 20 | enum IPTrafficType traffic_type; 21 | pthread_mutex_t stream_mutex; 22 | // once the connection is established 23 | /** 24 | * Note: default_stream should be used in most cases. Often, insecure_stream and secure_stream will be 25 | * the same. This should be re-thought, probably better named, and simplified. Perhaps 1 stream and 26 | * indicators regarding which protocols have been negotiated (i.e. multistream over secio)? 27 | */ 28 | struct Stream* insecure_stream; 29 | struct Stream* secure_stream; 30 | struct Stream* default_stream; 31 | struct Datastore* datastore; 32 | struct Filestore* filestore; 33 | // filled in during negotiations 34 | char* chosen_curve; 35 | char* chosen_cipher; 36 | char* chosen_hash; 37 | unsigned char* shared_key; // a shared key based off of the ephemeral private key 38 | size_t shared_key_size; 39 | //unsigned char* mac; 40 | //size_t mac_size; 41 | // the following items carry state for the sha256 stream cipher, and should probably not be touched. 42 | size_t aes_encode_nonce_offset; 43 | unsigned char aes_encode_stream_block[16]; 44 | size_t aes_decode_nonce_offset; 45 | unsigned char aes_decode_stream_block[16]; 46 | /** 47 | * The mac function to use 48 | * @param 1 the incoming data bytes 49 | * @param 2 the size of the incoming array 50 | * @param 3 the results. Must be allocated to correct size (or larger) 51 | * @returns true(1) on success, false(0) otherwise 52 | */ 53 | int (*mac_function)(const unsigned char*, size_t, unsigned char*); 54 | // local only stuff 55 | unsigned char local_nonce[16]; 56 | struct EphemeralPrivateKey* ephemeral_private_key; 57 | struct StretchedKey* local_stretched_key; 58 | // remote stuff 59 | unsigned char remote_nonce[16]; 60 | struct PublicKey remote_key; 61 | char* remote_peer_id; 62 | struct StretchedKey* remote_stretched_key; 63 | unsigned char* remote_ephemeral_public_key; 64 | size_t remote_ephemeral_public_key_size; 65 | }; 66 | 67 | /*** 68 | * Allocate resources for a new SessionContext struct 69 | * @returns the newly allocated SessionContext, or NULL 70 | */ 71 | struct SessionContext* libp2p_session_context_new(); 72 | /** 73 | * Free resources of a SessionContext struct 74 | * @param context the SessionContext 75 | * @returns true(1) 76 | */ 77 | int libp2p_session_context_free(struct SessionContext* session); 78 | 79 | /*** 80 | * Compare 2 SessionContext structs for equality 81 | * @param a side A 82 | * @param b side B 83 | * @returns 0 if equal, <0 if A wins, >0 if B wins 84 | */ 85 | int libp2p_session_context_compare(const struct SessionContext* a, const struct SessionContext* b); 86 | 87 | struct SessionContext* libp2p_session_context_copy(const struct SessionContext* original); 88 | -------------------------------------------------------------------------------- /include/libp2p/net/connectionstream.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "libp2p/net/stream.h" 4 | #include "libp2p/conn/session.h" 5 | 6 | /*** 7 | * This is a Stream wrapper around a basic tcp/ip connection 8 | */ 9 | 10 | /*** 11 | * Create a new stream based on a network connection, and attempt to connect 12 | * @param fd the handle to the network connection 13 | * @param ip the IP address of the connection 14 | * @param port the port of the connection 15 | * @returns a Stream 16 | */ 17 | struct Stream* libp2p_net_connection_new(int fd, char* ip, int port, struct SessionContext* session_context); 18 | 19 | /*** 20 | * Create a new stream based on a network connection 21 | * @param fd the handle to the network connection 22 | * @param ip the IP address of the connection 23 | * @param port the port of the connection 24 | * @returns a Stream 25 | */ 26 | struct Stream* libp2p_net_connection_established(int fd, char* ip, int port, struct SessionContext* session_context); 27 | 28 | /** 29 | * Attempt to upgrade the parent_stream to use the new stream by default 30 | * @param parent_stream the parent stream 31 | * @param new_stream the new stream 32 | * @returns true(1) on success, false(0) if not 33 | */ 34 | int libp2p_net_connection_upgrade(struct Stream* parent_stream, struct Stream* new_stream); 35 | 36 | /** 37 | * Given a stream, find the SessionContext 38 | * NOTE: This is done by navigating to the root context, which should 39 | * be a ConnectionContext, then grabbing the SessionContext there. 40 | * @param stream the stream to use 41 | * @returns the SessionContext for this stream 42 | */ 43 | struct SessionContext* libp2p_net_connection_get_session_context(struct Stream* stream); 44 | 45 | /*** 46 | * These are put here to allow implementations of struct Stream 47 | * to use them. They should not be called by external code 48 | */ 49 | 50 | 51 | /** 52 | * Close a network connection 53 | * @param stream_context the ConnectionContext 54 | * @returns true(1) on success, false(0) otherwise 55 | */ 56 | int libp2p_net_connection_close(void* stream_context); 57 | 58 | /*** 59 | * Check and see if there is anything waiting on this network connection 60 | * @param stream_context the ConnectionContext 61 | * @returns number of bytes waiting, or -1 on error 62 | */ 63 | int libp2p_net_connection_peek(void* stream_context); 64 | 65 | /** 66 | * Read from the network 67 | * @param stream_context the ConnectionContext 68 | * @param msg where to put the results 69 | * @returns true(1) on success, false(0) otherwise 70 | */ 71 | int libp2p_net_connection_read(void* stream_context, struct StreamMessage** msg, int timeout_secs); 72 | 73 | /** 74 | * Reads a certain amount of bytes directly from the stream 75 | * @param stream_context the context 76 | * @param buffer where to put the results 77 | * @param buffer_size the number of bytes to read 78 | * @param timeout_secs number of seconds before a timeout 79 | * @returns number of bytes read, or -1 on error 80 | */ 81 | int libp2p_net_connection_read_raw(void* stream_context, uint8_t* buffer, int buffer_size, int timeout_secs); 82 | 83 | /** 84 | * Writes to a stream 85 | * @param stream the stream context (usually a SessionContext pointer) 86 | * @param buffer what to write 87 | * @returns number of bytes written 88 | */ 89 | int libp2p_net_connection_write(void* stream_context, struct StreamMessage* msg); 90 | -------------------------------------------------------------------------------- /swarm/HowConnectionsWork.txt: -------------------------------------------------------------------------------- 1 | This document is related to "SwamConnectionFlow.txt", but should probably be read first. This is not a discussion of how other ipfs implementations 2 | work, but rather how the c-ipfs implementation works now. Over time, implementation details may change. But the following will (should?) make 3 | other implementations happy to have c-ipfs join the swarm. 4 | 5 | To make this document a little less confusing, let me define some terms: 6 | 7 | connection - a network connection. It could be a pipe, a tcp connection, or anything else. For now, we're only handling TCP 8 | 9 | connection message - a simple struct to store the bytes, the size of the bytes, and any error conditions 10 | 11 | connection handler - an instance of a connection handler handles the traffic across 1 connection 12 | 13 | stream handler - a routine that processes a byte array (coming from / going to) a (stream handler / connection), and can return with a byte array that 14 | may (probably will) be sent back to the same (stream handler / connection ). 15 | 16 | Stream handlers are chained together. They pass a connection message, and expect a connection message in return. Let's work with an example. 17 | 18 | A possible (and normal) setup is that incoming data is received by the connection, 19 | passed to a multistream stream handler, which unwraps it and passes it to a secio stream handler, which unwraps it and passes it to a multistream 20 | stream handler, which unwraps it, and passes it to a yamux stream handler, which unwraps it and determines that it is a kademlia message. It looks up its 21 | kademlia stream handler, which unwraps it, processes it, and returns a response (Note: NULL is a valid response, meaning don't bother sending anything 22 | back). Then the chain is traversed in the opposite direction. 23 | 24 | connection handler 25 | - Multistream 26 | -- Secio 27 | --- Multistream 28 | ---- Yamux 29 | ----- Kademlia 30 | ---- Yamux 31 | --- Multistream 32 | -- Secio 33 | - Multistream 34 | connection handler 35 | 36 | Now lets work with another example. 37 | 38 | A client wants to send a kademlia message to another peer. It asks the peer for its kademlia stream handler (which will create one if necessary), and 39 | passes the handler its message. The kademlia handler passes that data to yamux, which passes it to multistream, which passes it to secio, which 40 | passes it to multistream, which passes it to the connection handler, which actually sends the message across the wire. Any results are returned in 41 | a connection message. 42 | 43 | User has a Kademlia message to send 44 | - Kademlia handler 45 | -- yamux handler 46 | --- Multistream handler 47 | ---- Secio handler 48 | ----- Multistream handler 49 | ------ connection handler 50 | ----- Multistream handler 51 | ---- Secio handler 52 | --- Multistream handler 53 | -- yamux handler 54 | - Kademlia handler 55 | User processes the response 56 | 57 | Why so much complexity? Because servers can choose to communicate in a variety of ways. It is up to you and the server to decide if you want to 58 | talk to each other. You can choose to not use secio, or replace yamux with another stream muxer, etc. You can choose to have multiple connections 59 | to one server, or use a stream muxer. 60 | 61 | Now, after all of the discussion above, read the document "SwarmConnectionFlow.txt" to see the typical way swarm peers are connected. -------------------------------------------------------------------------------- /include/libp2p/conn/dialer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /*** 4 | * A local dialer. Uses MultiAddr to figure out the best way to 5 | * connect to a client, then returns an open Connection that can be 6 | * closed, read from and written to. The normal procedure is as follows: 7 | * 1) Create a Dialer struct, with the required information about the local host 8 | * 2) Call _get_connection to create the connection with a specific host 9 | * NOTE: 1 Dialer could be used to create all connections, saving time and resources 10 | * if it is not too difficult to pass it around. The struct has enough information to 11 | * build connections that negotiate many protocols 12 | */ 13 | 14 | #include "libp2p/crypto/key.h" 15 | #include "multiaddr/multiaddr.h" 16 | #include "libp2p/conn/connection.h" 17 | #include "libp2p/conn/transport_dialer.h" 18 | #include "libp2p/peer/peer.h" 19 | #include "libp2p/swarm/swarm.h" 20 | 21 | struct Dialer { 22 | /** 23 | * These two are used to create connections 24 | */ 25 | char* peer_id; // the local peer ID as null terminated string 26 | struct RsaPrivateKey* private_key; // used to initiate secure connections, can be NULL, and connections will not be secured 27 | struct Peerstore* peerstore; // used by secio to add peers to the collection 28 | 29 | /** 30 | * A linked list of transport dialers. A transport dialer can be selected 31 | * based on the MultiAddr being dialed. Most common: TCP and UDP 32 | */ 33 | struct Libp2pLinkedList* transport_dialers; 34 | 35 | //TODO: See dial.go, need to implement Protector 36 | 37 | struct TransportDialer* fallback_dialer; // the default dialer. NOTE: this should not be in the list of transport_dialers 38 | struct SwarmContext* swarm; 39 | }; 40 | 41 | /** 42 | * Create a Dialer with the specified local information 43 | * NOTE: This fills in the fallback_dialer too 44 | * @param peer the local Peer 45 | * @param peerstore the local peerstore 46 | * @param private_key the local private key 47 | * @param swarm the swarm 48 | * @returns a new Dialer struct 49 | */ 50 | struct Dialer* libp2p_conn_dialer_new(struct Libp2pPeer* peer, struct Peerstore* peerstore, struct RsaPrivateKey* private_key, struct SwarmContext* swarm); 51 | 52 | /** 53 | * free resources from the Dialer struct 54 | * @param in the Dialer struct to relieve of their resources 55 | */ 56 | void libp2p_conn_dialer_free(struct Dialer* in); 57 | 58 | /*** 59 | * Attempt to connect to a particular peer 60 | * @param dialer the dialer 61 | * @param peer the peer to join 62 | * @param timeout_secs network timeout in seconds 63 | * @returns true(1) on success, false(0) otherwise 64 | */ 65 | int libp2p_conn_dialer_join_swarm(const struct Dialer* dialer, struct Libp2pPeer* peer, int timeout_secs); 66 | 67 | /** 68 | * Retrieve a Connection struct from the dialer 69 | * @param dialer the dialer to use 70 | * @param muiltiaddress who to connect to 71 | * @returns a Connection, or NULL 72 | */ 73 | struct Stream* libp2p_conn_dialer_get_connection(const struct Dialer* dialer, const struct MultiAddress* multiaddress); 74 | 75 | /** 76 | * return a Stream that is already set up to use the passed in protocol 77 | * @param dialer the dialer to use 78 | * @param peer the host 79 | * @param protocol the protocol to use (right now only 'multistream' is supported) 80 | * @returns the ready-to-use stream 81 | */ 82 | struct Stream* libp2p_conn_dialer_get_stream(const struct Dialer* dialer, const struct Libp2pPeer* peer, const char* protocol); 83 | 84 | -------------------------------------------------------------------------------- /include/mbedtls/base64.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file base64.h 3 | * 4 | * \brief RFC 1521 base64 encoding/decoding 5 | * 6 | * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 7 | * SPDX-License-Identifier: Apache-2.0 8 | * 9 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 10 | * not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 17 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | * 21 | * This file is part of mbed TLS (https://tls.mbed.org) 22 | */ 23 | #ifndef MBEDTLS_BASE64_H 24 | #define MBEDTLS_BASE64_H 25 | 26 | #include 27 | 28 | #define MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL -0x002A /**< Output buffer too small. */ 29 | #define MBEDTLS_ERR_BASE64_INVALID_CHARACTER -0x002C /**< Invalid character in input. */ 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | /** 36 | * \brief Encode a buffer into base64 format 37 | * 38 | * \param dst destination buffer 39 | * \param dlen size of the destination buffer 40 | * \param olen number of bytes written 41 | * \param src source buffer 42 | * \param slen amount of data to be encoded 43 | * 44 | * \return 0 if successful, or MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL. 45 | * *olen is always updated to reflect the amount 46 | * of data that has (or would have) been written. 47 | * If that length cannot be represented, then no data is 48 | * written to the buffer and *olen is set to the maximum 49 | * length representable as a size_t. 50 | * 51 | * \note Call this function with dlen = 0 to obtain the 52 | * required buffer size in *olen 53 | */ 54 | int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen, 55 | const unsigned char *src, size_t slen ); 56 | 57 | /** 58 | * \brief Decode a base64-formatted buffer 59 | * 60 | * \param dst destination buffer (can be NULL for checking size) 61 | * \param dlen size of the destination buffer 62 | * \param olen number of bytes written 63 | * \param src source buffer 64 | * \param slen amount of data to be decoded 65 | * 66 | * \return 0 if successful, MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL, or 67 | * MBEDTLS_ERR_BASE64_INVALID_CHARACTER if the input data is 68 | * not correct. *olen is always updated to reflect the amount 69 | * of data that has (or would have) been written. 70 | * 71 | * \note Call this function with *dst = NULL or dlen = 0 to obtain 72 | * the required buffer size in *olen 73 | */ 74 | int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen, 75 | const unsigned char *src, size_t slen ); 76 | 77 | /** 78 | * \brief Checkup routine 79 | * 80 | * \return 0 if successful, or 1 if the test failed 81 | */ 82 | int mbedtls_base64_self_test( int verbose ); 83 | 84 | #ifdef __cplusplus 85 | } 86 | #endif 87 | 88 | #endif /* base64.h */ 89 | -------------------------------------------------------------------------------- /test/test_peer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "libp2p/peer/peer.h" 5 | #include "libp2p/peer/peerstore.h" 6 | 7 | /*** 8 | * Includes Libp2pPeer, PeerEntry, Peerstore 9 | */ 10 | 11 | /** 12 | * Test the basics of peer 13 | */ 14 | int test_peer() { 15 | struct Libp2pPeer* obj = libp2p_peer_new(); 16 | if (obj == NULL) 17 | return 0; 18 | 19 | libp2p_peer_free(obj); 20 | return 1; 21 | } 22 | 23 | /** 24 | * Test the peerstore 25 | */ 26 | int test_peerstore() { 27 | 28 | // create a Peer 29 | struct Libp2pPeer* peer = libp2p_peer_new(); 30 | peer->id = malloc(10); 31 | strcpy(peer->id, "Qmabcdefg"); 32 | peer->id_size = strlen(peer->id); 33 | 34 | // create a PeerStore 35 | struct Peerstore* peerstore = libp2p_peerstore_new(peer); 36 | struct PeerEntry* peer_entry = NULL; 37 | struct PeerEntry* results = NULL; 38 | int retVal = 0; 39 | 40 | if (peerstore == NULL) 41 | goto exit; 42 | 43 | // add a peer entry to the peerstore 44 | /* 45 | peer_entry = libp2p_peer_entry_new(); 46 | peer_entry->peer = libp2p_peer_new(); 47 | peer_entry->peer->id_size = 6; 48 | peer_entry->peer->id = malloc(peer_entry->peer->id_size); 49 | memcpy(peer_entry->peer->id, "ABC123", peer_entry->peer->id_size); 50 | peer_entry->peer->connection_type = CONNECTION_TYPE_NOT_CONNECTED; 51 | */ 52 | 53 | if (!libp2p_peerstore_add_peer(peerstore, peer)) { 54 | fprintf(stderr, "libp2p_peerstore_add_peer returned false\n"); 55 | goto exit; 56 | } 57 | 58 | /* 59 | if (!libp2p_peerstore_add_peer_entry(peerstore, peer_entry)) 60 | goto exit; 61 | */ 62 | 63 | // now try to retrieve it 64 | results = libp2p_peerstore_get_peer_entry(peerstore, (unsigned char*)"Qmabcdefg", 9); 65 | 66 | if (results == NULL || results->peer->id_size != 9) { 67 | fprintf(stderr, "libp2p_peerstore_get_peer_entry returned NULL or was the wrong size\n"); 68 | goto exit; 69 | } 70 | 71 | // cleanup 72 | retVal = 1; 73 | 74 | exit: 75 | if (peerstore != NULL) 76 | libp2p_peerstore_free(peerstore); 77 | if (peer != NULL) 78 | libp2p_peer_free(peer); 79 | return retVal; 80 | } 81 | 82 | int test_peer_protobuf() { 83 | int retVal = 0; 84 | struct Libp2pPeer *peer = NULL, *peer_result = NULL; 85 | struct MultiAddress* ma = NULL, *ma_result = NULL; 86 | char* peer_id = "QmW8CYQuoJhgfxTeNVFWktGFnTRzdUAimerSsHaE4rUXk8"; 87 | unsigned char* protobuf = NULL; 88 | size_t protobuf_size; 89 | 90 | peer = libp2p_peer_new(); 91 | peer->id_size = strlen(peer_id); 92 | peer->id = malloc(peer->id_size); 93 | memcpy(peer->id, peer_id, peer->id_size); 94 | peer->addr_head = libp2p_utils_linked_list_new(); 95 | ma = multiaddress_new_from_string("/ip4/127.0.0.1/tcp/4001/ipfs/QmW8CYQuoJhgfxTeNVFWktGFnTRzdUAimerSsHaE4rUXk8/"); 96 | peer->addr_head->item = ma; 97 | 98 | // protobuf 99 | libp2p_peer_protobuf_encode_with_alloc(peer, &protobuf, &protobuf_size); 100 | 101 | // unprotobuf 102 | libp2p_peer_protobuf_decode(protobuf, protobuf_size, &peer_result); 103 | ma_result = peer_result->addr_head->item; 104 | 105 | if (strcmp(ma->string, ma_result->string) != 0) { 106 | fprintf(stderr, "Results to not match: %s vs %s\n", ma->string, ma_result->string); 107 | goto exit; 108 | } 109 | 110 | retVal = 1; 111 | exit: 112 | //multiaddress_free(ma); 113 | libp2p_peer_free(peer); 114 | libp2p_peer_free(peer_result); 115 | if (protobuf != NULL) 116 | free(protobuf); 117 | return retVal; 118 | } 119 | -------------------------------------------------------------------------------- /test/crypto/test_base58.h: -------------------------------------------------------------------------------- 1 | #ifndef test_base58_h 2 | #define test_base58_h 3 | 4 | #include "libp2p/crypto/encoding/base58.h" 5 | 6 | /*** 7 | * tests the base58 encoding and decoding 8 | */ 9 | int test_base58_encode_decode() { 10 | 11 | unsigned char original[3] = { 0x41, 0x42 ,0x00 }; 12 | 13 | size_t buffer_size = 10; 14 | unsigned char buffer[buffer_size]; 15 | unsigned char* ptr = buffer; 16 | 17 | int retVal = libp2p_crypto_encoding_base58_encode(original, 3, &ptr, &buffer_size); 18 | if (retVal == 0) 19 | return 0; 20 | 21 | size_t result_size = 3; 22 | unsigned char result[result_size]; 23 | unsigned char* ptr2 = result; 24 | memset(result, 0, result_size); 25 | 26 | retVal = libp2p_crypto_encoding_base58_decode(ptr, buffer_size, &ptr2, &result_size); 27 | if (retVal == 0) 28 | return 0; 29 | 30 | for (int i = 0; i < 3; i++) 31 | if (original[i] != result[i]) 32 | return 0; 33 | 34 | return 1; 35 | } 36 | 37 | int test_base58_size() { 38 | unsigned char* unencoded = (unsigned char*)"Hello, World!"; // 13 chars + 1 null 39 | size_t string_length = strlen((char*)unencoded) + 1; 40 | 41 | size_t encoded_length = libp2p_crypto_encoding_base58_encode_size(string_length); 42 | 43 | if (encoded_length != 20) { 44 | fprintf(stderr, "Encoded length incorrect. Should have been 20 and is %lu\n", encoded_length); 45 | return 0; 46 | } 47 | 48 | size_t encoded_max_length = 100; 49 | unsigned char encoded[encoded_max_length]; 50 | unsigned char* ptr = encoded; 51 | 52 | // now encode it 53 | libp2p_crypto_encoding_base58_encode(unencoded, string_length-1, &ptr, &encoded_max_length); 54 | 55 | size_t decoded_length = libp2p_crypto_encoding_base58_decode_size(encoded_max_length); 56 | 57 | if (decoded_length != string_length) { 58 | fprintf(stderr, "String length and decoded length are different. Decoded length = %lu and string length is %lu\n", decoded_length, string_length); 59 | return 0; 60 | } 61 | 62 | return 1; 63 | } 64 | 65 | int test_base58_max_size() { 66 | unsigned char hash[5] = {'S', 'D', 'Y', 'h', 'd' }; 67 | 68 | size_t results = libp2p_crypto_encoding_base58_decode_size(5); 69 | if (results != 4) 70 | return 0; 71 | 72 | return 1; 73 | } 74 | 75 | int test_base58_peer_address() { 76 | char* x_data = "QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB"; 77 | size_t x_data_length = strlen(x_data); 78 | size_t result_buffer_length = libp2p_crypto_encoding_base58_decode_size(x_data_length); 79 | unsigned char result_buffer[result_buffer_length]; 80 | unsigned char* ptr_to_result = result_buffer; 81 | memset(result_buffer, 0, result_buffer_length); 82 | // now get the decoded address 83 | int return_value = libp2p_crypto_encoding_base58_decode((unsigned char*)x_data, x_data_length, &ptr_to_result, &result_buffer_length); 84 | if (return_value == 0) 85 | return 0; 86 | // add 2 bytes to the front for the varint 87 | unsigned char final_result[result_buffer_length + 2]; 88 | // TODO: put the 2 bytes of your varint here, and erase the memset line below. 89 | memset(final_result, 0, 2); 90 | memcpy(&(final_result[2]), result_buffer, result_buffer_length); 91 | // throw everything in a hex string so we can debug the results 92 | for(int i = 0; i < result_buffer_length + 2; i++) { 93 | // get the char so we can see it in the debugger 94 | unsigned char c = final_result[i]; 95 | printf("%02x", c); 96 | } 97 | printf("\n"); 98 | return 1; 99 | } 100 | 101 | #endif /* test_base58_h */ 102 | -------------------------------------------------------------------------------- /include/mbedtls/pkcs5.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file pkcs5.h 3 | * 4 | * \brief PKCS#5 functions 5 | * 6 | * \author Mathias Olsson 7 | * 8 | * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 9 | * SPDX-License-Identifier: Apache-2.0 10 | * 11 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 12 | * not use this file except in compliance with the License. 13 | * You may obtain a copy of the License at 14 | * 15 | * http://www.apache.org/licenses/LICENSE-2.0 16 | * 17 | * Unless required by applicable law or agreed to in writing, software 18 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 19 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | * See the License for the specific language governing permissions and 21 | * limitations under the License. 22 | * 23 | * This file is part of mbed TLS (https://tls.mbed.org) 24 | */ 25 | #ifndef MBEDTLS_PKCS5_H 26 | #define MBEDTLS_PKCS5_H 27 | 28 | #include "asn1.h" 29 | #include "md.h" 30 | 31 | #include 32 | #include 33 | 34 | #define MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA -0x2f80 /**< Bad input parameters to function. */ 35 | #define MBEDTLS_ERR_PKCS5_INVALID_FORMAT -0x2f00 /**< Unexpected ASN.1 data. */ 36 | #define MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE -0x2e80 /**< Requested encryption or digest alg not available. */ 37 | #define MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH -0x2e00 /**< Given private key password does not allow for correct decryption. */ 38 | 39 | #define MBEDTLS_PKCS5_DECRYPT 0 40 | #define MBEDTLS_PKCS5_ENCRYPT 1 41 | 42 | #ifdef __cplusplus 43 | extern "C" { 44 | #endif 45 | 46 | /** 47 | * \brief PKCS#5 PBES2 function 48 | * 49 | * \param pbe_params the ASN.1 algorithm parameters 50 | * \param mode either MBEDTLS_PKCS5_DECRYPT or MBEDTLS_PKCS5_ENCRYPT 51 | * \param pwd password to use when generating key 52 | * \param pwdlen length of password 53 | * \param data data to process 54 | * \param datalen length of data 55 | * \param output output buffer 56 | * 57 | * \returns 0 on success, or a MBEDTLS_ERR_XXX code if verification fails. 58 | */ 59 | int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode, 60 | const unsigned char *pwd, size_t pwdlen, 61 | const unsigned char *data, size_t datalen, 62 | unsigned char *output ); 63 | 64 | /** 65 | * \brief PKCS#5 PBKDF2 using HMAC 66 | * 67 | * \param ctx Generic HMAC context 68 | * \param password Password to use when generating key 69 | * \param plen Length of password 70 | * \param salt Salt to use when generating key 71 | * \param slen Length of salt 72 | * \param iteration_count Iteration count 73 | * \param key_length Length of generated key in bytes 74 | * \param output Generated key. Must be at least as big as key_length 75 | * 76 | * \returns 0 on success, or a MBEDTLS_ERR_XXX code if verification fails. 77 | */ 78 | int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *password, 79 | size_t plen, const unsigned char *salt, size_t slen, 80 | unsigned int iteration_count, 81 | uint32_t key_length, unsigned char *output ); 82 | 83 | /** 84 | * \brief Checkup routine 85 | * 86 | * \return 0 if successful, or 1 if the test failed 87 | */ 88 | int mbedtls_pkcs5_self_test( int verbose ); 89 | 90 | #ifdef __cplusplus 91 | } 92 | #endif 93 | 94 | #endif /* pkcs5.h */ 95 | -------------------------------------------------------------------------------- /include/libp2p/routing/dht.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009-2011 by Juliusz Chroboczek 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | */ 22 | 23 | #ifdef __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | /** 28 | * The callback method that you can implement 29 | * to receive events 30 | */ 31 | typedef void dht_callback(void *closure, int event, 32 | const unsigned char *info_hash, 33 | const void *data, size_t data_len); 34 | 35 | #define DHT_EVENT_NONE 0 36 | #define DHT_EVENT_VALUES 1 37 | #define DHT_EVENT_VALUES6 2 38 | #define DHT_EVENT_SEARCH_DONE 3 39 | #define DHT_EVENT_SEARCH_DONE6 4 40 | 41 | extern FILE *dht_debug; 42 | 43 | int dht_init(int s, int s6, const unsigned char *id, const unsigned char *v); 44 | int dht_insert_node(const unsigned char *id, struct sockaddr *sa, int salen); 45 | int dht_ping_node(const struct sockaddr *sa, int salen); 46 | /*** 47 | * Called when something is received from the network or 48 | * the network times out (things that should be done 49 | * periodically) 50 | * @param buf what came in from the network 51 | * @param buflen the size of buf 52 | * @param from where it came from 53 | * @param fromlen 54 | * @param tosleep 55 | * @param callback 56 | * @param closure 57 | * @returns ?? 58 | */ 59 | int dht_periodic(const void *buf, size_t buflen, 60 | const struct sockaddr *from, int fromlen, 61 | time_t *tosleep, dht_callback *callback, void *closure); 62 | /** 63 | * Start a search. If port is non-zero, perform an announce when the 64 | * search is complete. 65 | * @param id the hash to search for 66 | * @param port where it is available 67 | * @param af IP family (AF_INET or AF_INET6) 68 | * @param callback the callback method 69 | * @param closure 70 | * @returns -1 on failure, 1 on success 71 | **/ 72 | int dht_search(const unsigned char *id, int port, int af, 73 | dht_callback *callback, void *closure); 74 | int dht_nodes(int af, 75 | int *good_return, int *dubious_return, int *cached_return, 76 | int *incoming_return); 77 | void dht_dump_tables(FILE *f); 78 | int dht_get_nodes(struct sockaddr_in *sin, int *num, 79 | struct sockaddr_in6 *sin6, int *num6); 80 | int dht_uninit(void); 81 | 82 | /* This must be provided by the user. */ 83 | int dht_blacklisted(const struct sockaddr *sa, int salen); 84 | void dht_hash(void *hash_return, int hash_size, 85 | const void *v1, int len1, 86 | const void *v2, int len2, 87 | const void *v3, int len3); 88 | int dht_random_bytes(void *buf, size_t size); 89 | 90 | #ifdef __cplusplus 91 | } 92 | #endif 93 | -------------------------------------------------------------------------------- /include/mbedtls/md_internal.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file md_internal.h 3 | * 4 | * \brief Message digest wrappers. 5 | * 6 | * \warning This in an internal header. Do not include directly. 7 | * 8 | * \author Adriaan de Jong 9 | * 10 | * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 11 | * SPDX-License-Identifier: Apache-2.0 12 | * 13 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 14 | * not use this file except in compliance with the License. 15 | * You may obtain a copy of the License at 16 | * 17 | * http://www.apache.org/licenses/LICENSE-2.0 18 | * 19 | * Unless required by applicable law or agreed to in writing, software 20 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 21 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | * See the License for the specific language governing permissions and 23 | * limitations under the License. 24 | * 25 | * This file is part of mbed TLS (https://tls.mbed.org) 26 | */ 27 | #ifndef MBEDTLS_MD_WRAP_H 28 | #define MBEDTLS_MD_WRAP_H 29 | 30 | #if !defined(MBEDTLS_CONFIG_FILE) 31 | #include "config.h" 32 | #else 33 | #include MBEDTLS_CONFIG_FILE 34 | #endif 35 | 36 | #include "md.h" 37 | 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | /** 43 | * Message digest information. 44 | * Allows message digest functions to be called in a generic way. 45 | */ 46 | struct mbedtls_md_info_t 47 | { 48 | /** Digest identifier */ 49 | mbedtls_md_type_t type; 50 | 51 | /** Name of the message digest */ 52 | const char * name; 53 | 54 | /** Output length of the digest function in bytes */ 55 | int size; 56 | 57 | /** Block length of the digest function in bytes */ 58 | int block_size; 59 | 60 | /** Digest initialisation function */ 61 | void (*starts_func)( void *ctx ); 62 | 63 | /** Digest update function */ 64 | void (*update_func)( void *ctx, const unsigned char *input, size_t ilen ); 65 | 66 | /** Digest finalisation function */ 67 | void (*finish_func)( void *ctx, unsigned char *output ); 68 | 69 | /** Generic digest function */ 70 | void (*digest_func)( const unsigned char *input, size_t ilen, 71 | unsigned char *output ); 72 | 73 | /** Allocate a new context */ 74 | void * (*ctx_alloc_func)( void ); 75 | 76 | /** Free the given context */ 77 | void (*ctx_free_func)( void *ctx ); 78 | 79 | /** Clone state from a context */ 80 | void (*clone_func)( void *dst, const void *src ); 81 | 82 | /** Internal use only */ 83 | void (*process_func)( void *ctx, const unsigned char *input ); 84 | }; 85 | 86 | #if defined(MBEDTLS_MD2_C) 87 | extern const mbedtls_md_info_t mbedtls_md2_info; 88 | #endif 89 | #if defined(MBEDTLS_MD4_C) 90 | extern const mbedtls_md_info_t mbedtls_md4_info; 91 | #endif 92 | #if defined(MBEDTLS_MD5_C) 93 | extern const mbedtls_md_info_t mbedtls_md5_info; 94 | #endif 95 | #if defined(MBEDTLS_RIPEMD160_C) 96 | extern const mbedtls_md_info_t mbedtls_ripemd160_info; 97 | #endif 98 | #if defined(MBEDTLS_SHA1_C) 99 | extern const mbedtls_md_info_t mbedtls_sha1_info; 100 | #endif 101 | #if defined(MBEDTLS_SHA256_C) 102 | extern const mbedtls_md_info_t mbedtls_sha224_info; 103 | extern const mbedtls_md_info_t mbedtls_sha256_info; 104 | #endif 105 | #if defined(MBEDTLS_SHA512_C) 106 | extern const mbedtls_md_info_t mbedtls_sha384_info; 107 | extern const mbedtls_md_info_t mbedtls_sha512_info; 108 | #endif 109 | 110 | #ifdef __cplusplus 111 | } 112 | #endif 113 | 114 | #endif /* MBEDTLS_MD_WRAP_H */ 115 | -------------------------------------------------------------------------------- /include/mbedtls/padlock.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file padlock.h 3 | * 4 | * \brief VIA PadLock ACE for HW encryption/decryption supported by some 5 | * processors 6 | * 7 | * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 8 | * SPDX-License-Identifier: Apache-2.0 9 | * 10 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 11 | * not use this file except in compliance with the License. 12 | * You may obtain a copy of the License at 13 | * 14 | * http://www.apache.org/licenses/LICENSE-2.0 15 | * 16 | * Unless required by applicable law or agreed to in writing, software 17 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 18 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | * See the License for the specific language governing permissions and 20 | * limitations under the License. 21 | * 22 | * This file is part of mbed TLS (https://tls.mbed.org) 23 | */ 24 | #ifndef MBEDTLS_PADLOCK_H 25 | #define MBEDTLS_PADLOCK_H 26 | 27 | #include "aes.h" 28 | 29 | #define MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED -0x0030 /**< Input data should be aligned. */ 30 | 31 | #if defined(__has_feature) 32 | #if __has_feature(address_sanitizer) 33 | #define MBEDTLS_HAVE_ASAN 34 | #endif 35 | #endif 36 | 37 | /* Some versions of ASan result in errors about not enough registers */ 38 | #if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && defined(__i386__) && \ 39 | !defined(MBEDTLS_HAVE_ASAN) 40 | 41 | #ifndef MBEDTLS_HAVE_X86 42 | #define MBEDTLS_HAVE_X86 43 | #endif 44 | 45 | #include 46 | 47 | #define MBEDTLS_PADLOCK_RNG 0x000C 48 | #define MBEDTLS_PADLOCK_ACE 0x00C0 49 | #define MBEDTLS_PADLOCK_PHE 0x0C00 50 | #define MBEDTLS_PADLOCK_PMM 0x3000 51 | 52 | #define MBEDTLS_PADLOCK_ALIGN16(x) (uint32_t *) (16 + ((int32_t) x & ~15)) 53 | 54 | #ifdef __cplusplus 55 | extern "C" { 56 | #endif 57 | 58 | /** 59 | * \brief PadLock detection routine 60 | * 61 | * \param feature The feature to detect 62 | * 63 | * \return 1 if CPU has support for the feature, 0 otherwise 64 | */ 65 | int mbedtls_padlock_has_support( int feature ); 66 | 67 | /** 68 | * \brief PadLock AES-ECB block en(de)cryption 69 | * 70 | * \param ctx AES context 71 | * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT 72 | * \param input 16-byte input block 73 | * \param output 16-byte output block 74 | * 75 | * \return 0 if success, 1 if operation failed 76 | */ 77 | int mbedtls_padlock_xcryptecb( mbedtls_aes_context *ctx, 78 | int mode, 79 | const unsigned char input[16], 80 | unsigned char output[16] ); 81 | 82 | /** 83 | * \brief PadLock AES-CBC buffer en(de)cryption 84 | * 85 | * \param ctx AES context 86 | * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT 87 | * \param length length of the input data 88 | * \param iv initialization vector (updated after use) 89 | * \param input buffer holding the input data 90 | * \param output buffer holding the output data 91 | * 92 | * \return 0 if success, 1 if operation failed 93 | */ 94 | int mbedtls_padlock_xcryptcbc( mbedtls_aes_context *ctx, 95 | int mode, 96 | size_t length, 97 | unsigned char iv[16], 98 | const unsigned char *input, 99 | unsigned char *output ); 100 | 101 | #ifdef __cplusplus 102 | } 103 | #endif 104 | 105 | #endif /* HAVE_X86 */ 106 | 107 | #endif /* padlock.h */ 108 | -------------------------------------------------------------------------------- /include/mbedtls/ssl_cookie.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file ssl_cookie.h 3 | * 4 | * \brief DTLS cookie callbacks implementation 5 | * 6 | * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 7 | * SPDX-License-Identifier: Apache-2.0 8 | * 9 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 10 | * not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 17 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | * 21 | * This file is part of mbed TLS (https://tls.mbed.org) 22 | */ 23 | #ifndef MBEDTLS_SSL_COOKIE_H 24 | #define MBEDTLS_SSL_COOKIE_H 25 | 26 | #include "ssl.h" 27 | 28 | #if defined(MBEDTLS_THREADING_C) 29 | #include "threading.h" 30 | #endif 31 | 32 | /** 33 | * \name SECTION: Module settings 34 | * 35 | * The configuration options you can set for this module are in this section. 36 | * Either change them in config.h or define them on the compiler command line. 37 | * \{ 38 | */ 39 | #ifndef MBEDTLS_SSL_COOKIE_TIMEOUT 40 | #define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */ 41 | #endif 42 | 43 | /* \} name SECTION: Module settings */ 44 | 45 | #ifdef __cplusplus 46 | extern "C" { 47 | #endif 48 | 49 | /** 50 | * \brief Context for the default cookie functions. 51 | */ 52 | typedef struct 53 | { 54 | mbedtls_md_context_t hmac_ctx; /*!< context for the HMAC portion */ 55 | #if !defined(MBEDTLS_HAVE_TIME) 56 | unsigned long serial; /*!< serial number for expiration */ 57 | #endif 58 | unsigned long timeout; /*!< timeout delay, in seconds if HAVE_TIME, 59 | or in number of tickets issued */ 60 | 61 | #if defined(MBEDTLS_THREADING_C) 62 | mbedtls_threading_mutex_t mutex; 63 | #endif 64 | } mbedtls_ssl_cookie_ctx; 65 | 66 | /** 67 | * \brief Initialize cookie context 68 | */ 69 | void mbedtls_ssl_cookie_init( mbedtls_ssl_cookie_ctx *ctx ); 70 | 71 | /** 72 | * \brief Setup cookie context (generate keys) 73 | */ 74 | int mbedtls_ssl_cookie_setup( mbedtls_ssl_cookie_ctx *ctx, 75 | int (*f_rng)(void *, unsigned char *, size_t), 76 | void *p_rng ); 77 | 78 | /** 79 | * \brief Set expiration delay for cookies 80 | * (Default MBEDTLS_SSL_COOKIE_TIMEOUT) 81 | * 82 | * \param ctx Cookie contex 83 | * \param delay Delay, in seconds if HAVE_TIME, or in number of cookies 84 | * issued in the meantime. 85 | * 0 to disable expiration (NOT recommended) 86 | */ 87 | void mbedtls_ssl_cookie_set_timeout( mbedtls_ssl_cookie_ctx *ctx, unsigned long delay ); 88 | 89 | /** 90 | * \brief Free cookie context 91 | */ 92 | void mbedtls_ssl_cookie_free( mbedtls_ssl_cookie_ctx *ctx ); 93 | 94 | /** 95 | * \brief Generate cookie, see \c mbedtls_ssl_cookie_write_t 96 | */ 97 | mbedtls_ssl_cookie_write_t mbedtls_ssl_cookie_write; 98 | 99 | /** 100 | * \brief Verify cookie, see \c mbedtls_ssl_cookie_write_t 101 | */ 102 | mbedtls_ssl_cookie_check_t mbedtls_ssl_cookie_check; 103 | 104 | #ifdef __cplusplus 105 | } 106 | #endif 107 | 108 | #endif /* ssl_cookie.h */ 109 | -------------------------------------------------------------------------------- /include/mbedtls/error.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file error.h 3 | * 4 | * \brief Error to string translation 5 | * 6 | * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 7 | * SPDX-License-Identifier: Apache-2.0 8 | * 9 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 10 | * not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 17 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | * 21 | * This file is part of mbed TLS (https://tls.mbed.org) 22 | */ 23 | #ifndef MBEDTLS_ERROR_H 24 | #define MBEDTLS_ERROR_H 25 | 26 | #include 27 | 28 | /** 29 | * Error code layout. 30 | * 31 | * Currently we try to keep all error codes within the negative space of 16 32 | * bits signed integers to support all platforms (-0x0001 - -0x7FFF). In 33 | * addition we'd like to give two layers of information on the error if 34 | * possible. 35 | * 36 | * For that purpose the error codes are segmented in the following manner: 37 | * 38 | * 16 bit error code bit-segmentation 39 | * 40 | * 1 bit - Unused (sign bit) 41 | * 3 bits - High level module ID 42 | * 5 bits - Module-dependent error code 43 | * 7 bits - Low level module errors 44 | * 45 | * For historical reasons, low-level error codes are divided in even and odd, 46 | * even codes were assigned first, and -1 is reserved for other errors. 47 | * 48 | * Low-level module errors (0x0002-0x007E, 0x0003-0x007F) 49 | * 50 | * Module Nr Codes assigned 51 | * MPI 7 0x0002-0x0010 52 | * GCM 2 0x0012-0x0014 53 | * BLOWFISH 2 0x0016-0x0018 54 | * THREADING 3 0x001A-0x001E 55 | * AES 2 0x0020-0x0022 56 | * CAMELLIA 2 0x0024-0x0026 57 | * XTEA 1 0x0028-0x0028 58 | * BASE64 2 0x002A-0x002C 59 | * OID 1 0x002E-0x002E 0x000B-0x000B 60 | * PADLOCK 1 0x0030-0x0030 61 | * DES 1 0x0032-0x0032 62 | * CTR_DBRG 4 0x0034-0x003A 63 | * ENTROPY 3 0x003C-0x0040 0x003D-0x003F 64 | * NET 11 0x0042-0x0052 0x0043-0x0045 65 | * ASN1 7 0x0060-0x006C 66 | * PBKDF2 1 0x007C-0x007C 67 | * HMAC_DRBG 4 0x0003-0x0009 68 | * CCM 2 0x000D-0x000F 69 | * 70 | * High-level module nr (3 bits - 0x0...-0x7...) 71 | * Name ID Nr of Errors 72 | * PEM 1 9 73 | * PKCS#12 1 4 (Started from top) 74 | * X509 2 19 75 | * PKCS5 2 4 (Started from top) 76 | * DHM 3 9 77 | * PK 3 14 (Started from top) 78 | * RSA 4 9 79 | * ECP 4 8 (Started from top) 80 | * MD 5 4 81 | * CIPHER 6 6 82 | * SSL 6 17 (Started from top) 83 | * SSL 7 31 84 | * 85 | * Module dependent error code (5 bits 0x.00.-0x.F8.) 86 | */ 87 | 88 | #ifdef __cplusplus 89 | extern "C" { 90 | #endif 91 | 92 | /** 93 | * \brief Translate a mbed TLS error code into a string representation, 94 | * Result is truncated if necessary and always includes a terminating 95 | * null byte. 96 | * 97 | * \param errnum error code 98 | * \param buffer buffer to place representation in 99 | * \param buflen length of the buffer 100 | */ 101 | void mbedtls_strerror( int errnum, char *buffer, size_t buflen ); 102 | 103 | #ifdef __cplusplus 104 | } 105 | #endif 106 | 107 | #endif /* error.h */ 108 | -------------------------------------------------------------------------------- /include/mbedtls/cipher_internal.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file cipher_internal.h 3 | * 4 | * \brief Cipher wrappers. 5 | * 6 | * \author Adriaan de Jong 7 | * 8 | * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 9 | * SPDX-License-Identifier: Apache-2.0 10 | * 11 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 12 | * not use this file except in compliance with the License. 13 | * You may obtain a copy of the License at 14 | * 15 | * http://www.apache.org/licenses/LICENSE-2.0 16 | * 17 | * Unless required by applicable law or agreed to in writing, software 18 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 19 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | * See the License for the specific language governing permissions and 21 | * limitations under the License. 22 | * 23 | * This file is part of mbed TLS (https://tls.mbed.org) 24 | */ 25 | #ifndef MBEDTLS_CIPHER_WRAP_H 26 | #define MBEDTLS_CIPHER_WRAP_H 27 | 28 | #if !defined(MBEDTLS_CONFIG_FILE) 29 | #include "config.h" 30 | #else 31 | #include MBEDTLS_CONFIG_FILE 32 | #endif 33 | 34 | #include "cipher.h" 35 | 36 | #ifdef __cplusplus 37 | extern "C" { 38 | #endif 39 | 40 | /** 41 | * Base cipher information. The non-mode specific functions and values. 42 | */ 43 | struct mbedtls_cipher_base_t 44 | { 45 | /** Base Cipher type (e.g. MBEDTLS_CIPHER_ID_AES) */ 46 | mbedtls_cipher_id_t cipher; 47 | 48 | /** Encrypt using ECB */ 49 | int (*ecb_func)( void *ctx, mbedtls_operation_t mode, 50 | const unsigned char *input, unsigned char *output ); 51 | 52 | #if defined(MBEDTLS_CIPHER_MODE_CBC) 53 | /** Encrypt using CBC */ 54 | int (*cbc_func)( void *ctx, mbedtls_operation_t mode, size_t length, 55 | unsigned char *iv, const unsigned char *input, 56 | unsigned char *output ); 57 | #endif 58 | 59 | #if defined(MBEDTLS_CIPHER_MODE_CFB) 60 | /** Encrypt using CFB (Full length) */ 61 | int (*cfb_func)( void *ctx, mbedtls_operation_t mode, size_t length, size_t *iv_off, 62 | unsigned char *iv, const unsigned char *input, 63 | unsigned char *output ); 64 | #endif 65 | 66 | #if defined(MBEDTLS_CIPHER_MODE_CTR) 67 | /** Encrypt using CTR */ 68 | int (*ctr_func)( void *ctx, size_t length, size_t *nc_off, 69 | unsigned char *nonce_counter, unsigned char *stream_block, 70 | const unsigned char *input, unsigned char *output ); 71 | #endif 72 | 73 | #if defined(MBEDTLS_CIPHER_MODE_STREAM) 74 | /** Encrypt using STREAM */ 75 | int (*stream_func)( void *ctx, size_t length, 76 | const unsigned char *input, unsigned char *output ); 77 | #endif 78 | 79 | /** Set key for encryption purposes */ 80 | int (*setkey_enc_func)( void *ctx, const unsigned char *key, 81 | unsigned int key_bitlen ); 82 | 83 | /** Set key for decryption purposes */ 84 | int (*setkey_dec_func)( void *ctx, const unsigned char *key, 85 | unsigned int key_bitlen); 86 | 87 | /** Allocate a new context */ 88 | void * (*ctx_alloc_func)( void ); 89 | 90 | /** Free the given context */ 91 | void (*ctx_free_func)( void *ctx ); 92 | 93 | }; 94 | 95 | typedef struct 96 | { 97 | mbedtls_cipher_type_t type; 98 | const mbedtls_cipher_info_t *info; 99 | } mbedtls_cipher_definition_t; 100 | 101 | extern const mbedtls_cipher_definition_t mbedtls_cipher_definitions[]; 102 | 103 | extern int mbedtls_cipher_supported[]; 104 | 105 | #ifdef __cplusplus 106 | } 107 | #endif 108 | 109 | #endif /* MBEDTLS_CIPHER_WRAP_H */ 110 | -------------------------------------------------------------------------------- /include/mbedtls/entropy_poll.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file entropy_poll.h 3 | * 4 | * \brief Platform-specific and custom entropy polling functions 5 | * 6 | * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved 7 | * SPDX-License-Identifier: Apache-2.0 8 | * 9 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 10 | * not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 17 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | * 21 | * This file is part of mbed TLS (https://tls.mbed.org) 22 | */ 23 | #ifndef MBEDTLS_ENTROPY_POLL_H 24 | #define MBEDTLS_ENTROPY_POLL_H 25 | 26 | #if !defined(MBEDTLS_CONFIG_FILE) 27 | #include "config.h" 28 | #else 29 | #include MBEDTLS_CONFIG_FILE 30 | #endif 31 | 32 | #include 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | /* 39 | * Default thresholds for built-in sources, in bytes 40 | */ 41 | #define MBEDTLS_ENTROPY_MIN_PLATFORM 32 /**< Minimum for platform source */ 42 | #define MBEDTLS_ENTROPY_MIN_HAVEGE 32 /**< Minimum for HAVEGE */ 43 | #define MBEDTLS_ENTROPY_MIN_HARDCLOCK 4 /**< Minimum for mbedtls_timing_hardclock() */ 44 | #if !defined(MBEDTLS_ENTROPY_MIN_HARDWARE) 45 | #define MBEDTLS_ENTROPY_MIN_HARDWARE 32 /**< Minimum for the hardware source */ 46 | #endif 47 | 48 | /** 49 | * \brief Entropy poll callback that provides 0 entropy. 50 | */ 51 | #if defined(MBEDTLS_TEST_NULL_ENTROPY) 52 | int mbedtls_null_entropy_poll( void *data, 53 | unsigned char *output, size_t len, size_t *olen ); 54 | #endif 55 | 56 | #if !defined(MBEDTLS_NO_PLATFORM_ENTROPY) 57 | /** 58 | * \brief Platform-specific entropy poll callback 59 | */ 60 | int mbedtls_platform_entropy_poll( void *data, 61 | unsigned char *output, size_t len, size_t *olen ); 62 | #endif 63 | 64 | #if defined(MBEDTLS_HAVEGE_C) 65 | /** 66 | * \brief HAVEGE based entropy poll callback 67 | * 68 | * Requires an HAVEGE state as its data pointer. 69 | */ 70 | int mbedtls_havege_poll( void *data, 71 | unsigned char *output, size_t len, size_t *olen ); 72 | #endif 73 | 74 | #if defined(MBEDTLS_TIMING_C) 75 | /** 76 | * \brief mbedtls_timing_hardclock-based entropy poll callback 77 | */ 78 | int mbedtls_hardclock_poll( void *data, 79 | unsigned char *output, size_t len, size_t *olen ); 80 | #endif 81 | 82 | #if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) 83 | /** 84 | * \brief Entropy poll callback for a hardware source 85 | * 86 | * \warning This is not provided by mbed TLS! 87 | * See \c MBEDTLS_ENTROPY_HARDWARE_ALT in config.h. 88 | * 89 | * \note This must accept NULL as its first argument. 90 | */ 91 | int mbedtls_hardware_poll( void *data, 92 | unsigned char *output, size_t len, size_t *olen ); 93 | #endif 94 | 95 | #if defined(MBEDTLS_ENTROPY_NV_SEED) 96 | /** 97 | * \brief Entropy poll callback for a non-volatile seed file 98 | * 99 | * \note This must accept NULL as its first argument. 100 | */ 101 | int mbedtls_nv_seed_poll( void *data, 102 | unsigned char *output, size_t len, size_t *olen ); 103 | #endif 104 | 105 | #ifdef __cplusplus 106 | } 107 | #endif 108 | 109 | #endif /* entropy_poll.h */ 110 | -------------------------------------------------------------------------------- /swarm/SwarmConnectionFlow.txt: -------------------------------------------------------------------------------- 1 | This is a rough outline of how the existing GO version connects to the swarm. This was engineered by parsing log files. So some details may be missing 2 | or inaccurate. 3 | 4 | Conneting to the swarm: 5 | 6 | 0) Network connection 7 | 8 | 1) Negotiate Multistream 9 | 10 | 2) Negotiate secio 11 | 12 | 3) Negotiate Multistream over secio 13 | 14 | 4) Negotiate yamux over multistrem over secio. They should reply with the yamux protocol id. Then there are about 6 streams. It appears that odd number 15 | streams are opened by the "client" and even numbered streams by the "server". 16 | 17 | It does not seem that these streams are synchronized with one another, although each stream must complete its transmission before another can be sent 18 | (i.e. yamux header + all data must be sent before another stream can use the connection) 19 | 20 | The miscellaneous bytes sent still have to be sorted as to why and when they should be sent. 21 | 22 | Stream 1: Us sending the ID protocol and ID message 23 | Send a Window Update 24 | They will send one back 25 | Send multistream protocol id (18 bytes) plus \n (1 byte) 26 | Send id protocol (?? bytes) plus \n (1 byte) 27 | Receive ID protocol back (16 bytes) 28 | Receive yamux header with 2 bytes (167, 4) (not sure why just yet, but it looks like the id protocol sends the size, then the bytes, and yamux wraps them both) 29 | Receive 551 bytes (with yamux header) must be the id protocol blob 30 | Receive window update 31 | 32 | Stream 2: // them sending the ID protocol and ID message 33 | They send us a window update 34 | We send one back 35 | We send the multistream protocol id (18 bytes) plus \n (1 byte) 36 | They send the multistream protocol id back 37 | They send us the id protocol id 38 | We send the protocol id back 39 | We send a yamux header with 2 bytes, {161, 4} 40 | We send a yamux header with 545 bytes 41 | We send a window update 42 | We receive a window update 43 | 44 | Stream 3: // us setting up the kademlia protocol 45 | Send a window update 46 | They will send one back 47 | We receive a multistream protocol id 48 | We send a yamux protocol id 49 | We send a multistream protocol id 50 | We send a yamux header with 1 byte (16) 51 | We send a kad protocol id 52 | We receive the kad protocol id back 53 | We send a window update 54 | 55 | Stream 4: // them setting up the circuit relay protocol 56 | They send us a window update 57 | We send one back 58 | We send the multistream protocol 59 | We receive the yamux header with 1 bytes (19) 60 | We receive the multistream protocol id 61 | We receive the yamux header with 1 byte (28) 62 | We receive the circuit relay protocol id 63 | We send the circuit relay protocol id back 64 | We recieve the yamux header with 1 byte (2) 65 | We receive the yamux header with 2 bytes (8, 4) 66 | We send the value 5 back 67 | We then send the values { 8, 3, 32, 142, 2 } 68 | We send a window update 69 | We receive a window update 70 | 71 | Stream 5: // us setting up the circuit relay protocol 72 | We send a window update 73 | We receive a window update 74 | We receive the multistream protocol id 75 | We send the multistream protocol id 76 | We send a yamux header with 1 byte (28) 77 | We send the circuit relay protocol id 78 | We receive the circuit relay protocol id back 79 | We send the value (2) 80 | We send a yamux header with 2 decimals (8, 2) 81 | We read a yamux header with 1 decimal (5) 82 | We read a yamux header with 5 decimals (8, 3, 32, 142, 2) 83 | We receive a window update 84 | We send a window update 85 | 86 | Stream 6: // them setting up the kademlia protocol 87 | We receive a window update 88 | We send them a window update 89 | We send the multistream protocol id 90 | We received the decimal (19) 91 | We receive the multistream protocol id 92 | We receive the decimal (16) 93 | We receive the kad protocol id 94 | We send the kad protocol id back 95 | We receive a winodw update 96 | We send a window update -------------------------------------------------------------------------------- /include/mbedtls/certs.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file certs.h 3 | * 4 | * \brief Sample certificates and DHM parameters for testing 5 | * 6 | * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 7 | * SPDX-License-Identifier: Apache-2.0 8 | * 9 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 10 | * not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 17 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | * 21 | * This file is part of mbed TLS (https://tls.mbed.org) 22 | */ 23 | #ifndef MBEDTLS_CERTS_H 24 | #define MBEDTLS_CERTS_H 25 | 26 | #include 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | #if defined(MBEDTLS_PEM_PARSE_C) 33 | /* Concatenation of all CA certificates in PEM format if available */ 34 | extern const char mbedtls_test_cas_pem[]; 35 | extern const size_t mbedtls_test_cas_pem_len; 36 | #endif 37 | 38 | /* List of all CA certificates, terminated by NULL */ 39 | extern const char * mbedtls_test_cas[]; 40 | extern const size_t mbedtls_test_cas_len[]; 41 | 42 | /* 43 | * Convenience for users who just want a certificate: 44 | * RSA by default, or ECDSA if RSA is not available 45 | */ 46 | extern const char * mbedtls_test_ca_crt; 47 | extern const size_t mbedtls_test_ca_crt_len; 48 | extern const char * mbedtls_test_ca_key; 49 | extern const size_t mbedtls_test_ca_key_len; 50 | extern const char * mbedtls_test_ca_pwd; 51 | extern const size_t mbedtls_test_ca_pwd_len; 52 | extern const char * mbedtls_test_srv_crt; 53 | extern const size_t mbedtls_test_srv_crt_len; 54 | extern const char * mbedtls_test_srv_key; 55 | extern const size_t mbedtls_test_srv_key_len; 56 | extern const char * mbedtls_test_cli_crt; 57 | extern const size_t mbedtls_test_cli_crt_len; 58 | extern const char * mbedtls_test_cli_key; 59 | extern const size_t mbedtls_test_cli_key_len; 60 | 61 | #if defined(MBEDTLS_ECDSA_C) 62 | extern const char mbedtls_test_ca_crt_ec[]; 63 | extern const size_t mbedtls_test_ca_crt_ec_len; 64 | extern const char mbedtls_test_ca_key_ec[]; 65 | extern const size_t mbedtls_test_ca_key_ec_len; 66 | extern const char mbedtls_test_ca_pwd_ec[]; 67 | extern const size_t mbedtls_test_ca_pwd_ec_len; 68 | extern const char mbedtls_test_srv_crt_ec[]; 69 | extern const size_t mbedtls_test_srv_crt_ec_len; 70 | extern const char mbedtls_test_srv_key_ec[]; 71 | extern const size_t mbedtls_test_srv_key_ec_len; 72 | extern const char mbedtls_test_cli_crt_ec[]; 73 | extern const size_t mbedtls_test_cli_crt_ec_len; 74 | extern const char mbedtls_test_cli_key_ec[]; 75 | extern const size_t mbedtls_test_cli_key_ec_len; 76 | #endif 77 | 78 | #if defined(MBEDTLS_RSA_C) 79 | extern const char mbedtls_test_ca_crt_rsa[]; 80 | extern const size_t mbedtls_test_ca_crt_rsa_len; 81 | extern const char mbedtls_test_ca_key_rsa[]; 82 | extern const size_t mbedtls_test_ca_key_rsa_len; 83 | extern const char mbedtls_test_ca_pwd_rsa[]; 84 | extern const size_t mbedtls_test_ca_pwd_rsa_len; 85 | extern const char mbedtls_test_srv_crt_rsa[]; 86 | extern const size_t mbedtls_test_srv_crt_rsa_len; 87 | extern const char mbedtls_test_srv_key_rsa[]; 88 | extern const size_t mbedtls_test_srv_key_rsa_len; 89 | extern const char mbedtls_test_cli_crt_rsa[]; 90 | extern const size_t mbedtls_test_cli_crt_rsa_len; 91 | extern const char mbedtls_test_cli_key_rsa[]; 92 | extern const size_t mbedtls_test_cli_key_rsa_len; 93 | #endif 94 | 95 | #ifdef __cplusplus 96 | } 97 | #endif 98 | 99 | #endif /* certs.h */ 100 | -------------------------------------------------------------------------------- /include/mbedtls/version.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file version.h 3 | * 4 | * \brief Run-time version information 5 | * 6 | * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 7 | * SPDX-License-Identifier: Apache-2.0 8 | * 9 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 10 | * not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 17 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | * 21 | * This file is part of mbed TLS (https://tls.mbed.org) 22 | */ 23 | /* 24 | * This set of compile-time defines and run-time variables can be used to 25 | * determine the version number of the mbed TLS library used. 26 | */ 27 | #ifndef MBEDTLS_VERSION_H 28 | #define MBEDTLS_VERSION_H 29 | 30 | #if !defined(MBEDTLS_CONFIG_FILE) 31 | #include "config.h" 32 | #else 33 | #include MBEDTLS_CONFIG_FILE 34 | #endif 35 | 36 | /** 37 | * The version number x.y.z is split into three parts. 38 | * Major, Minor, Patchlevel 39 | */ 40 | #define MBEDTLS_VERSION_MAJOR 2 41 | #define MBEDTLS_VERSION_MINOR 4 42 | #define MBEDTLS_VERSION_PATCH 0 43 | 44 | /** 45 | * The single version number has the following structure: 46 | * MMNNPP00 47 | * Major version | Minor version | Patch version 48 | */ 49 | #define MBEDTLS_VERSION_NUMBER 0x02040000 50 | #define MBEDTLS_VERSION_STRING "2.4.0" 51 | #define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.4.0" 52 | 53 | #if defined(MBEDTLS_VERSION_C) 54 | 55 | #ifdef __cplusplus 56 | extern "C" { 57 | #endif 58 | 59 | /** 60 | * Get the version number. 61 | * 62 | * \return The constructed version number in the format 63 | * MMNNPP00 (Major, Minor, Patch). 64 | */ 65 | unsigned int mbedtls_version_get_number( void ); 66 | 67 | /** 68 | * Get the version string ("x.y.z"). 69 | * 70 | * \param string The string that will receive the value. 71 | * (Should be at least 9 bytes in size) 72 | */ 73 | void mbedtls_version_get_string( char *string ); 74 | 75 | /** 76 | * Get the full version string ("mbed TLS x.y.z"). 77 | * 78 | * \param string The string that will receive the value. The mbed TLS version 79 | * string will use 18 bytes AT MOST including a terminating 80 | * null byte. 81 | * (So the buffer should be at least 18 bytes to receive this 82 | * version string). 83 | */ 84 | void mbedtls_version_get_string_full( char *string ); 85 | 86 | /** 87 | * \brief Check if support for a feature was compiled into this 88 | * mbed TLS binary. This allows you to see at runtime if the 89 | * library was for instance compiled with or without 90 | * Multi-threading support. 91 | * 92 | * \note only checks against defines in the sections "System 93 | * support", "mbed TLS modules" and "mbed TLS feature 94 | * support" in config.h 95 | * 96 | * \param feature The string for the define to check (e.g. "MBEDTLS_AES_C") 97 | * 98 | * \return 0 if the feature is present, 99 | * -1 if the feature is not present and 100 | * -2 if support for feature checking as a whole was not 101 | * compiled in. 102 | */ 103 | int mbedtls_version_check_feature( const char *feature ); 104 | 105 | #ifdef __cplusplus 106 | } 107 | #endif 108 | 109 | #endif /* MBEDTLS_VERSION_C */ 110 | 111 | #endif /* version.h */ 112 | -------------------------------------------------------------------------------- /include/mbedtls/aesni.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file aesni.h 3 | * 4 | * \brief AES-NI for hardware AES acceleration on some Intel processors 5 | * 6 | * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 7 | * SPDX-License-Identifier: Apache-2.0 8 | * 9 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 10 | * not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 17 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | * 21 | * This file is part of mbed TLS (https://tls.mbed.org) 22 | */ 23 | #ifndef MBEDTLS_AESNI_H 24 | #define MBEDTLS_AESNI_H 25 | 26 | #include "aes.h" 27 | 28 | #define MBEDTLS_AESNI_AES 0x02000000u 29 | #define MBEDTLS_AESNI_CLMUL 0x00000002u 30 | 31 | #if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && \ 32 | ( defined(__amd64__) || defined(__x86_64__) ) && \ 33 | ! defined(MBEDTLS_HAVE_X86_64) 34 | #define MBEDTLS_HAVE_X86_64 35 | #endif 36 | 37 | #if defined(MBEDTLS_HAVE_X86_64) 38 | 39 | #ifdef __cplusplus 40 | extern "C" { 41 | #endif 42 | 43 | /** 44 | * \brief AES-NI features detection routine 45 | * 46 | * \param what The feature to detect 47 | * (MBEDTLS_AESNI_AES or MBEDTLS_AESNI_CLMUL) 48 | * 49 | * \return 1 if CPU has support for the feature, 0 otherwise 50 | */ 51 | int mbedtls_aesni_has_support( unsigned int what ); 52 | 53 | /** 54 | * \brief AES-NI AES-ECB block en(de)cryption 55 | * 56 | * \param ctx AES context 57 | * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT 58 | * \param input 16-byte input block 59 | * \param output 16-byte output block 60 | * 61 | * \return 0 on success (cannot fail) 62 | */ 63 | int mbedtls_aesni_crypt_ecb( mbedtls_aes_context *ctx, 64 | int mode, 65 | const unsigned char input[16], 66 | unsigned char output[16] ); 67 | 68 | /** 69 | * \brief GCM multiplication: c = a * b in GF(2^128) 70 | * 71 | * \param c Result 72 | * \param a First operand 73 | * \param b Second operand 74 | * 75 | * \note Both operands and result are bit strings interpreted as 76 | * elements of GF(2^128) as per the GCM spec. 77 | */ 78 | void mbedtls_aesni_gcm_mult( unsigned char c[16], 79 | const unsigned char a[16], 80 | const unsigned char b[16] ); 81 | 82 | /** 83 | * \brief Compute decryption round keys from encryption round keys 84 | * 85 | * \param invkey Round keys for the equivalent inverse cipher 86 | * \param fwdkey Original round keys (for encryption) 87 | * \param nr Number of rounds (that is, number of round keys minus one) 88 | */ 89 | void mbedtls_aesni_inverse_key( unsigned char *invkey, 90 | const unsigned char *fwdkey, int nr ); 91 | 92 | /** 93 | * \brief Perform key expansion (for encryption) 94 | * 95 | * \param rk Destination buffer where the round keys are written 96 | * \param key Encryption key 97 | * \param bits Key size in bits (must be 128, 192 or 256) 98 | * 99 | * \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH 100 | */ 101 | int mbedtls_aesni_setkey_enc( unsigned char *rk, 102 | const unsigned char *key, 103 | size_t bits ); 104 | 105 | #ifdef __cplusplus 106 | } 107 | #endif 108 | 109 | #endif /* MBEDTLS_HAVE_X86_64 */ 110 | 111 | #endif /* MBEDTLS_AESNI_H */ 112 | --------------------------------------------------------------------------------