/*
* s_client command
*
* Copyright (C) 2019 Patrick McDermott
*
* This file is part of wolfssl-util.
*
* wolfssl-util is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfssl-util is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with wolfssl-util. If not, see .
*/
#include
#include
#include
#include
#include
#include
#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)
{
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;
}