fix(rustls) (#1022)

* fix(rustls)

updated tests

* we should provide llvm asan
This commit is contained in:
Jacob Heider 2023-03-29 17:25:52 -04:00 committed by GitHub
parent b764300106
commit f62e152b10
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 60 additions and 64 deletions

View file

@ -34,7 +34,7 @@ int
make_conn(const char *hostname, const char *port) make_conn(const char *hostname, const char *port)
{ {
int sockfd = 0; int sockfd = 0;
enum crustls_demo_result result = 0; enum demo_result result = 0;
struct addrinfo *getaddrinfo_output = NULL, hints; struct addrinfo *getaddrinfo_output = NULL, hints;
memset(&hints, 0, sizeof(hints)); memset(&hints, 0, sizeof(hints));
@ -64,7 +64,7 @@ make_conn(const char *hostname, const char *port)
goto cleanup; goto cleanup;
} }
result = nonblock(sockfd); result = nonblock(sockfd);
if(result != CRUSTLS_DEMO_OK) { if(result != DEMO_OK) {
return 1; return 1;
} }
@ -85,13 +85,13 @@ cleanup:
* Do one read from the socket, and process all resulting bytes into the * Do one read from the socket, and process all resulting bytes into the
* rustls_connection, then copy all plaintext bytes from the session to stdout. * rustls_connection, then copy all plaintext bytes from the session to stdout.
* Returns: * Returns:
* - CRUSTLS_DEMO_OK for success * - DEMO_OK for success
* - CRUSTLS_DEMO_AGAIN if we got an EAGAIN or EWOULDBLOCK reading from the * - DEMO_AGAIN if we got an EAGAIN or EWOULDBLOCK reading from the
* socket * socket
* - CRUSTLS_DEMO_EOF if we got EOF * - DEMO_EOF if we got EOF
* - CRUSTLS_DEMO_ERROR for other errors. * - DEMO_ERROR for other errors.
*/ */
enum crustls_demo_result enum demo_result
do_read(struct conndata *conn, struct rustls_connection *rconn) do_read(struct conndata *conn, struct rustls_connection *rconn)
{ {
int err = 1; int err = 1;
@ -106,21 +106,21 @@ do_read(struct conndata *conn, struct rustls_connection *rconn)
fprintf(stderr, fprintf(stderr,
"client: reading from socket: EAGAIN or EWOULDBLOCK: %s\n", "client: reading from socket: EAGAIN or EWOULDBLOCK: %s\n",
strerror(errno)); strerror(errno));
return CRUSTLS_DEMO_AGAIN; return DEMO_AGAIN;
} }
else if(err != 0) { else if(err != 0) {
fprintf(stderr, "client: reading from socket: errno %d\n", err); fprintf(stderr, "client: reading from socket: errno %d\n", err);
return CRUSTLS_DEMO_ERROR; return DEMO_ERROR;
} }
result = rustls_connection_process_new_packets(rconn); result = rustls_connection_process_new_packets(rconn);
if(result != RUSTLS_RESULT_OK) { if(result != RUSTLS_RESULT_OK) {
print_error("server", "in process_new_packets", result); print_error("server", "in process_new_packets", result);
return CRUSTLS_DEMO_ERROR; return DEMO_ERROR;
} }
result = copy_plaintext_to_buffer(conn); result = copy_plaintext_to_buffer(conn);
if(result != CRUSTLS_DEMO_EOF) { if(result != DEMO_EOF) {
return result; return result;
} }
@ -131,15 +131,15 @@ do_read(struct conndata *conn, struct rustls_connection *rconn)
fprintf(stderr, fprintf(stderr,
"client: error: read returned %zu bytes after receiving close_notify\n", "client: error: read returned %zu bytes after receiving close_notify\n",
n); n);
return CRUSTLS_DEMO_ERROR; return DEMO_ERROR;
} }
else if (signed_n < 0 && errno != EWOULDBLOCK) { else if (signed_n < 0 && errno != EWOULDBLOCK) {
fprintf(stderr, fprintf(stderr,
"client: error: read returned incorrect error after receiving close_notify: %s\n", "client: error: read returned incorrect error after receiving close_notify: %s\n",
strerror(errno)); strerror(errno));
return CRUSTLS_DEMO_ERROR; return DEMO_ERROR;
} }
return CRUSTLS_DEMO_EOF; return DEMO_EOF;
} }
static const char *CONTENT_LENGTH = "Content-Length"; static const char *CONTENT_LENGTH = "Content-Length";
@ -224,13 +224,13 @@ send_request_and_read_response(struct conndata *conn,
select awaiting the next bit of data. */ select awaiting the next bit of data. */
for(;;) { for(;;) {
result = do_read(conn, rconn); result = do_read(conn, rconn);
if(result == CRUSTLS_DEMO_AGAIN) { if(result == DEMO_AGAIN) {
break; break;
} }
else if(result == CRUSTLS_DEMO_EOF) { else if(result == DEMO_EOF) {
goto drain_plaintext; goto drain_plaintext;
} }
else if(result != CRUSTLS_DEMO_OK) { else if(result != DEMO_OK) {
goto cleanup; goto cleanup;
} }
if(headers_len == 0) { if(headers_len == 0) {
@ -276,7 +276,7 @@ send_request_and_read_response(struct conndata *conn,
stderr, "client: error in rustls_connection_write_tls: errno %d\n", err); stderr, "client: error in rustls_connection_write_tls: errno %d\n", err);
goto cleanup; goto cleanup;
} }
if(result == CRUSTLS_DEMO_AGAIN) { if(result == DEMO_AGAIN) {
break; break;
} }
else if(n == 0) { else if(n == 0) {
@ -291,7 +291,7 @@ send_request_and_read_response(struct conndata *conn,
drain_plaintext: drain_plaintext:
result = copy_plaintext_to_buffer(conn); result = copy_plaintext_to_buffer(conn);
if(result != CRUSTLS_DEMO_OK && result != CRUSTLS_DEMO_EOF) { if(result != DEMO_OK && result != DEMO_EOF) {
goto cleanup; goto cleanup;
} }
fprintf(stderr, "client: writing %zu bytes to stdout\n", conn->data.len); fprintf(stderr, "client: writing %zu bytes to stdout\n", conn->data.len);
@ -373,8 +373,8 @@ verify(void *userdata, const rustls_verify_server_cert_params *params)
fprintf(stderr, fprintf(stderr,
"client: custom certificate verifier called for %.*s\n", "client: custom certificate verifier called for %.*s\n",
(int)params->dns_name.len, (int)params->server_name.len,
params->dns_name.data); params->server_name.data);
fprintf(stderr, "client: end entity len: %zu\n", params->end_entity_cert_der.len); fprintf(stderr, "client: end entity len: %zu\n", params->end_entity_cert_der.len);
fprintf(stderr, "client: intermediates:\n"); fprintf(stderr, "client: intermediates:\n");
for(i = 0; i < intermediates_len; i++) { for(i = 0; i < intermediates_len; i++) {
@ -461,4 +461,4 @@ cleanup:
#endif #endif
return ret; return ret;
} }

View file

@ -74,9 +74,9 @@ write_all(int fd, const char *buf, int n)
/* /*
* Set a socket to be nonblocking. * Set a socket to be nonblocking.
* *
* Returns CRUSTLS_DEMO_OK on success, CRUSTLS_DEMO_ERROR on error. * Returns DEMO_OK on success, DEMO_ERROR on error.
*/ */
enum crustls_demo_result enum demo_result
nonblock(int sockfd) nonblock(int sockfd)
{ {
#ifdef _WIN32 #ifdef _WIN32
@ -84,22 +84,22 @@ nonblock(int sockfd)
if(ioctlsocket(sockfd, FIONBIO, &nonblock) != 0) { if(ioctlsocket(sockfd, FIONBIO, &nonblock) != 0) {
perror("Error setting socket nonblocking"); perror("Error setting socket nonblocking");
return CRUSTLS_DEMO_ERROR; return DEMO_ERROR;
} }
#else #else
int flags; int flags;
flags = fcntl(sockfd, F_GETFL, 0); flags = fcntl(sockfd, F_GETFL, 0);
if(flags < 0) { if(flags < 0) {
perror("getting socket flags"); perror("getting socket flags");
return CRUSTLS_DEMO_ERROR; return DEMO_ERROR;
} }
flags = fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); flags = fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
if(flags < 0) { if(flags < 0) {
perror("setting socket nonblocking"); perror("setting socket nonblocking");
return CRUSTLS_DEMO_ERROR; return DEMO_ERROR;
} }
#endif #endif
return CRUSTLS_DEMO_OK; return DEMO_OK;
} }
int int
@ -183,8 +183,8 @@ bytevec_consume(struct bytevec *vec, size_t n)
// Ensure there are at least n bytes available between vec->len and // Ensure there are at least n bytes available between vec->len and
// vec->capacity. If this requires reallocating, this may return // vec->capacity. If this requires reallocating, this may return
// CRUSTLS_DEMO_ERROR. // DEMO_ERROR.
enum crustls_demo_result enum demo_result
bytevec_ensure_available(struct bytevec *vec, size_t n) bytevec_ensure_available(struct bytevec *vec, size_t n)
{ {
size_t available = vec->capacity - vec->len; size_t available = vec->capacity - vec->len;
@ -198,12 +198,12 @@ bytevec_ensure_available(struct bytevec *vec, size_t n)
newdata = realloc(vec->data, newsize); newdata = realloc(vec->data, newsize);
if(newdata == NULL) { if(newdata == NULL) {
fprintf(stderr, "out of memory trying to get %zu bytes\n", newsize); fprintf(stderr, "out of memory trying to get %zu bytes\n", newsize);
return CRUSTLS_DEMO_ERROR; return DEMO_ERROR;
} }
vec->data = newdata; vec->data = newdata;
vec->capacity = newsize; vec->capacity = newsize;
} }
return CRUSTLS_DEMO_OK; return DEMO_OK;
} }
/** /**
@ -217,8 +217,8 @@ copy_plaintext_to_buffer(struct conndata *conn)
size_t n; size_t n;
struct rustls_connection *rconn = conn->rconn; struct rustls_connection *rconn = conn->rconn;
if(bytevec_ensure_available(&conn->data, 1024) != CRUSTLS_DEMO_OK) { if(bytevec_ensure_available(&conn->data, 1024) != DEMO_OK) {
return CRUSTLS_DEMO_ERROR; return DEMO_ERROR;
} }
for(;;) { for(;;) {
@ -227,23 +227,23 @@ copy_plaintext_to_buffer(struct conndata *conn)
result = rustls_connection_read(rconn, (uint8_t *)buf, avail, &n); result = rustls_connection_read(rconn, (uint8_t *)buf, avail, &n);
if(result == RUSTLS_RESULT_PLAINTEXT_EMPTY) { if(result == RUSTLS_RESULT_PLAINTEXT_EMPTY) {
/* This is expected. It just means "no more bytes for now." */ /* This is expected. It just means "no more bytes for now." */
return CRUSTLS_DEMO_OK; return DEMO_OK;
} }
if(result != RUSTLS_RESULT_OK) { if(result != RUSTLS_RESULT_OK) {
print_error(conn->program_name, "Error in rustls_connection_read", result); print_error(conn->program_name, "Error in rustls_connection_read", result);
return CRUSTLS_DEMO_ERROR; return DEMO_ERROR;
} }
if(n == 0) { if(n == 0) {
fprintf(stderr, "got 0-byte read, cleanly ending connection\n"); fprintf(stderr, "got 0-byte read, cleanly ending connection\n");
return CRUSTLS_DEMO_EOF; return DEMO_EOF;
} }
bytevec_consume(&conn->data, n); bytevec_consume(&conn->data, n);
if(bytevec_ensure_available(&conn->data, 1024) != CRUSTLS_DEMO_OK) { if(bytevec_ensure_available(&conn->data, 1024) != DEMO_OK) {
return CRUSTLS_DEMO_ERROR; return DEMO_ERROR;
} }
} }
return CRUSTLS_DEMO_ERROR; return DEMO_ERROR;
} }
/** /**
@ -352,4 +352,4 @@ log_cb(void *userdata, const struct rustls_log_params *params)
struct rustls_str level_str = rustls_log_level_str(params->level); struct rustls_str level_str = rustls_log_level_str(params->level);
fprintf(stderr, "%s[fd %d][%.*s]: %.*s\n", conn->program_name, conn->fd, fprintf(stderr, "%s[fd %d][%.*s]: %.*s\n", conn->program_name, conn->fd,
(int)level_str.len, level_str.data, (int)params->message.len, params->message.data); (int)level_str.len, level_str.data, (int)params->message.len, params->message.data);
} }

View file

@ -23,12 +23,12 @@ const char * ws_strerror(int err);
#endif /* !STDOUT_FILENO */ #endif /* !STDOUT_FILENO */
#endif /* _WIN32 */ #endif /* _WIN32 */
enum crustls_demo_result enum demo_result
{ {
CRUSTLS_DEMO_OK, DEMO_OK,
CRUSTLS_DEMO_ERROR, DEMO_ERROR,
CRUSTLS_DEMO_AGAIN, DEMO_AGAIN,
CRUSTLS_DEMO_EOF, DEMO_EOF,
}; };
/* A growable vector of bytes. */ /* A growable vector of bytes. */
@ -53,7 +53,7 @@ int
write_all(int fd, const char *buf, int n); write_all(int fd, const char *buf, int n);
/* Make a socket nonblocking. */ /* Make a socket nonblocking. */
enum crustls_demo_result enum demo_result
nonblock(int sockfd); nonblock(int sockfd);
/* A callback that reads bytes from the network. */ /* A callback that reads bytes from the network. */
@ -88,17 +88,17 @@ bytevec_consume(struct bytevec *vec, size_t n);
/* Ensure there are at least n bytes available between vec->len and /* Ensure there are at least n bytes available between vec->len and
* vec->capacity. If this requires reallocating, this may return * vec->capacity. If this requires reallocating, this may return
* CRUSTLS_DEMO_ERROR. */ * DEMO_ERROR. */
enum crustls_demo_result enum demo_result
bytevec_ensure_available(struct bytevec *vec, size_t n); bytevec_ensure_available(struct bytevec *vec, size_t n);
/* Read all available bytes from the rustls_connection until EOF. /* Read all available bytes from the rustls_connection until EOF.
* Note that EOF here indicates "no more bytes until * Note that EOF here indicates "no more bytes until
* process_new_packets", not "stream is closed". * process_new_packets", not "stream is closed".
* *
* Returns CRUSTLS_DEMO_OK for success, * Returns DEMO_OK for success,
* CRUSTLS_DEMO_ERROR for error, * DEMO_ERROR for error,
* CRUSTLS_DEMO_EOF for "connection cleanly terminated by peer" * DEMO_EOF for "connection cleanly terminated by peer"
*/ */
int int
copy_plaintext_to_buffer(struct conndata *conn); copy_plaintext_to_buffer(struct conndata *conn);
@ -125,4 +125,4 @@ get_first_header_value(const char *headers, size_t headers_len,
void void
log_cb(void *userdata, const struct rustls_log_params *params); log_cb(void *userdata, const struct rustls_log_params *params);
#endif /* COMMON_H */ #endif /* COMMON_H */

View file

@ -21,22 +21,18 @@ test:
tea.xyz/gx/cc: c99 tea.xyz/gx/cc: c99
openssl.org: '*' # needed for SSL_CERT_FILE openssl.org: '*' # needed for SSL_CERT_FILE
env: env:
LIBS: ARGS:
- -lrustls - -lrustls
- -lc
linux: linux:
LIBS: ARGS:
- -lgcc_s - -Wl,--gc-sections
- -lutil
- -lrt
- -lpthread - -lpthread
- -lm
- -ldl - -ldl
darwin: darwin:
LIBS: ARGS:
- -Wl,-dead_strip
- -framework Security - -framework Security
- -liconv - -framework Foundation
- -lSystem
script: | script: |
cc client.c common.c -o client $LIBS cc client.c common.c -o client $ARGS
CA_FILE=$SSL_CERT_FILE ./client tea.xyz 443 / CA_FILE=$SSL_CERT_FILE ./client tea.xyz 443 /