Public Key Check Callback

The public key check callback hook is given a pointer to the public key, the size of the key, and the application-specific context data.
1. Added a callback function hook for checking the public key sent to the client by the server. It defaults to accepting the key.
2. Added accessors for the public key check callback function and context data.
3. Added a dummy callback to all the example tools.
pull/145/head
John Safranek 2019-03-26 13:51:10 -07:00
parent 0ca04e4248
commit 8a267e2bd2
8 changed files with 99 additions and 1 deletions

View File

@ -152,6 +152,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);
return 0;
}
static int NonBlockSSH_connect(WOLFSSH* ssh)
{
int ret;
@ -269,6 +279,9 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args)
if (password != NULL)
wolfSSH_SetUserAuthCtx(ssh, (void*)password);
wolfSSH_CTX_SetPublicKeyCheck(ctx, wsPublicKeyCheck);
wolfSSH_SetPublicKeyCheckCtx(ssh, (void*)"You've been sampled!");
ret = wolfSSH_SetUsername(ssh, username);
if (ret != WS_SUCCESS)
err_sys("Couldn't set the username.");

View File

@ -180,6 +180,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);
return 0;
}
/*
* fwdFromHost - address to bind the local listener socket to (default: any)
* fwdFromHostPort - port number to bind the local listener socket to
@ -312,6 +322,9 @@ THREAD_RETURN WOLFSSH_THREAD portfwd_worker(void* args)
if (password != NULL)
wolfSSH_SetUserAuthCtx(ssh, (void*)password);
wolfSSH_CTX_SetPublicKeyCheck(ctx, wsPublicKeyCheck);
wolfSSH_SetPublicKeyCheckCtx(ssh, (void*)"You've been sampled.");
ret = wolfSSH_SetUsername(ssh, username);
if (ret != WS_SUCCESS)
err_sys("Couldn't set the username.");

View File

@ -326,6 +326,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);
return 0;
}
/* returns 0 on success */
static INLINE int SFTP_FPUTS(func_args* args, const char* msg)
{
@ -1065,6 +1075,9 @@ THREAD_RETURN WOLFSSH_THREAD sftpclient_test(void* args)
if (password != NULL)
wolfSSH_SetUserAuthCtx(ssh, (void*)password);
wolfSSH_CTX_SetPublicKeyCheck(ctx, wsPublicKeyCheck);
wolfSSH_SetPublicKeyCheckCtx(ssh, (void*)"You've been sampled!");
ret = wolfSSH_SetUsername(ssh, username);
if (ret != WS_SUCCESS)
err_sys("Couldn't set the username.");

View File

@ -266,6 +266,9 @@ const char* GetErrorString(int err)
case WS_CLOSE_FILE_E:
return "Unable to close local file";
case WS_PUBKEY_REJECTED_E:
return "server's public key is rejected";
default:
return "Unknown error code";
}
@ -2342,7 +2345,26 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
if (ret == WS_SUCCESS && (pubKeySz > len - LENGTH_SZ - begin )) {
ret = WS_BUFFER_E;
}
}
if (ret == WS_SUCCESS) {
if (ssh->ctx->publicKeyCheckCb != NULL) {
WLOG(WS_LOG_DEBUG, "DKDR: Calling the public key check callback");
ret = ssh->ctx->publicKeyCheckCb(pubKey, pubKeySz,
ssh->publicKeyCheckCtx);
if (ret == 0) {
WLOG(WS_LOG_DEBUG, "DKDR: public key accepted");
ret = WS_SUCCESS;
}
else {
WLOG(WS_LOG_DEBUG, "DKDR: public key rejected");
ret = WS_PUBKEY_REJECTED_E;
}
}
else {
WLOG(WS_LOG_DEBUG, "DKDR: no public key check callback, accepted");
ret = WS_SUCCESS;
}
}
if (ret == WS_SUCCESS)

View File

@ -924,6 +924,32 @@ void* wolfSSH_GetUserAuthCtx(WOLFSSH* ssh)
}
void wolfSSH_CTX_SetPublicKeyCheck(WOLFSSH_CTX* ctx,
WS_CallbackPublicKeyCheck cb)
{
if (ctx != NULL) {
ctx->publicKeyCheckCb = cb;
}
}
void wolfSSH_SetPublicKeyCheckCtx(WOLFSSH* ssh, void* publicKeyCheckCtx)
{
if (ssh != NULL) {
ssh->publicKeyCheckCtx = publicKeyCheckCtx;
}
}
void* wolfSSH_GetPublicKeyCheckCtx(WOLFSSH* ssh)
{
if (ssh != NULL) {
return ssh->publicKeyCheckCtx;
}
return NULL;
}
/* Used to set the channel request type sent in wolfSSH connect. The default
* type set is shell if this function is not called.
*

View File

@ -103,8 +103,9 @@ enum WS_ErrorCodes {
WS_SFTP_FILE_DNE = -63, /* SFTP File Does Not Exist */
WS_SIZE_ONLY = -64, /* Only getting the size of buffer needed */
WS_CLOSE_FILE_E = -65, /* Unable to close local file */
WS_PUBKEY_REJECTED_E = -66, /* Server public key rejected */
WS_LAST_E = -65 /* Update this to indicate last error */
WS_LAST_E = -66 /* Update this to indicate last error */
};

View File

@ -181,6 +181,8 @@ struct WOLFSSH_CTX {
WS_CallbackScpRecv scpRecvCb; /* SCP receive callback */
WS_CallbackScpSend scpSendCb; /* SCP send callback */
#endif
WS_CallbackPublicKeyCheck publicKeyCheckCb;
/* Check server's public key callback */
byte* privateKey; /* Owned by CTX */
word32 privateKeySz;
@ -388,6 +390,7 @@ struct WOLFSSH {
word32 pkBlobSz;
byte* peerProtoId; /* Save for rekey */
word32 peerProtoIdSz;
void* publicKeyCheckCtx;
#ifdef WOLFSSH_SFTP
word32 reqId;

View File

@ -148,6 +148,13 @@ WOLFSSH_API void wolfSSH_SetUserAuth(WOLFSSH_CTX*, WS_CallbackUserAuth);
WOLFSSH_API void wolfSSH_SetUserAuthCtx(WOLFSSH*, void*);
WOLFSSH_API void* wolfSSH_GetUserAuthCtx(WOLFSSH*);
/* Public Key Check Callback */
typedef int (*WS_CallbackPublicKeyCheck)(const byte*, word32, void*);
WOLFSSH_API void wolfSSH_CTX_SetPublicKeyCheck(WOLFSSH_CTX*,
WS_CallbackPublicKeyCheck);
WOLFSSH_API void wolfSSH_SetPublicKeyCheckCtx(WOLFSSH*, void*);
WOLFSSH_API void* wolfSSH_GetPublicKeyCheckCtx(WOLFSSH*);
WOLFSSH_API int wolfSSH_SetUsername(WOLFSSH*, const char*);
WOLFSSH_API int wolfSSH_CTX_SetBanner(WOLFSSH_CTX*, const char*);