MatrixSSL 4.3.0
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
* Interactive client-side test tool.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2013-2018 INSIDE Secure Corporation
|
||||
* Copyright (c) 2013-2019 INSIDE Secure Corporation
|
||||
* Copyright (c) PeerSec Networks, 2002-2011
|
||||
* All Rights Reserved
|
||||
*
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "osdep.h"
|
||||
|
||||
# ifdef USE_CLIENT_SIDE_SSL
|
||||
# include "interactiveCommon.h"
|
||||
|
||||
# if defined(USE_TLS_1_2) && defined(USE_SECP256R1) && defined(USE_SHA256) && defined(USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) && defined(USE_IDENTITY_CERTIFICATES)
|
||||
|
||||
@@ -44,35 +45,23 @@
|
||||
# include <unistd.h>
|
||||
# include <limits.h>
|
||||
|
||||
/* Key material. */
|
||||
# include "testkeys/EC/256_EC.h"
|
||||
# include "testkeys/EC/256_EC_KEY.h"
|
||||
# include "testkeys/EC/256_EC_CA.h"
|
||||
# include "testkeys/RSA/2048_RSA.h"
|
||||
# include "testkeys/RSA/2048_RSA_KEY.h"
|
||||
# include "testkeys/RSA/3072_RSA.h"
|
||||
# include "testkeys/RSA/3072_RSA_KEY.h"
|
||||
# include "testkeys/RSA/ALL_RSA_CAS.h"
|
||||
# include "testkeys/EC/ALL_EC_CAS.h"
|
||||
# include "testkeys/PSK/tls13_psk.h"
|
||||
|
||||
# define SERVER_IP_ADDRESS "127.0.0.1"
|
||||
# define SERVER_PORT 4433
|
||||
|
||||
/* Do we expect the server to the first piece of app data? */
|
||||
static int g_server_sends_first;
|
||||
int g_server_sends_first;
|
||||
/* Use matrixSslEncodeToOutdata for encoding small app data? */
|
||||
static int g_encode_to_outdata;
|
||||
int g_encode_to_outdata;
|
||||
/* Already received MATRIXSSL_HANDSHAKE_COMPLETE? */
|
||||
static int g_handshake_complete;
|
||||
int g_handshake_complete;
|
||||
/* Skip server authentication entirely? */
|
||||
static psBool_t g_skip_server_auth;
|
||||
psBool_t g_skip_server_auth;
|
||||
|
||||
static size_t leftNBytes;
|
||||
static size_t sentNBytes;
|
||||
size_t leftNBytes;
|
||||
size_t sentNBytes;
|
||||
|
||||
/* HTTP GET request header. */
|
||||
static unsigned char g_httpRequestHdr[] = "GET %s HTTP/1.1\r\n"
|
||||
unsigned char g_httpRequestHdr[] = "GET %s HTTP/1.1\r\n"
|
||||
"Host: %s\r\n"
|
||||
"User-Agent: MatrixSSL/" MATRIXSSL_VERSION "\r\n"
|
||||
"Accept: */*\r\n"
|
||||
@@ -94,871 +83,6 @@ static int32_t certCb(ssl_t *ssl, psX509Cert_t *cert, int32_t alert)
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns a line of user input (without the newline character),
|
||||
or < 0 on error. The returned string may be truncated if it
|
||||
did not fit into buf. */
|
||||
int get_user_input(char *buf, int buf_len)
|
||||
{
|
||||
char *s, *p;
|
||||
char c;
|
||||
|
||||
s = fgets(buf, buf_len, stdin);
|
||||
if (s == NULL)
|
||||
{
|
||||
return PS_FAILURE;
|
||||
}
|
||||
|
||||
p = strchr(buf, '\n');
|
||||
if (p)
|
||||
{
|
||||
*p = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Flush stdin up to newline or EOF. */
|
||||
c = getchar();
|
||||
while (c != '\n' && !feof(stdin) && !ferror(stdin))
|
||||
{
|
||||
c = getchar();
|
||||
}
|
||||
}
|
||||
|
||||
//printf("Got: %s (len: %zu)\n", buf, strlen(buf));
|
||||
|
||||
return PS_SUCCESS;
|
||||
}
|
||||
|
||||
int get_user_input_char(char *c, char defaultChoice)
|
||||
{
|
||||
char buf[2] = {0};
|
||||
size_t buf_len = sizeof(buf);
|
||||
int rc;
|
||||
|
||||
rc = get_user_input(buf, buf_len);
|
||||
if (rc < 0)
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (Strlen(buf) == 0)
|
||||
{
|
||||
*c = defaultChoice;
|
||||
}
|
||||
else
|
||||
{
|
||||
*c = buf[0];
|
||||
}
|
||||
|
||||
return PS_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t getAppDataFromUser(ssl_t *ssl,
|
||||
unsigned char *data,
|
||||
size_t *dataLen)
|
||||
{
|
||||
int rc;
|
||||
char buf[1024] = {0};
|
||||
size_t buf_len = sizeof(buf);
|
||||
size_t max_len;
|
||||
|
||||
max_len = buf_len;
|
||||
if (*dataLen < buf_len && *dataLen < INT_MAX)
|
||||
{
|
||||
max_len = *dataLen;
|
||||
}
|
||||
|
||||
rc = get_user_input(buf, (int)max_len);
|
||||
if (rc < 0)
|
||||
{
|
||||
printf("Failed to get user input\n");
|
||||
return PS_FAILURE;
|
||||
}
|
||||
|
||||
Memcpy(data, buf, Strlen(buf) + 1);
|
||||
*dataLen = Strlen(buf) + 1;
|
||||
|
||||
return PS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
Ask the for app data to send over the encrypted connection,
|
||||
or for some other action.
|
||||
Return value:
|
||||
< 0 on error,
|
||||
PS_SUCCESS for nominal connection closure
|
||||
MATRIXSSL_REQUEST_SEND to send app data.
|
||||
*/
|
||||
static int32_t askSendAppData(ssl_t *ssl)
|
||||
{
|
||||
int32_t rc;
|
||||
unsigned char *buf;
|
||||
unsigned char data[1024] = {0};
|
||||
size_t dataLen = sizeof(data);
|
||||
size_t sendNBytes;
|
||||
static unsigned char *fileData = NULL;
|
||||
unsigned char *pData;
|
||||
const char *s;
|
||||
|
||||
if (leftNBytes > 0)
|
||||
{
|
||||
pData = fileData;
|
||||
goto continue_sending;
|
||||
}
|
||||
|
||||
printf("You: ");
|
||||
rc = getAppDataFromUser(ssl, data, &dataLen);
|
||||
if (rc < 0)
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (data[0] == ':')
|
||||
{
|
||||
/* Handle commands. */
|
||||
|
||||
/* Handle :quit, :exit and :q */
|
||||
s = (char*)&data[1];
|
||||
if (!Strncmp(s, "quit", strlen("quit"))
|
||||
|| !Strncmp(s, "exit", strlen("exit"))
|
||||
|| (dataLen == 2 && data[1] == 'q'))
|
||||
{
|
||||
rc = matrixSslEncodeClosureAlert(ssl);
|
||||
(void)rc;
|
||||
return PS_SUCCESS;
|
||||
}
|
||||
if (!Strncmp(s, "file", strlen("file")))
|
||||
{
|
||||
# ifdef MATRIX_USE_FILE_SYSTEM
|
||||
printf("Enter file name: ");
|
||||
dataLen = sizeof(data);
|
||||
rc = getAppDataFromUser(ssl, data, &dataLen);
|
||||
if (rc < 0)
|
||||
{
|
||||
goto out_fail;
|
||||
}
|
||||
rc = psGetFileBuf(NULL, (char*)data, &fileData, &dataLen);
|
||||
if (rc < 0)
|
||||
{
|
||||
printf("Unable to open file\n");
|
||||
sprintf((char*)data, "%s", "[I tried to send a file, but failed]");
|
||||
}
|
||||
# else
|
||||
printf("Need MATRIX_USE_FILE_SYSTEM for this\n");
|
||||
rc = PS_UNSUPPORTED_FAIL;
|
||||
goto out_fail;
|
||||
# endif /* MATRIX_USE_FILE_SYSTEM */
|
||||
}
|
||||
if (!Strncmp(s, "url", strlen("url")))
|
||||
{
|
||||
unsigned char url[sizeof(data)] = {0};
|
||||
int n;
|
||||
|
||||
printf("Enter URL to GET: ");
|
||||
dataLen = sizeof(url);
|
||||
rc = getAppDataFromUser(ssl, url, &dataLen);
|
||||
if (rc < 0)
|
||||
{
|
||||
goto out_fail;
|
||||
}
|
||||
n = Snprintf((char*)data,
|
||||
sizeof(data),
|
||||
(char*)g_httpRequestHdr,
|
||||
(char*)url,
|
||||
"localhost");
|
||||
dataLen = n + 1;
|
||||
printf("Sending: %s (len: %zu)\n", data, dataLen);
|
||||
}
|
||||
}
|
||||
|
||||
if (fileData != NULL)
|
||||
{
|
||||
pData = fileData;
|
||||
}
|
||||
else
|
||||
{
|
||||
pData = data;
|
||||
}
|
||||
|
||||
leftNBytes = dataLen;
|
||||
sentNBytes = 0;
|
||||
|
||||
continue_sending:
|
||||
/* Get pointer to the internal plaintext buffer and fill
|
||||
it with the plaintext data. The returned buffer may
|
||||
be smaller, in which case we'll come back here to
|
||||
continue on next call. */
|
||||
if (g_encode_to_outdata && leftNBytes < 16384)
|
||||
{
|
||||
rc = matrixSslEncodeToOutdata(ssl, pData, leftNBytes);
|
||||
if (rc < 0)
|
||||
{
|
||||
printf("matrixSslEncodeToOutdata failed: %d\n", rc);
|
||||
goto out_fail;
|
||||
}
|
||||
leftNBytes = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = matrixSslGetWritebuf(ssl, &buf, leftNBytes);
|
||||
if (rc < 0)
|
||||
{
|
||||
rc = PS_FAILURE;
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
if (rc < leftNBytes)
|
||||
{
|
||||
sendNBytes = rc;
|
||||
}
|
||||
else
|
||||
{
|
||||
sendNBytes = leftNBytes;
|
||||
}
|
||||
|
||||
memcpy(buf, pData, sendNBytes);
|
||||
sentNBytes += sendNBytes;
|
||||
leftNBytes -= sendNBytes;
|
||||
|
||||
printf("Sent %zu/%zu bytes\n", sentNBytes, sentNBytes + leftNBytes);
|
||||
|
||||
/* Encrypt. */
|
||||
rc = matrixSslEncodeWritebuf(ssl, sendNBytes);
|
||||
if (rc < 0)
|
||||
{
|
||||
rc = PS_FAILURE;
|
||||
goto out_fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* Ask the main loop to send it over the wire. */
|
||||
rc = MATRIXSSL_REQUEST_SEND;
|
||||
|
||||
out_fail:
|
||||
if (fileData != NULL)
|
||||
{
|
||||
if (leftNBytes == 0)
|
||||
{
|
||||
psFree(fileData, NULL);
|
||||
fileData = NULL;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
psRes_t getUserProtocolVersion(psProtocolVersion_t *verOut)
|
||||
{
|
||||
const char *proto_ver_prompt =
|
||||
"Select protocol version to use:\n" \
|
||||
"(4) TLS 1.3 (default)\n" \
|
||||
"(3) TLS 1.2\n" \
|
||||
"(2) TLS 1.1\n" \
|
||||
"(1) TLS 1.0\n";
|
||||
char c;
|
||||
psProtocolVersion_t v;
|
||||
int got_it = 0;
|
||||
int rc;
|
||||
|
||||
printf("%s", proto_ver_prompt);
|
||||
|
||||
while (got_it == 0)
|
||||
{
|
||||
rc = get_user_input_char(&c, '4');
|
||||
if (rc < 0)
|
||||
{
|
||||
printf("getUserProtocolVersion failed\n");
|
||||
return PS_FAILURE;
|
||||
}
|
||||
got_it = 1;
|
||||
switch (c)
|
||||
{
|
||||
case '4':
|
||||
v = v_tls_1_3;
|
||||
break;
|
||||
case '3':
|
||||
v = v_tls_1_2;
|
||||
break;
|
||||
case '2':
|
||||
v = v_tls_1_1;
|
||||
break;
|
||||
case '1':
|
||||
v = v_tls_1_0;
|
||||
break;
|
||||
case 'q':
|
||||
return PS_FAILURE;
|
||||
default:
|
||||
printf("Invalid choice: %c\n", c);
|
||||
got_it = 0;
|
||||
}
|
||||
}
|
||||
|
||||
*verOut = v;
|
||||
|
||||
return PS_SUCCESS;
|
||||
}
|
||||
|
||||
psRes_t getUserKeyPair(const unsigned char **cert,
|
||||
int32_t *certLen,
|
||||
const unsigned char **key,
|
||||
int32_t *keyLen,
|
||||
int32_t *keyType,
|
||||
int32_t *pskLen)
|
||||
{
|
||||
const char *key_prompt =
|
||||
"Select authentication key pair to use:\n" \
|
||||
"(1) P-256 ECDSA (default)\n" \
|
||||
"(2) 2048-bit RSA\n" \
|
||||
"(3) 3072-bit RSA\n" \
|
||||
"(4) PSK (32 bytes)\n" \
|
||||
"(5) PSK (48 bytes)\n";
|
||||
char c;
|
||||
int got_it = 0;
|
||||
int rc;
|
||||
|
||||
/* Default keys. */
|
||||
*cert = EC256;
|
||||
*certLen = EC256_SIZE;
|
||||
*key = EC256KEY;
|
||||
*keyLen = EC256KEY_SIZE;
|
||||
*keyType = PS_ECC;
|
||||
*pskLen = 0;
|
||||
|
||||
printf("%s", key_prompt);
|
||||
|
||||
while (got_it == 0)
|
||||
{
|
||||
rc = get_user_input_char(&c, '1');
|
||||
if (rc < 0)
|
||||
{
|
||||
printf("getUserKeyPair failed\n");
|
||||
return PS_FAILURE;
|
||||
}
|
||||
got_it = 1;
|
||||
switch (c)
|
||||
{
|
||||
case '1':
|
||||
/* Use defaults from above. */
|
||||
break;
|
||||
case '2':
|
||||
*cert = RSA2048;
|
||||
*certLen = RSA2048_SIZE;
|
||||
*key = RSA2048KEY;
|
||||
*keyLen = RSA2048KEY_SIZE;
|
||||
*keyType = PS_RSA;
|
||||
break;
|
||||
case '3':
|
||||
*cert = RSA3072;
|
||||
*certLen = RSA3072_SIZE;
|
||||
*key = RSA3072KEY;
|
||||
*keyLen = RSA3072KEY_SIZE;
|
||||
*keyType = PS_RSA;
|
||||
break;
|
||||
case '4':
|
||||
*pskLen = 32;
|
||||
/* Load default keys in addition to the PSK. */
|
||||
break;
|
||||
case '5':
|
||||
*pskLen = 48;
|
||||
/* Load default keys in addition to the PSK. */
|
||||
break;
|
||||
case 'q':
|
||||
return PS_FAILURE;
|
||||
default:
|
||||
printf("Invalid choice: %c\n", c);
|
||||
got_it = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return PS_SUCCESS;
|
||||
}
|
||||
|
||||
int load_keys(sslKeys_t *keys)
|
||||
{
|
||||
const unsigned char *key, *cert;
|
||||
int32_t keyLen, certLen;
|
||||
int32_t keyType;
|
||||
const unsigned char *psk;
|
||||
const unsigned char *psk_id;
|
||||
psSize_t psk_id_len;
|
||||
int32_t pskLen;
|
||||
int rc;
|
||||
matrixSslLoadKeysOpts_t keyOpts;
|
||||
|
||||
rc = getUserKeyPair(&key, &keyLen, &cert, &certLen, &keyType, &pskLen);
|
||||
if (rc < 0)
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
Memset(&keyOpts, 0, sizeof(keyOpts));
|
||||
keyOpts.key_type = keyType;
|
||||
|
||||
# ifdef USE_TLS_1_3
|
||||
if (pskLen > 0)
|
||||
{
|
||||
if (pskLen == 32)
|
||||
{
|
||||
psk = g_tls13_test_psk_256;
|
||||
psk_id = g_tls13_test_psk_id_sha256;
|
||||
psk_id_len = sizeof(g_tls13_test_psk_id_sha256);
|
||||
}
|
||||
else if (pskLen == 48)
|
||||
{
|
||||
psk = g_tls13_test_psk_384;
|
||||
psk_id = g_tls13_test_psk_id_sha384;
|
||||
psk_id_len = sizeof(g_tls13_test_psk_id_sha384);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Invalid PSK length\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
rc = matrixSslLoadTls13Psk(
|
||||
keys,
|
||||
psk,
|
||||
pskLen,
|
||||
psk_id,
|
||||
psk_id_len,
|
||||
NULL);
|
||||
if (rc < 0)
|
||||
{
|
||||
printf("matrixSslLoadTls13Psk failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
rc = matrixSslLoadKeysMem(
|
||||
keys,
|
||||
key,
|
||||
keyLen,
|
||||
cert,
|
||||
certLen,
|
||||
RSACAS,
|
||||
sizeof(RSACAS),
|
||||
&keyOpts);
|
||||
if (rc < 0)
|
||||
{
|
||||
printf("matrixSslLoadKeysMem failed for key pair: %d\n", rc);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (keyType == PS_ECC)
|
||||
{
|
||||
rc = matrixSslLoadKeysMem(
|
||||
keys,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
ECCAS,
|
||||
sizeof(ECCAS),
|
||||
&keyOpts);
|
||||
if (rc < 0)
|
||||
{
|
||||
printf("matrixSslLoadKeysMem failed for ECC CAs: %d\n", rc);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return PS_SUCCESS;
|
||||
}
|
||||
|
||||
psRes_t getUserFirstSender(void)
|
||||
{
|
||||
const char *get_first_sender_prompt =
|
||||
"Who will send app data first?\n" \
|
||||
"(1) client (default)\n" \
|
||||
"(2) server\n";
|
||||
int rc;
|
||||
char c;
|
||||
int got_it = 0;
|
||||
|
||||
printf("%s", get_first_sender_prompt);
|
||||
while (got_it == 0)
|
||||
{
|
||||
rc = get_user_input_char(&c, '1');
|
||||
if (rc < 0)
|
||||
{
|
||||
printf("getUserFirstSender failed\n");
|
||||
return PS_FAILURE;
|
||||
}
|
||||
got_it = 1;
|
||||
switch (c)
|
||||
{
|
||||
case '1':
|
||||
g_server_sends_first = 0;
|
||||
break;
|
||||
case '2':
|
||||
g_server_sends_first = 1;
|
||||
break;
|
||||
case 'q':
|
||||
return PS_FAILURE;
|
||||
default:
|
||||
printf("Invalid choice: %c\n", c);
|
||||
got_it = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return PS_SUCCESS;
|
||||
}
|
||||
|
||||
psRes_t getEncodingFunc(void)
|
||||
{
|
||||
const char *get_encoding_func_prompt =
|
||||
"Use matrixSslEncodeToOutdata for small <16KB application data?\n" \
|
||||
"(1) no (default)\n" \
|
||||
"(2) yes\n";
|
||||
int rc;
|
||||
char c;
|
||||
int got_it = 0;
|
||||
|
||||
printf("%s", get_encoding_func_prompt);
|
||||
while (got_it == 0)
|
||||
{
|
||||
rc = get_user_input_char(&c, '1');
|
||||
if (rc < 0)
|
||||
{
|
||||
printf("getUserFirstSender failed\n");
|
||||
return PS_FAILURE;
|
||||
}
|
||||
got_it = 1;
|
||||
switch (c)
|
||||
{
|
||||
case '1':
|
||||
g_encode_to_outdata = 0;
|
||||
break;
|
||||
case '2':
|
||||
g_encode_to_outdata = 1;
|
||||
break;
|
||||
case 'q':
|
||||
return PS_FAILURE;
|
||||
default:
|
||||
printf("Invalid choice: %c\n", c);
|
||||
got_it = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return PS_SUCCESS;
|
||||
}
|
||||
|
||||
psRes_t getUserSigAlgs(uint16_t *sigAlgs, psSize_t *numSigAlgs)
|
||||
{
|
||||
const char *sig_algs_prompt =
|
||||
"Signature algorithms to use:\n" \
|
||||
"(1) sigalg_ecdsa_secp256r1_sha256 (default)\n" \
|
||||
"(2) sigalg_rsa_pss_rsae_sha256\n" \
|
||||
"(3) sigalg_rsa_pkcs1_sha256\n";
|
||||
|
||||
int rc;
|
||||
char c;
|
||||
int got_it = 0;
|
||||
psSize_t i = 0;
|
||||
|
||||
printf("%s", sig_algs_prompt);
|
||||
while (got_it == 0)
|
||||
{
|
||||
rc = get_user_input_char(&c, '1');
|
||||
if (rc < 0)
|
||||
{
|
||||
printf("getUserSigAlgs failed\n");
|
||||
return PS_FAILURE;
|
||||
}
|
||||
got_it = 1;
|
||||
switch (c)
|
||||
{
|
||||
case '1':
|
||||
sigAlgs[i++] = sigalg_ecdsa_secp256r1_sha256;
|
||||
break;
|
||||
case '2':
|
||||
sigAlgs[i++] = sigalg_rsa_pss_rsae_sha256;
|
||||
break;
|
||||
case '3':
|
||||
sigAlgs[i++] = sigalg_rsa_pkcs1_sha256;
|
||||
break;
|
||||
case 'q':
|
||||
return PS_FAILURE;
|
||||
default:
|
||||
printf("Invalid choice: %c\n", c);
|
||||
got_it = 0;
|
||||
}
|
||||
}
|
||||
|
||||
*numSigAlgs = i;
|
||||
|
||||
return PS_SUCCESS;
|
||||
}
|
||||
|
||||
psRes_t getUserCiphersuites(psCipher16_t *ciphersuites,
|
||||
psSize_t *numCiphersuites)
|
||||
{
|
||||
static const char *ciphersuites_prompt =
|
||||
"Ciphersuite to use:\n" \
|
||||
"(1) TLS_AES_128_GCM_SHA256 (default)\n" \
|
||||
"(2) TLS_AES_256_GCM_SHA384\n" \
|
||||
"(3) TLS_CHACHA20_POLY1305_SHA256\n" \
|
||||
"(4) TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256\n" \
|
||||
"(5) TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256\n" \
|
||||
"(6) TLS_RSA_WITH_AES_128_GCM_SHA256\n" \
|
||||
"(7) All TLS 1.3 suites (prefer SHA256)\n" \
|
||||
"(8) All TLS 1.3 suites (prefer SHA384)\n";
|
||||
int rc;
|
||||
char c;
|
||||
int got_it = 0;
|
||||
psSize_t i = 0;
|
||||
|
||||
printf("%s", ciphersuites_prompt);
|
||||
while (got_it == 0)
|
||||
{
|
||||
rc = get_user_input_char(&c, '1');
|
||||
if (rc < 0)
|
||||
{
|
||||
printf("getUserCiphersuites failed\n");
|
||||
return PS_FAILURE;
|
||||
}
|
||||
got_it = 1;
|
||||
switch (c)
|
||||
{
|
||||
case '1':
|
||||
ciphersuites[i++] = TLS_AES_128_GCM_SHA256;
|
||||
break;
|
||||
case '2':
|
||||
ciphersuites[i++] = TLS_AES_256_GCM_SHA384;
|
||||
break;
|
||||
case '3':
|
||||
ciphersuites[i++] = TLS_CHACHA20_POLY1305_SHA256;
|
||||
break;
|
||||
case '4':
|
||||
ciphersuites[i++] = TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256;
|
||||
break;
|
||||
case '5':
|
||||
ciphersuites[i++] = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256;
|
||||
break;
|
||||
case '6':
|
||||
ciphersuites[i++] = TLS_RSA_WITH_AES_128_GCM_SHA256;
|
||||
break;
|
||||
case '7':
|
||||
ciphersuites[i++] = TLS_AES_128_GCM_SHA256;
|
||||
ciphersuites[i++] = TLS_AES_256_GCM_SHA384;
|
||||
ciphersuites[i++] = TLS_CHACHA20_POLY1305_SHA256;
|
||||
break;
|
||||
case '8':
|
||||
ciphersuites[i++] = TLS_AES_256_GCM_SHA384;
|
||||
ciphersuites[i++] = TLS_AES_128_GCM_SHA256;
|
||||
ciphersuites[i++] = TLS_CHACHA20_POLY1305_SHA256;
|
||||
break;
|
||||
case 'q':
|
||||
return PS_FAILURE;
|
||||
default:
|
||||
printf("Invalid choice: %c\n", c);
|
||||
got_it = 0;
|
||||
}
|
||||
}
|
||||
|
||||
*numCiphersuites = i;
|
||||
|
||||
return PS_SUCCESS;
|
||||
}
|
||||
|
||||
psRes_t getMaximumFragmentLength(short *maxFragLen)
|
||||
{
|
||||
const char *max_frag_len_prompt =
|
||||
"Maximum fragment length\n" \
|
||||
"(1) none (default)\n" \
|
||||
"(2) 512\n" \
|
||||
"(3) 1024\n" \
|
||||
"(4) 2048\n" \
|
||||
"(5) 4096\n";
|
||||
int rc;
|
||||
char c;
|
||||
int got_it = 0;
|
||||
|
||||
printf("%s", max_frag_len_prompt);
|
||||
while (got_it == 0)
|
||||
{
|
||||
rc = get_user_input_char(&c, '1');
|
||||
if (rc < 0)
|
||||
{
|
||||
printf("getMaximumFragmentLength failed\n");
|
||||
return PS_FAILURE;
|
||||
}
|
||||
got_it = 1;
|
||||
switch (c)
|
||||
{
|
||||
case '1':
|
||||
*maxFragLen = 0;
|
||||
break;
|
||||
case '2':
|
||||
*maxFragLen = 512;
|
||||
break;
|
||||
case '3':
|
||||
*maxFragLen = 1024;
|
||||
break;
|
||||
case '4':
|
||||
*maxFragLen = 2048;
|
||||
break;
|
||||
case '5':
|
||||
*maxFragLen = 4096;
|
||||
break;
|
||||
default:
|
||||
printf("Invalid choice: %c\n", c);
|
||||
got_it = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return PS_SUCCESS;
|
||||
}
|
||||
|
||||
psRes_t getServerAddress(char *addr_out, int *addr_out_len)
|
||||
{
|
||||
const char *server_address_prompt =
|
||||
"Server IP address (default 127.0.0.1):\n";
|
||||
char addr[40];
|
||||
int addr_len = (int)sizeof(addr);
|
||||
const char *addr_default = "127.0.0.1";
|
||||
int rc;
|
||||
|
||||
printf("%s", server_address_prompt);
|
||||
rc = get_user_input(addr, addr_len);
|
||||
if (rc < 0)
|
||||
{
|
||||
return PS_FAILURE;
|
||||
}
|
||||
|
||||
if (Strlen(addr) == 0)
|
||||
{
|
||||
Strncpy(addr_out, addr_default, 39);
|
||||
}
|
||||
else
|
||||
{
|
||||
Strncpy(addr_out, addr, 39);
|
||||
}
|
||||
|
||||
*addr_out_len = strlen(addr);
|
||||
|
||||
return PS_SUCCESS;
|
||||
}
|
||||
|
||||
psRes_t getServerPort(int *port_out)
|
||||
{
|
||||
const char *server_port_prompt =
|
||||
"Server port (default: 4433)\n";
|
||||
char buf[6];
|
||||
int buf_len = sizeof(buf);
|
||||
long int port;
|
||||
char *end;
|
||||
int got_it = 0;
|
||||
int rc;
|
||||
|
||||
printf("%s", server_port_prompt);
|
||||
|
||||
while (got_it == 0)
|
||||
{
|
||||
rc = get_user_input(buf, buf_len);
|
||||
if (rc < 0)
|
||||
{
|
||||
return PS_FAILURE;
|
||||
}
|
||||
got_it = 1;
|
||||
port = Strtol(buf, &end, 10);
|
||||
if (port < 0 || port > 65536)
|
||||
{
|
||||
printf("Invalid port\n");
|
||||
got_it = 0;
|
||||
}
|
||||
if (buf == end)
|
||||
{
|
||||
port = 4433;
|
||||
}
|
||||
}
|
||||
|
||||
*port_out = port;
|
||||
return PS_SUCCESS;
|
||||
}
|
||||
|
||||
psRes_t getServerName(
|
||||
char *name_out,
|
||||
int name_out_len,
|
||||
char *ip_addr)
|
||||
{
|
||||
const char *server_name_prompt_fmt =
|
||||
"Server name (default: %s)\n";
|
||||
char server_name_prompt[256];
|
||||
char buf[256];
|
||||
int buf_len = sizeof(buf);
|
||||
int got_it = 0;
|
||||
int rc;
|
||||
|
||||
/* Default name = previously selected IP address. */
|
||||
snprintf(server_name_prompt,
|
||||
256,
|
||||
server_name_prompt_fmt,
|
||||
ip_addr);
|
||||
printf("%s", server_name_prompt);
|
||||
|
||||
while (got_it == 0)
|
||||
{
|
||||
rc = get_user_input(buf, buf_len);
|
||||
if (rc < 0)
|
||||
{
|
||||
return PS_FAILURE;
|
||||
}
|
||||
got_it = 1;
|
||||
}
|
||||
|
||||
if (Strlen(buf) == 0)
|
||||
{
|
||||
if (name_out_len < Strlen(ip_addr))
|
||||
{
|
||||
printf("Default server name won't fit into output buffer\n");
|
||||
return PS_FAILURE;
|
||||
}
|
||||
Strncpy(name_out, ip_addr, name_out_len - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
Strncpy(name_out, buf, buf_len - 1);
|
||||
}
|
||||
|
||||
return PS_SUCCESS;
|
||||
}
|
||||
|
||||
psRes_t getAllowAnon(psBool_t *allow)
|
||||
{
|
||||
const char *allow_anon_prompt =
|
||||
"Skip server authentication?\n" \
|
||||
"(1) no (default)\n" \
|
||||
"(2) yes\n";
|
||||
int rc;
|
||||
char c;
|
||||
int got_it = 0;
|
||||
|
||||
printf("%s", allow_anon_prompt);
|
||||
while (got_it == 0)
|
||||
{
|
||||
rc = get_user_input_char(&c, '1');
|
||||
if (rc < 0)
|
||||
{
|
||||
printf("getAllowAnon failed\n");
|
||||
return PS_FAILURE;
|
||||
}
|
||||
got_it = 1;
|
||||
switch (c)
|
||||
{
|
||||
case '1':
|
||||
*allow = PS_FALSE;
|
||||
break;
|
||||
case '2':
|
||||
*allow = PS_TRUE;
|
||||
break;
|
||||
default:
|
||||
printf("Invalid choice: %c\n", c);
|
||||
got_it = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return PS_SUCCESS;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
uint16_t sigAlgs[16];
|
||||
|
||||
Reference in New Issue
Block a user