Skip to content

Commit 5478fda

Browse files
authored
Merge pull request #694 from JacobBarthelmeh/544
Key completion callback
2 parents 5ef2bc5 + 9285a0a commit 5478fda

5 files changed

Lines changed: 313 additions & 4 deletions

File tree

examples/echoserver/echoserver.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ static int callbackReqFailure(WOLFSSH *ssh, void *buf, word32 sz, void *ctx)
289289
return WS_SUCCESS;
290290
}
291291

292+
292293
static void *global_req(void *ctx)
293294
{
294295
int ret;
@@ -328,6 +329,50 @@ static void *global_req(void *ctx)
328329
#endif
329330

330331

332+
static void printKeyCompleteText(WOLFSSH* ssh, WS_Text id, const char* tag)
333+
{
334+
char str[200];
335+
size_t strSz = sizeof(str);
336+
size_t ret;
337+
338+
ret = wolfSSH_GetText(ssh, id, str, strSz);
339+
if (ret == strSz) {
340+
printf("\tString size was not large enough for %s\n", tag);
341+
}
342+
printf("\t%-30s : %s\n", tag, str);
343+
}
344+
345+
346+
static void callbackKeyingComplete(void* ctx)
347+
{
348+
WOLFSSH* ssh = (WOLFSSH*)ctx;
349+
350+
if (ssh != NULL) {
351+
printf("Keying Complete:\n");
352+
printKeyCompleteText(ssh, WOLFSSH_TEXT_KEX_ALGO,
353+
"WOLFSSH_TEXT_KEX_ALGO");
354+
355+
printKeyCompleteText(ssh, WOLFSSH_TEXT_KEX_CURVE,
356+
"WOLFSSH_TEXT_KEX_CURVE");
357+
358+
printKeyCompleteText(ssh, WOLFSSH_TEXT_KEX_HASH,
359+
"WOLFSSH_TEXT_KEX_HASH");
360+
361+
printKeyCompleteText(ssh, WOLFSSH_TEXT_CRYPTO_IN_CIPHER,
362+
"WOLFSSH_TEXT_CRYPTO_IN_CIPHER");
363+
364+
printKeyCompleteText(ssh, WOLFSSH_TEXT_CRYPTO_IN_MAC,
365+
"WOLFSSH_TEXT_CRYPTO_IN_MAC");
366+
367+
printKeyCompleteText(ssh, WOLFSSH_TEXT_CRYPTO_OUT_CIPHER,
368+
"WOLFSSH_TEXT_CRYPTO_OUT_CIPHER");
369+
370+
printKeyCompleteText(ssh, WOLFSSH_TEXT_CRYPTO_OUT_MAC,
371+
"WOLFSSH_TEXT_CRYPTO_OUT_MAC");
372+
}
373+
}
374+
375+
331376
#ifdef WOLFSSH_AGENT
332377

333378
static const char EnvNameAuthPort[] = "SSH_AUTH_SOCK";
@@ -2435,6 +2480,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
24352480
ES_ERROR("Couldn't allocate SSH CTX data.\n");
24362481
}
24372482

