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 "net_conn_client.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::NetConnClient::GetInstance().GetTrustAnchorsForHostName(hostname, cert_paths) != 0) {
175         NETSTACK_LOGE("get customize trusted CAs failed");
176         return false;
177     }
178     for (const auto &path : cert_paths) {
179         if (!X509_STORE_load_path(SSL_CTX_get_cert_store(tlsContext->ctx_), path.c_str())) {
180             NETSTACK_LOGE("load customize certificates failed");
181             return false;
182         }
183     }
184 #endif // HAS_NETMANAGER_BASE
185 
186     if (access(ROOT_CERT_PATH.c_str(), F_OK | R_OK) == 0) {
187         NETSTACK_LOGD("root CA certificates folder exist and can read");
188         if (!X509_STORE_load_path(SSL_CTX_get_cert_store(tlsContext->ctx_), ROOT_CERT_PATH.c_str())) {
189             NETSTACK_LOGE("load root certificates failed");
190             return false;
191         }
192     } else {
193         NETSTACK_LOGD("root CA certificates folder not exist or can not read");
194     }
195     std::string userCertPath = BASE_PATH + std::to_string(getuid() / UID_TRANSFORM_DIVISOR);
196     if (access(userCertPath.c_str(), F_OK | R_OK) == 0) {
197         NETSTACK_LOGD("user CA certificates folder exist and can read");
198         if (!X509_STORE_load_path(SSL_CTX_get_cert_store(tlsContext->ctx_), userCertPath.c_str())) {
199             NETSTACK_LOGE("load user certificates failed");
200             return false;
201         }
202     } else {
203         NETSTACK_LOGD("user CA certificates folder not exist or can not read");
204     }
205     if (!X509_STORE_load_path(SSL_CTX_get_cert_store(tlsContext->ctx_), SYSTEM_REPLACE_CA_PATH.c_str())) {
206         NETSTACK_LOGE("load system replace certificates failed");
207         return false;
208     }
209     return true;
210 }
211 
SetCaAndVerify(TLSContextServer * tlsContext,const TLSConfiguration & configuration)212 bool TLSContextServer::SetCaAndVerify(TLSContextServer *tlsContext, const TLSConfiguration &configuration)
213 {
214     NETSTACK_LOGI("SetCaAndVerify  ");
215 
216     if (!tlsContext) {
217         NETSTACK_LOGE("tlsContext is null");
218         return false;
219     }
220 
221     if (configuration.GetCaCertificate().empty()) {
222         return SetDefaultCa(tlsContext, configuration);
223     } else {
224         for (const auto &cert : configuration.GetCaCertificate()) {
225             TLSCertificate ca(cert, CA_CERT);
226             if (!X509_STORE_add_cert(SSL_CTX_get_cert_store(tlsContext->ctx_), static_cast<X509 *>(ca.handle()))) {
227                 NETSTACK_LOGE("Failed to add x509 cert");
228                 return false;
229             }
230         }
231     }
232 
233     NETSTACK_LOGI("SetCaAndVerify  ok");
234     return true;
235 }
236 
SetLocalCertificate(TLSContextServer * tlsContext,const TLSConfiguration & configuration)237 bool TLSContextServer::SetLocalCertificate(TLSContextServer *tlsContext, const TLSConfiguration &configuration)
238 {
239     if (!tlsContext) {
240         NETSTACK_LOGE("tlsContext is null");
241         return false;
242     }
243     if (!SSL_CTX_use_certificate(tlsContext->ctx_, static_cast<X509 *>(configuration.GetLocalCertificate().handle()))) {
244         NETSTACK_LOGD("The local certificate is unavailable");
245         return false;
246     }
247     return true;
248 }
249 
SetKeyAndCheck(TLSContextServer * tlsContext,const TLSConfiguration & configuration)250 bool TLSContextServer::SetKeyAndCheck(TLSContextServer *tlsContext, const TLSConfiguration &configuration)
251 {
252     if (!tlsContext) {
253         NETSTACK_LOGE("The parameter tlsContext is null");
254         return false;
255     }
256     if (configuration.GetPrivateKey().Algorithm() == OPAQUE) {
257         tlsContext->pkey_ = reinterpret_cast<EVP_PKEY *>(configuration.GetPrivateKey().handle());
258     } else {
259         tlsContext->pkey_ = EVP_PKEY_new();
260         if (configuration.GetPrivateKey().Algorithm() == ALGORITHM_RSA) {
261             EVP_PKEY_set1_RSA(tlsContext->pkey_, reinterpret_cast<RSA *>(configuration.GetPrivateKey().handle()));
262         } else if (tlsContext->tlsConfiguration_.GetPrivateKey().Algorithm() == ALGORITHM_DSA) {
263             EVP_PKEY_set1_DSA(tlsContext->pkey_, reinterpret_cast<DSA *>(configuration.GetPrivateKey().handle()));
264         }
265     }
266 
267     if (configuration.GetPrivateKey().Algorithm() == OPAQUE) {
268         tlsContext->pkey_ = nullptr;
269     }
270     auto pkey_ = tlsContext->pkey_;
271     if (!SSL_CTX_use_PrivateKey(tlsContext->ctx_, pkey_)) {
272         NETSTACK_LOGE("SSL_CTX_use_PrivateKey is error");
273         return false;
274     }
275 
276     if (!configuration.GetPrivateKey().GetKeyPass().Length()) {
277         SSL_CTX_set_default_passwd_cb_userdata(tlsContext->ctx_,
278                                                reinterpret_cast<void *>(const_cast<char *>(
279                                                    tlsContext->tlsConfiguration_.GetPrivateKey().GetKeyPass().Data())));
280     }
281     // Check if the certificate matches the private key.
282     if (!SSL_CTX_check_private_key(tlsContext->ctx_)) {
283         NETSTACK_LOGE("Check if the certificate matches the private key is error");
284         return false;
285     }
286     return true;
287 }
288 
SetVerify(TLSContextServer * tlsContext)289 void TLSContextServer::SetVerify(TLSContextServer *tlsContext)
290 {
291     if (!tlsContext) {
292         NETSTACK_LOGE("tlsContext is null");
293         return;
294     }
295 
296     if (!tlsContext->tlsConfiguration_.GetCertificate().data.Length() ||
297         !tlsContext->tlsConfiguration_.GetPrivateKey().GetKeyData().Length() ||
298         tlsContext->tlsConfiguration_.GetVerifyMode() == ONE_WAY_MODE) {
299         SSL_CTX_set_verify(tlsContext->ctx_, SSL_VERIFY_NONE, nullptr);
300         verifyMode_ = ONE_WAY_MODE;
301     } else {
302         verifyMode_ = TWO_WAY_MODE;
303         SSL_CTX_set_verify(tlsContext->ctx_, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
304     }
305 
306     NETSTACK_LOGD("Authentication mode is %{public}s",
307                   verifyMode_ ? "two-way authentication" : "one-way authentication");
308 }
309 
InitTlsContext(TLSContextServer * tlsContext,const TLSConfiguration & configuration)310 bool TLSContextServer::InitTlsContext(TLSContextServer *tlsContext, const TLSConfiguration &configuration)
311 {
312     if (!tlsContext) {
313         NETSTACK_LOGE("tlsContext is null");
314         return false;
315     }
316     InitEnvServer();
317     tlsContext->tlsConfiguration_ = configuration;
318     tlsContext->ctx_ = SSL_CTX_new(TLS_server_method());
319     if (tlsContext->ctx_ == nullptr) {
320         NETSTACK_LOGE("ctx is nullptr");
321         return false;
322     }
323     if (!configuration.GetCipherSuite().empty()) {
324         if (!SetCipherList(tlsContext, configuration)) {
325             NETSTACK_LOGE("Failed to set cipher suite");
326             return false;
327         }
328     }
329     if (!configuration.GetSignatureAlgorithms().empty()) {
330         if (!SetSignatureAlgorithms(tlsContext, configuration)) {
331             NETSTACK_LOGE("Failed to set signature algorithms");
332             return false;
333         }
334     }
335     GetCiphers(tlsContext);
336     UseRemoteCipher(tlsContext);
337     SetMinAndMaxProtocol(tlsContext);
338     SetVerify(tlsContext);
339     if (!SetCaAndVerify(tlsContext, configuration)) {
340         return false;
341     }
342     if (!SetLocalCertificate(tlsContext, configuration)) {
343         return false;
344     }
345     if (!SetKeyAndCheck(tlsContext, configuration)) {
346         return false;
347     }
348     return true;
349 }
CreateSsl()350 SSL *TLSContextServer::CreateSsl()
351 {
352     ctxSsl_ = SSL_new(ctx_);
353     return ctxSsl_;
354 }
355 
CloseCtx()356 void TLSContextServer::CloseCtx()
357 {
358     SSL_CTX_free(ctx_);
359 }
360 } // namespace TlsSocket
361 } // namespace NetStack
362 } // namespace OHOS
363