1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "tls_context_server.h"
17
18 #include <cinttypes>
19 #include <string>
20 #include <openssl/err.h>
21 #include <openssl/ssl.h>
22
23 #include "netstack_log.h"
24 #include "netstack_common_utils.h"
25 #include "tls_utils.h"
26 #ifdef HAS_NETMANAGER_BASE
27 #include "network_security_config.h"
28 #endif
29
30 namespace OHOS {
31 namespace NetStack {
32 namespace TlsSocket {
33 VerifyMode TLSContextServer::verifyMode_ = TWO_WAY_MODE;
CreateConfiguration(const TLSConfiguration & configuration)34 std::unique_ptr<TLSContextServer> TLSContextServer::CreateConfiguration(const TLSConfiguration &configuration)
35 {
36 auto tlsContext = std::make_unique<TLSContextServer>();
37 if (!InitTlsContext(tlsContext.get(), configuration)) {
38 NETSTACK_LOGE("Failed to init tls context");
39 return nullptr;
40 }
41 return tlsContext;
42 }
43
InitEnvServer()44 void InitEnvServer()
45 {
46 SSL_library_init();
47 OpenSSL_add_all_algorithms();
48 SSL_load_error_strings();
49 }
50
SetCipherList(TLSContextServer * tlsContext,const TLSConfiguration & configuration)51 bool TLSContextServer::SetCipherList(TLSContextServer *tlsContext, const TLSConfiguration &configuration)
52 {
53 if (!tlsContext) {
54 NETSTACK_LOGE("tlsContext is null");
55 return false;
56 }
57 NETSTACK_LOGD("GetCipherSuite = %{public}s", configuration.GetCipherSuite().c_str());
58 if (SSL_CTX_set_cipher_list(tlsContext->ctx_, configuration.GetCipherSuite().c_str()) <= 0) {
59 NETSTACK_LOGE("Error setting the cipher list");
60 return false;
61 }
62 return true;
63 }
64
GetCiphers(TLSContextServer * tlsContext)65 void TLSContextServer::GetCiphers(TLSContextServer *tlsContext)
66 {
67 if (!tlsContext) {
68 NETSTACK_LOGE("tlsContext is null");
69 return;
70 }
71 std::vector<CipherSuite> cipherSuiteVec;
72 STACK_OF(SSL_CIPHER) *sk = SSL_CTX_get_ciphers(tlsContext->ctx_);
73 if (!sk) {
74 NETSTACK_LOGE("sk is null");
75 return;
76 }
77 CipherSuite cipherSuite;
78 for (int i = 0; i < sk_SSL_CIPHER_num(sk); i++) {
79 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(sk, i);
80 cipherSuite.cipherId_ = SSL_CIPHER_get_id(cipher);
81 cipherSuite.cipherName_ = SSL_CIPHER_get_name(cipher);
82 cipherSuiteVec.push_back(cipherSuite);
83 }
84 }
85
SetSignatureAlgorithms(TLSContextServer * tlsContext,const TLSConfiguration & configuration)86 bool TLSContextServer::SetSignatureAlgorithms(TLSContextServer *tlsContext, const TLSConfiguration &configuration)
87 {
88 if (!tlsContext) {
89 NETSTACK_LOGE("tlsContext is null");
90 return false;
91 }
92 if (configuration.GetSignatureAlgorithms().empty()) {
93 NETSTACK_LOGE("configuration get signature algorithms is empty");
94 return false;
95 }
96
97 if (!SSL_CTX_set1_sigalgs_list(tlsContext->ctx_, configuration.GetSignatureAlgorithms().c_str())) {
98 NETSTACK_LOGE("Error setting the Signature Algorithms");
99 return false;
100 }
101 return true;
102 }
103
UseRemoteCipher(TLSContextServer * tlsContext)104 void TLSContextServer::UseRemoteCipher(TLSContextServer *tlsContext)
105 {
106 if (!tlsContext) {
107 NETSTACK_LOGE("TLSContextServer::UseRemoteCipher: tlsContext is null");
108 return;
109 }
110 if (tlsContext->tlsConfiguration_.GetUseRemoteCipherPrefer()) {
111 SSL_CTX_set_options(tlsContext->ctx_, SSL_OP_CIPHER_SERVER_PREFERENCE);
112 }
113 NETSTACK_LOGI("SSL_CTX_get_options = %{public}" PRIx64,
114 static_cast<uint64_t>(SSL_CTX_get_options(tlsContext->ctx_)));
115 }
116
SetMinAndMaxProtocol(TLSContextServer * tlsContext)117 void TLSContextServer::SetMinAndMaxProtocol(TLSContextServer *tlsContext)
118 {
119 if (!tlsContext) {
120 NETSTACK_LOGE("TLSContextServer::SetMinAndMaxProtocol: tlsContext is null");
121 return;
122 }
123 const long anyVersion = TLS_ANY_VERSION;
124 long minVersion = anyVersion;
125 long maxVersion = anyVersion;
126
127 switch (tlsContext->tlsConfiguration_.GetMinProtocol()) {
128 case TLS_V1_2:
129 minVersion = TLS1_2_VERSION;
130 break;
131 case TLS_V1_3:
132 minVersion = TLS1_3_VERSION;
133 break;
134 case UNKNOW_PROTOCOL:
135 break;
136 default:
137 break;
138 }
139
140 switch (tlsContext->tlsConfiguration_.GetMaxProtocol()) {
141 case TLS_V1_2:
142 maxVersion = TLS1_2_VERSION;
143 break;
144 case TLS_V1_3:
145 maxVersion = TLS1_3_VERSION;
146 break;
147 case UNKNOW_PROTOCOL:
148 break;
149 default:
150 break;
151 }
152
153 if (minVersion != anyVersion && !SSL_CTX_set_min_proto_version(tlsContext->ctx_, minVersion)) {
154 NETSTACK_LOGE("Error while setting the minimal protocol version");
155 return;
156 }
157
158 if (maxVersion != anyVersion && !SSL_CTX_set_max_proto_version(tlsContext->ctx_, maxVersion)) {
159 NETSTACK_LOGE("Error while setting the maximum protocol version");
160 return;
161 }
162
163 NETSTACK_LOGD("minProtocol = %{public}lx, maxProtocol = %{public}lx",
164 SSL_CTX_get_min_proto_version(tlsContext->ctx_), SSL_CTX_get_max_proto_version(tlsContext->ctx_));
165 }
166
SetDefaultCa(TLSContextServer * tlsContext,const TLSConfiguration & configuration)167 bool TLSContextServer::SetDefaultCa(TLSContextServer *tlsContext, const TLSConfiguration &configuration)
168 {
169 #ifdef HAS_NETMANAGER_BASE
170 auto hostname = CommonUtils::GetHostnameFromURL(configuration.GetNetAddress().GetAddress());
171 // customize trusted CAs.
172 std::vector<std::string> cert_paths;
173
174 if (NetManagerStandard::NetworkSecurityConfig::GetInstance().
175 GetTrustAnchorsForHostName(hostname, cert_paths) != 0) {
176 NETSTACK_LOGE("get customize trusted CAs failed");
177 return false;
178 }
179 for (const auto &path : cert_paths) {
180 if (!X509_STORE_load_path(SSL_CTX_get_cert_store(tlsContext->ctx_), path.c_str())) {
181 NETSTACK_LOGE("load customize certificates failed");
182 return false;
183 }
184 }
185 #endif // HAS_NETMANAGER_BASE
186
187 if (access(ROOT_CERT_PATH.c_str(), F_OK | R_OK) == 0) {
188 NETSTACK_LOGD("root CA certificates folder exist and can read");
189 if (!X509_STORE_load_path(SSL_CTX_get_cert_store(tlsContext->ctx_), ROOT_CERT_PATH.c_str())) {
190 NETSTACK_LOGE("load root certificates failed");
191 return false;
192 }
193 } else {
194 NETSTACK_LOGD("root CA certificates folder not exist or can not read");
195 }
196 std::string userCertPath = BASE_PATH + std::to_string(getuid() / UID_TRANSFORM_DIVISOR);
197 if (access(userCertPath.c_str(), F_OK | R_OK) == 0) {
198 NETSTACK_LOGD("user CA certificates folder exist and can read");
199 if (!X509_STORE_load_path(SSL_CTX_get_cert_store(tlsContext->ctx_), userCertPath.c_str())) {
200 NETSTACK_LOGE("load user certificates failed");
201 return false;
202 }
203 } else {
204 NETSTACK_LOGD("user CA certificates folder not exist or can not read");
205 }
206 if (!X509_STORE_load_path(SSL_CTX_get_cert_store(tlsContext->ctx_), SYSTEM_REPLACE_CA_PATH.c_str())) {
207 NETSTACK_LOGE("load system replace certificates failed");
208 return false;
209 }
210 return true;
211 }
212
SetCaAndVerify(TLSContextServer * tlsContext,const TLSConfiguration & configuration)213 bool TLSContextServer::SetCaAndVerify(TLSContextServer *tlsContext, const TLSConfiguration &configuration)
214 {
215 NETSTACK_LOGI("SetCaAndVerify ");
216
217 if (!tlsContext) {
218 NETSTACK_LOGE("tlsContext is null");
219 return false;
220 }
221
222 if (configuration.GetCaCertificate().empty()) {
223 return SetDefaultCa(tlsContext, configuration);
224 } else {
225 for (const auto &cert : configuration.GetCaCertificate()) {
226 TLSCertificate ca(cert, CA_CERT);
227 if (!X509_STORE_add_cert(SSL_CTX_get_cert_store(tlsContext->ctx_), static_cast<X509 *>(ca.handle()))) {
228 NETSTACK_LOGE("Failed to add x509 cert");
229 return false;
230 }
231 }
232 }
233
234 NETSTACK_LOGI("SetCaAndVerify ok");
235 return true;
236 }
237
SetLocalCertificate(TLSContextServer * tlsContext,const TLSConfiguration & configuration)238 bool TLSContextServer::SetLocalCertificate(TLSContextServer *tlsContext, const TLSConfiguration &configuration)
239 {
240 if (!tlsContext) {
241 NETSTACK_LOGE("tlsContext is null");
242 return false;
243 }
244 if (!SSL_CTX_use_certificate(tlsContext->ctx_, static_cast<X509 *>(configuration.GetLocalCertificate().handle()))) {
245 NETSTACK_LOGD("The local certificate is unavailable");
246 return false;
247 }
248 return true;
249 }
250
SetKeyAndCheck(TLSContextServer * tlsContext,const TLSConfiguration & configuration)251 bool TLSContextServer::SetKeyAndCheck(TLSContextServer *tlsContext, const TLSConfiguration &configuration)
252 {
253 if (!tlsContext) {
254 NETSTACK_LOGE("The parameter tlsContext is null");
255 return false;
256 }
257 if (configuration.GetPrivateKey().Algorithm() == OPAQUE) {
258 tlsContext->pkey_ = reinterpret_cast<EVP_PKEY *>(configuration.GetPrivateKey().handle());
259 } else {
260 tlsContext->pkey_ = EVP_PKEY_new();
261 if (configuration.GetPrivateKey().Algorithm() == ALGORITHM_RSA) {
262 EVP_PKEY_set1_RSA(tlsContext->pkey_, reinterpret_cast<RSA *>(configuration.GetPrivateKey().handle()));
263 } else if (tlsContext->tlsConfiguration_.GetPrivateKey().Algorithm() == ALGORITHM_DSA) {
264 EVP_PKEY_set1_DSA(tlsContext->pkey_, reinterpret_cast<DSA *>(configuration.GetPrivateKey().handle()));
265 }
266 }
267
268 if (configuration.GetPrivateKey().Algorithm() == OPAQUE) {
269 tlsContext->pkey_ = nullptr;
270 }
271 auto pkey_ = tlsContext->pkey_;
272 if (!SSL_CTX_use_PrivateKey(tlsContext->ctx_, pkey_)) {
273 NETSTACK_LOGE("SSL_CTX_use_PrivateKey is error");
274 return false;
275 }
276
277 if (!configuration.GetPrivateKey().GetKeyPass().Length()) {
278 SSL_CTX_set_default_passwd_cb_userdata(tlsContext->ctx_,
279 reinterpret_cast<void *>(const_cast<char *>(
280 tlsContext->tlsConfiguration_.GetPrivateKey().GetKeyPass().Data())));
281 }
282 // Check if the certificate matches the private key.
283 if (!SSL_CTX_check_private_key(tlsContext->ctx_)) {
284 NETSTACK_LOGE("Check if the certificate matches the private key is error");
285 return false;
286 }
287 return true;
288 }
289
SetVerify(TLSContextServer * tlsContext)290 void TLSContextServer::SetVerify(TLSContextServer *tlsContext)
291 {
292 if (!tlsContext) {
293 NETSTACK_LOGE("tlsContext is null");
294 return;
295 }
296
297 if (!tlsContext->tlsConfiguration_.GetCertificate().data.Length() ||
298 !tlsContext->tlsConfiguration_.GetPrivateKey().GetKeyData().Length() ||
299 tlsContext->tlsConfiguration_.GetVerifyMode() == ONE_WAY_MODE) {
300 SSL_CTX_set_verify(tlsContext->ctx_, SSL_VERIFY_NONE, nullptr);
301 verifyMode_ = ONE_WAY_MODE;
302 } else {
303 verifyMode_ = TWO_WAY_MODE;
304 SSL_CTX_set_verify(tlsContext->ctx_, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
305 }
306
307 NETSTACK_LOGD("Authentication mode is %{public}s",
308 verifyMode_ ? "two-way authentication" : "one-way authentication");
309 }
310
InitTlsContext(TLSContextServer * tlsContext,const TLSConfiguration & configuration)311 bool TLSContextServer::InitTlsContext(TLSContextServer *tlsContext, const TLSConfiguration &configuration)
312 {
313 if (!tlsContext) {
314 NETSTACK_LOGE("tlsContext is null");
315 return false;
316 }
317 InitEnvServer();
318 tlsContext->tlsConfiguration_ = configuration;
319 tlsContext->ctx_ = SSL_CTX_new(TLS_server_method());
320 if (tlsContext->ctx_ == nullptr) {
321 NETSTACK_LOGE("ctx is nullptr");
322 return false;
323 }
324 if (!configuration.GetCipherSuite().empty()) {
325 if (!SetCipherList(tlsContext, configuration)) {
326 NETSTACK_LOGE("Failed to set cipher suite");
327 return false;
328 }
329 }
330 if (!configuration.GetSignatureAlgorithms().empty()) {
331 if (!SetSignatureAlgorithms(tlsContext, configuration)) {
332 NETSTACK_LOGE("Failed to set signature algorithms");
333 return false;
334 }
335 }
336 GetCiphers(tlsContext);
337 UseRemoteCipher(tlsContext);
338 SetMinAndMaxProtocol(tlsContext);
339 SetVerify(tlsContext);
340 if (!SetCaAndVerify(tlsContext, configuration)) {
341 return false;
342 }
343 if (!SetLocalCertificate(tlsContext, configuration)) {
344 return false;
345 }
346 if (!SetKeyAndCheck(tlsContext, configuration)) {
347 return false;
348 }
349 return true;
350 }
CreateSsl()351 SSL *TLSContextServer::CreateSsl()
352 {
353 ctxSsl_ = SSL_new(ctx_);
354 return ctxSsl_;
355 }
356
CloseCtx()357 void TLSContextServer::CloseCtx()
358 {
359 SSL_CTX_free(ctx_);
360 }
361 } // namespace TlsSocket
362 } // namespace NetStack
363 } // namespace OHOS
364