2483+
wolfSSH_SetKeyingCompletionCb(ctx, callbackKeyingComplete);
24382484
if (keyList) {
24392485
if (wolfSSH_CTX_SetAlgoListKey(ctx, keyList) != WS_SUCCESS) {
24402486
ES_ERROR("Error setting key list.\n");
@@ -2678,6 +2724,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
26782724
wolfSSH_MemoryConnPrintStats(heap);
26792725
#endif
26802726
wolfSSH_SetUserAuthCtx(ssh, &pwMapList);
2727+
wolfSSH_SetKeyingCompletionCbCtx(ssh, (void*)ssh);
26812728
/* Use the session object for its own highwater callback ctx */
26822729
if (defaultHighwater > 0) {
26832730
wolfSSH_SetHighwaterCtx(ssh, (void*)ssh);

src/internal.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,6 +1072,8 @@ WOLFSSH* SshInit(WOLFSSH* ssh, WOLFSSH_CTX* ctx)
10721072
#endif
10731073
#endif
10741074

1075+
ssh->keyingCompletionCtx = (void*)ssh;
1076+
10751077
if (BufferInit(&ssh->inputBuffer, 0, ctx->heap) != WS_SUCCESS ||
10761078
BufferInit(&ssh->outputBuffer, 0, ctx->heap) != WS_SUCCESS ||
10771079
BufferInit(&ssh->extDataBuffer, 0, ctx->heap) != WS_SUCCESS) {
@@ -3557,8 +3559,7 @@ static INLINE byte KeySzForId(byte id)
35573559
}
35583560
}
35593561

3560-
3561-
static INLINE enum wc_HashType HashForId(byte id)
3562+
INLINE enum wc_HashType HashForId(byte id)
35623563
{
35633564
switch (id) {
35643565

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

36503651

36513652
#if !defined(WOLFSSH_NO_ECDSA) || !defined(WOLFSSH_NO_ECDH)
3652-
static INLINE int wcPrimeForId(byte id)
3653+
int wcPrimeForId(byte id)
36533654
{
36543655
switch (id) {
36553656
#ifndef WOLFSSH_NO_ECDH_NISTP256_KYBER_LEVEL1_SHA256
@@ -3819,7 +3820,7 @@ static int DoKexInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
38193820
}
38203821
}
38213822
if (ret == WS_SUCCESS) {
3822-
ssh->handshake->kexId = algoId;
3823+
ssh->kexId = ssh->handshake->kexId = algoId;
38233824
ssh->handshake->kexHashId = HashForId(algoId);
38243825
}
38253826
/* Extension Info Flag */
@@ -5565,6 +5566,9 @@ static int DoNewKeys(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
55655566
HandshakeInfoFree(ssh->handshake, ssh->ctx->heap);
55665567
ssh->handshake = NULL;
55675568
WLOG(WS_LOG_DEBUG, "Keying completed");
5569+
5570+
if (ssh->ctx->keyingCompletionCb)
5571+
ssh->ctx->keyingCompletionCb(ssh->keyingCompletionCtx);
55685572
}
55695573

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

1053210536
if (ret == WS_SUCCESS) {
10537+
ssh->primeGroupSz = primeGroupSz;
1053310538
ret = wc_InitDhKey(privKey);
1053410539
}
1053510540
if (ret == 0)

src/ssh.c

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2834,6 +2834,220 @@ int wolfSSH_ChannelGetEof(WOLFSSH_CHANNEL* channel)
28342834
return eof;
28352835
}
28362836

2837+
static const char* HashNameForId(byte id)
2838+
{
2839+
enum wc_HashType hash = HashForId(id);
2840+
2841+
if (hash == WC_HASH_TYPE_SHA)
2842+
return "SHA-1";
2843+
2844+
if (hash == WC_HASH_TYPE_SHA256)
2845+
return "SHA-256";
2846+
2847+
if (hash == WC_HASH_TYPE_SHA384)
2848+
return "SHA-384";
2849+
2850+
if (hash == WC_HASH_TYPE_SHA512)
2851+
return "SHA-512";
2852+
2853+
return "";
2854+
}
2855+
2856+
static const char* CurveNameForId(byte id)
2857+
{
2858+
#if !defined(WOLFSSH_NO_ECDSA) || !defined(WOLFSSH_NO_ECDH)
2859+
switch (wcPrimeForId(id)) {
2860+
case ECC_SECP256R1:
2861+
return "nistp256";
2862+
2863+
case ECC_SECP384R1:
2864+
return "nistp384";
2865+
2866+
case ECC_SECP521R1:
2867+
return "nistp521";
2868+
2869+
#ifdef HAVE_CURVE25519
2870+
case ECC_X25519:
2871+
return "Curve25519";
2872+
#endif
2873+
}
2874+
#endif
2875+
return "";
2876+
}
2877+
2878+
static const char* CipherNameForId(byte id)
2879+
{
2880+
switch (id) {
2881+
case ID_AES128_CBC:
2882+
return "AES-128 CBC";
2883+
2884+
case ID_AES192_CBC:
2885+
return "AES-192 CBC";
2886+
2887+
case ID_AES256_CBC:
2888+
return "AES-256 CBC";
2889+
2890+
case ID_AES128_CTR:
2891+
return "AES-128 SDCTR";
2892+
2893+
case ID_AES192_CTR:
2894+
return "AES-192 SDCTR";
2895+
2896+
case ID_AES256_CTR:
2897+
return "AES-256 SDCTR";
2898+
2899+
case ID_AES128_GCM:
2900+
return "AES-128 GCM";
2901+
2902+
case ID_AES192_GCM:
2903+
return "AES-192 GCM";
2904+
2905+
case ID_AES256_GCM:
2906+
return "AES-256 GCM";
2907+
}
2908+
2909+
return "";
2910+
}
2911+
2912+
static const char* MacNameForId(byte macid, byte cipherid)
2913+
{
2914+
if (macid != ID_NONE) {
2915+
switch (macid) {
2916+
case ID_HMAC_SHA1:
2917+
return "HMAC-SHA-1";
2918+
2919+
case ID_HMAC_SHA1_96:
2920+
return "HMAC-SHA-1-96";
2921+
2922+
case ID_HMAC_SHA2_256:
2923+
return "HMAC-SHA-256";
2924+
}
2925+
}
2926+
else {
2927+
switch (cipherid) {
2928+
case ID_AES128_GCM:
2929+
return "AES128 GCM (in ETM mode)";
2930+
2931+
case ID_AES192_GCM:
2932+
return "AES192 GCM (in ETM mode)";
2933+
2934+
case ID_AES256_GCM:
2935+
return "AES256 GCM (in ETM mode)";
2936+
}
2937+
}
2938+
2939+
return "";
2940+
}
2941+
2942+
size_t wolfSSH_GetText(WOLFSSH *ssh, WS_Text id, char *str, size_t strSz)
2943+
{
2944+
int ret = 0;
2945+
2946+
#ifndef WOLFSSH_NO_DH
2947+
static const char standard_dh_format[] =
2948+
"%d-bit Diffie-Hellman with standard group %d";
2949+
#endif
2950+
2951+
if (!ssh || str == NULL || strSz <= 0)
2952+
return 0;
2953+
2954+
switch (id) {
2955+
case WOLFSSH_TEXT_KEX_HASH:
2956+
ret = WSNPRINTF(str, strSz, "%s", HashNameForId(ssh->kexId));
2957+
break;
2958+
2959+
case WOLFSSH_TEXT_KEX_CURVE:
2960+
ret = WSNPRINTF(str, strSz, "%s", CurveNameForId(ssh->kexId));
2961+
break;
2962+
2963+
case WOLFSSH_TEXT_CRYPTO_IN_CIPHER:
2964+
ret = WSNPRINTF(str, strSz, "%s",
2965+
CipherNameForId(ssh->peerEncryptId));
2966+
break;
2967+
2968+
case WOLFSSH_TEXT_CRYPTO_OUT_CIPHER:
2969+
ret = WSNPRINTF(str, strSz, "%s", CipherNameForId(ssh->encryptId));
2970+
break;
2971+
2972+
case WOLFSSH_TEXT_CRYPTO_IN_MAC:
2973+
ret = WSNPRINTF(str, strSz, "%s", MacNameForId(ssh->peerMacId,
2974+
ssh->peerEncryptId));
2975+
break;
2976+
2977+
case WOLFSSH_TEXT_CRYPTO_OUT_MAC:
2978+
ret = WSNPRINTF(str, strSz, "%s", MacNameForId(ssh->macId,
2979+
ssh->encryptId));
2980+
break;
2981+
2982+
case WOLFSSH_TEXT_KEX_ALGO:
2983+
switch (ssh->kexId) {
2984+
case ID_ECDH_SHA2_NISTP256:
2985+
case ID_ECDH_SHA2_NISTP384:
2986+
case ID_ECDH_SHA2_NISTP521:
2987+
case ID_ECDH_SHA2_ED25519:
2988+
case ID_ECDH_SHA2_ED25519_LIBSSH:
2989+
#ifndef WOLFSSH_NO_CURVE25519_SHA256
2990+
case ID_CURVE25519_SHA256:
2991+
#endif
2992+
ret = WSNPRINTF(str, strSz, "%s", "ECDH");
2993+
break;
2994+
2995+
#ifndef WOLFSSH_NO_ECDH_NISTP256_KYBER_LEVEL1_SHA256
2996+
case ID_ECDH_NISTP256_KYBER_LEVEL1_SHA256:
2997+
ret = WSNPRINTF(str, strSz, "%s", "Kyber1");
2998+
break;
2999+
#endif
3000+
3001+
#ifndef WOLFSSH_NO_DH
3002+
case ID_DH_GROUP1_SHA1:
3003+
ret = WSNPRINTF(str, strSz, standard_dh_format,
3004+
ssh->primeGroupSz*8, 1);
3005+
break;
3006+
3007+
case ID_DH_GROUP14_SHA1:
3008+
case ID_DH_GROUP14_SHA256:
3009+
ret = WSNPRINTF(str, strSz, standard_dh_format,
3010+
ssh->primeGroupSz*8, 14);
3011+
break;
3012+
3013+
case ID_DH_GEX_SHA256:
3014+
ret = WSNPRINTF(str, strSz,
3015+
"%d-bit Diffie-Hellman with server-supplied group",
3016+
ssh->primeGroupSz*8);
3017+
break;
3018+
#endif /* !WOLFSSH_NO_DH */
3019+
3020+
case ID_EXTINFO_S:
3021+
ret = WSNPRINTF(str, strSz, "Server extensions KEX");
3022+
break;
3023+
3024+
case ID_EXTINFO_C:
3025+
ret = WSNPRINTF(str, strSz, "Client extensions KEX");
3026+
break;
3027+
3028+
}
3029+
break;
3030+
}
3031+
3032+
return ret < 0 ? 0 : (size_t)ret;
3033+
}
3034+
3035+
void wolfSSH_SetKeyingCompletionCb(WOLFSSH_CTX* ctx, WS_CallbackKeyingCompletion cb)
3036+
{
3037+
WLOG(WS_LOG_DEBUG, "Entering wolfSSH_SetKeyingCompletionCb()");
3038+
3039+
if (ctx)
3040+
ctx->keyingCompletionCb = cb;
3041+
}
3042+
3043+
void wolfSSH_SetKeyingCompletionCbCtx(WOLFSSH* ssh, void* ctx)
3044+
{
3045+
WLOG(WS_LOG_DEBUG, "Entering wolfSSH_SetKeyingCompletionCbCtx()");
3046+
3047+
if (ssh)
3048+
ssh->keyingCompletionCtx = ctx;
3049+
}
3050+
28373051

28383052
#if (defined(WOLFSSH_SFTP) || defined(WOLFSSH_SCP)) && \
28393053
!defined(NO_WOLFSSH_SERVER)

wolfssh/internal.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,7 @@ struct WOLFSSH_CTX {
535535
#ifdef WOLFSSH_AGENT
536536
byte agentEnabled;
537537
#endif /* WOLFSSH_AGENT */
538+
WS_CallbackKeyingCompletion keyingCompletionCb;
538539
};
539540

540541

@@ -725,6 +726,7 @@ struct WOLFSSH {
725726
byte isClosed;
726727
byte clientOpenSSH;
727728

729+
byte kexId;
728730
byte blockSz;
729731
byte encryptId;
730732
byte macId;
@@ -735,6 +737,9 @@ struct WOLFSSH {
735737
byte peerMacId;
736738
byte peerMacSz;
737739
byte peerAeadMode;
740+
#ifndef WOLFSSH_NO_DH
741+
word32 primeGroupSz;
742+
#endif
738743

739744
Ciphers encryptCipher;
740745
Ciphers decryptCipher;
@@ -853,6 +858,7 @@ struct WOLFSSH {
853858
#if defined(WOLFSSH_TERM) || defined(WOLFSSH_SHELL)
854859
word32 exitStatus;
855860
#endif
861+
void* keyingCompletionCtx;
856862
};
857863

858864

@@ -989,6 +995,10 @@ WOLFSSH_LOCAL int SendChannelExitStatus(WOLFSSH* ssh, word32 channelId,
989995
word32 exitStatus);
990996
WOLFSSH_LOCAL int GenerateKey(byte, byte, byte*, word32, const byte*, word32,
991997
const byte*, word32, const byte*, word32, byte doKeyPad);
998+
#if !defined(WOLFSSH_NO_ECDSA) || !defined(WOLFSSH_NO_ECDH)
999+
WOLFSSH_LOCAL int wcPrimeForId(byte);
1000+
#endif
1001+
WOLFSSH_LOCAL enum wc_HashType HashForId(byte);
9921002

9931003

9941004
enum AcceptStates {

0 commit comments

Comments
 (0)