Public key authentication

1. Cleanup some debug printouts.
2. Add option to the echoserver and wolfSFTP client to use ECC keys or RSA
keys for user authentication.
3. Add option to the echoserver to use ECC keys for peer authentication.

Note, the user authentication type is still hardcoded in the library as
password. To use public key, need to update the authId in
SendUserAuthFailure().
pull/169/head
John Safranek 2019-06-06 11:59:35 -07:00
parent d755132ccf
commit 56616d3416
4 changed files with 79 additions and 31 deletions

View File

@ -184,7 +184,7 @@ static int wsUserAuth(byte authType,
}
}
else if (authType == WOLFSSH_USERAUTH_PUBLICKEY) {
fprintf(stderr, "username = %p\n", authData->username);
ret = WOLFSSH_USERAUTH_INVALID_AUTHTYPE;
}
return ret;
@ -193,10 +193,16 @@ static int wsUserAuth(byte authType,
static int wsPublicKeyCheck(const byte* pubKey, word32 pubKeySz, void* ctx)
{
printf("Sample public key check callback\n"
" public key = %p\n"
" public key size = %u\n"
" ctx = %s\n", pubKey, pubKeySz, (const char*)ctx);
#ifdef DEBUG_WOLFSSH
printf("Sample public key check callback\n"
" public key = %p\n"
" public key size = %u\n"
" ctx = %s\n", pubKey, pubKeySz, (const char*)ctx);
#else
(void)pubKey;
(void)pubKeySz;
(void)ctx;
#endif
return 0;
}
@ -525,10 +531,8 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args)
ret = wolfSSH_connect(ssh);
else
ret = NonBlockSSH_connect(ssh);
if (ret != WS_SUCCESS) {
printf("err = %s\n", wolfSSH_get_error_name(ssh));
if (ret != WS_SUCCESS)
err_sys("Couldn't connect SSH stream.");
}
#if !defined(SINGLE_THREADED) && !defined(WOLFSSL_NUCLEUS)
if (keepOpen) /* set up for psuedo-terminal */

View File

