Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
colmmacc committed Mar 5, 2015
2 parents 217e2e1 + f10b68e commit 903fdf2
Show file tree
Hide file tree
Showing 22 changed files with 705 additions and 151 deletions.
7 changes: 6 additions & 1 deletion api/s2n.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,14 @@ extern int s2n_config_free_cert_chain_and_key(struct s2n_config *config);
extern const char *s2n_strerror(int error, const char *lang);

extern int s2n_config_add_cert_chain_and_key(struct s2n_config *config, char *cert_chain_pem, char *private_key_pem);
extern int s2n_config_add_cert_chain_and_key_with_status(struct s2n_config *config,
char *cert_chain_pem, char *private_key_pem, const uint8_t *status, uint32_t length);
extern int s2n_config_add_dhparams(struct s2n_config *config, char *dhparams_pem);
extern int s2n_config_set_key_exchange_preferences(struct s2n_config *config, const char *preferences);
extern int s2n_config_set_cipher_preferences(struct s2n_config *config, const char *version);
extern int s2n_config_set_protocol_preferences(struct s2n_config *config, const char **protocols, int protocol_count);
extern int s2n_config_set_protocol_preferences(struct s2n_config *config, const char * const *protocols, int protocol_count);
typedef enum { S2N_STATUS_REQUEST_NONE = 0, S2N_STATUS_REQUEST_OCSP = 1 } s2n_status_request_type;
extern int s2n_config_set_status_request_type(struct s2n_config *config, s2n_status_request_type type);

struct s2n_connection;
typedef enum { S2N_SERVER, S2N_CLIENT } s2n_mode;
Expand All @@ -62,6 +66,7 @@ extern int s2n_connection_get_delay(struct s2n_connection *conn);
extern int s2n_set_server_name(struct s2n_connection *conn, const char *server_name);
extern const char *s2n_get_server_name(struct s2n_connection *conn);
extern const char *s2n_get_application_protocol(struct s2n_connection *conn);
extern const uint8_t *s2n_connection_get_ocsp_response(struct s2n_connection *conn, uint32_t *length);

extern int s2n_negotiate(struct s2n_connection *conn, int *more);
extern ssize_t s2n_send(struct s2n_connection *conn, void *buf, ssize_t size, int *more);
Expand Down
5 changes: 5 additions & 0 deletions bin/echo.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ int echo(struct s2n_connection *conn, int sockfd)
printf("Application protocol: %s\n",
s2n_get_application_protocol(conn));
}
uint32_t length;
const uint8_t *status = s2n_connection_get_ocsp_response(conn, &length);
if (status && length > 0) {
fprintf(stderr, "OCSP response received, length %d\n", length);
}

printf("Cipher negotiated: %s\n", s2n_connection_get_cipher(conn));

Expand Down
143 changes: 133 additions & 10 deletions bin/s2nc.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,33 +23,91 @@
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <getopt.h>

#include <errno.h>

#include <s2n.h>

void usage()
{
fprintf(stderr, "usage: s2nc host [port]\n");
fprintf(stderr, "usage: s2nc [options] host [port]\n");
fprintf(stderr, " host: hostname or IP address to connect to\n");
fprintf(stderr, " port: port to connect to\n");

fprintf(stderr, "\n Options:\n\n");
fprintf(stderr, " -a [protocols]\n");
fprintf(stderr, " --alpn [protocols]\n");
fprintf(stderr, " Sets the application protocols supported by this client, as a comma seperated list.\n");
fprintf(stderr, " -h,--help\n");
fprintf(stderr, " Display this message and quit.\n");
fprintf(stderr, " -n [server name]\n");
fprintf(stderr, " --name [server name]\n");
fprintf(stderr, " Sets the SNI server name header for this client. If not specified, the host value is used.\n");
fprintf(stderr, " --s,--status\n");
fprintf(stderr, " Request the OCSP status of the remote server certificate\n");
fprintf(stderr, "\n");
exit(1);
}

extern int echo(struct s2n_connection *conn, int sockfd);

