Skip to content

Commit

Permalink
Callback on keying completion, plus wolfSSH_GetText.
Browse files Browse the repository at this point in the history
  • Loading branch information
falemagn authored and JacobBarthelmeh committed May 17, 2024
1 parent 5ef2bc5 commit b40dfaf
Show file tree
Hide file tree
Showing 4 changed files with 236 additions and 4 deletions.
13 changes: 9 additions & 4 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -1072,6 +1072,8 @@ WOLFSSH* SshInit(WOLFSSH* ssh, WOLFSSH_CTX* ctx)
#endif
#endif

ssh->keyingCompletionCtx = (void*)ssh;

if (BufferInit(&ssh->inputBuffer, 0, ctx->heap) != WS_SUCCESS ||
BufferInit(&ssh->outputBuffer, 0, ctx->heap) != WS_SUCCESS ||
BufferInit(&ssh->extDataBuffer, 0, ctx->heap) != WS_SUCCESS) {
Expand Down Expand Up @@ -3557,8 +3559,7 @@ static INLINE byte KeySzForId(byte id)
}
}


static INLINE enum wc_HashType HashForId(byte id)
INLINE enum wc_HashType HashForId(byte id)
{
switch (id) {

Expand Down Expand Up @@ -3649,7 +3650,7 @@ static INLINE enum wc_HashType HashForId(byte id)


#if !defined(WOLFSSH_NO_ECDSA) || !defined(WOLFSSH_NO_ECDH)
static INLINE int wcPrimeForId(byte id)
INLINE int wcPrimeForId(byte id)
{
switch (id) {
#ifndef WOLFSSH_NO_ECDH_NISTP256_KYBER_LEVEL1_SHA256
Expand Down Expand Up @@ -3819,7 +3820,7 @@ static int DoKexInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
}
}
if (ret == WS_SUCCESS) {
ssh->handshake->kexId = algoId;
ssh->kexId = ssh->handshake->kexId = algoId;
ssh->handshake->kexHashId = HashForId(algoId);
}
/* Extension Info Flag */
Expand Down Expand Up @@ -5565,6 +5566,9 @@ static int DoNewKeys(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
HandshakeInfoFree(ssh->handshake, ssh->ctx->heap);
ssh->handshake = NULL;
WLOG(WS_LOG_DEBUG, "Keying completed");

if (ssh->ctx->keyingCompletionCb)
ssh->ctx->keyingCompletionCb(ssh->keyingCompletionCtx);
}

return ret;
Expand Down Expand Up @@ -10530,6 +10534,7 @@ static int KeyAgreeDh_server(WOLFSSH* ssh, byte hashId, byte* f, word32* fSz)
&primeGroupSz, &generator, &generatorSz);

if (ret == WS_SUCCESS) {
ssh->primeGroupSz = primeGroupSz;
ret = wc_InitDhKey(privKey);
}
if (ret == 0)
Expand Down
184 changes: 184 additions & 0 deletions src/ssh.c
Original file line number Diff line number Diff line change
Expand Up @@ -2834,6 +2834,190 @@ int wolfSSH_ChannelGetEof(WOLFSSH_CHANNEL* channel)
return eof;
}

static const char* HashNameForId(byte id)
{
enum wc_HashType hash = HashForId(id);

if (hash == WC_HASH_TYPE_SHA)
return "SHA-1";

if (hash == WC_HASH_TYPE_SHA256)
return "SHA-256";

if (hash == WC_HASH_TYPE_SHA384)
return "SHA-384";

if (hash == WC_HASH_TYPE_SHA512)
return "SHA-512";

return "";
}

static const char* CurveNameForId(byte id)
{
#if !defined(WOLFSSH_NO_ECDSA) || !defined(WOLFSSH_NO_ECDH)
switch (wcPrimeForId(id)) {
case ECC_SECP256R1:
return "nistp256";

case ECC_SECP384R1:
return "nistp384";

case ECC_SECP521R1:
return "nistp521";

#ifdef HAVE_CURVE25519
case ECC_X25519:
return "Curve25519";
#endif
}
#endif
return "";
}

