• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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