int main(int argc, const char *argv[])
int main(int argc, char * const *argv)
{
struct addrinfo hints, *ai_list, *ai;
const char *port = "443";
int r, sockfd = 0;
/* Optional args */
const char *alpn_protocols = NULL;
const char *server_name = NULL;
s2n_status_request_type type = S2N_STATUS_REQUEST_NONE;
/* required args */
const char *host = NULL;
const char *port = "443";

static struct option long_options[] = {
{ "alpn", required_argument, 0, 'a' },
{ "help", no_argument, 0, 'h' },
{ "name", required_argument, 0, 'n' },
{ "status", no_argument, 0, 's' },
};
while (1) {
int option_index = 0;
int c = getopt_long (argc, argv, "a:hn:s", long_options, &option_index);
if (c == -1) {
break;
}
switch (c) {
case 'a':
alpn_protocols = optarg;
break;
case 'h':
usage();
break;
case 'n':
server_name = optarg;
break;
case 's':
type = S2N_STATUS_REQUEST_OCSP;
break;
case '?':
default:
usage();
break;
}
}

if (optind < argc) {
host = argv[optind++];
}
if (optind < argc) {
port = argv[optind++];
}

if (argc < 2 || argc > 3) {
if (!host) {
usage();
}
if (argc == 3) {
port = argv[2];

if (!server_name) {
server_name = host;
}

if (memset(&hints, 0, sizeof(hints)) != &hints) {
Expand All @@ -60,7 +118,7 @@ int main(int argc, const char *argv[])
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;

if ((r = getaddrinfo(argv[1], port, &hints, &ai_list)) != 0) {
if ((r = getaddrinfo(host, port, &hints, &ai_list)) != 0) {
fprintf(stderr, "error: %s\n", gai_strerror(r));
return -1;
}
Expand Down Expand Up @@ -101,21 +159,86 @@ int main(int argc, const char *argv[])
exit(1);
}

if (s2n_config_set_status_request_type(config, type) < 0) {
fprintf(stderr, "Error setting status request type: '%s'\n", s2n_strerror(s2n_errno, "EN"));
exit(1);
}

if (alpn_protocols) {
/* Count the number of commas, this tells us how many protocols there
are in the list */
const char *ptr = alpn_protocols;
int protocol_count = 1;
while (*ptr) {
if (*ptr == ',') {
protocol_count++;
}
ptr++;
}

char **protocols = malloc(sizeof(char *) * protocol_count);
if (!protocols) {
fprintf(stderr, "Error allocating memory\n");
exit(1);
}

const char *next = alpn_protocols;
int index = 0;
int length = 0;
ptr = alpn_protocols;
while (*ptr) {
if (*ptr == ',') {
protocols[index] = malloc(length + 1);
if (!protocols[index]) {
fprintf(stderr, "Error allocating memory\n");
exit(1);
}
memcpy(protocols[index], next, length);
protocols[index][length] = '\0';
length = 0;
index++;
ptr++;
next = ptr;
} else {
length++;
ptr++;
}
}
if (ptr != next) {
protocols[index] = malloc(length + 1);
if (!protocols[index]) {
fprintf(stderr, "Error allocating memory\n");
exit(1);
}
memcpy(protocols[index], next, length);
protocols[index][length] = '\0';
}
if (s2n_config_set_protocol_preferences(config, (const char * const *)protocols, protocol_count) < 0) {
fprintf(stderr, "Failed to set protocol preferences: '%s'\n", s2n_strerror(s2n_errno, "EN"));
exit(1);
}
while(protocol_count) {
protocol_count--;
free(protocols[protocol_count]);
}
free(protocols);
}

struct s2n_connection *conn = s2n_connection_new(S2N_CLIENT);

if (conn == NULL) {
fprintf(stderr, "Error getting new connection: '%s'\n", s2n_strerror(s2n_errno, "EN"));
exit(1);
}

printf("Connected to %s:%s\n", argv[1], port);
printf("Connected to %s:%s\n", host, port);

if (s2n_connection_set_config(conn, config) < 0) {
fprintf(stderr, "Error setting configuration: '%s'\n", s2n_strerror(s2n_errno, "EN"));
exit(1);
}

if (s2n_set_server_name(conn, argv[1]) < 0) {
if (s2n_set_server_name(conn, server_name) < 0) {
fprintf(stderr, "Error setting server name: '%s'\n", s2n_strerror(s2n_errno, "EN"));
exit(1);
}
Expand Down
6 changes: 3 additions & 3 deletions tests/unit/s2n_3des_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ int main(int argc, char **argv)
uint8_t mac_key[] = "sample mac key";
uint8_t des3_key[] = "12345678901234567890123";
struct s2n_blob des3 = {.data = des3_key,.size = sizeof(des3_key) };
uint8_t random_data[S2N_MAXIMUM_FRAGMENT_LENGTH + 1];
uint8_t random_data[S2N_DEFAULT_FRAGMENT_LENGTH + 1];

BEGIN_TEST();

EXPECT_SUCCESS(s2n_init());
EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER));
EXPECT_SUCCESS(s2n_get_random_data(random_data, S2N_MAXIMUM_FRAGMENT_LENGTH + 1));
EXPECT_SUCCESS(s2n_get_random_data(random_data, S2N_DEFAULT_FRAGMENT_LENGTH + 1));

/* Peer and we are in sync */
conn->server = &conn->active;
Expand All @@ -57,7 +57,7 @@ int main(int argc, char **argv)
EXPECT_SUCCESS(s2n_hmac_init(&conn->active.server_record_mac, S2N_HMAC_SHA1, mac_key, sizeof(mac_key)));
conn->actual_protocol_version = S2N_TLS11;

int max_aligned_fragment = S2N_MAXIMUM_FRAGMENT_LENGTH - (S2N_MAXIMUM_FRAGMENT_LENGTH % 8);
int max_aligned_fragment = S2N_DEFAULT_FRAGMENT_LENGTH - (S2N_DEFAULT_FRAGMENT_LENGTH % 8);
for (int i = 0; i <= max_aligned_fragment + 1; i++) {
struct s2n_blob in = {.data = random_data,.size = i };
int bytes_written;
Expand Down
23 changes: 14 additions & 9 deletions tests/unit/s2n_aead_aes_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
int main(int argc, char **argv)
{
struct s2n_connection *conn;
uint8_t random_data[S2N_MAXIMUM_FRAGMENT_LENGTH + 1];
uint8_t random_data[S2N_DEFAULT_FRAGMENT_LENGTH + 1];
uint8_t mac_key[] = "sample mac key";
uint8_t aes128_key[] = "123456789012345";
uint8_t aes256_key[] = "1234567890123456789012345678901";
Expand All @@ -59,18 +59,21 @@ int main(int argc, char **argv)
EXPECT_SUCCESS(s2n_hmac_init(&conn->active.server_record_mac, S2N_HMAC_SHA1, mac_key, sizeof(mac_key)));
conn->actual_protocol_version = S2N_TLS12;

int max_aligned_fragment = S2N_MAXIMUM_FRAGMENT_LENGTH - (S2N_MAXIMUM_FRAGMENT_LENGTH % 16);
for (int i = 0; i <= max_aligned_fragment + 1; i++) {
int max_fragment = S2N_DEFAULT_FRAGMENT_LENGTH;
for (int i = 0; i <= max_fragment + 1; i++) {
struct s2n_blob in = {.data = random_data,.size = i };
int bytes_written;

EXPECT_SUCCESS(s2n_stuffer_wipe(&conn->out));
EXPECT_SUCCESS(bytes_written = s2n_record_write(conn, TLS_APPLICATION_DATA, &in));

if (i < max_aligned_fragment - 20 - 8 - 1) {
static const int overhead = 20 /* TLS header */
+ 8 /* IV */
+ 16; /* TAG */
if (i < max_fragment - overhead) {
EXPECT_EQUAL(bytes_written, i);
} else {
EXPECT_EQUAL(bytes_written, max_aligned_fragment - 20 - 8 - 1);
EXPECT_EQUAL(bytes_written, max_fragment - overhead);
}

uint16_t predicted_length = bytes_written + 20;
Expand Down Expand Up @@ -187,18 +190,20 @@ int main(int argc, char **argv)
EXPECT_SUCCESS(s2n_hmac_init(&conn->active.server_record_mac, S2N_HMAC_SHA1, mac_key, sizeof(mac_key)));
conn->actual_protocol_version = S2N_TLS12;

max_aligned_fragment = S2N_MAXIMUM_FRAGMENT_LENGTH - (S2N_MAXIMUM_FRAGMENT_LENGTH % 16);
for (int i = 0; i <= max_aligned_fragment + 1; i++) {
for (int i = 0; i <= max_fragment + 1; i++) {
struct s2n_blob in = {.data = random_data,.size = i };
int bytes_written;

EXPECT_SUCCESS(s2n_stuffer_wipe(&conn->out));
EXPECT_SUCCESS(bytes_written = s2n_record_write(conn, TLS_APPLICATION_DATA, &in));

if (i < max_aligned_fragment - 20 - 8 - 1) {
static const int overhead = 20 /* TLS header */
+ 8 /* IV */
+ 16; /* TAG */
if (i < max_fragment - overhead) {
EXPECT_EQUAL(bytes_written, i);
} else {
EXPECT_EQUAL(bytes_written, max_aligned_fragment - 20 - 8 - 1);
EXPECT_EQUAL(bytes_written, max_fragment - overhead);
}

uint16_t predicted_length = bytes_written + 20;
Expand Down
8 changes: 4 additions & 4 deletions tests/unit/s2n_aes_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ int main(int argc, char **argv)
uint8_t aes256_key[] = "1234567890123456789012345678901";
struct s2n_blob aes128 = {.data = aes128_key,.size = sizeof(aes128_key) };
struct s2n_blob aes256 = {.data = aes256_key,.size = sizeof(aes256_key) };
uint8_t random_data[S2N_MAXIMUM_FRAGMENT_LENGTH + 1];
uint8_t random_data[S2N_DEFAULT_FRAGMENT_LENGTH + 1];

BEGIN_TEST();

EXPECT_SUCCESS(s2n_init());
EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER));
EXPECT_SUCCESS(s2n_get_random_data(random_data, S2N_MAXIMUM_FRAGMENT_LENGTH + 1));
EXPECT_SUCCESS(s2n_get_random_data(random_data, S2N_DEFAULT_FRAGMENT_LENGTH + 1));

/* Peer and we are in sync */
conn->server = &conn->active;
Expand All @@ -59,7 +59,7 @@ int main(int argc, char **argv)
EXPECT_SUCCESS(s2n_hmac_init(&conn->active.server_record_mac, S2N_HMAC_SHA1, mac_key, sizeof(mac_key)));
conn->actual_protocol_version = S2N_TLS11;

int max_aligned_fragment = S2N_MAXIMUM_FRAGMENT_LENGTH - (S2N_MAXIMUM_FRAGMENT_LENGTH % 16);
int max_aligned_fragment = S2N_DEFAULT_FRAGMENT_LENGTH - (S2N_DEFAULT_FRAGMENT_LENGTH % 16);
for (int i = 0; i <= max_aligned_fragment + 1; i++) {
struct s2n_blob in = {.data = random_data,.size = i };
int bytes_written;
Expand Down Expand Up @@ -120,7 +120,7 @@ int main(int argc, char **argv)
EXPECT_SUCCESS(s2n_hmac_init(&conn->active.server_record_mac, S2N_HMAC_SHA1, mac_key, sizeof(mac_key)));
conn->actual_protocol_version = S2N_TLS11;

max_aligned_fragment = S2N_MAXIMUM_FRAGMENT_LENGTH - (S2N_MAXIMUM_FRAGMENT_LENGTH % 16);
max_aligned_fragment = S2N_DEFAULT_FRAGMENT_LENGTH - (S2N_DEFAULT_FRAGMENT_LENGTH % 16);
for (int i = 0; i <= max_aligned_fragment + 1; i++) {
struct s2n_blob in = {.data = random_data,.size = i };
int bytes_written;
Expand Down
8 changes: 4 additions & 4 deletions tests/unit/s2n_cbc_verify_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,21 +115,21 @@ int main(int argc, char **argv)
{
struct s2n_connection *conn;
uint8_t mac_key[] = "sample mac key";
uint8_t fragment[S2N_MAXIMUM_FRAGMENT_LENGTH];
uint8_t random_data[S2N_MAXIMUM_FRAGMENT_LENGTH];
uint8_t fragment[S2N_DEFAULT_FRAGMENT_LENGTH];
uint8_t random_data[S2N_DEFAULT_FRAGMENT_LENGTH];
struct s2n_hmac_state check_mac, record_mac;

BEGIN_TEST();

EXPECT_SUCCESS(s2n_init());
EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER));
EXPECT_SUCCESS(s2n_get_random_data(random_data, S2N_MAXIMUM_FRAGMENT_LENGTH));
EXPECT_SUCCESS(s2n_get_random_data(random_data, S2N_DEFAULT_FRAGMENT_LENGTH));

/* Emulate TLS1.2 */
conn->actual_protocol_version = S2N_TLS12;

/* Try every 16 bytes to simulate block alignments */
for (int i = 288; i < S2N_MAXIMUM_FRAGMENT_LENGTH; i += 16) {
for (int i = 288; i < S2N_DEFAULT_FRAGMENT_LENGTH; i += 16) {

EXPECT_SUCCESS(s2n_hmac_init(&record_mac, S2N_HMAC_SHA1, mac_key, sizeof(mac_key)));

Expand Down
Loading

0 comments on commit 903fdf2

Please sign in to comment.