diff options
-rw-r--r-- | src/s_client.c | 110 |
1 files changed, 109 insertions, 1 deletions
diff --git a/src/s_client.c b/src/s_client.c index 0bcb20c..7865a78 100644 --- a/src/s_client.c +++ b/src/s_client.c @@ -19,10 +19,118 @@ * along with wolfssl-util. If not, see <http://www.gnu.org/licenses/>. */ +#include <stdbool.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include <wolfssl/ssl.h> +#include <wolfssl/wolfcrypt/settings.h> + #include "commands.h" +#define CA_CERTS "/etc/ssl/certs" + +static _Bool +parse_host_port(char *hostport, char **host, char **port) +{ + *host = hostport; + /* XXX: Port is required. Otherwise, this will mangle IPv6 addresses + * without some more intelligent (and larger) code. */ + *port = strrchr(*host, ':'); + if (!*port) { + fputs("Port is required\n", stderr); + return false; + } + **port = '\0'; + ++*port; + + return true; +} + int s_client(int argc, char **argv) { - return 0; + char *host = NULL; + char *port = NULL; + const char *servername = NULL; + int ret = EXIT_SUCCESS; + WOLFSSL_METHOD *method; + WOLFSSL_CTX *ctx; + WOLFSSL *ssl; + + for (; argc > 0; --argc, ++argv) { + if (strcmp(*argv, "-quiet") == 0) { + /* No-op */ + } else if (strcmp(*argv, "-connect") == 0) { + --argc, ++argv; + if (parse_host_port(*argv, &host, &port) == false) { + return EXIT_FAILURE; + } + } else if (strcmp(*argv, "-servername") == 0) { + --argc, ++argv; + servername = *argv; + } else if (**argv == '-') { + fprintf(stderr, "Unsupported option \"%s\"\n", *argv); + } + } + + wolfSSL_Init(); + + method = wolfSSLv23_client_method(); + if (method == NULL) { + fputs("Out of memory\n", stderr); + ret = EXIT_FAILURE; + goto cleanup; + } + + ctx = wolfSSL_CTX_new(method); + if (ctx == NULL) { + fputs("Out of memory\n", stderr); + ret = EXIT_FAILURE; + goto cleanup; + } + + if (wolfSSL_CTX_load_verify_locations_ex(ctx, NULL, CA_CERTS, + WOLFSSL_LOAD_FLAG_IGNORE_ERR) != + WOLFSSL_SUCCESS) { + fputs("Failed to load CA certificates\n", stderr); + ret = EXIT_FAILURE; + goto ctx_free; + } + +#ifdef HAVE_OCSP + if (wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_CHECKALL) != + WOLFSSL_SUCCESS) { + fputs("Failed to enable OCSP\n", stderr); + goto ctx_free; + } +#endif +#ifdef HAVE_SNI + if (servername != NULL) { + if (wolfSSL_CTX_UseSNI(ctx, WOLFSSL_SNI_HOST_NAME, servername, + strlen(servername)) != WOLFSSL_SUCCESS){ + fputs("Out of memory\n", stderr); + ret = EXIT_FAILURE; + goto ctx_free; + } + } +#else + (void) servername; +#endif + + ssl = wolfSSL_new(ctx); + if (ssl == NULL) { + fputs("Out of memory\n", stderr); + ret = EXIT_FAILURE; + goto ctx_free; + } + + wolfSSL_free(ssl); +ctx_free: + wolfSSL_CTX_free(ctx); +cleanup: + wolfSSL_Cleanup(); + + return ret; } |