static const char* CipherNameForId(byte id)
{
switch (id) {
case ID_AES128_CBC:
return "AES-128 CBC";

case ID_AES192_CBC:
return "AES-192 CBC";

case ID_AES256_CBC:
return "AES-256 CBC";

case ID_AES128_CTR:
return "AES-128 SDCTR";

case ID_AES192_CTR:
return "AES-192 SDCTR";

case ID_AES256_CTR:
return "AES-256 SDCTR";

case ID_AES128_GCM:
return "AES-128 GCM";

case ID_AES192_GCM:
return "AES-192 GCM";

case ID_AES256_GCM:
return "AES-256 GCM";
}

return "";
}

static const char* MacNameForId(byte macid, byte cipherid)
{
if (macid != ID_NONE) {
switch (macid) {
case ID_HMAC_SHA1:
return "HMAC-SHA-1";

case ID_HMAC_SHA1_96:
return "HMAC-SHA-1-96";

case ID_HMAC_SHA2_256:
return "HMAC-SHA-256";
}
}
else {
switch (cipherid) {
case ID_AES128_GCM:
return "AES128 GCM (in ETM mode)";

case ID_AES192_GCM:
return "AES192 GCM (in ETM mode)";

case ID_AES256_GCM:
return "AES256 GCM (in ETM mode)";
}
}

return "";
}

size_t wolfSSH_GetText(WOLFSSH *ssh, WS_Text id, char *str, size_t strsz)
{
int ret = 0;

if (!ssh)
return 0;

static const char standard_dh_format[] = "%d-bit Diffie-Hellman with standard group %d";

switch (id) {
case WOLFSSH_TEXT_KEX_HASH:
ret = WSNPRINTF(str, strsz, "%s", HashNameForId(ssh->kexId));
break;

case WOLFSSH_TEXT_KEX_CURVE:
ret = WSNPRINTF(str, strsz, "%s", CurveNameForId(ssh->kexId));
break;

case WOLFSSH_TEXT_CRYPTO_IN_CIPHER:
ret = WSNPRINTF(str, strsz, "%s", CipherNameForId(ssh->peerEncryptId));
break;

case WOLFSSH_TEXT_CRYPTO_OUT_CIPHER:
ret = WSNPRINTF(str, strsz, "%s", CipherNameForId(ssh->encryptId));
break;

case WOLFSSH_TEXT_CRYPTO_IN_MAC:
ret = WSNPRINTF(str, strsz, "%s", MacNameForId(ssh->peerMacId, ssh->peerEncryptId));
break;

case WOLFSSH_TEXT_CRYPTO_OUT_MAC:
ret = WSNPRINTF(str, strsz, "%s", MacNameForId(ssh->macId, ssh->encryptId));
break;

case WOLFSSH_TEXT_KEX_ALGO:
switch (ssh->kexId) {
case ID_ECDH_SHA2_NISTP256:
case ID_ECDH_SHA2_NISTP384:
case ID_ECDH_SHA2_NISTP521:
case ID_ECDH_SHA2_ED25519:
case ID_ECDH_SHA2_ED25519_LIBSSH:
ret = WSNPRINTF(str, strsz, "%s", "ECDH");
break;

case ID_DH_GROUP1_SHA1:
ret = WSNPRINTF(str, strsz, standard_dh_format, ssh->primeGroupSz*8, 1);
break;

case ID_DH_GROUP14_SHA1:
case ID_DH_GROUP14_SHA256:
ret = WSNPRINTF(str, strsz, standard_dh_format, ssh->primeGroupSz*8, 14);
break;

case ID_DH_GEX_SHA256:
ret = WSNPRINTF(str, strsz, "%d-bit Diffie-Hellman with server-supplied group", ssh->primeGroupSz*8);
break;
}
break;
}

return ret < 0 ? 0 : (size_t)ret;
}

void wolfSSH_SetKeyingCompletionCb(WOLFSSH_CTX* ctx, WS_CallbackKeyingCompletion cb)
{
WLOG(WS_LOG_DEBUG, "Entering wolfSSH_SetKeyingCompletionCb()");

if (ctx)
ctx->keyingCompletionCb = cb;
}

