From ade970cda5000d49915013b2a26bfbcf5c9d6ba5 Mon Sep 17 00:00:00 2001 From: Takeshi Yoshino <4511440+tyoshino@users.noreply.github.com> Date: Thu, 26 Feb 2026 04:39:04 +0000 Subject: [PATCH 1/5] feat(wish): add TLS support + some tweaks --- .vscode/settings.json | 3 + wish/cpp/CMakeLists.txt | 24 ++++- wish/cpp/certs/ca.crt | 19 ++++ wish/cpp/certs/ca.key | 28 ++++++ wish/cpp/certs/ca.srl | 1 + wish/cpp/certs/client.crt | 18 ++++ wish/cpp/certs/client.csr | 15 +++ wish/cpp/certs/client.key | 28 ++++++ wish/cpp/certs/server.crt | 18 ++++ wish/cpp/certs/server.csr | 15 +++ wish/cpp/certs/server.key | 28 ++++++ wish/cpp/examples/client.cc | 125 +++++++++++++---------- wish/cpp/examples/server.cc | 190 +++++++++++++++++++++-------------- wish/cpp/src/tls_context.cc | 82 +++++++++++++++ wish/cpp/src/tls_context.h | 37 +++++++ wish/cpp/src/wish_handler.cc | 105 +++++++++---------- wish/cpp/src/wish_handler.h | 38 +++---- 17 files changed, 570 insertions(+), 204 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 wish/cpp/certs/ca.crt create mode 100644 wish/cpp/certs/ca.key create mode 100644 wish/cpp/certs/ca.srl create mode 100644 wish/cpp/certs/client.crt create mode 100644 wish/cpp/certs/client.csr create mode 100644 wish/cpp/certs/client.key create mode 100644 wish/cpp/certs/server.crt create mode 100644 wish/cpp/certs/server.csr create mode 100644 wish/cpp/certs/server.key create mode 100644 wish/cpp/src/tls_context.cc create mode 100644 wish/cpp/src/tls_context.h diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..f66f639 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "C_Cpp.clang_format_style": "Google", +} \ No newline at end of file diff --git a/wish/cpp/CMakeLists.txt b/wish/cpp/CMakeLists.txt index 7cf6102..f24890c 100644 --- a/wish/cpp/CMakeLists.txt +++ b/wish/cpp/CMakeLists.txt @@ -17,25 +17,43 @@ FetchContent_Declare( GIT_REPOSITORY https://github.com/libevent/libevent.git GIT_TAG master ) -# Disable OpenSSL and other heavy features for libevent to keep build fast/simple if possible + +FetchContent_Declare( + boringssl + GIT_REPOSITORY https://boringssl.googlesource.com/boringssl + GIT_TAG main +) + +# Disable OpenSSL and Mbed TLS. We use BoringSSL instead. set(EVENT__DISABLE_OPENSSL ON CACHE BOOL "" FORCE) set(EVENT__DISABLE_MBEDTLS ON CACHE BOOL "" FORCE) + +# Exclude tests, sample files, etc. that we don't need. +set(EVENT__DISABLE_BENCHMARKS ON CACHE BOOL "" FORCE) set(EVENT__DISABLE_TESTS ON CACHE BOOL "" FORCE) set(EVENT__DISABLE_REGRESS ON CACHE BOOL "" FORCE) set(EVENT__DISABLE_SAMPLES ON CACHE BOOL "" FORCE) -FetchContent_MakeAvailable(wslay libevent) +FetchContent_MakeAvailable(wslay libevent boringssl) include_directories(${wslay_SOURCE_DIR}/lib/includes) include_directories(${libevent_SOURCE_DIR}/include) include_directories(${libevent_BINARY_DIR}/include) +include_directories(${boringssl_SOURCE_DIR}/include) include_directories(src) +# We will compile libevent's bufferevent_openssl.c inside our library +# since we disabled it in libevent's own build. add_library(wish_handler src/wish_handler.cc src/wish_handler.h + ${libevent_SOURCE_DIR}/bufferevent_openssl.c + ${libevent_SOURCE_DIR}/bufferevent_ssl.c + src/tls_context.cc + src/tls_context.h ) -target_link_libraries(wish_handler wslay event) +# BoringSSL targets: ssl and crypto +target_link_libraries(wish_handler wslay event ssl crypto) add_executable(wish-server examples/server.cc) target_link_libraries(wish-server wish_handler) diff --git a/wish/cpp/certs/ca.crt b/wish/cpp/certs/ca.crt new file mode 100644 index 0000000..4d31e16 --- /dev/null +++ b/wish/cpp/certs/ca.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDAzCCAeugAwIBAgIULUllQ/GTW3bJoBxzDeGx+PnANfgwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGVGVzdENBMB4XDTI2MDIyNTA0NTIwM1oXDTI3MDIyNTA0 +NTIwM1owETEPMA0GA1UEAwwGVGVzdENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEA2WlzLjr4zzS4mNp37NUUl/nJrC17QmNt7fsNszR7u8PuY8Opw9F6 +BBMsP0V4TT3Vht8BBgFJcOrC6cbMURxk2b+Qflzbn4WNKwx014BGIFwDoG3x3LT7 +3cTdVweHm9x6HX23XF7NZr//TOJ2Dkkix8jmvxjinn1ebfJOC+oMDYeUkO7UpolB +2KF+b+oPurVL8690Db6iVb3X4goCW+vE9VdDBRrujo7zSztg8TVGilIuv3W2WKzF +hzd1EXt8MwSLR5HXWpoVm6wuIt/wiylkvzayc3yUCYMS+Z7dCZibhLdYIkITzCb/ ++k8p9B+nXY6lHKfeChryqOOcsgp8sliBmQIDAQABo1MwUTAdBgNVHQ4EFgQUulOC +wCKuUv1iwoNFir55WHgiunwwHwYDVR0jBBgwFoAUulOCwCKuUv1iwoNFir55WHgi +unwwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAjkYV7MyJHlJS +lzHXUSTKQxwchllofsNPJ6BXEeNKPvfOTTe+KJKjSyldvzmQmVQpoqBpi5NBPNuC +yYesF7A002MSlH6udsBYiDlMr0z0oj0fdJZkXSxQgMKtigw7Qr60uNhT5Cb3Sn95 +PHAOfUnwH2iQ8omd7OnCOs/80xp//cwMKlOuMbq7X4YOQxRP04RK8AU0fyrrpuj6 +A+opTHhTQBr81OngLf4DKl9L7sS8fmHmo31pGHALP2+goDVB5YT6m4Hysp9PeVdc +zKlGbV/OZRNaEqqZdhkr6gUiV6TxLb3eaAN55AlTsVMS2CPGljsf9gyXnX0HdeOO +R80+cmIbmg== +-----END CERTIFICATE----- diff --git a/wish/cpp/certs/ca.key b/wish/cpp/certs/ca.key new file mode 100644 index 0000000..edf892d --- /dev/null +++ b/wish/cpp/certs/ca.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDZaXMuOvjPNLiY +2nfs1RSX+cmsLXtCY23t+w2zNHu7w+5jw6nD0XoEEyw/RXhNPdWG3wEGAUlw6sLp +xsxRHGTZv5B+XNufhY0rDHTXgEYgXAOgbfHctPvdxN1XB4eb3HodfbdcXs1mv/9M +4nYOSSLHyOa/GOKefV5t8k4L6gwNh5SQ7tSmiUHYoX5v6g+6tUvzr3QNvqJVvdfi +CgJb68T1V0MFGu6OjvNLO2DxNUaKUi6/dbZYrMWHN3URe3wzBItHkddamhWbrC4i +3/CLKWS/NrJzfJQJgxL5nt0JmJuEt1giQhPMJv/6Tyn0H6ddjqUcp94KGvKo45yy +CnyyWIGZAgMBAAECggEAFfW7YTjqawZ+m0zc1maG6htcQhiFddUUdFhaf8Z+NX7i +wD+yEPICjrEPk/P8xOOJIvJ5OF2uqPnDdojCmDJDowVhD0xqkBQ1qDqdvisqGihl +IuIcDxCWTKYO+9SKP2VfjcVGHS3DtjxQKZhJt6NuQIsDuJtnP343CKiz9qrdLQv8 +JqqbIETgJD2i/JOhmVFB00Xx1sGSGUe7LpDGtZ0S4Yv6deoRM1OFZ8wLJyf1rmlh +c0FJqRGyKAsSERYYBUnKsVB8MOMDgucmrFkSowslPQW1F3TeX1Jq3fS3DX0ie7pt ++CO15FhKc7EEKEsgtgRt4o49nXTscmaQwkM/vDh+sQKBgQD7EEdzYeBhYWnt+keb +/h4tAkKiRnQGYXMJbIhvsGHx+eFo+eV/2ntZAQq1MOVpVF6p4aM41Z4r3+GiurLe +ymt7mTrLYpkNQ02tkL6cMqEF8EghuAMHSTPY29/ZiiihU5bckhIfmCXX9YEjNskA +vWEO5Ed73GxiL02Zu8+mBpEY6QKBgQDdr8lAPJnlABu5vAxrLqqYySCNW77ihMpU +7/SuiwDnK3CDvCGaclL4C3R7HMKOCa7SbK9nGgllEs2hfTQrcbP0Qz47qYdhnXdr +S8KcSZMgAH0L3sA3dKO9QsbvumMRBN+8kxN0o3PkYqpE+L0Zmq+ZYd9awB2Cy98q +MoGNUIa1MQKBgQCrA4a3+Iafrnw6Zw4aGrmxTOXYpYboxb5XP/+bnJjK+7voBrim +I0t77/K8QycxXQ/yRckpsJDCMAkBEI1Apr8Z/OEIowu/9gVWYc8ElJQMeISZuz8M +2ncfk33iL3LHmSmc6z6/GKNGfGtPckTuZRFU1HhAzX9iTfhc7Ipf+/8f6QKBgBK4 +K0hPVbduoOi4JlxOnn00TplhK+c4y1UMxh6PAk6C7odRNY0zJipn3TggH5Wa37ZJ +Ey6jljOAuPhv+B3LBiUUIIctM49cmp7m0NIdrFzBbc24y4ZjRQhQQTgxBviC7tmf +mb75pmmco0AbuOwWkclj6FZjbpqC2J9ZkHL8X8OhAoGAGCky9qOEZSIGwOFGwnM/ +Y1a1xI0kZSYfA7AnacqAXUQ0tjMMTB1O8t+qKFLCRWVgnphWKpJ5WCGabZ0uFywM +O7MS5FFhmkNFdlS4ajJVscY4yWtPbb9SGHW572zqYEaI0kUbvSDXqqpUBh+9fvLk +URpPRg1F1oO2Lgox3tYamCw= +-----END PRIVATE KEY----- diff --git a/wish/cpp/certs/ca.srl b/wish/cpp/certs/ca.srl new file mode 100644 index 0000000..1e535db --- /dev/null +++ b/wish/cpp/certs/ca.srl @@ -0,0 +1 @@ +4881D8895D13397DC3319D6AFCE4BD764D28B887 diff --git a/wish/cpp/certs/client.crt b/wish/cpp/certs/client.crt new file mode 100644 index 0000000..5e7731a --- /dev/null +++ b/wish/cpp/certs/client.crt @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC9jCCAd6gAwIBAgIUSIHYiV0TOX3DMZ1q/OS9dk0ouIcwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGVGVzdENBMB4XDTI2MDIyNTA0NTIwM1oXDTI3MDIyNTA0 +NTIwM1owFTETMBEGA1UEAwwKVGVzdENsaWVudDCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAL7UV/B4sfiqkHPY8BrwprfXc6zuvCKQmK9wSVSHB12dFNnN +/05B05cTjCtwx+k/OvqOAqtfm4Fj5h5Gzv0VYcJvOkoOGtG/+Fwm3J2yCcjQLuhe +osgONk+5PG5emSbtjkmt1NWP8gdzydm93eCIp7CdQDNEqQHPsxLgLwUeiSXWNIw2 +TKZ/9/jEavkI7T/ex3Wowpc8qk2sQdXHOQSDhERZ2xKbrenujTfu3xjis/ajhdg5 +P78qiVmK2BVtxp+m/tIIrn5vJJHQXiO3QObWUxKGJqiDgDn3YX3P23cRcM6jiD/7 +jPH9qi9EMatnznUqdG9W9+n9VouE3bDbo4yMTesCAwEAAaNCMEAwHQYDVR0OBBYE +FLEyhA7GYfN1bFgtCg2ZaMrzPJMIMB8GA1UdIwQYMBaAFLpTgsAirlL9YsKDRYq+ +eVh4Irp8MA0GCSqGSIb3DQEBCwUAA4IBAQAdWTsNALb5EC4zdUSeLOOPUMIuAyuE +kce1gIqrJz6+dFdm4VFQzd+t69q2VDHaMjoJYUGaFj9LRngtXVZVhNktk27KtIst +62TzdvOwGZ0SxieI9ZNyaPw4d55TNH5JLroA0P7Xs/lSZxBiidJUPSGEAEQBi7Kn +nHJUk2NzVnglsT+s32B/i2+w/Kab3U1GLZxqZcf2rWBgv/gKvSXmKY1tsoRQAcFs +ZLVBo+3WPmbOa6uh6bIZ/mCLtpZ9fn+Sg5uJsjhSOIrVLReY5sncTuhuX/XGY2Mx +LhJvlTsy9arpWQCGAbKkllQglzSYPrCO4ne9wiEtHZe3kFGEZPSJ9pYz +-----END CERTIFICATE----- diff --git a/wish/cpp/certs/client.csr b/wish/cpp/certs/client.csr new file mode 100644 index 0000000..cabb8b5 --- /dev/null +++ b/wish/cpp/certs/client.csr @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICWjCCAUICAQAwFTETMBEGA1UEAwwKVGVzdENsaWVudDCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAL7UV/B4sfiqkHPY8BrwprfXc6zuvCKQmK9wSVSH +B12dFNnN/05B05cTjCtwx+k/OvqOAqtfm4Fj5h5Gzv0VYcJvOkoOGtG/+Fwm3J2y +CcjQLuheosgONk+5PG5emSbtjkmt1NWP8gdzydm93eCIp7CdQDNEqQHPsxLgLwUe +iSXWNIw2TKZ/9/jEavkI7T/ex3Wowpc8qk2sQdXHOQSDhERZ2xKbrenujTfu3xji +s/ajhdg5P78qiVmK2BVtxp+m/tIIrn5vJJHQXiO3QObWUxKGJqiDgDn3YX3P23cR +cM6jiD/7jPH9qi9EMatnznUqdG9W9+n9VouE3bDbo4yMTesCAwEAAaAAMA0GCSqG +SIb3DQEBCwUAA4IBAQCTBMs1gqu0wKetW81iJ+7Px37NONLgSXzXUmAU0OYID5w4 +7UH9EhgfSbiOWxagJeTngiDIUDl4ZqpGMKqszY2BYpEQKm/Cg1pVmsfIBWWoOa1o +dlQngoxMP1M8TE5KE0/I855l8vWoHoNGG6YCIlkvmkUReolYrT2uksry5ph2a8lG +xu16uoiHuukKalw9p04tfopYgEsstmgIigNR/uEvF/CMhtFOmwM0UCkuqYJAy5Mi +m56I3fZqtCqgOj8i5JEgOPtFYV7mzLEkkmoFXKpBSDjutzf49ph+AVaQsA2kMif8 +5lO9LFWelCH5xQYBYXMQfpcp8xB+/qsRvki5fNNG +-----END CERTIFICATE REQUEST----- diff --git a/wish/cpp/certs/client.key b/wish/cpp/certs/client.key new file mode 100644 index 0000000..fd56458 --- /dev/null +++ b/wish/cpp/certs/client.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC+1FfweLH4qpBz +2PAa8Ka313Os7rwikJivcElUhwddnRTZzf9OQdOXE4wrcMfpPzr6jgKrX5uBY+Ye +Rs79FWHCbzpKDhrRv/hcJtydsgnI0C7oXqLIDjZPuTxuXpkm7Y5JrdTVj/IHc8nZ +vd3giKewnUAzRKkBz7MS4C8FHokl1jSMNkymf/f4xGr5CO0/3sd1qMKXPKpNrEHV +xzkEg4REWdsSm63p7o037t8Y4rP2o4XYOT+/KolZitgVbcafpv7SCK5+bySR0F4j +t0Dm1lMShiaog4A592F9z9t3EXDOo4g/+4zx/aovRDGrZ851KnRvVvfp/VaLhN2w +26OMjE3rAgMBAAECggEANnq82GQ8uvdG4ivu8GH/1sBlv9swTtXlIUD3TnB2Q92S +lFPhLWBRnfHwtH4wNIDev6VHUdGrvZbdnYstkMdH75B9naLFOViK+RQHK+YmMPRu +T9yksGSOUNhbTk8nfhuX4aUE/CtqN4Jw//7alz2sUhmyuHBDp8a6IwtpoRaEpQ4x +8gNgN8QLFCGGMypK//bJCIFaZeWwwXqvdzhtWjsJ98g4/cHsmY5TqAjrn/nsh+es +LMHAQP867NIPn9kzhXC8mho1bjdl13q/Fc43kvzdXvi//BviHf4hy3Iq6MZVDkSl +9ii+46Hz0Hm+hEv/z9eaA9P7DHeW/Eu5xmq9Thp1MQKBgQDpeuQcuiUe3c08nMyG +qoAc6CLH02y1ZnK8kTuKZ9xfKcnlBdmO9kEby2JjL2tB9unReUkOsJsJ4P+eyQ0m +eldUsz+yOkKZUL8wfWumO3aorN8OVKpXeoC5XgWPsBh8enQOqM2h9Z0kkaQxpH54 +27tJTCNcs/as1H147THueVyrtwKBgQDRPFIhGmgbyqQRpRoxMNVjtuTegc5/U7UW +k9LZyPOZo+en0D3cWjqhTtKLD1iSErbGggxyJej0kLGVYgoNGsWperh2nA8nMhAh +du+cg4Yw0QEO5vbt4yvl+ZbRR0UrGv8eJyMfKnLBLv6BYYmVJKX0jVLDWXR8gmxs +pLu+pCRXbQKBgEBPvW28SGVMKzA68ItXg5pyxsHMFvGQmqIeTww8t5Lu69HN3rNm +WWDSkPNJKH4vCRDOG7WUJ+B8vWx7bMfggxWtmin5qkaY21D7+x762iB0HazQ3Wrj +L3nf0CBYHSaMhFNVY+7svLBJ/bQ+3ydjPx9dfZAXcicBEN6yV0Kc403ZAoGBALY5 +17l22xbhPFUVuqL+ycnnPpq+6I4h5AP+yFLeXbIAer+/cDDZ8FgOYvWzbssBO2fV +WWuMsr9UySS11tUk7OM2uzKppdTYGA5dHD/umE8pp8dHxeTWxaOr5PrtHEN3Zprn +MQJyoLC48fTSctWOrm43Ks5xuS67FBzmt5BIOlJdAoGAGlDOnrIq3kBsCzjltUMi +NKcC9Zv2U45lxLpFXDn88EJjK822P41nFEPOrFxz92rU+m6tLh+v9oxzeVyTXz0t +2wFOpUmyqp3dx+ao0MmZ2osnTHDy4CZlbDsq2Zgutp6FJIuwrnGqQvrm5dzLi7K1 +EUN76mURJTkwNGavgFB+QUw= +-----END PRIVATE KEY----- diff --git a/wish/cpp/certs/server.crt b/wish/cpp/certs/server.crt new file mode 100644 index 0000000..6a1415a --- /dev/null +++ b/wish/cpp/certs/server.crt @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC9TCCAd2gAwIBAgIUSIHYiV0TOX3DMZ1q/OS9dk0ouIYwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGVGVzdENBMB4XDTI2MDIyNTA0NTIwM1oXDTI3MDIyNTA0 +NTIwM1owFDESMBAGA1UEAwwJMTI3LjAuMC4xMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAx+Nj4qUS5OHJFk+ododRkifW2Av/rHj+w90e8riOTYYl4JfS +kymur/ytAgg6cmXg0t9BNwfogOxPPdSI7pHEW9uo7Ckt6HsvkjNiEgIKhpoM6cee +RovXvUMfZz87oaTgWJLAVIuy9KDAbiH2S6YsWBeHVYW6gG6/+DzOp4EtR2mIatL9 +oNYhymbT92Wh94kEwS08rYkDkpely36C1pY4JrQSbi56FTTly796MHXVdbKwJ/iA +HWCVrwLJO2KR2alLlanGeDzI80PvOis2VoLk73Rip1KtN82uVQaGLj/Ue87ra6Er +/UAIh7xeNLBwJy+ms/eUN+Qb1RHxLxoYUVlffQIDAQABo0IwQDAdBgNVHQ4EFgQU +ELOIoZF2Uon8O0zVTay9IbotxZ8wHwYDVR0jBBgwFoAUulOCwCKuUv1iwoNFir55 +WHgiunwwDQYJKoZIhvcNAQELBQADggEBABjGHfP9mwhYM/7cQX+zPWrgx/SdoiCB +ddNytI7P3zodQLyiArwn03gmO1XG4J/7dXfdxL64Y8Ome41XfgnqOoSFcT3GAaWD +l1BfWxbwe7QwoZLNrV4oUjX9BzjAIOYVcxuHc9d46aiX3q3USf9oZRVkimEMlXVI +MpRaGEmJ83mjyzdk/ECKmOilFMWB5fgOwTiKI2vt0rL0Q3UJ/jxz+AzaX0flGvym +hTiwFTUmR4y+VZDb0qvQX/gY+EqJwXiNZN8QO7BmKdPxhdtFuxbkdMjbVOR9IkgJ +X1MiZsrMdQTAohJ4nCLgKdiCXdOhSWJWyKjKl3orn52zHHVgBqhwZtU= +-----END CERTIFICATE----- diff --git a/wish/cpp/certs/server.csr b/wish/cpp/certs/server.csr new file mode 100644 index 0000000..870ced9 --- /dev/null +++ b/wish/cpp/certs/server.csr @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICWTCCAUECAQAwFDESMBAGA1UEAwwJMTI3LjAuMC4xMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAx+Nj4qUS5OHJFk+ododRkifW2Av/rHj+w90e8riO +TYYl4JfSkymur/ytAgg6cmXg0t9BNwfogOxPPdSI7pHEW9uo7Ckt6HsvkjNiEgIK +hpoM6ceeRovXvUMfZz87oaTgWJLAVIuy9KDAbiH2S6YsWBeHVYW6gG6/+DzOp4Et +R2mIatL9oNYhymbT92Wh94kEwS08rYkDkpely36C1pY4JrQSbi56FTTly796MHXV +dbKwJ/iAHWCVrwLJO2KR2alLlanGeDzI80PvOis2VoLk73Rip1KtN82uVQaGLj/U +e87ra6Er/UAIh7xeNLBwJy+ms/eUN+Qb1RHxLxoYUVlffQIDAQABoAAwDQYJKoZI +hvcNAQELBQADggEBABgXHLjpfS5F+ELiq+ouMMFbgZvcopB5+aO6serFg+bCcFPe +EfEwbmggF6vUnfXg3YOV8IHw+sYmaN02f1xydRtupeIbyLB2drsmS/5Nd8iwcO0w +GQlLIhY0L8a85sjNfoy2qn4GFkAo7YRFUkOU0PcE7LWNQqUMccovUtCddI2chEuB +XAfE4LNQd7z6o//Fh4AReOY+Z98qMU9jJe+Of9QPqzXdI+27gLKj9aGrKl4LuqE7 +vVjkjCCuWn7VoEv5Re5X/sa37K3DxWtr6ee1q2DnDqBLCxZh7cgHNjWx8MLZCQtP +JhFJfpScoBTVlM8rc7KmYD9yycoFgacZ+qTCPDE= +-----END CERTIFICATE REQUEST----- diff --git a/wish/cpp/certs/server.key b/wish/cpp/certs/server.key new file mode 100644 index 0000000..88136a4 --- /dev/null +++ b/wish/cpp/certs/server.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDH42PipRLk4ckW +T6h2h1GSJ9bYC/+seP7D3R7yuI5NhiXgl9KTKa6v/K0CCDpyZeDS30E3B+iA7E89 +1IjukcRb26jsKS3oey+SM2ISAgqGmgzpx55Gi9e9Qx9nPzuhpOBYksBUi7L0oMBu +IfZLpixYF4dVhbqAbr/4PM6ngS1HaYhq0v2g1iHKZtP3ZaH3iQTBLTytiQOSl6XL +foLWljgmtBJuLnoVNOXLv3owddV1srAn+IAdYJWvAsk7YpHZqUuVqcZ4PMjzQ+86 +KzZWguTvdGKnUq03za5VBoYuP9R7zutroSv9QAiHvF40sHAnL6az95Q35BvVEfEv +GhhRWV99AgMBAAECggEAAtT5Zs4g6OY8A5loURmUscXnuNLesfJa5ap91EGCHp4O +blKoVJZsF6k0SEmWjmVcHJC2K1Hs3Nq8OquGrx6YkhaYG5RvxpHsOB2LP6cQwBxx +n2RJHUXA7jkDumI+dYlQ9mBJ4kjCZc3bPBQ2GZdGnI7kx3ToEga/qIQwB1aArjjN +nANPbyP1ttLi5cM0wrXlYaBwpLFaxdPBdDUCvx3ER2gpC7D8PbKBMgjGkQI+KR1m +NZ785s57lTdTPRF/t41Iw0mzCwXcYH9XMglNls5EOZJkRzf6ycMvQD8yk199tL3+ +vCkmPw0HGe2LTAOLwUMSVJmw14ZfzNsJoyBfhRCzsQKBgQD1mNEUnVUWSw1+7txV +2AcUrIJWQWHmRQqr35WIGNT08faXw1v1psJqIU4KW0b1dC4T/PRpveRfwtUXt39b +bwvNorOeUuhvnKi93o/aDrOOMradExXICl8BRp+xc7fl7ta28QC+zlYs9urLh5/E +az6pSvvHTW39I1wW5zTnOO8zWQKBgQDQWuveIvbz2IO7JOf/orQ67kE6M+hmLdX2 +fEF/DHetCDqqi2HoMHtV4d6XdQL9aJ5MwcbfbMBXpISxi2d588hHVoEpvSLi0hDe +ijPu7hrgOZt8n1VLQzih6KSjxSCnxA6LSSr/iCtMNPdIoYdKmRyG8ZgCEbDlJQDZ +RUXtSW48xQKBgGzf8wg9eyPn37K+tyTDINh0ZU9RqtHHF6T7+DEeOQHhZhz/OPwc +kiE0ZIFI15smhurLf5qE2QHuwELEUQw6nTPrBc+RF4OrIk8RpBnZ3JWUO8pEVKqa +lmVdZpvnHcYr7Dmre1Ya6K8EQzA5DoWnuV6ZZCaFV9YZX9CzbIt4fOn5AoGAHbGX +g+T/xOjKfVVZKvmJLgzehuj26fkGUUaMHwsr0yElG0EaBvlB2o+CJZurfWn3hYDo +Utcw4ky0DImNibfQhzow1j36RtEhTlXr6NVORz5uhmg+w6ck3w5EyIJDkSVD3V3k +Ht7NLOMvis5adas0gZbUzxauWznW0SAqQxL//vECgYEAoqNdpO/hvOaIRKZLrzfR +fp/v0Kth2v8p5GF1ukdYGtmuP4qDLekxgkn6AO9ocv/orBtF1ec/pOUG6+rqlZX0 +3IJvNF9N0FBEieFxlWpMwIAQr2/VtSOyyyNknhNpxpHBTKWX1nPmjB6pm+AEB8KW +HmCOYVwhpOyitHAfHC7s3hk= +-----END PRIVATE KEY----- diff --git a/wish/cpp/examples/client.cc b/wish/cpp/examples/client.cc index 7502190..e585c50 100644 --- a/wish/cpp/examples/client.cc +++ b/wish/cpp/examples/client.cc @@ -1,59 +1,80 @@ -#include -#include -#include - -#include +#define EVENT__HAVE_OPENSSL 1 #include +#include #include +#include +#include +#include +#include +#include + +#include "../src/tls_context.h" #include "../src/wish_handler.h" int main() { - struct event_base *base = event_base_new(); - if (!base) { - std::cerr << "Could not initialize libevent!" << std::endl; - return 1; - } - - struct evdns_base *dns_base = evdns_base_new(base, 1); - if (!dns_base) { - std::cerr << "Could not initialize dns!" << std::endl; - return 1; - } - - struct bufferevent *bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE); - if (!bev) { - std::cerr << "Could not create bufferevent!" << std::endl; - return 1; - } - - if (bufferevent_socket_connect_hostname(bev, dns_base, AF_INET, "127.0.0.1", 8080) < 0) { - std::cerr << "Could not connect!" << std::endl; - return 1; - } - - // Handler manages its own lifecycle (deletes itself on close) - WishHandler* handler = new WishHandler(bev, false); // is_server = false - - handler->SetOnOpen([handler]() { - std::cout << "Connected and Handshake Complete!" << std::endl; - - handler->SendText("Hello WiSH Text!"); - handler->SendBinary("Hello WiSH Binary!"); - handler->SendMetadata(true, "Hello WiSH Metadata!"); - }); - - handler->SetOnMessage([](uint8_t opcode, const std::string& msg) { - std::cout << "Server says [opcode " << (int)opcode << "]: " << msg << std::endl; - }); - - handler->Start(); - - std::cout << "Client running..." << std::endl; - event_base_dispatch(base); - - evdns_base_free(dns_base, 0); - event_base_free(base); - - return 0; + // Initialize OpenSSL + SSL_library_init(); + SSL_load_error_strings(); + + TlsContext tls_ctx; + tls_ctx.set_ca_path("../certs/ca.crt"); + tls_ctx.set_identity_certificate_path("../certs/client.crt"); + tls_ctx.set_private_key_path("../certs/client.key"); + if (!tls_ctx.Init(false)) { + std::cerr << "Failed to init TLS context" << std::endl; + return 1; + } + struct event_base* base = event_base_new(); + if (!base) { + std::cerr << "Could not initialize libevent!" << std::endl; + return 1; + } + + struct evdns_base* dns_base = evdns_base_new(base, 1); + if (!dns_base) { + std::cerr << "Could not initialize dns!" << std::endl; + return 1; + } + + SSL* ssl = SSL_new(tls_ctx.ssl_ctx()); + struct bufferevent* bev = + bufferevent_openssl_socket_new(base, -1, ssl, BUFFEREVENT_SSL_CONNECTING, + BEV_OPT_CLOSE_ON_FREE); + if (!bev) { + std::cerr << "Could not create bufferevent!" << std::endl; + return 1; + } + + if (bufferevent_socket_connect_hostname(bev, dns_base, AF_INET, "127.0.0.1", + 8080) < 0) { + std::cerr << "Could not connect!" << std::endl; + return 1; + } + + // Handler manages its own lifecycle (deletes itself on close) + WishHandler* handler = new WishHandler(bev, false); // is_server = false + + handler->SetOnOpen([handler]() { + std::cout << "Connected and Handshake Complete!" << std::endl; + + handler->SendText("Hello WiSH Text!"); + handler->SendBinary("Hello WiSH Binary!"); + handler->SendMetadata(true, "Hello WiSH Metadata!"); + }); + + handler->SetOnMessage([](uint8_t opcode, const std::string& msg) { + std::cout << "Server says [opcode " << (int)opcode << "]: " << msg + << std::endl; + }); + + handler->Start(); + + std::cout << "Client running..." << std::endl; + event_base_dispatch(base); + + evdns_base_free(dns_base, 0); + event_base_free(base); + + return 0; } diff --git a/wish/cpp/examples/server.cc b/wish/cpp/examples/server.cc index 1f47ce8..3e2aa76 100644 --- a/wish/cpp/examples/server.cc +++ b/wish/cpp/examples/server.cc @@ -1,88 +1,124 @@ -#include -#include -#include // Added for std::to_string - +#include +#define EVENT__HAVE_OPENSSL 1 +#include +#include #include #include -#include -#include - -#include "../src/wish_handler.h" - -void accept_conn_cb(struct evconnlistener *listener, evutil_socket_t fd, - struct sockaddr *address, int socklen, void *ctx) { - - struct event_base *base = evconnlistener_get_base(listener); - struct bufferevent *bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE); - - std::cout << "Client connected." << std::endl; - - // Handler manages its own lifecycle (deletes itself on close) - WishHandler* handler = new WishHandler(bev, true); - - handler->SetOnMessage([handler](uint8_t opcode, const std::string& msg) { - std::string type; - switch(opcode) { - case 1: type = "TEXT"; break; - case 2: type = "BINARY"; break; - case 3: type = "TEXT_METADATA"; break; - case 4: type = "BINARY_METADATA"; break; - default: type = "UNKNOWN(" + std::to_string(opcode) + ")"; break; - } - std::cout << "Received [" << type << "]: " << msg << std::endl; - - // Echo back - int res = 0; - if (opcode == 1) res = handler->SendText("Echo: " + msg); - else if (opcode == 2) res = handler->SendBinary("Echo: " + msg); - else if (opcode == 3 || opcode == 4) res = handler->SendMetadata(opcode == 3, "Echo: " + msg); - - if (res != 0) { - std::cerr << "Failed to send echo." << std::endl; - } - }); - - handler->Start(); -} +#include -void accept_error_cb(struct evconnlistener *listener, void *ctx) { - struct event_base *base = evconnlistener_get_base(listener); - int err = EVUTIL_SOCKET_ERROR(); - std::cerr << "Got an error " << err << " (" << evutil_socket_error_to_string(err) << ") on the listener. Shutting down." << std::endl; - event_base_loopexit(base, NULL); -} +#include +#include +#include // Added for std::to_string -int main(int argc, char **argv) { - struct event_base *base; - struct evconnlistener *listener; - struct sockaddr_in sin; - int port = 8080; +#include "../src/tls_context.h" +#include "../src/wish_handler.h" - base = event_base_new(); - if (!base) { - std::cerr << "Could not initialize libevent!" << std::endl; - return 1; +void accept_conn_cb(struct evconnlistener* listener, evutil_socket_t fd, + struct sockaddr* address, int socklen, void* ctx) { + struct event_base* base = evconnlistener_get_base(listener); + TlsContext* tls_ctx = static_cast(ctx); + + SSL* ssl = SSL_new(tls_ctx->ssl_ctx()); + struct bufferevent* bev = + bufferevent_openssl_socket_new(base, fd, ssl, BUFFEREVENT_SSL_ACCEPTING, + BEV_OPT_CLOSE_ON_FREE); + + std::cout << "Client connected." << std::endl; + + // Handler manages its own lifecycle (deletes itself on close) + WishHandler* handler = new WishHandler(bev, true); + + handler->SetOnMessage([handler](uint8_t opcode, const std::string& msg) { + std::string type; + switch (opcode) { + case 1: + type = "TEXT"; + break; + case 2: + type = "BINARY"; + break; + case 3: + type = "TEXT_METADATA"; + break; + case 4: + type = "BINARY_METADATA"; + break; + default: + type = "UNKNOWN(" + std::to_string(opcode) + ")"; + break; } - - memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = htonl(0); - sin.sin_port = htons(port); - - listener = evconnlistener_new_bind(base, accept_conn_cb, NULL, - LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, -1, - (struct sockaddr*)&sin, sizeof(sin)); - - if (!listener) { - std::cerr << "Could not create a listener!" << std::endl; - return 1; + std::cout << "Received [" << type << "]: " << msg << std::endl; + + // Echo back + int res = 0; + if (opcode == 1) + res = handler->SendText("Echo: " + msg); + else if (opcode == 2) + res = handler->SendBinary("Echo: " + msg); + else if (opcode == 3 || opcode == 4) + res = handler->SendMetadata(opcode == 3, "Echo: " + msg); + + if (res != 0) { + std::cerr << "Failed to send echo." << std::endl; } + }); - std::cout << "Server listening on port " << port << "..." << std::endl; - event_base_dispatch(base); + handler->Start(); +} - evconnlistener_free(listener); - event_base_free(base); +void accept_error_cb(struct evconnlistener* listener, void* ctx) { + struct event_base* base = evconnlistener_get_base(listener); + int err = EVUTIL_SOCKET_ERROR(); + std::cerr << "Got an error " << err << " (" + << evutil_socket_error_to_string(err) + << ") on the listener. Shutting down." << std::endl; + event_base_loopexit(base, NULL); +} - return 0; +int main(int argc, char** argv) { + // Initialize OpenSSL + SSL_library_init(); + SSL_load_error_strings(); + + TlsContext tls_ctx; + tls_ctx.set_ca_path("../certs/ca.crt"); + tls_ctx.set_identity_certificate_path("../certs/server.crt"); + tls_ctx.set_private_key_path("../certs/server.key"); + if (!tls_ctx.Init(true)) { + std::cerr << "Failed to init TLS context" << std::endl; + return 1; + } + + struct event_base* base; + struct evconnlistener* listener; + struct sockaddr_in sin; + int port = 8080; + + base = event_base_new(); + if (!base) { + std::cerr << "Could not initialize libevent!" << std::endl; + return 1; + } + + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = htonl(0); + sin.sin_port = htons(port); + + listener = evconnlistener_new_bind(base, accept_conn_cb, &tls_ctx, + LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, + -1, (struct sockaddr*)&sin, sizeof(sin)); + + if (!listener) { + std::cerr << "Could not create a listener!" << std::endl; + return 1; + } + + std::cout << "Server listening on port " << port << "..." << std::endl; + event_base_dispatch(base); + + evconnlistener_free(listener); + event_base_free(base); + + return 0; } diff --git a/wish/cpp/src/tls_context.cc b/wish/cpp/src/tls_context.cc new file mode 100644 index 0000000..3589f2c --- /dev/null +++ b/wish/cpp/src/tls_context.cc @@ -0,0 +1,82 @@ +#include "tls_context.h" + +#include + +TlsContext::TlsContext() : ssl_ctx_(nullptr) {} + +TlsContext::~TlsContext() { + if (ssl_ctx_) { + SSL_CTX_free(ssl_ctx_); + } +} + +void TlsContext::set_identity_certificate_path(const std::string& path) { identity_certificate_path_ = path; } +void TlsContext::set_private_key_path(const std::string& path) { private_key_path_ = path; } +void TlsContext::set_ca_path(const std::string& path) { ca_path_ = path; } + +const std::string& TlsContext::identity_certificate_path() const { return identity_certificate_path_; } +const std::string& TlsContext::private_key_path() const { return private_key_path_; } +const std::string& TlsContext::ca_path() const { return ca_path_; } + +bool TlsContext::Init(bool is_server) { + if (ssl_ctx_) { + SSL_CTX_free(ssl_ctx_); + ssl_ctx_ = nullptr; + } + + const SSL_METHOD* method = + is_server ? TLS_server_method() : TLS_client_method(); + ssl_ctx_ = SSL_CTX_new(method); + + if (!ssl_ctx_) { + std::cerr << "Failed to create SSL_CTX" << std::endl; + return false; + } + + // Load CA certificate for verifying the peer + if (!ca_path_.empty()) { + if (SSL_CTX_load_verify_locations(ssl_ctx_, ca_path_.c_str(), nullptr) != + 1) { + std::cerr << "Error loading CA file: " << ca_path_ << std::endl; + return false; + } + } + + // Set verification mode for mTLS + if (is_server) { + SSL_CTX_set_verify(ssl_ctx_, + SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, + nullptr); + } else { + SSL_CTX_set_verify(ssl_ctx_, SSL_VERIFY_PEER, nullptr); + } + + // Load own certificate and key + if (!identity_certificate_path_.empty() && !private_key_path_.empty()) { + if (SSL_CTX_use_certificate_file(ssl_ctx_, identity_certificate_path_.c_str(), + SSL_FILETYPE_PEM) <= 0) { + std::cerr << "Error loading certificate file: " << identity_certificate_path_ + << std::endl; + return false; + } + + if (SSL_CTX_use_PrivateKey_file(ssl_ctx_, private_key_path_.c_str(), + SSL_FILETYPE_PEM) <= 0) { + std::cerr << "Error loading key file: " << private_key_path_ << std::endl; + return false; + } + + if (!SSL_CTX_check_private_key(ssl_ctx_)) { + std::cerr << "Private key does not match the certificate public key" + << std::endl; + return false; + } + } else { + std::cerr << "Warning: cert_path or key_path is empty. mTLS may fail." + << std::endl; + } + + return true; +} + +SSL_CTX* TlsContext::ssl_ctx() const { return ssl_ctx_; } diff --git a/wish/cpp/src/tls_context.h b/wish/cpp/src/tls_context.h new file mode 100644 index 0000000..7a07713 --- /dev/null +++ b/wish/cpp/src/tls_context.h @@ -0,0 +1,37 @@ +#ifndef WISH_CPP_SRC_TLS_CONTEXT_H_ +#define WISH_CPP_SRC_TLS_CONTEXT_H_ + +#include + +#include +#include + +class TlsContext { + public: + TlsContext(); + ~TlsContext(); + + void set_identity_certificate_path(const std::string& identity_certificate_path); + void set_private_key_path(const std::string& private_key_path); + void set_ca_path(const std::string& ca_path); + + const std::string& identity_certificate_path() const; + const std::string& private_key_path() const; + const std::string& ca_path() const; + + // Initialize the SSL_CTX. If is_server is true, it is configured for a server + // and requires client certificates (mTLS). If is_server is false, it is + // configured for a client and verifies the server. + bool Init(bool is_server); + + SSL_CTX* ssl_ctx() const; + + private: + std::string identity_certificate_path_; + std::string private_key_path_; + std::string ca_path_; + + SSL_CTX* ssl_ctx_; +}; + +#endif // WISH_CPP_SRC_TLS_CONTEXT_H_ diff --git a/wish/cpp/src/wish_handler.cc b/wish/cpp/src/wish_handler.cc index 17d6e83..f9ed132 100644 --- a/wish/cpp/src/wish_handler.cc +++ b/wish/cpp/src/wish_handler.cc @@ -1,28 +1,21 @@ +#include "wish_handler.h" + +#include #include -#include #include -#include +#include #include -#include -#include #include +#include #include - -#include "wish_handler.h" +#include WishHandler::WishHandler(struct bufferevent* bev, bool is_server) : bev_(bev), is_server_(is_server), ctx_(nullptr), state_(HANDSHAKE) { - struct wslay_event_callbacks callbacks = { - RecvCallback, - SendCallback, - GenMaskCallback, - NULL, - NULL, - NULL, - OnMsgRecvCallback - }; + RecvCallback, SendCallback, GenMaskCallback, NULL, + NULL, NULL, OnMsgRecvCallback}; if (is_server_) { wslay_event_context_server_init(&ctx_, &callbacks, this); @@ -47,18 +40,15 @@ void WishHandler::Start() { } } -void WishHandler::SetOnMessage(MessageCallback cb) { - on_message_ = cb; -} +void WishHandler::SetOnMessage(MessageCallback cb) { on_message_ = cb; } -void WishHandler::SetOnOpen(OpenCallback cb) { - on_open_ = cb; -} +void WishHandler::SetOnOpen(OpenCallback cb) { on_open_ = cb; } -ssize_t WishHandler::RecvCallback(wslay_event_context *ctx, uint8_t *buf, size_t len, int flags, void *user_data) { +ssize_t WishHandler::RecvCallback(wslay_event_context* ctx, uint8_t* buf, + size_t len, int flags, void* user_data) { WishHandler* handler = static_cast(user_data); - struct evbuffer *input = bufferevent_get_input(handler->bev_); - + struct evbuffer* input = bufferevent_get_input(handler->bev_); + size_t data_len = evbuffer_get_length(input); if (data_len == 0) { wslay_event_set_error(ctx, WSLAY_ERR_WOULDBLOCK); @@ -70,13 +60,15 @@ ssize_t WishHandler::RecvCallback(wslay_event_context *ctx, uint8_t *buf, size_t return copy_len; } -ssize_t WishHandler::SendCallback(wslay_event_context *ctx, const uint8_t *data, size_t len, int flags, void *user_data) { +ssize_t WishHandler::SendCallback(wslay_event_context* ctx, const uint8_t* data, + size_t len, int flags, void* user_data) { WishHandler* handler = static_cast(user_data); bufferevent_write(handler->bev_, data, len); return len; } -int WishHandler::GenMaskCallback(wslay_event_context *ctx, uint8_t *buf, size_t len, void *user_data) { +int WishHandler::GenMaskCallback(wslay_event_context* ctx, uint8_t* buf, + size_t len, void* user_data) { static std::mt19937 rng(std::random_device{}()); std::uniform_int_distribution dist(0, 255); for (size_t i = 0; i < len; ++i) { @@ -85,7 +77,9 @@ int WishHandler::GenMaskCallback(wslay_event_context *ctx, uint8_t *buf, size_t return 0; } -void WishHandler::OnMsgRecvCallback(wslay_event_context *ctx, const wslay_event_on_msg_recv_arg *arg, void *user_data) { +void WishHandler::OnMsgRecvCallback(wslay_event_context* ctx, + const wslay_event_on_msg_recv_arg* arg, + void* user_data) { WishHandler* handler = static_cast(user_data); if (handler->on_message_) { std::string msg(reinterpret_cast(arg->msg), arg->msg_length); @@ -93,25 +87,28 @@ void WishHandler::OnMsgRecvCallback(wslay_event_context *ctx, const wslay_event_ } } -void WishHandler::ReadCallback(struct bufferevent *bev, void *ctx) { +void WishHandler::ReadCallback(struct bufferevent* bev, void* ctx) { WishHandler* handler = static_cast(ctx); - + if (handler->state_ == HANDSHAKE) { handler->HandleHandshake(); } - + if (handler->state_ == OPEN) { int err = wslay_event_recv(handler->ctx_); if (err != 0) { - std::cerr << "wslay_event_recv failed: " << err << std::endl; - // Should we close? + std::cerr << "wslay_event_recv failed: " << err << std::endl; + // Should we close? } } } -void WishHandler::EventCallback(struct bufferevent *bev, short events, void *ctx) { +void WishHandler::EventCallback(struct bufferevent* bev, short events, + void* ctx) { if (events & BEV_EVENT_ERROR) { - std::cerr << "Error on socket: " << evutil_socket_error_to_string(EVUTIL_SOCKET_ERROR()) << std::endl; + std::cerr << "Error on socket: " + << evutil_socket_error_to_string(EVUTIL_SOCKET_ERROR()) + << std::endl; } if (events & (BEV_EVENT_EOF | BEV_EVENT_ERROR)) { // Connection closed @@ -123,12 +120,9 @@ void WishHandler::EventCallback(struct bufferevent *bev, short events, void *ctx int WishHandler::SendMessage(uint8_t opcode, const std::string& msg) { if (state_ != OPEN) return -1; - + struct wslay_event_msg msg_frame = { - opcode, - reinterpret_cast(msg.c_str()), - msg.length() - }; + opcode, reinterpret_cast(msg.c_str()), msg.length()}; // Queue msg int res = wslay_event_queue_msg(ctx_, &msg_frame); if (res != 0) return res; @@ -154,29 +148,29 @@ int WishHandler::SendMetadata(bool is_text, const std::string& msg) { void WishHandler::HandleHandshake() { if (is_server_) { if (ReadHttpRequest()) { - SendHttpResponse("200 OK", "application/web-stream"); - state_ = OPEN; - if (on_open_) on_open_(); + SendHttpResponse("200 OK", "application/web-stream"); + state_ = OPEN; + if (on_open_) on_open_(); } } else { // Client waits for response if (ReadHttpResponse()) { - state_ = OPEN; - // Maybe trigger some on_open callback? - std::cout << "Handshake complete!" << std::endl; - if (on_open_) on_open_(); + state_ = OPEN; + // Maybe trigger some on_open callback? + std::cout << "Handshake complete!" << std::endl; + if (on_open_) on_open_(); } } } bool WishHandler::ReadHttpRequest() { - struct evbuffer *input = bufferevent_get_input(bev_); + struct evbuffer* input = bufferevent_get_input(bev_); size_t len = evbuffer_get_length(input); if (len == 0) return false; // Search for \r\n\r\n struct evbuffer_ptr ptr = evbuffer_search(input, "\r\n\r\n", 4, NULL); - if (ptr.pos == -1) return false; // Not full headers yet + if (ptr.pos == -1) return false; // Not full headers yet // Read up to the end of headers size_t header_len = ptr.pos + 4; @@ -188,18 +182,19 @@ bool WishHandler::ReadHttpRequest() { // Check for WiSH specific header if (data.find("Content-Type: application/web-stream") == std::string::npos && - data.find("content-type: application/web-stream") == std::string::npos) { + data.find("content-type: application/web-stream") == std::string::npos) { std::cerr << "Missing WiSH Content-Type!" << std::endl; return false; } return true; } -void WishHandler::SendHttpResponse(const std::string& status, const std::string& content_type) { +void WishHandler::SendHttpResponse(const std::string& status, + const std::string& content_type) { std::stringstream ss; ss << "HTTP/1.1 " << status << "\r\n"; ss << "Content-Type: " << content_type << "\r\n"; - ss << "\r\n"; // End of headers + ss << "\r\n"; // End of headers std::string data = ss.str(); bufferevent_write(bev_, data.c_str(), data.length()); } @@ -215,11 +210,11 @@ void WishHandler::SendHttpRequest() { } bool WishHandler::ReadHttpResponse() { - struct evbuffer *input = bufferevent_get_input(bev_); - + struct evbuffer* input = bufferevent_get_input(bev_); + // Search for \r\n\r\n struct evbuffer_ptr ptr = evbuffer_search(input, "\r\n\r\n", 4, NULL); - if (ptr.pos == -1) return false; + if (ptr.pos == -1) return false; size_t header_len = ptr.pos + 4; char* headers = new char[header_len + 1]; @@ -227,7 +222,7 @@ bool WishHandler::ReadHttpResponse() { headers[header_len] = '\0'; std::string data(headers); delete[] headers; - + if (data.find("200 OK") == std::string::npos) { std::cerr << "Bad Handy handshake response: " << data << std::endl; return false; diff --git a/wish/cpp/src/wish_handler.h b/wish/cpp/src/wish_handler.h index bde6077..4ad6b22 100644 --- a/wish/cpp/src/wish_handler.h +++ b/wish/cpp/src/wish_handler.h @@ -1,13 +1,13 @@ #ifndef WISH_CPP_SRC_WISH_HANDLER_H_ #define WISH_CPP_SRC_WISH_HANDLER_H_ -#include -#include #include #include +#include +#include -#include #include +#include // wslay forward decl extern "C" { @@ -17,7 +17,8 @@ struct wslay_event_on_msg_recv_arg; class WishHandler { public: - using MessageCallback = std::function; + using MessageCallback = + std::function; using OpenCallback = std::function; // Constructor takes an already created bufferevent @@ -42,32 +43,35 @@ class WishHandler { MessageCallback on_message_; OpenCallback on_open_; - enum State { - HANDSHAKE, - OPEN, - CLOSED - }; + enum State { HANDSHAKE, OPEN, CLOSED }; State state_; // wslay callbacks - static ssize_t RecvCallback(struct wslay_event_context *ctx, uint8_t *buf, size_t len, int flags, void *user_data); - static ssize_t SendCallback(struct wslay_event_context *ctx, const uint8_t *data, size_t len, int flags, void *user_data); - static int GenMaskCallback(struct wslay_event_context *ctx, uint8_t *buf, size_t len, void *user_data); - static void OnMsgRecvCallback(struct wslay_event_context *ctx, const struct wslay_event_on_msg_recv_arg *arg, void *user_data); + static ssize_t RecvCallback(struct wslay_event_context* ctx, uint8_t* buf, + size_t len, int flags, void* user_data); + static ssize_t SendCallback(struct wslay_event_context* ctx, + const uint8_t* data, size_t len, int flags, + void* user_data); + static int GenMaskCallback(struct wslay_event_context* ctx, uint8_t* buf, + size_t len, void* user_data); + static void OnMsgRecvCallback(struct wslay_event_context* ctx, + const struct wslay_event_on_msg_recv_arg* arg, + void* user_data); // libevent callbacks - static void ReadCallback(struct bufferevent *bev, void *ctx); + static void ReadCallback(struct bufferevent* bev, void* ctx); // We might not need a write callback unless we want flow control // static void WriteCallback(struct bufferevent *bev, void *ctx); - static void EventCallback(struct bufferevent *bev, short events, void *ctx); + static void EventCallback(struct bufferevent* bev, short events, void* ctx); void HandleHandshake(); bool ReadHttpRequest(); bool ReadHttpResponse(); - void SendHttpResponse(const std::string& status, const std::string& content_type); + void SendHttpResponse(const std::string& status, + const std::string& content_type); void SendHttpRequest(); int SendMessage(uint8_t opcode, const std::string& msg); }; -#endif // WISH_CPP_SRC_WISH_HANDLER_H_ +#endif // WISH_CPP_SRC_WISH_HANDLER_H_ From e0d9160d0f61e3ca190a7345f888ccb4923955a5 Mon Sep 17 00:00:00 2001 From: Takeshi Yoshino <4511440+tyoshino@users.noreply.github.com> Date: Thu, 26 Feb 2026 04:55:00 +0000 Subject: [PATCH 2/5] fix --- .vscode/settings.json | 3 --- wish/cpp/examples/client.cc | 9 +++++---- wish/cpp/examples/server.cc | 10 ++++++---- 3 files changed, 11 insertions(+), 11 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index f66f639..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "C_Cpp.clang_format_style": "Google", -} \ No newline at end of file diff --git a/wish/cpp/examples/client.cc b/wish/cpp/examples/client.cc index e585c50..ac8eb73 100644 --- a/wish/cpp/examples/client.cc +++ b/wish/cpp/examples/client.cc @@ -1,3 +1,8 @@ +#include +#include +#include + +// To use BoringSSL #define EVENT__HAVE_OPENSSL 1 #include #include @@ -5,10 +10,6 @@ #include #include -#include -#include -#include - #include "../src/tls_context.h" #include "../src/wish_handler.h" diff --git a/wish/cpp/examples/server.cc b/wish/cpp/examples/server.cc index 3e2aa76..f001780 100644 --- a/wish/cpp/examples/server.cc +++ b/wish/cpp/examples/server.cc @@ -1,4 +1,10 @@ #include + +#include +#include +#include // Added for std::to_string + +// To use BoringSSL #define EVENT__HAVE_OPENSSL 1 #include #include @@ -6,10 +12,6 @@ #include #include -#include -#include -#include // Added for std::to_string - #include "../src/tls_context.h" #include "../src/wish_handler.h" From 61e88599581603e7249aded9af1f3459c38b8977 Mon Sep 17 00:00:00 2001 From: Takeshi Yoshino <4511440+tyoshino@users.noreply.github.com> Date: Thu, 26 Feb 2026 05:03:53 +0000 Subject: [PATCH 3/5] fix --- wish/cpp/examples/client.cc | 102 +++++++++++++------------ wish/cpp/examples/server.cc | 143 +++++++++++++++++++----------------- 2 files changed, 127 insertions(+), 118 deletions(-) diff --git a/wish/cpp/examples/client.cc b/wish/cpp/examples/client.cc index ac8eb73..4389c24 100644 --- a/wish/cpp/examples/client.cc +++ b/wish/cpp/examples/client.cc @@ -14,68 +14,72 @@ #include "../src/wish_handler.h" int main() { - // Initialize OpenSSL - SSL_library_init(); - SSL_load_error_strings(); + // Initialize OpenSSL + SSL_library_init(); + SSL_load_error_strings(); - TlsContext tls_ctx; - tls_ctx.set_ca_path("../certs/ca.crt"); - tls_ctx.set_identity_certificate_path("../certs/client.crt"); - tls_ctx.set_private_key_path("../certs/client.key"); - if (!tls_ctx.Init(false)) { - std::cerr << "Failed to init TLS context" << std::endl; - return 1; - } - struct event_base* base = event_base_new(); - if (!base) { - std::cerr << "Could not initialize libevent!" << std::endl; - return 1; - } + TlsContext tls_ctx; + tls_ctx.set_ca_path("../certs/ca.crt"); + tls_ctx.set_identity_certificate_path("../certs/client.crt"); + tls_ctx.set_private_key_path("../certs/client.key"); + if (!tls_ctx.Init(false)) + { + std::cerr << "Failed to init TLS context" << std::endl; + return 1; + } + struct event_base *base = event_base_new(); + if (!base) + { + std::cerr << "Could not initialize libevent!" << std::endl; + return 1; + } - struct evdns_base* dns_base = evdns_base_new(base, 1); - if (!dns_base) { - std::cerr << "Could not initialize dns!" << std::endl; - return 1; - } + struct evdns_base *dns_base = evdns_base_new(base, 1); + if (!dns_base) + { + std::cerr << "Could not initialize dns!" << std::endl; + return 1; + } - SSL* ssl = SSL_new(tls_ctx.ssl_ctx()); - struct bufferevent* bev = - bufferevent_openssl_socket_new(base, -1, ssl, BUFFEREVENT_SSL_CONNECTING, - BEV_OPT_CLOSE_ON_FREE); - if (!bev) { - std::cerr << "Could not create bufferevent!" << std::endl; - return 1; - } + SSL *ssl = SSL_new(tls_ctx.ssl_ctx()); + struct bufferevent *bev = + bufferevent_openssl_socket_new(base, -1, ssl, BUFFEREVENT_SSL_CONNECTING, + BEV_OPT_CLOSE_ON_FREE); + if (!bev) + { + std::cerr << "Could not create bufferevent!" << std::endl; + return 1; + } - if (bufferevent_socket_connect_hostname(bev, dns_base, AF_INET, "127.0.0.1", - 8080) < 0) { - std::cerr << "Could not connect!" << std::endl; - return 1; - } + if (bufferevent_socket_connect_hostname(bev, dns_base, AF_INET, "127.0.0.1", + 8080) < 0) + { + std::cerr << "Could not connect!" << std::endl; + return 1; + } - // Handler manages its own lifecycle (deletes itself on close) - WishHandler* handler = new WishHandler(bev, false); // is_server = false + // Handler manages its own lifecycle (deletes itself on close) + WishHandler *handler = new WishHandler(bev, false); // is_server = false - handler->SetOnOpen([handler]() { + handler->SetOnOpen([handler]() + { std::cout << "Connected and Handshake Complete!" << std::endl; handler->SendText("Hello WiSH Text!"); handler->SendBinary("Hello WiSH Binary!"); - handler->SendMetadata(true, "Hello WiSH Metadata!"); - }); + handler->SendMetadata(true, "Hello WiSH Metadata!"); }); - handler->SetOnMessage([](uint8_t opcode, const std::string& msg) { - std::cout << "Server says [opcode " << (int)opcode << "]: " << msg - << std::endl; - }); + handler->SetOnMessage([](uint8_t opcode, const std::string &msg) + { std::cout << "Server says [opcode " << (int)opcode << "]: " << msg + << std::endl; }); - handler->Start(); + handler->Start(); - std::cout << "Client running..." << std::endl; - event_base_dispatch(base); + std::cout << "Client running..." << std::endl; + event_base_dispatch(base); - evdns_base_free(dns_base, 0); - event_base_free(base); + evdns_base_free(dns_base, 0); + event_base_free(base); - return 0; + return 0; } diff --git a/wish/cpp/examples/server.cc b/wish/cpp/examples/server.cc index f001780..6cdd714 100644 --- a/wish/cpp/examples/server.cc +++ b/wish/cpp/examples/server.cc @@ -2,7 +2,7 @@ #include #include -#include // Added for std::to_string +#include // Added for std::to_string // To use BoringSSL #define EVENT__HAVE_OPENSSL 1 @@ -15,22 +15,23 @@ #include "../src/tls_context.h" #include "../src/wish_handler.h" -void accept_conn_cb(struct evconnlistener* listener, evutil_socket_t fd, - struct sockaddr* address, int socklen, void* ctx) { - struct event_base* base = evconnlistener_get_base(listener); - TlsContext* tls_ctx = static_cast(ctx); +void accept_conn_cb(struct evconnlistener *listener, evutil_socket_t fd, + struct sockaddr *address, int socklen, void *ctx) { + struct event_base *base = evconnlistener_get_base(listener); + TlsContext *tls_ctx = static_cast(ctx); - SSL* ssl = SSL_new(tls_ctx->ssl_ctx()); - struct bufferevent* bev = - bufferevent_openssl_socket_new(base, fd, ssl, BUFFEREVENT_SSL_ACCEPTING, - BEV_OPT_CLOSE_ON_FREE); + SSL *ssl = SSL_new(tls_ctx->ssl_ctx()); + struct bufferevent *bev = + bufferevent_openssl_socket_new(base, fd, ssl, BUFFEREVENT_SSL_ACCEPTING, + BEV_OPT_CLOSE_ON_FREE); - std::cout << "Client connected." << std::endl; + std::cout << "Client connected." << std::endl; - // Handler manages its own lifecycle (deletes itself on close) - WishHandler* handler = new WishHandler(bev, true); + // Handler manages its own lifecycle (deletes itself on close) + WishHandler *handler = new WishHandler(bev, true); - handler->SetOnMessage([handler](uint8_t opcode, const std::string& msg) { + handler->SetOnMessage([handler](uint8_t opcode, const std::string &msg) + { std::string type; switch (opcode) { case 1: @@ -62,65 +63,69 @@ void accept_conn_cb(struct evconnlistener* listener, evutil_socket_t fd, if (res != 0) { std::cerr << "Failed to send echo." << std::endl; - } - }); + } }); - handler->Start(); + handler->Start(); } -void accept_error_cb(struct evconnlistener* listener, void* ctx) { - struct event_base* base = evconnlistener_get_base(listener); - int err = EVUTIL_SOCKET_ERROR(); - std::cerr << "Got an error " << err << " (" - << evutil_socket_error_to_string(err) - << ") on the listener. Shutting down." << std::endl; - event_base_loopexit(base, NULL); +void accept_error_cb(struct evconnlistener *listener, void *ctx) +{ + struct event_base *base = evconnlistener_get_base(listener); + int err = EVUTIL_SOCKET_ERROR(); + std::cerr << "Got an error " << err << " (" + << evutil_socket_error_to_string(err) + << ") on the listener. Shutting down." << std::endl; + event_base_loopexit(base, NULL); } -int main(int argc, char** argv) { - // Initialize OpenSSL - SSL_library_init(); - SSL_load_error_strings(); - - TlsContext tls_ctx; - tls_ctx.set_ca_path("../certs/ca.crt"); - tls_ctx.set_identity_certificate_path("../certs/server.crt"); - tls_ctx.set_private_key_path("../certs/server.key"); - if (!tls_ctx.Init(true)) { - std::cerr << "Failed to init TLS context" << std::endl; - return 1; - } - - struct event_base* base; - struct evconnlistener* listener; - struct sockaddr_in sin; - int port = 8080; - - base = event_base_new(); - if (!base) { - std::cerr << "Could not initialize libevent!" << std::endl; - return 1; - } - - memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = htonl(0); - sin.sin_port = htons(port); - - listener = evconnlistener_new_bind(base, accept_conn_cb, &tls_ctx, - LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, - -1, (struct sockaddr*)&sin, sizeof(sin)); - - if (!listener) { - std::cerr << "Could not create a listener!" << std::endl; - return 1; - } - - std::cout << "Server listening on port " << port << "..." << std::endl; - event_base_dispatch(base); - - evconnlistener_free(listener); - event_base_free(base); - - return 0; +int main(int argc, char **argv) +{ + // Initialize OpenSSL + SSL_library_init(); + SSL_load_error_strings(); + + TlsContext tls_ctx; + tls_ctx.set_ca_path("../certs/ca.crt"); + tls_ctx.set_identity_certificate_path("../certs/server.crt"); + tls_ctx.set_private_key_path("../certs/server.key"); + if (!tls_ctx.Init(true)) + { + std::cerr << "Failed to init TLS context" << std::endl; + return 1; + } + + struct event_base *base; + struct evconnlistener *listener; + struct sockaddr_in sin; + int port = 8080; + + base = event_base_new(); + if (!base) + { + std::cerr << "Could not initialize libevent!" << std::endl; + return 1; + } + + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = htonl(0); + sin.sin_port = htons(port); + + listener = evconnlistener_new_bind(base, accept_conn_cb, &tls_ctx, + LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, + -1, (struct sockaddr *)&sin, sizeof(sin)); + + if (!listener) + { + std::cerr << "Could not create a listener!" << std::endl; + return 1; + } + + std::cout << "Server listening on port " << port << "..." << std::endl; + event_base_dispatch(base); + + evconnlistener_free(listener); + event_base_free(base); + + return 0; } From c3120d790349184c04af499e2333317ab65279ac Mon Sep 17 00:00:00 2001 From: Takeshi Yoshino <4511440+tyoshino@users.noreply.github.com> Date: Thu, 26 Feb 2026 05:05:49 +0000 Subject: [PATCH 4/5] fix --- wish/cpp/examples/client.cc | 17 +++----- wish/cpp/examples/server.cc | 77 ++++++++++++++++++------------------- 2 files changed, 43 insertions(+), 51 deletions(-) diff --git a/wish/cpp/examples/client.cc b/wish/cpp/examples/client.cc index 4389c24..45ad46c 100644 --- a/wish/cpp/examples/client.cc +++ b/wish/cpp/examples/client.cc @@ -14,7 +14,7 @@ #include "../src/wish_handler.h" int main() { - // Initialize OpenSSL + // Initialize BoringSSL SSL_library_init(); SSL_load_error_strings(); @@ -22,21 +22,18 @@ int main() { tls_ctx.set_ca_path("../certs/ca.crt"); tls_ctx.set_identity_certificate_path("../certs/client.crt"); tls_ctx.set_private_key_path("../certs/client.key"); - if (!tls_ctx.Init(false)) - { + if (!tls_ctx.Init(false)) { std::cerr << "Failed to init TLS context" << std::endl; return 1; } struct event_base *base = event_base_new(); - if (!base) - { + if (!base) { std::cerr << "Could not initialize libevent!" << std::endl; return 1; } struct evdns_base *dns_base = evdns_base_new(base, 1); - if (!dns_base) - { + if (!dns_base) { std::cerr << "Could not initialize dns!" << std::endl; return 1; } @@ -45,15 +42,13 @@ int main() { struct bufferevent *bev = bufferevent_openssl_socket_new(base, -1, ssl, BUFFEREVENT_SSL_CONNECTING, BEV_OPT_CLOSE_ON_FREE); - if (!bev) - { + if (!bev) { std::cerr << "Could not create bufferevent!" << std::endl; return 1; } if (bufferevent_socket_connect_hostname(bev, dns_base, AF_INET, "127.0.0.1", - 8080) < 0) - { + 8080) < 0) { std::cerr << "Could not connect!" << std::endl; return 1; } diff --git a/wish/cpp/examples/server.cc b/wish/cpp/examples/server.cc index 6cdd714..aa83743 100644 --- a/wish/cpp/examples/server.cc +++ b/wish/cpp/examples/server.cc @@ -30,40 +30,40 @@ void accept_conn_cb(struct evconnlistener *listener, evutil_socket_t fd, // Handler manages its own lifecycle (deletes itself on close) WishHandler *handler = new WishHandler(bev, true); - handler->SetOnMessage([handler](uint8_t opcode, const std::string &msg) - { - std::string type; - switch (opcode) { - case 1: - type = "TEXT"; - break; - case 2: - type = "BINARY"; - break; - case 3: - type = "TEXT_METADATA"; - break; - case 4: - type = "BINARY_METADATA"; - break; - default: - type = "UNKNOWN(" + std::to_string(opcode) + ")"; - break; - } - std::cout << "Received [" << type << "]: " << msg << std::endl; - - // Echo back - int res = 0; - if (opcode == 1) - res = handler->SendText("Echo: " + msg); - else if (opcode == 2) - res = handler->SendBinary("Echo: " + msg); - else if (opcode == 3 || opcode == 4) - res = handler->SendMetadata(opcode == 3, "Echo: " + msg); - - if (res != 0) { - std::cerr << "Failed to send echo." << std::endl; - } }); + handler->SetOnMessage([handler](uint8_t opcode, const std::string &msg) { + std::string type; + switch (opcode) { + case 1: + type = "TEXT"; + break; + case 2: + type = "BINARY"; + break; + case 3: + type = "TEXT_METADATA"; + break; + case 4: + type = "BINARY_METADATA"; + break; + default: + type = "UNKNOWN(" + std::to_string(opcode) + ")"; + break; + } + std::cout << "Received [" << type << "]: " << msg << std::endl; + + // Echo back + int res = 0; + if (opcode == 1) + res = handler->SendText("Echo: " + msg); + else if (opcode == 2) + res = handler->SendBinary("Echo: " + msg); + else if (opcode == 3 || opcode == 4) + res = handler->SendMetadata(opcode == 3, "Echo: " + msg); + + if (res != 0) { + std::cerr << "Failed to send echo." << std::endl; + } + }); handler->Start(); } @@ -88,8 +88,7 @@ int main(int argc, char **argv) tls_ctx.set_ca_path("../certs/ca.crt"); tls_ctx.set_identity_certificate_path("../certs/server.crt"); tls_ctx.set_private_key_path("../certs/server.key"); - if (!tls_ctx.Init(true)) - { + if (!tls_ctx.Init(true)) { std::cerr << "Failed to init TLS context" << std::endl; return 1; } @@ -100,8 +99,7 @@ int main(int argc, char **argv) int port = 8080; base = event_base_new(); - if (!base) - { + if (!base) { std::cerr << "Could not initialize libevent!" << std::endl; return 1; } @@ -115,8 +113,7 @@ int main(int argc, char **argv) LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, -1, (struct sockaddr *)&sin, sizeof(sin)); - if (!listener) - { + if (!listener){ std::cerr << "Could not create a listener!" << std::endl; return 1; } From 687a966ef4b7ac871c438c2ec3a2205c14063df9 Mon Sep 17 00:00:00 2001 From: Takeshi Yoshino <4511440+tyoshino@users.noreply.github.com> Date: Mon, 2 Mar 2026 03:23:13 +0000 Subject: [PATCH 5/5] fix --- wish/cpp/examples/client.cc | 6 +++--- wish/cpp/examples/server.cc | 6 +++--- wish/cpp/src/tls_context.cc | 28 ++++++++++++++-------------- wish/cpp/src/tls_context.h | 18 +++++++++--------- 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/wish/cpp/examples/client.cc b/wish/cpp/examples/client.cc index 45ad46c..41ac36e 100644 --- a/wish/cpp/examples/client.cc +++ b/wish/cpp/examples/client.cc @@ -19,9 +19,9 @@ int main() { SSL_load_error_strings(); TlsContext tls_ctx; - tls_ctx.set_ca_path("../certs/ca.crt"); - tls_ctx.set_identity_certificate_path("../certs/client.crt"); - tls_ctx.set_private_key_path("../certs/client.key"); + tls_ctx.set_ca_file("../certs/ca.crt"); + tls_ctx.set_certificate_file("../certs/client.crt"); + tls_ctx.set_private_key_file("../certs/client.key"); if (!tls_ctx.Init(false)) { std::cerr << "Failed to init TLS context" << std::endl; return 1; diff --git a/wish/cpp/examples/server.cc b/wish/cpp/examples/server.cc index aa83743..1a9d5f4 100644 --- a/wish/cpp/examples/server.cc +++ b/wish/cpp/examples/server.cc @@ -85,9 +85,9 @@ int main(int argc, char **argv) SSL_load_error_strings(); TlsContext tls_ctx; - tls_ctx.set_ca_path("../certs/ca.crt"); - tls_ctx.set_identity_certificate_path("../certs/server.crt"); - tls_ctx.set_private_key_path("../certs/server.key"); + tls_ctx.set_ca_file("../certs/ca.crt"); + tls_ctx.set_certificate_file("../certs/server.crt"); + tls_ctx.set_private_key_file("../certs/server.key"); if (!tls_ctx.Init(true)) { std::cerr << "Failed to init TLS context" << std::endl; return 1; diff --git a/wish/cpp/src/tls_context.cc b/wish/cpp/src/tls_context.cc index 3589f2c..765509f 100644 --- a/wish/cpp/src/tls_context.cc +++ b/wish/cpp/src/tls_context.cc @@ -10,13 +10,13 @@ TlsContext::~TlsContext() { } } -void TlsContext::set_identity_certificate_path(const std::string& path) { identity_certificate_path_ = path; } -void TlsContext::set_private_key_path(const std::string& path) { private_key_path_ = path; } -void TlsContext::set_ca_path(const std::string& path) { ca_path_ = path; } +void TlsContext::set_certificate_file(const std::string& file) { certificate_file_ = file; } +void TlsContext::set_private_key_file(const std::string& file) { private_key_file_ = file; } +void TlsContext::set_ca_file(const std::string& file) { ca_file_ = file; } -const std::string& TlsContext::identity_certificate_path() const { return identity_certificate_path_; } -const std::string& TlsContext::private_key_path() const { return private_key_path_; } -const std::string& TlsContext::ca_path() const { return ca_path_; } +const std::string& TlsContext::certificate_file() const { return certificate_file_; } +const std::string& TlsContext::private_key_file() const { return private_key_file_; } +const std::string& TlsContext::ca_file() const { return ca_file_; } bool TlsContext::Init(bool is_server) { if (ssl_ctx_) { @@ -34,10 +34,10 @@ bool TlsContext::Init(bool is_server) { } // Load CA certificate for verifying the peer - if (!ca_path_.empty()) { - if (SSL_CTX_load_verify_locations(ssl_ctx_, ca_path_.c_str(), nullptr) != + if (!ca_file_.empty()) { + if (SSL_CTX_load_verify_locations(ssl_ctx_, ca_file_.c_str(), nullptr) != 1) { - std::cerr << "Error loading CA file: " << ca_path_ << std::endl; + std::cerr << "Error loading CA file: " << ca_file_ << std::endl; return false; } } @@ -52,17 +52,17 @@ bool TlsContext::Init(bool is_server) { } // Load own certificate and key - if (!identity_certificate_path_.empty() && !private_key_path_.empty()) { - if (SSL_CTX_use_certificate_file(ssl_ctx_, identity_certificate_path_.c_str(), + if (!certificate_file_.empty() && !private_key_file_.empty()) { + if (SSL_CTX_use_certificate_file(ssl_ctx_, certificate_file_.c_str(), SSL_FILETYPE_PEM) <= 0) { - std::cerr << "Error loading certificate file: " << identity_certificate_path_ + std::cerr << "Error loading certificate file: " << certificate_file_ << std::endl; return false; } - if (SSL_CTX_use_PrivateKey_file(ssl_ctx_, private_key_path_.c_str(), + if (SSL_CTX_use_PrivateKey_file(ssl_ctx_, private_key_file_.c_str(), SSL_FILETYPE_PEM) <= 0) { - std::cerr << "Error loading key file: " << private_key_path_ << std::endl; + std::cerr << "Error loading key file: " << private_key_file_ << std::endl; return false; } diff --git a/wish/cpp/src/tls_context.h b/wish/cpp/src/tls_context.h index 7a07713..71be9bb 100644 --- a/wish/cpp/src/tls_context.h +++ b/wish/cpp/src/tls_context.h @@ -11,13 +11,13 @@ class TlsContext { TlsContext(); ~TlsContext(); - void set_identity_certificate_path(const std::string& identity_certificate_path); - void set_private_key_path(const std::string& private_key_path); - void set_ca_path(const std::string& ca_path); + void set_certificate_file(const std::string& identity_certificate_path); + void set_private_key_file(const std::string& private_key_path); + void set_ca_file(const std::string& ca_path); - const std::string& identity_certificate_path() const; - const std::string& private_key_path() const; - const std::string& ca_path() const; + const std::string& certificate_file() const; + const std::string& private_key_file() const; + const std::string& ca_file() const; // Initialize the SSL_CTX. If is_server is true, it is configured for a server // and requires client certificates (mTLS). If is_server is false, it is @@ -27,9 +27,9 @@ class TlsContext { SSL_CTX* ssl_ctx() const; private: - std::string identity_certificate_path_; - std::string private_key_path_; - std::string ca_path_; + std::string certificate_file_; + std::string private_key_file_; + std::string ca_file_; SSL_CTX* ssl_ctx_; };