|
31 | 31 | #include <wolfssh/port.h> |
32 | 32 |
|
33 | 33 | #include <stdio.h> |
| 34 | +#include <string.h> |
34 | 35 | #include <wolfssh/ssh.h> |
35 | 36 | #include <wolfssh/internal.h> |
36 | 37 | #ifdef WOLFSSH_SCP |
37 | 38 | #include <wolfssh/wolfscp.h> |
38 | 39 | #endif |
| 40 | +#ifdef WOLFSSH_AGENT |
| 41 | + #include <wolfssh/agent.h> |
| 42 | +#endif |
39 | 43 |
|
40 | 44 | #ifdef WOLFSSH_SFTP |
41 | 45 | #define WOLFSSH_TEST_LOCKING |
@@ -873,6 +877,209 @@ static void test_wolfSSH_SCP_CB(void) |
873 | 877 | static void test_wolfSSH_SCP_CB(void) { ; } |
874 | 878 | #endif /* WOLFSSH_SCP */ |
875 | 879 |
|
| 880 | +#ifdef WOLFSSH_AGENT |
| 881 | +typedef struct AgentTestCtx { |
| 882 | + int partialWrite; |
| 883 | + byte response[128]; |
| 884 | + word32 responseSz; |
| 885 | + int writeCalls; |
| 886 | + int readCalls; |
| 887 | +} AgentTestCtx; |
| 888 | + |
| 889 | +static int test_agent_cb(WS_AgentCbAction action, void* ctx) |
| 890 | +{ |
| 891 | + (void)ctx; |
| 892 | + |
| 893 | + if (action == WOLFSSH_AGENT_LOCAL_SETUP || |
| 894 | + action == WOLFSSH_AGENT_LOCAL_CLEANUP) { |
| 895 | + return WS_AGENT_SUCCESS; |
| 896 | + } |
| 897 | + |
| 898 | + return WS_AGENT_INVALID_ACTION; |
| 899 | +} |
| 900 | + |
| 901 | +static void put_uint32(byte* dst, word32 value) |
| 902 | +{ |
| 903 | + dst[0] = (byte)((value >> 24) & 0xff); |
| 904 | + dst[1] = (byte)((value >> 16) & 0xff); |
| 905 | + dst[2] = (byte)((value >> 8) & 0xff); |
| 906 | + dst[3] = (byte)(value & 0xff); |
| 907 | +} |
| 908 | + |
| 909 | +static void build_agent_message(byte* out, word32* outSz, byte id, |
| 910 | + const byte* body, word32 bodySz) |
| 911 | +{ |
| 912 | + word32 payloadSz = 1 + bodySz; |
| 913 | + |
| 914 | + put_uint32(out, payloadSz); |
| 915 | + out[4] = id; |
| 916 | + if (bodySz > 0) |
| 917 | + memcpy(out + 5, body, bodySz); |
| 918 | + *outSz = payloadSz + LENGTH_SZ; |
| 919 | +} |
| 920 | + |
| 921 | +static void build_sign_response(AgentTestCtx* ctx, const byte* sig, |
| 922 | + word32 sigSz) |
| 923 | +{ |
| 924 | + byte body[4 + 64]; |
| 925 | + |
| 926 | + AssertTrue(sigSz <= 64); |
| 927 | + put_uint32(body, sigSz); |
| 928 | + if (sigSz > 0) |
| 929 | + memcpy(body + LENGTH_SZ, sig, sigSz); |
| 930 | + build_agent_message(ctx->response, &ctx->responseSz, |
| 931 | + MSGID_AGENT_SIGN_RESPONSE, body, LENGTH_SZ + sigSz); |
| 932 | +} |
| 933 | + |
| 934 | +static void build_simple_response(AgentTestCtx* ctx, byte id) |
| 935 | +{ |
| 936 | + build_agent_message(ctx->response, &ctx->responseSz, id, NULL, 0); |
| 937 | +} |
| 938 | + |
| 939 | +static int test_agent_io_cb(WS_AgentIoCbAction action, void* buf, word32 bufSz, |
| 940 | + void* ctx) |
| 941 | +{ |
| 942 | + AgentTestCtx* io = (AgentTestCtx*)ctx; |
| 943 | + |
| 944 | + if (action == WOLFSSH_AGENT_IO_WRITE) { |
| 945 | + io->writeCalls++; |
| 946 | + if (io->partialWrite && bufSz > 0) { |
| 947 | + io->partialWrite = 0; |
| 948 | + return (int)(bufSz - 1); |
| 949 | + } |
| 950 | + return (int)bufSz; |
| 951 | + } |
| 952 | + |
| 953 | + io->readCalls++; |
| 954 | + if (io->responseSz == 0 || bufSz < io->responseSz) |
| 955 | + return 0; |
| 956 | + memcpy(buf, io->response, io->responseSz); |
| 957 | + return (int)io->responseSz; |
| 958 | +} |
| 959 | + |
| 960 | +static void setup_agent_test(WOLFSSH_CTX** ctx, WOLFSSH** ssh, AgentTestCtx* io) |
| 961 | +{ |
| 962 | + AssertNotNull(*ctx = wolfSSH_CTX_new(WOLFSSH_ENDPOINT_CLIENT, NULL)); |
| 963 | + AssertIntEQ(wolfSSH_CTX_AGENT_enable(*ctx, 1), WS_SUCCESS); |
| 964 | + AssertIntEQ(wolfSSH_CTX_set_agent_cb(*ctx, test_agent_cb, |
| 965 | + test_agent_io_cb), WS_SUCCESS); |
| 966 | + AssertNotNull(*ssh = wolfSSH_new(*ctx)); |
| 967 | + AssertIntEQ(wolfSSH_set_agent_cb_ctx(*ssh, io), WS_SUCCESS); |
| 968 | + AssertIntEQ(wolfSSH_AGENT_enable(*ssh, 1), WS_SUCCESS); |
| 969 | +} |
| 970 | + |
| 971 | +static void cleanup_agent_test(WOLFSSH_CTX* ctx, WOLFSSH* ssh) |
| 972 | +{ |
| 973 | + wolfSSH_free(ssh); |
| 974 | + wolfSSH_CTX_free(ctx); |
| 975 | +} |
| 976 | + |
| 977 | +static void test_wolfSSH_agent_signrequest_partial_write(void) |
| 978 | +{ |
| 979 | + WOLFSSH_CTX* ctx; |
| 980 | + WOLFSSH* ssh; |
| 981 | + AgentTestCtx io; |
| 982 | + byte digest[16] = {0}; |
| 983 | + byte keyBlob[8] = {0}; |
| 984 | + byte sig[8]; |
| 985 | + word32 sigSz = sizeof(sig); |
| 986 | + int ret; |
| 987 | + |
| 988 | + memset(&io, 0, sizeof(io)); |
| 989 | + io.partialWrite = 1; |
| 990 | + setup_agent_test(&ctx, &ssh, &io); |
| 991 | + |
| 992 | + ret = wolfSSH_AGENT_SignRequest(ssh, digest, sizeof(digest), |
| 993 | + sig, &sigSz, keyBlob, sizeof(keyBlob), 0); |
| 994 | + AssertIntEQ(ret, WS_AGENT_CXN_FAIL); |
| 995 | + AssertIntEQ(sigSz, 0); |
| 996 | + AssertIntEQ(io.writeCalls, 1); |
| 997 | + AssertIntEQ(io.readCalls, 0); |
| 998 | + |
| 999 | + cleanup_agent_test(ctx, ssh); |
| 1000 | +} |
| 1001 | + |
| 1002 | +static void test_wolfSSH_agent_signrequest_wrong_message(void) |
| 1003 | +{ |
| 1004 | + WOLFSSH_CTX* ctx; |
| 1005 | + WOLFSSH* ssh; |
| 1006 | + AgentTestCtx io; |
| 1007 | + byte digest[16] = {0}; |
| 1008 | + byte keyBlob[8] = {0}; |
| 1009 | + byte sig[16]; |
| 1010 | + word32 sigSz = sizeof(sig); |
| 1011 | + int ret; |
| 1012 | + |
| 1013 | + memset(&io, 0, sizeof(io)); |
| 1014 | + build_simple_response(&io, MSGID_AGENT_SUCCESS); |
| 1015 | + setup_agent_test(&ctx, &ssh, &io); |
| 1016 | + |
| 1017 | + ret = wolfSSH_AGENT_SignRequest(ssh, digest, sizeof(digest), |
| 1018 | + sig, &sigSz, keyBlob, sizeof(keyBlob), 0); |
| 1019 | + AssertIntEQ(ret, WS_AGENT_NO_KEY_E); |
| 1020 | + AssertIntEQ(sigSz, 0); |
| 1021 | + AssertIntEQ(io.writeCalls, 1); |
| 1022 | + AssertIntEQ(io.readCalls, 1); |
| 1023 | + |
| 1024 | + cleanup_agent_test(ctx, ssh); |
| 1025 | +} |
| 1026 | + |
| 1027 | +static void test_wolfSSH_agent_signrequest_signature_too_large(void) |
| 1028 | +{ |
| 1029 | + WOLFSSH_CTX* ctx; |
| 1030 | + WOLFSSH* ssh; |
| 1031 | + AgentTestCtx io; |
| 1032 | + byte digest[16] = {0}; |
| 1033 | + byte keyBlob[8] = {0}; |
| 1034 | + byte signatureData[12]; |
| 1035 | + byte sig[8]; |
| 1036 | + word32 sigSz = sizeof(sig); |
| 1037 | + int ret; |
| 1038 | + |
| 1039 | + memset(signatureData, 0x5a, sizeof(signatureData)); |
| 1040 | + memset(&io, 0, sizeof(io)); |
| 1041 | + build_sign_response(&io, signatureData, sizeof(signatureData)); |
| 1042 | + setup_agent_test(&ctx, &ssh, &io); |
| 1043 | + |
| 1044 | + ret = wolfSSH_AGENT_SignRequest(ssh, digest, sizeof(digest), |
| 1045 | + sig, &sigSz, keyBlob, sizeof(keyBlob), 0); |
| 1046 | + AssertIntEQ(ret, WS_BUFFER_E); |
| 1047 | + AssertIntEQ(sigSz, 0); |
| 1048 | + AssertIntEQ(io.writeCalls, 1); |
| 1049 | + AssertIntEQ(io.readCalls, 1); |
| 1050 | + |
| 1051 | + cleanup_agent_test(ctx, ssh); |
| 1052 | +} |
| 1053 | + |
| 1054 | +static void test_wolfSSH_agent_signrequest_success(void) |
| 1055 | +{ |
| 1056 | + WOLFSSH_CTX* ctx; |
| 1057 | + WOLFSSH* ssh; |
| 1058 | + AgentTestCtx io; |
| 1059 | + byte digest[16] = {0}; |
| 1060 | + byte keyBlob[8] = {0}; |
| 1061 | + byte signatureData[8]; |
| 1062 | + byte sig[16]; |
| 1063 | + word32 sigSz = sizeof(sig); |
| 1064 | + int ret; |
| 1065 | + |
| 1066 | + memset(signatureData, 0xa5, sizeof(signatureData)); |
| 1067 | + memset(&io, 0, sizeof(io)); |
| 1068 | + build_sign_response(&io, signatureData, sizeof(signatureData)); |
| 1069 | + setup_agent_test(&ctx, &ssh, &io); |
| 1070 | + |
| 1071 | + ret = wolfSSH_AGENT_SignRequest(ssh, digest, sizeof(digest), |
| 1072 | + sig, &sigSz, keyBlob, sizeof(keyBlob), 0); |
| 1073 | + AssertIntEQ(ret, WS_SUCCESS); |
| 1074 | + AssertIntEQ(sigSz, sizeof(signatureData)); |
| 1075 | + AssertTrue(memcmp(sig, signatureData, sizeof(signatureData)) == 0); |
| 1076 | + AssertIntEQ(io.writeCalls, 1); |
| 1077 | + AssertIntEQ(io.readCalls, 1); |
| 1078 | + |
| 1079 | + cleanup_agent_test(ctx, ssh); |
| 1080 | +} |
| 1081 | +#endif /* WOLFSSH_AGENT */ |
| 1082 | + |
876 | 1083 |
|
877 | 1084 | #if defined(WOLFSSH_SFTP) && !defined(NO_WOLFSSH_CLIENT) && \ |
878 | 1085 | !defined(SINGLE_THREADED) |
@@ -1779,6 +1986,12 @@ int wolfSSH_ApiTest(int argc, char** argv) |
1779 | 1986 | test_wolfSSH_ReadKey(); |
1780 | 1987 | test_wolfSSH_QueryAlgoList(); |
1781 | 1988 | test_wolfSSH_SetAlgoList(); |
| 1989 | +#ifdef WOLFSSH_AGENT |
| 1990 | + test_wolfSSH_agent_signrequest_partial_write(); |
| 1991 | + test_wolfSSH_agent_signrequest_wrong_message(); |
| 1992 | + test_wolfSSH_agent_signrequest_signature_too_large(); |
| 1993 | + test_wolfSSH_agent_signrequest_success(); |
| 1994 | +#endif |
1782 | 1995 | #ifdef WOLFSSH_KEYBOARD_INTERACTIVE |
1783 | 1996 | test_wolfSSH_KeyboardInteractive(); |
1784 | 1997 | #endif |
|
0 commit comments