void wolfSSH_SetKeyingCompletionCbCtx(WOLFSSH* ssh, void* ctx)
{
WLOG(WS_LOG_DEBUG, "Entering wolfSSH_SetKeyingCompletionCbCtx()");

if (ssh)
ssh->keyingCompletionCtx = ctx;
}


#if (defined(WOLFSSH_SFTP) || defined(WOLFSSH_SCP)) && \
!defined(NO_WOLFSSH_SERVER)
Expand Down
10 changes: 10 additions & 0 deletions wolfssh/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,7 @@ struct WOLFSSH_CTX {
#ifdef WOLFSSH_AGENT
byte agentEnabled;
#endif /* WOLFSSH_AGENT */
WS_CallbackKeyingCompletion keyingCompletionCb;
};


Expand Down Expand Up @@ -725,6 +726,7 @@ struct WOLFSSH {
byte isClosed;
byte clientOpenSSH;

byte kexId;
byte blockSz;
byte encryptId;
byte macId;
Expand All @@ -735,6 +737,9 @@ struct WOLFSSH {
byte peerMacId;
byte peerMacSz;
byte peerAeadMode;
#ifndef WOLFSSH_NO_DH
word32 primeGroupSz;
#endif

Ciphers encryptCipher;
Ciphers decryptCipher;
Expand Down Expand Up @@ -853,6 +858,7 @@ struct WOLFSSH {
#if defined(WOLFSSH_TERM) || defined(WOLFSSH_SHELL)
word32 exitStatus;
#endif
void* keyingCompletionCtx;
};


Expand Down Expand Up @@ -989,6 +995,10 @@ WOLFSSH_LOCAL int SendChannelExitStatus(WOLFSSH* ssh, word32 channelId,
word32 exitStatus);
WOLFSSH_LOCAL int GenerateKey(byte, byte, byte*, word32, const byte*, word32,
const byte*, word32, const byte*, word32, byte doKeyPad);
#if !defined(WOLFSSH_NO_ECDSA) || !defined(WOLFSSH_NO_ECDH)
WOLFSSH_LOCAL int wcPrimeForId(byte);
#endif
WOLFSSH_LOCAL enum wc_HashType HashForId(byte);


enum AcceptStates {
Expand Down
33 changes: 33 additions & 0 deletions wolfssh/ssh.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,39 @@ WOLFSSH_API const char* wolfSSH_QueryKey(word32* index);
WOLFSSH_API const char* wolfSSH_QueryCipher(word32* index);
WOLFSSH_API const char* wolfSSH_QueryMac(word32* index);

typedef enum WS_Text {
WOLFSSH_TEXT_KEX_ALGO,
WOLFSSH_TEXT_KEX_CURVE,
WOLFSSH_TEXT_KEX_HASH,

WOLFSSH_TEXT_CRYPTO_IN_CIPHER,
WOLFSSH_TEXT_CRYPTO_IN_MAC,
WOLFSSH_TEXT_CRYPTO_OUT_CIPHER,
WOLFSSH_TEXT_CRYPTO_OUT_MAC,
} WS_Text;

/*
* Outputs the c-string representation of the data entry identified by the id to
* the character string str, writing no more than strsz bytes, including the
* terminating null byte ('\0').
*
* Returns the number of characters written (excluding the null byte used to end
* output to strings), unless the output was truncated, in which case the return
* value is the number of characters (excluding the terminating null byte) which
* would have been written to the final string if enough space had been
* available.
*
* Thus, a return value of strsz or more means that the output was truncated.
*/

WOLFSSH_API size_t wolfSSH_GetText(WOLFSSH *ssh, WS_Text id, char *str,
size_t strsz);

typedef void (*WS_CallbackKeyingCompletion)(void *);
WOLFSSH_API void wolfSSH_SetKeyingCompletionCb(WOLFSSH_CTX*,
WS_CallbackKeyingCompletion);
WOLFSSH_API void wolfSSH_SetKeyingCompletionCbCtx(WOLFSSH*,
void*);

#define WS_CHANNEL_ID_SELF 0
#define WS_CHANNEL_ID_PEER 1
Expand Down

0 comments on commit b40dfaf

Please sign in to comment.