@ -720,7 +720,8 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
word32 defaultHighwater = EXAMPLE_HIGHWATER_MARK;
word32 threadCount = 0;
int multipleConnections = 1;
int useEcc = 0;
int userEcc = 0;
int peerEcc = 0;
int ch;
word16 port = wolfSshPort;
char* readyFile = NULL;
@ -732,7 +733,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
serverArgs->return_code = 0;
if (argc > 0) {
while ((ch = mygetopt(argc, argv, "?1d:ep:R:N")) != -1) {
while ((ch = mygetopt(argc, argv, "?1d:eEp:R:N")) != -1) {
switch (ch) {
case '?' :
ShowUsage();
@ -743,7 +744,11 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
break;
case 'e' :
useEcc = 1;
userEcc = 1;
break;
case 'E':
peerEcc = 1;
break;
case 'p':
@ -804,7 +809,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
byte buf[SCRATCH_BUFFER_SZ];
word32 bufSz;
bufSz = load_key(useEcc, buf, SCRATCH_BUFFER_SZ);
bufSz = load_key(peerEcc, buf, SCRATCH_BUFFER_SZ);
if (bufSz == 0) {
fprintf(stderr, "Couldn't load key file.\n");
exit(EXIT_FAILURE);
@ -820,8 +825,8 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
buf[bufSz] = 0;
LoadPasswordBuffer(buf, bufSz, &pwMapList);
bufName = useEcc ? samplePublicKeyEccBuffer :
samplePublicKeyRsaBuffer;
bufName = userEcc ? samplePublicKeyEccBuffer :
samplePublicKeyRsaBuffer;
bufSz = (word32)strlen(bufName);
memcpy(buf, bufName, bufSz);
buf[bufSz] = 0;

View File

@ -280,6 +280,8 @@ static void ShowUsage(void)
printf(" -P <password> password for username, prompted if omitted\n");
printf(" -d <path> set the default local path\n");
printf(" -N use non blocking sockets\n");
printf(" -e use ECC user authentication\n");
/*printf(" -E use ECC server authentication\n");*/
ShowCommands();
}
@ -289,6 +291,8 @@ byte userPassword[256];
byte userPublicKeyType[32];
byte userPublicKey[512];
word32 userPublicKeySz;
const byte* userPrivateKey;
word32 userPrivateKeySz;
const char hanselPublicRsa[] =
"AAAAB3NzaC1yc2EAAAADAQABAAABAQC9P3ZFowOsONXHD5MwWiCciXytBRZGho"
@ -443,7 +447,8 @@ static int wsUserAuth(byte authType,
else {
printf("Password: ");
SetEcho(0);
if (WFGETS((char*)userPassword, sizeof(userPassword), stdin) == NULL) {
if (WFGETS((char*)userPassword, sizeof(userPassword),
stdin) == NULL) {
printf("Getting password failed.\n");
ret = WOLFSSH_USERAUTH_FAILURE;
}
@ -467,20 +472,12 @@ static int wsUserAuth(byte authType,
else if (authType == WOLFSSH_USERAUTH_PUBLICKEY) {
WS_UserAuthData_PublicKey* pk = &authData->sf.publicKey;
userPublicKeySz = (word32)sizeof(userPublicKey);
Base64_Decode((byte*)hanselPublicRsa,
(word32)WSTRLEN(hanselPublicRsa),
(byte*)userPublicKey, &userPublicKeySz);
strncpy((char*)userPublicKeyType, "ssh-rsa",
sizeof(userPublicKeyType));
pk->publicKeyType = userPublicKeyType;
pk->publicKeyTypeSz = (word32)WSTRLEN((char*)userPublicKeyType);
pk->publicKey = userPublicKey;
pk->publicKeySz = userPublicKeySz;
pk->privateKey = hanselPrivateRsa;
pk->privateKeySz = hanselPrivateRsaSz;
pk->privateKey = userPrivateKey;
pk->privateKeySz = userPrivateKeySz;
ret = WOLFSSH_USERAUTH_SUCCESS;
}
@ -490,10 +487,16 @@ static int wsUserAuth(byte authType,
static int wsPublicKeyCheck(const byte* pubKey, word32 pubKeySz, void* ctx)
{
printf("Sample public key check callback\n"
" public key = %p\n"
" public key size = %u\n"
" ctx = %s\n", pubKey, pubKeySz, (const char*)ctx);
#ifdef DEBUG_WOLFSSH
printf("Sample public key check callback\n"
" public key = %p\n"
" public key size = %u\n"
" ctx = %s\n", pubKey, pubKeySz, (const char*)ctx);
#else
(void)pubKey;
(void)pubKeySz;
(void)ctx;
#endif
return 0;
}
@ -1146,6 +1149,8 @@ THREAD_RETURN WOLFSSH_THREAD sftpclient_test(void* args)
socklen_t clientAddrSz = sizeof(clientAddr);
int ret;
int ch;
int userEcc = 0;
/* int peerEcc = 0; */
word16 port = wolfSshPort;
char* host = (char*)wolfSshIp;
const char* username = NULL;
@ -1157,12 +1162,22 @@ THREAD_RETURN WOLFSSH_THREAD sftpclient_test(void* args)
char** argv = ((func_args*)args)->argv;
((func_args*)args)->return_code = 0;
while ((ch = mygetopt(argc, argv, "?d:h:p:u:P:N")) != -1) {
while ((ch = mygetopt(argc, argv, "?d:eEh:p:u:P:N")) != -1) {
switch (ch) {
case 'd':
defaultSftpPath = myoptarg;
break;
case 'e':
userEcc = 1;
break;
case 'E':
/* peerEcc = 1; */
err_sys("wolfSFTP ECC server authentication "
"not yet supported.");
break;
case 'h':
host = myoptarg;
break;
@ -1208,6 +1223,29 @@ THREAD_RETURN WOLFSSH_THREAD sftpclient_test(void* args)
}
#endif
if (userEcc) {
userPublicKeySz = (word32)sizeof(userPublicKey);
Base64_Decode((byte*)hanselPublicEcc,
(word32)WSTRLEN(hanselPublicEcc),
(byte*)userPublicKey, &userPublicKeySz);
strncpy((char*)userPublicKeyType, "ecdsa-sha2-nistp256",
sizeof(userPublicKeyType));
userPrivateKey = hanselPrivateEcc;
userPrivateKeySz = hanselPrivateEccSz;
}
else {
userPublicKeySz = (word32)sizeof(userPublicKey);
Base64_Decode((byte*)hanselPublicRsa,
(word32)WSTRLEN(hanselPublicRsa),
(byte*)userPublicKey, &userPublicKeySz);
strncpy((char*)userPublicKeyType, "ssh-rsa",
sizeof(userPublicKeyType));
userPrivateKey = hanselPrivateRsa;
userPrivateKeySz = hanselPrivateRsaSz;
}
ctx = wolfSSH_CTX_new(WOLFSSH_ENDPOINT_CLIENT, NULL);
if (ctx == NULL)
err_sys("Couldn't create wolfSSH client context.");

View File

@ -3703,7 +3703,8 @@ static int DoUserAuthFailure(WOLFSSH* ssh,
byte authList[3]; /* Should only ever be password, publickey, hostname */
word32 authListSz = 3;
byte partialSuccess;
byte authId = ID_USERAUTH_PUBLICKEY;
byte authId = ID_USERAUTH_PASSWORD;
/* To use public key authentication, change authId. */
int ret = WS_SUCCESS;
WLOG(WS_LOG_DEBUG, "Entering DoUserAuthFailure()");