+// client.c
+//
+// Example of using Ossuary as a client in C
+//
+// This is the client half of a C client/server example for Ossuary.
+// Run the server first, then run this client to send encrypted messages
+// one way from client to server.
+//
+// The purpose of this example is to show the Ossuary FFI API, and demonstrate
+// how it sits 'in between' the read and write calls of a TCP connection.
+//
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include "ossuary.h"
+int net_connect();
+
uint8_t secret_key[] = {
0x10, 0x86, 0x6e, 0xc4, 0x8a, 0x11, 0xf3, 0xc5,
0x6d, 0x77, 0xa6, 0x4b, 0x2f, 0x54, 0xaa, 0x06,
};
int main(int argc, char **argv) {
- uint8_t read_buf[1024];
- uint8_t write_buf[1024];
- struct sockaddr_in addr;
- struct in_addr inaddr;
+ uint8_t read_buf[1024]; // data received from network socket
+ uint8_t write_buf[1024]; // data to send on network socket
+ uint8_t text_buf[1024]; // data received and decrypted by ossuary
OssuaryConnection *client_conn = NULL;
int sock;
- int flags;
int read_len;
int handshake;
uint16_t read_buf_len;
uint16_t write_buf_len;
- printf("Connecting to localhost port 9981...\n");
- if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
- fprintf(stderr, "ERROR: could not create IPv4 socket\n");
- exit(1);
- }
- memset(&addr, 0, sizeof(struct sockaddr_in));
- addr.sin_family = AF_INET;
- addr.sin_port = htons(9981);
- inaddr.s_addr = inet_addr("127.0.0.1");
- addr.sin_addr = inaddr;
+ uint16_t text_buf_len;
- if (connect(sock, (const struct sockaddr*)&addr, sizeof(struct sockaddr_in)) < 0) {
- fprintf(stderr, "ERROR: could not connect to 127.0.0.1:9981\n");
- exit(1);
- }
+ // Wait for a TCP connection from a client
+ sock = net_connect();
+ // Create an Ossuary client
if ((client_conn = ossuary_create_connection(OSSUARY_CONN_TYPE_CLIENT, NULL)) == NULL) {
fprintf(stderr, "ERROR: could not create Ossuary connection\n");
exit(1);
}
ossuary_add_authorized_key(client_conn, public_key);
- flags = fcntl(sock, F_GETFL, 0);
- if (fcntl(sock, F_SETFL, flags | O_NONBLOCK) < 0) {
- fprintf(stderr, "ERROR: could not set non-blocking\n");
- exit(1);
- }
-
- printf("Connected!\n");
while (1) {
+ // Read from network socket
if ((read_len = read(sock, read_buf, sizeof(read_buf))) <= 0) {
if (errno != EAGAIN) {
fprintf(stderr, "ERROR: read failed: %d\n", read_len);
exit(1);
}
+ read_len = 0;
}
+ read_buf_len += read_len;
+ // Ossuary handshake
if ((handshake = ossuary_handshake_done(client_conn)) == 0) {
write_buf_len = sizeof(write_buf);
+ // Check if we have any handshake packets to send
if (ossuary_send_handshake(client_conn, write_buf, &write_buf_len) < 0) {
fprintf(stderr, "ERROR: handshake send failed\n");
exit(1);
}
- if (read_len > 0) {
- read_buf_len = read_len;
- if (ossuary_recv_handshake(client_conn, read_buf, &read_buf_len) < 0) {
+ // Check if we have any received handshake packets to parse
+ if (read_buf_len > 0) {
+ read_len = read_buf_len;
+ if (ossuary_recv_handshake(client_conn, read_buf, (uint16_t*)&read_len) < 0) {
fprintf(stderr, "ERROR: handshake recv failed\n");
exit(1);
}
- memmove(read_buf, read_buf + read_buf_len, read_len - read_buf_len);
- read_buf_len = 0;
+ // Consume bytes from read_buf
+ memmove(read_buf, read_buf + read_len, read_buf_len - read_len);
+ read_buf_len -= read_len;
}
}
+ // Ossuary handshake failed
else if (handshake < 0) {
fprintf(stderr, "ERROR: handshake failed: %d\n", handshake);
exit(1);
}
+ // Ossuary data exchange over established connection
else {
- if (read_len > 0) {
- write_buf_len = 0;
- if (ossuary_recv_data(client_conn, read_buf, read_buf_len, write_buf, &write_buf_len) > 0) {
- memmove(read_buf, read_buf + read_buf_len, read_len - read_buf_len);
- read_buf_len = 0;
- printf("Received %d encrypted bytes\n", read_len);
- write_buf_len = 0;
- }
- }
+ // Ask for a message from the user and encrypt it with Ossuary
printf("Enter message: ");
- read_buf[0] = 0;
- gets((char *)read_buf);
- read_buf_len = strlen((char *)read_buf) + 1;
+ text_buf[0] = 0;
+ gets((char *)text_buf);
+ text_buf_len = strlen((char *)text_buf) + 1;
write_buf_len = sizeof(write_buf);
- ossuary_send_data(client_conn, read_buf, read_buf_len, write_buf, &write_buf_len);
+ ossuary_send_data(client_conn, text_buf, text_buf_len, write_buf, &write_buf_len);
}
+ // Write any encrypted messages generated by Ossuary
if (write_buf_len > 0) {
if (write(sock, write_buf, write_buf_len) != write_buf_len) {
fprintf(stderr, "ERROR: write failed\n");
close(sock);
}
+
+int net_connect() {
+ struct sockaddr_in addr;
+ struct in_addr inaddr;
+ int sock;
+ int flags;
+
+ printf("Connecting to localhost port 9981...\n");
+ if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
+ fprintf(stderr, "ERROR: could not create IPv4 socket\n");
+ exit(1);
+ }
+ memset(&addr, 0, sizeof(struct sockaddr_in));
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(9981);
+ inaddr.s_addr = inet_addr("127.0.0.1");
+ addr.sin_addr = inaddr;
+
+ if (connect(sock, (const struct sockaddr*)&addr, sizeof(struct sockaddr_in)) < 0) {
+ fprintf(stderr, "ERROR: could not connect to 127.0.0.1:9981\n");
+ exit(1);
+ }
+
+ flags = fcntl(sock, F_GETFL, 0);
+ if (fcntl(sock, F_SETFL, flags | O_NONBLOCK) < 0) {
+ fprintf(stderr, "ERROR: could not set non-blocking\n");
+ exit(1);
+ }
+
+ printf("Connected!\n");
+ return sock;
+}
+// server.c
+//
+// Example of using Ossuary as a server in C
+//
+// This is the server half of a C client/server example for Ossuary.
+// Run this server first, then run the client to send encrypted messages
+// one way from client to server.
+//
+// The purpose of this example is to show the Ossuary FFI API, and demonstrate
+// how it sits 'in between' the read and write calls of a TCP connection.
+//
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <netinet/in.h>
#include "ossuary.h"
+int net_connect();
+
uint8_t secret_key[] = {
0x10, 0x86, 0x6e, 0xc4, 0x8a, 0x11, 0xf3, 0xc5,
0x6d, 0x77, 0xa6, 0x4b, 0x2f, 0x54, 0xaa, 0x06,
};
int main(int argc, char **argv) {
- uint8_t read_buf[1024];
- uint8_t write_buf[1024];
- struct sockaddr_in addr;
- struct in_addr inaddr;
- socklen_t addr_len;
+ uint8_t read_buf[1024]; // data received from network socket
+ uint8_t write_buf[1024]; // data to send on network socket
+ uint8_t text_buf[1024]; // data received and decrypted by ossuary
OssuaryConnection *server_conn = NULL;
- int sock;
- int conn;
- int flags;
- int client;
int read_len;
- uint16_t read_buf_len;
- uint16_t write_buf_len;
- printf("Starting on localhost port 9981...\n");
- if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
- fprintf(stderr, "ERROR: could not create IPv4 socket\n");
- exit(1);
- }
- memset(&addr, 0, sizeof(struct sockaddr_in));
- addr.sin_family = AF_INET;
- addr.sin_port = htons(9981);
- inaddr.s_addr = 0;
- addr.sin_addr = inaddr;
+ int client;
+ int handshake;
+ uint16_t read_buf_len = 0;
+ uint16_t write_buf_len = 0;
+ uint16_t text_buf_len = 0;
- if ((conn = bind(sock, (const struct sockaddr*)&addr, sizeof(struct sockaddr_in))) < 0) {
- fprintf(stderr, "ERROR: could not bind to 127.0.0.1:9981\n");
- exit(1);
- }
- if (listen(sock, 3) < 0) {
- fprintf(stderr, "ERROR: could not listen on 127.0.0.1:9981\n");
- exit(1);
- }
- addr_len = sizeof(struct sockaddr_in);
- if ((client = accept(sock, (struct sockaddr*)&addr, &addr_len)) < 0) {
- fprintf(stderr, "ERROR: could not listen on 127.0.0.1:9981\n");
- exit(1);
- }
+ // Wait for a TCP connection from a client
+ client = net_connect();
+ // Create an Ossuary server
if ((server_conn = ossuary_create_connection(OSSUARY_CONN_TYPE_UNAUTHENTICATED_SERVER, NULL)) == NULL) {
fprintf(stderr, "ERROR: could not create Ossuary connection\n");
exit(1);
}
ossuary_set_secret_key(server_conn, secret_key);
- flags = fcntl(client, F_GETFL, 0);
- if (fcntl(client, F_SETFL, flags | O_NONBLOCK) < 0) {
- fprintf(stderr, "ERROR: could not set non-blocking\n");
- exit(1);
- }
-
- printf("Connected!\n");
while (1) {
- if ((read_len = read(client, read_buf, sizeof(read_buf))) <= 0) {
+ // Read from network socket
+ if ((read_len = read(client, read_buf + read_buf_len, sizeof(read_buf) - read_buf_len)) <= 0) {
if (errno != EAGAIN) {
fprintf(stderr, "ERROR: read failed\n");
exit(1);
}
+ read_len = 0;
}
+ read_buf_len += read_len;
- if (ossuary_handshake_done(server_conn) == 0) {
+ // Ossuary handshake
+ if ((handshake = ossuary_handshake_done(server_conn)) == 0) {
write_buf_len = sizeof(write_buf);
+ // Check if we have any handshake packets to send
if (ossuary_send_handshake(server_conn, write_buf, &write_buf_len) < 0) {
fprintf(stderr, "ERROR: handshake send failed\n");
exit(1);
}
- if (read_len > 0) {
- read_buf_len = read_len;
- if (ossuary_recv_handshake(server_conn, read_buf, &read_buf_len) < 0) {
+ // Check if we have any received handshake packets to parse
+ if (read_buf_len > 0) {
+ read_len = read_buf_len;
+ if (ossuary_recv_handshake(server_conn, read_buf, (uint16_t*)&read_len) < 0) {
fprintf(stderr, "ERROR: handshake recv failed\n");
exit(1);
}
- memmove(read_buf, read_buf + read_buf_len, read_len - read_buf_len);
- read_buf_len = 0;
+ // Consume bytes from read_buf
+ memmove(read_buf, read_buf + read_len, read_buf_len - read_len);
+ read_buf_len -= read_len;
}
}
+ // Ossuary handshake failed
+ else if (handshake < 0) {
+ fprintf(stderr, "ERROR: handshake failed: %d\n", handshake);
+ exit(1);
+ }
+ // Ossuary data exchange over established connection
else {
- if (read_len > 0) {
- read_buf_len += read_len;
- write_buf_len = sizeof(write_buf);
- if ((read_len = ossuary_recv_data(server_conn, read_buf, read_buf_len, write_buf, &write_buf_len)) > 0) {
+ // If data has been received, decrypt and print it.
+ if (read_buf_len > 0) {
+ text_buf_len = sizeof(text_buf);
+ if ((read_len = ossuary_recv_data(server_conn, read_buf, read_buf_len, text_buf, &text_buf_len)) > 0) {
memmove(read_buf, read_buf + read_len, read_buf_len - read_len);
read_buf_len -= read_len;
- if (write_buf_len > 0) {
- printf("MSG: %s\n", write_buf);
+ if (text_buf_len > 0) {
+ printf("MSG: %s\n", text_buf);
}
- write_buf_len = 0;
- read_len = 0;
}
}
}
+ // Write any encrypted messages generated by Ossuary
if (write_buf_len) {
if (write(client, write_buf, write_buf_len) != write_buf_len) {
fprintf(stderr, "ERROR: write failed\n");
}
close(client);
+}
+
+int net_connect() {
+ struct sockaddr_in addr;
+ struct in_addr inaddr;
+ socklen_t addr_len;
+ int sock;
+ int conn;
+ int flags;
+ int client;
+
+ printf("Starting on localhost port 9981...\n");
+ if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
+ fprintf(stderr, "ERROR: could not create IPv4 socket\n");
+ exit(1);
+ }
+ memset(&addr, 0, sizeof(struct sockaddr_in));
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(9981);
+ inaddr.s_addr = 0;
+ addr.sin_addr = inaddr;
+
+ if ((conn = bind(sock, (const struct sockaddr*)&addr, sizeof(struct sockaddr_in))) < 0) {
+ fprintf(stderr, "ERROR: could not bind to 127.0.0.1:9981\n");
+ exit(1);
+ }
+ if (listen(sock, 3) < 0) {
+ fprintf(stderr, "ERROR: could not listen on 127.0.0.1:9981\n");
+ exit(1);
+ }
+ addr_len = sizeof(struct sockaddr_in);
+ printf("Waiting for client...\n");
+ if ((client = accept(sock, (struct sockaddr*)&addr, &addr_len)) < 0) {
+ fprintf(stderr, "ERROR: could not listen on 127.0.0.1:9981\n");
+ exit(1);
+ }
+
+ flags = fcntl(client, F_GETFL, 0);
+ if (fcntl(client, F_SETFL, flags | O_NONBLOCK) < 0) {
+ fprintf(stderr, "ERROR: could not set non-blocking\n");
+ exit(1);
+ }
+
close(sock);
+ printf("Client connected!\n");
+ return client;
}