ssl.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include "core/hle/service/ipc_helpers.h"
  4. #include "core/hle/service/server_manager.h"
  5. #include "core/hle/service/service.h"
  6. #include "core/hle/service/ssl/ssl.h"
  7. namespace Service::SSL {
  8. // This is nn::ssl::sf::CertificateFormat
  9. enum class CertificateFormat : u32 {
  10. Pem = 1,
  11. Der = 2,
  12. };
  13. // This is nn::ssl::sf::ContextOption
  14. enum class ContextOption : u32 {
  15. None = 0,
  16. CrlImportDateCheckEnable = 1,
  17. };
  18. // This is nn::ssl::sf::SslVersion
  19. struct SslVersion {
  20. union {
  21. u32 raw{};
  22. BitField<0, 1, u32> tls_auto;
  23. BitField<3, 1, u32> tls_v10;
  24. BitField<4, 1, u32> tls_v11;
  25. BitField<5, 1, u32> tls_v12;
  26. BitField<6, 1, u32> tls_v13;
  27. BitField<24, 7, u32> api_version;
  28. };
  29. };
  30. class ISslConnection final : public ServiceFramework<ISslConnection> {
  31. public:
  32. explicit ISslConnection(Core::System& system_, SslVersion version)
  33. : ServiceFramework{system_, "ISslConnection"}, ssl_version{version} {
  34. // clang-format off
  35. static const FunctionInfo functions[] = {
  36. {0, nullptr, "SetSocketDescriptor"},
  37. {1, nullptr, "SetHostName"},
  38. {2, nullptr, "SetVerifyOption"},
  39. {3, nullptr, "SetIoMode"},
  40. {4, nullptr, "GetSocketDescriptor"},
  41. {5, nullptr, "GetHostName"},
  42. {6, nullptr, "GetVerifyOption"},
  43. {7, nullptr, "GetIoMode"},
  44. {8, nullptr, "DoHandshake"},
  45. {9, nullptr, "DoHandshakeGetServerCert"},
  46. {10, nullptr, "Read"},
  47. {11, nullptr, "Write"},
  48. {12, nullptr, "Pending"},
  49. {13, nullptr, "Peek"},
  50. {14, nullptr, "Poll"},
  51. {15, nullptr, "GetVerifyCertError"},
  52. {16, nullptr, "GetNeededServerCertBufferSize"},
  53. {17, nullptr, "SetSessionCacheMode"},
  54. {18, nullptr, "GetSessionCacheMode"},
  55. {19, nullptr, "FlushSessionCache"},
  56. {20, nullptr, "SetRenegotiationMode"},
  57. {21, nullptr, "GetRenegotiationMode"},
  58. {22, nullptr, "SetOption"},
  59. {23, nullptr, "GetOption"},
  60. {24, nullptr, "GetVerifyCertErrors"},
  61. {25, nullptr, "GetCipherInfo"},
  62. {26, nullptr, "SetNextAlpnProto"},
  63. {27, nullptr, "GetNextAlpnProto"},
  64. {28, nullptr, "SetDtlsSocketDescriptor"},
  65. {29, nullptr, "GetDtlsHandshakeTimeout"},
  66. {30, nullptr, "SetPrivateOption"},
  67. {31, nullptr, "SetSrtpCiphers"},
  68. {32, nullptr, "GetSrtpCipher"},
  69. {33, nullptr, "ExportKeyingMaterial"},
  70. {34, nullptr, "SetIoTimeout"},
  71. {35, nullptr, "GetIoTimeout"},
  72. };
  73. // clang-format on
  74. RegisterHandlers(functions);
  75. }
  76. private:
  77. SslVersion ssl_version;
  78. };
  79. class ISslContext final : public ServiceFramework<ISslContext> {
  80. public:
  81. explicit ISslContext(Core::System& system_, SslVersion version)
  82. : ServiceFramework{system_, "ISslContext"}, ssl_version{version} {
  83. static const FunctionInfo functions[] = {
  84. {0, &ISslContext::SetOption, "SetOption"},
  85. {1, nullptr, "GetOption"},
  86. {2, &ISslContext::CreateConnection, "CreateConnection"},
  87. {3, nullptr, "GetConnectionCount"},
  88. {4, &ISslContext::ImportServerPki, "ImportServerPki"},
  89. {5, &ISslContext::ImportClientPki, "ImportClientPki"},
  90. {6, nullptr, "RemoveServerPki"},
  91. {7, nullptr, "RemoveClientPki"},
  92. {8, nullptr, "RegisterInternalPki"},
  93. {9, nullptr, "AddPolicyOid"},
  94. {10, nullptr, "ImportCrl"},
  95. {11, nullptr, "RemoveCrl"},
  96. {12, nullptr, "ImportClientCertKeyPki"},
  97. {13, nullptr, "GeneratePrivateKeyAndCert"},
  98. };
  99. RegisterHandlers(functions);
  100. }
  101. private:
  102. SslVersion ssl_version;
  103. void SetOption(HLERequestContext& ctx) {
  104. struct Parameters {
  105. ContextOption option;
  106. s32 value;
  107. };
  108. static_assert(sizeof(Parameters) == 0x8, "Parameters is an invalid size");
  109. IPC::RequestParser rp{ctx};
  110. const auto parameters = rp.PopRaw<Parameters>();
  111. LOG_WARNING(Service_SSL, "(STUBBED) called. option={}, value={}", parameters.option,
  112. parameters.value);
  113. IPC::ResponseBuilder rb{ctx, 2};
  114. rb.Push(ResultSuccess);
  115. }
  116. void CreateConnection(HLERequestContext& ctx) {
  117. LOG_WARNING(Service_SSL, "(STUBBED) called");
  118. IPC::ResponseBuilder rb{ctx, 2, 0, 1};
  119. rb.Push(ResultSuccess);
  120. rb.PushIpcInterface<ISslConnection>(system, ssl_version);
  121. }
  122. void ImportServerPki(HLERequestContext& ctx) {
  123. IPC::RequestParser rp{ctx};
  124. const auto certificate_format = rp.PopEnum<CertificateFormat>();
  125. [[maybe_unused]] const auto pkcs_12_certificates = ctx.ReadBuffer(0);
  126. constexpr u64 server_id = 0;
  127. LOG_WARNING(Service_SSL, "(STUBBED) called, certificate_format={}", certificate_format);
  128. IPC::ResponseBuilder rb{ctx, 4};
  129. rb.Push(ResultSuccess);
  130. rb.Push(server_id);
  131. }
  132. void ImportClientPki(HLERequestContext& ctx) {
  133. [[maybe_unused]] const auto pkcs_12_certificate = ctx.ReadBuffer(0);
  134. [[maybe_unused]] const auto ascii_password = [&ctx] {
  135. if (ctx.CanReadBuffer(1)) {
  136. return ctx.ReadBuffer(1);
  137. }
  138. return std::span<const u8>{};
  139. }();
  140. constexpr u64 client_id = 0;
  141. LOG_WARNING(Service_SSL, "(STUBBED) called");
  142. IPC::ResponseBuilder rb{ctx, 4};
  143. rb.Push(ResultSuccess);
  144. rb.Push(client_id);
  145. }
  146. };
  147. class ISslService final : public ServiceFramework<ISslService> {
  148. public:
  149. explicit ISslService(Core::System& system_) : ServiceFramework{system_, "ssl"} {
  150. // clang-format off
  151. static const FunctionInfo functions[] = {
  152. {0, &ISslService::CreateContext, "CreateContext"},
  153. {1, nullptr, "GetContextCount"},
  154. {2, nullptr, "GetCertificates"},
  155. {3, nullptr, "GetCertificateBufSize"},
  156. {4, nullptr, "DebugIoctl"},
  157. {5, &ISslService::SetInterfaceVersion, "SetInterfaceVersion"},
  158. {6, nullptr, "FlushSessionCache"},
  159. {7, nullptr, "SetDebugOption"},
  160. {8, nullptr, "GetDebugOption"},
  161. {8, nullptr, "ClearTls12FallbackFlag"},
  162. };
  163. // clang-format on
  164. RegisterHandlers(functions);
  165. }
  166. private:
  167. void CreateContext(HLERequestContext& ctx) {
  168. struct Parameters {
  169. SslVersion ssl_version;
  170. INSERT_PADDING_BYTES(0x4);
  171. u64 pid_placeholder;
  172. };
  173. static_assert(sizeof(Parameters) == 0x10, "Parameters is an invalid size");
  174. IPC::RequestParser rp{ctx};
  175. const auto parameters = rp.PopRaw<Parameters>();
  176. LOG_WARNING(Service_SSL, "(STUBBED) called, api_version={}, pid_placeholder={}",
  177. parameters.ssl_version.api_version, parameters.pid_placeholder);
  178. IPC::ResponseBuilder rb{ctx, 2, 0, 1};
  179. rb.Push(ResultSuccess);
  180. rb.PushIpcInterface<ISslContext>(system, parameters.ssl_version);
  181. }
  182. void SetInterfaceVersion(HLERequestContext& ctx) {
  183. IPC::RequestParser rp{ctx};
  184. u32 ssl_version = rp.Pop<u32>();
  185. LOG_DEBUG(Service_SSL, "called, ssl_version={}", ssl_version);
  186. IPC::ResponseBuilder rb{ctx, 2};
  187. rb.Push(ResultSuccess);
  188. }
  189. };
  190. void LoopProcess(Core::System& system) {
  191. auto server_manager = std::make_unique<ServerManager>(system);
  192. server_manager->RegisterNamedService("ssl", std::make_shared<ISslService>(system));
  193. ServerManager::RunServer(std::move(server_manager));
  194. }
  195. } // namespace Service::SSL