1 /*
2 * Copyright (c) 2023 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 <cstring>
17 #include <iostream>
18 #include <vector>
19 #include <string>
20
21 #include <openssl/ssl.h>
22
23 #include "net_ssl.h"
24 #include "net_ssl_c.h"
25 #include "net_ssl_c_type.h"
26 #include "securec.h"
27 #include "netstack_log.h"
28 #include "net_ssl_verify_cert.h"
29 #include "net_manager_constants.h"
30 #include "network_security_config.h"
31 #include "netmanager_base_permission.h"
32
SwitchToCertBlob(const struct NetStack_CertBlob cert)33 struct OHOS::NetStack::Ssl::CertBlob SwitchToCertBlob(const struct NetStack_CertBlob cert)
34 {
35 OHOS::NetStack::Ssl::CertBlob cb;
36 switch (cert.type) {
37 case NETSTACK_CERT_TYPE_PEM:
38 cb.type = OHOS::NetStack::Ssl::CertType::CERT_TYPE_PEM;
39 break;
40 case NETSTACK_CERT_TYPE_DER:
41 cb.type = OHOS::NetStack::Ssl::CertType::CERT_TYPE_DER;
42 break;
43 case NETSTACK_CERT_TYPE_INVALID:
44 cb.type = OHOS::NetStack::Ssl::CertType::CERT_TYPE_MAX;
45 break;
46 default:
47 break;
48 }
49 cb.size = cert.size;
50 cb.data = cert.data;
51 return cb;
52 }
53
VerifyCert_With_RootCa(const struct NetStack_CertBlob * cert)54 uint32_t VerifyCert_With_RootCa(const struct NetStack_CertBlob *cert)
55 {
56 uint32_t verifyResult = X509_V_ERR_UNSPECIFIED;
57 OHOS::NetStack::Ssl::CertBlob cb = SwitchToCertBlob(*cert);
58 verifyResult = OHOS::NetStack::Ssl::NetStackVerifyCertification(&cb);
59 return verifyResult;
60 }
61
VerifyCert_With_DesignatedCa(const struct NetStack_CertBlob * cert,const struct NetStack_CertBlob * caCert)62 uint32_t VerifyCert_With_DesignatedCa(const struct NetStack_CertBlob *cert, const struct NetStack_CertBlob *caCert)
63 {
64 uint32_t verifyResult = X509_V_ERR_UNSPECIFIED;
65 OHOS::NetStack::Ssl::CertBlob cb = SwitchToCertBlob(*cert);
66 OHOS::NetStack::Ssl::CertBlob caCb = SwitchToCertBlob(*caCert);
67 verifyResult = OHOS::NetStack::Ssl::NetStackVerifyCertification(&cb, &caCb);
68 return verifyResult;
69 }
70
OH_NetStack_CertVerification(const struct NetStack_CertBlob * cert,const struct NetStack_CertBlob * caCert)71 uint32_t OH_NetStack_CertVerification(const struct NetStack_CertBlob *cert, const struct NetStack_CertBlob *caCert)
72 {
73 if (cert == nullptr) {
74 return X509_V_ERR_INVALID_CALL;
75 }
76 if (caCert == nullptr) {
77 return VerifyCert_With_RootCa(cert);
78 } else {
79 return VerifyCert_With_DesignatedCa(cert, caCert);
80 }
81 }
82
OH_NetStack_GetPinSetForHostName(const char * hostname,NetStack_CertificatePinning * pin)83 int32_t OH_NetStack_GetPinSetForHostName(const char *hostname, NetStack_CertificatePinning *pin)
84 {
85 if (hostname == nullptr || pin == nullptr) {
86 NETSTACK_LOGE("OH_NetStack_GetPinSetForHostName received invalid parameters");
87 return OHOS::NetManagerStandard::NETMANAGER_ERR_PARAMETER_ERROR;
88 }
89
90 std::string innerHostname = std::string(hostname);
91 std::string innerPins;
92
93 int32_t ret = OHOS::NetManagerStandard::NetworkSecurityConfig::GetInstance().
94 GetPinSetForHostName(innerHostname, innerPins);
95 if (ret != OHOS::NetManagerStandard::NETMANAGER_SUCCESS) {
96 return ret;
97 }
98
99 if (innerPins.length() <= 0) {
100 pin->hashAlgorithm = NetStack_HashAlgorithm::SHA_256;
101 pin->kind = NetStack_CertificatePinningKind::PUBLIC_KEY;
102 pin->publicKeyHash = nullptr;
103 return OHOS::NetManagerStandard::NETMANAGER_SUCCESS;
104 }
105
106 size_t size = innerPins.length() + 1;
107 char *key = (char *)malloc(size);
108 if (key == nullptr) {
109 NETSTACK_LOGE("OH_NetStack_GetPinSetForHostName malloc failed");
110 return OHOS::NetStack::Ssl::SslErrorCode::SSL_X509_V_ERR_OUT_OF_MEMORY;
111 }
112
113 if (strcpy_s(key, size, innerPins.c_str()) != 0) {
114 free(key);
115 NETSTACK_LOGE("OH_NetStack_GetPinSetForHostName string copy failed");
116 return OHOS::NetStack::Ssl::SslErrorCode::SSL_X509_V_ERR_OUT_OF_MEMORY;
117 }
118 pin->hashAlgorithm = NetStack_HashAlgorithm::SHA_256;
119 pin->kind = NetStack_CertificatePinningKind::PUBLIC_KEY;
120 pin->publicKeyHash = key;
121
122 return OHOS::NetManagerStandard::NETMANAGER_SUCCESS;
123 }
124
OH_NetStack_GetCertificatesForHostName(const char * hostname,NetStack_Certificates * certs)125 int32_t OH_NetStack_GetCertificatesForHostName(const char *hostname, NetStack_Certificates *certs)
126 {
127 if (hostname == nullptr || certs == nullptr) {
128 NETSTACK_LOGE("OH_NetStack_GetCertificatesForHostName received invalid parameters");
129 return OHOS::NetManagerStandard::NETMANAGER_ERR_PARAMETER_ERROR;
130 }
131
132 std::string innerHostname = std::string(hostname);
133 std::vector<std::string> innerCerts;
134
135 int32_t ret = OHOS::NetManagerStandard::NetworkSecurityConfig::GetInstance()
136 .GetTrustAnchorsForHostName(innerHostname, innerCerts);
137 if (ret != OHOS::NetManagerStandard::NETMANAGER_SUCCESS) {
138 return ret;
139 }
140
141 size_t innerCertsLength = innerCerts.size();
142 if (innerCertsLength <= 0) {
143 certs->length = 0;
144 certs->content = nullptr;
145 return OHOS::NetManagerStandard::NETMANAGER_SUCCESS;
146 }
147
148 size_t contentPtrSize = innerCertsLength * sizeof(char *);
149 size_t totalMallocSize = contentPtrSize;
150 for (size_t i = 0; i < innerCertsLength; ++i) {
151 totalMallocSize += innerCerts[i].size() + 1;
152 }
153 char *ptr = (char *)malloc(totalMallocSize);
154 if (ptr == nullptr) {
155 NETSTACK_LOGE("OH_NetStack_GetCertificatesForHostName malloc failed");
156 return OHOS::NetStack::Ssl::SslErrorCode::SSL_X509_V_ERR_OUT_OF_MEMORY;
157 }
158 char **contentPtr = reinterpret_cast<char **>(ptr);
159 char *certPtr = ptr + contentPtrSize;
160
161 for (size_t i = 0; i < innerCertsLength; ++i) {
162 size_t certLen = innerCerts[i].size() + 1;
163 if (strcpy_s(certPtr, certLen, innerCerts[i].c_str()) != 0) {
164 free(ptr);
165 NETSTACK_LOGE("OH_NetStack_GetCertificatesForHostName string copy failed");
166 return OHOS::NetStack::Ssl::SslErrorCode::SSL_X509_V_ERR_OUT_OF_MEMORY;
167 }
168 contentPtr[i] = certPtr;
169 certPtr += certLen;
170 }
171
172 certs->length = innerCertsLength;
173 certs->content = contentPtr;
174 return OHOS::NetManagerStandard::NETMANAGER_SUCCESS;
175 }
176
OH_Netstack_DestroyCertificatesContent(NetStack_Certificates * certs)177 void OH_Netstack_DestroyCertificatesContent(NetStack_Certificates *certs)
178 {
179 if (certs == nullptr) {
180 NETSTACK_LOGE("OH_Netstack_DestroyCertificatesContent received invalid parameters");
181 return;
182 }
183
184 if (certs->content == nullptr) {
185 return;
186 }
187
188 free(certs->content);
189 certs->content = nullptr;
190 certs->length = 0;
191 }
192
OH_Netstack_IsCleartextPermitted(bool * isCleartextPermitted)193 int32_t OH_Netstack_IsCleartextPermitted(bool *isCleartextPermitted)
194 {
195 if (isCleartextPermitted == nullptr) {
196 NETSTACK_LOGE("OH_Netstack_IsCleartextPermitted received invalid parameters");
197 return OHOS::NetManagerStandard::NETMANAGER_ERR_PARAMETER_ERROR;
198 }
199 return OHOS::NetManagerStandard::NetworkSecurityConfig::GetInstance().IsCleartextPermitted(*isCleartextPermitted);
200 }
201
OH_Netstack_IsCleartextPermittedByHostName(const char * hostname,bool * isCleartextPermitted)202 int32_t OH_Netstack_IsCleartextPermittedByHostName(const char *hostname, bool *isCleartextPermitted)
203 {
204 if (hostname == nullptr || isCleartextPermitted == nullptr) {
205 NETSTACK_LOGE("OH_Netstack_IsCleartextPermittedByHostName received invalid parameters");
206 return OHOS::NetManagerStandard::NETMANAGER_ERR_PARAMETER_ERROR;
207 }
208 return OHOS::NetManagerStandard::NetworkSecurityConfig::GetInstance()
209 .IsCleartextPermitted(std::string(hostname), *isCleartextPermitted);
210 }
211
OH_Netstack_IsCleartextCfgByComponent(const char * component,bool * componentCfg)212 int32_t OH_Netstack_IsCleartextCfgByComponent(const char *component, bool *componentCfg)
213 {
214 if (component == nullptr || componentCfg == nullptr) {
215 NETSTACK_LOGE("OH_Netstack_IsCleartextCfgByComponent received invalid parameters");
216 return OHOS::NetManagerStandard::NETMANAGER_ERR_INVALID_PARAMETER;
217 }
218 return OHOS::NetManagerStandard::NetworkSecurityConfig::GetInstance()
219 .IsCleartextCfgByComponent(std::string(component), *componentCfg);
220 }