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_certificate.h"
17
18 #include <cerrno>
19 #include <cstdlib>
20 #include <memory>
21 #include <map>
22 #include <securec.h>
23
24 #include <openssl/asn1.h>
25 #include <openssl/bn.h>
26 #include <openssl/pem.h>
27
28 #include "netstack_log.h"
29 #include "tls_utils.h"
30
31 namespace OHOS {
32 namespace NetStack {
33 namespace TlsSocket {
34 namespace {
35 constexpr const char *BIO_FILE_FLAG = "r";
36 constexpr const char *FILE_OPEN_FLAG = "rb";
37 constexpr const char *CERT_VERSION_FLAG = "V";
38 constexpr int FILE_READ_CERT_LEN = 4096;
39 } // namespace
40
TLSCertificate(const std::string & data,EncodingFormat format,CertType certType)41 TLSCertificate::TLSCertificate(const std::string &data, EncodingFormat format, CertType certType)
42 {
43 rawData_.encodingFormat = PEM;
44 if (data.empty()) {
45 NETSTACK_LOGE("The parameter data is empty");
46 return;
47 }
48 switch (format) {
49 case PEM:
50 if (!CertificateFromPem(data, certType)) {
51 NETSTACK_LOGE("return CertificateFromPem(data, certs) is false");
52 }
53 break;
54 case DER:
55 if (!CertificateFromDer(data, certType)) {
56 NETSTACK_LOGE("return CertificateFromDer(data, certs) is false");
57 }
58 break;
59 default:
60 NETSTACK_LOGE("%{public}u is not supported, only support PEM =0 and DER = 1", format);
61 }
62 }
63
TLSCertificate(const std::string & data,CertType certType)64 TLSCertificate::TLSCertificate(const std::string &data, CertType certType)
65 {
66 rawData_.encodingFormat = PEM;
67 if (data.empty()) {
68 NETSTACK_LOGE("data is null in the TLSCertificate constructor");
69 return;
70 }
71 if (!CertificateFromData(data, certType)) {
72 NETSTACK_LOGE("return CertificatesFromPem(data, certs) is false");
73 }
74 }
75
TLSCertificate(const TLSCertificate & other)76 TLSCertificate::TLSCertificate(const TLSCertificate &other)
77 {
78 *this = other;
79 }
80
operator =(const TLSCertificate & other)81 TLSCertificate &TLSCertificate::operator=(const TLSCertificate &other)
82 {
83 if (other.x509_ != nullptr) {
84 x509_ = X509_new();
85 x509_ = other.x509_;
86 }
87 version_ = other.version_;
88 serialNumber_ = other.serialNumber_;
89 signatureAlgorithm_ = other.signatureAlgorithm_;
90 localCertString_ = other.localCertString_;
91 caCertString_ = other.caCertString_;
92 rawData_.data = other.rawData_.data;
93 rawData_.encodingFormat = other.rawData_.encodingFormat;
94 return *this;
95 }
96
CertificateFromData(const std::string & data,CertType certType)97 bool TLSCertificate::CertificateFromData(const std::string &data, CertType certType)
98 {
99 if (data.empty()) {
100 NETSTACK_LOGE("The parameter data is empty");
101 return false;
102 }
103 BIO *bio = BIO_new_mem_buf(data.c_str(), -1);
104 if (!bio) {
105 NETSTACK_LOGE("create BIO mem buf failed!");
106 return false;
107 }
108 X509 *x509 = PEM_read_bio_X509(bio, nullptr, nullptr, nullptr);
109 BIO_free(bio);
110
111 if (!x509) {
112 NETSTACK_LOGE("x509 is null");
113 return false;
114 }
115
116 x509_ = X509_dup(x509);
117 if (!AnalysisCertificate(certType, x509)) {
118 NETSTACK_LOGE("Analysis certificate is false");
119 X509_free(x509);
120 return false;
121 }
122 X509_free(x509);
123 return true;
124 }
125
CertificateFromPem(const std::string & data,CertType certType)126 bool TLSCertificate::CertificateFromPem(const std::string &data, CertType certType)
127 {
128 BIO *bio = BIO_new_file((data.c_str()), BIO_FILE_FLAG);
129 if (!bio) {
130 NETSTACK_LOGE("bio new file fail errno");
131 return false;
132 }
133 X509 *x509 = PEM_read_bio_X509(bio, nullptr, nullptr, nullptr);
134 BIO_free(bio);
135
136 if (!x509) {
137 NETSTACK_LOGE("x509 is null");
138 return false;
139 }
140
141 x509_ = X509_dup(x509);
142 if (!AnalysisCertificate(certType, x509)) {
143 NETSTACK_LOGE("Analysis certificate is false");
144 X509_free(x509);
145 return false;
146 }
147 X509_free(x509);
148 return true;
149 }
150
CertificateFromDer(const std::string & data,CertType certType)151 bool TLSCertificate::CertificateFromDer(const std::string &data, CertType certType)
152 {
153 if (data.empty()) {
154 NETSTACK_LOGE("The certificate file to be converted is empty");
155 return false;
156 }
157 std::string realPath;
158 if (!CheckFilePath(data, realPath)) {
159 NETSTACK_LOGE("file name is error");
160 return false;
161 }
162
163 FILE *fp = fopen(realPath.c_str(), FILE_OPEN_FLAG);
164 if (!fp) {
165 NETSTACK_LOGE("Couldn't open file for reading, error string %{public}s", strerror(errno));
166 return false;
167 }
168 unsigned char cert[FILE_READ_CERT_LEN] = {};
169 size_t certLen = fread(cert, 1, FILE_READ_CERT_LEN, fp);
170 fclose(fp);
171 if (!certLen) {
172 NETSTACK_LOGE("Insufficient size bytes were read");
173 return false;
174 }
175 const auto *cert_data = reinterpret_cast<const unsigned char *>(cert);
176 X509 *x509 = d2i_X509(nullptr, &cert_data, static_cast<long>(certLen));
177 if (!x509) {
178 NETSTACK_LOGE("x509 is null");
179 return false;
180 }
181 x509_ = X509_dup(x509);
182 if (!AnalysisCertificate(certType, x509)) {
183 NETSTACK_LOGE("Analysis certificate is false");
184 X509_free(x509);
185 return false;
186 }
187 X509_free(x509);
188 return true;
189 }
190
AnalysisCertificate(CertType certType,X509 * x509)191 bool TLSCertificate::AnalysisCertificate(CertType certType, X509 *x509)
192 {
193 if (!x509) {
194 NETSTACK_LOGE("x509 is null");
195 return false;
196 }
197 if (certType == CA_CERT) {
198 if (!CaCertToString(x509)) {
199 NETSTACK_LOGE("Get CA cert as string failed");
200 return false;
201 }
202 }
203 if (certType == LOCAL_CERT) {
204 if (!LocalCertToString(x509)) {
205 NETSTACK_LOGE("Failed to convert certificate to string");
206 return false;
207 }
208 }
209 if (!SetLocalCertRawData(x509)) {
210 NETSTACK_LOGE("Failed to set x509 certificata Serialization data");
211 return false;
212 }
213 if (!SetX509Version(x509)) {
214 NETSTACK_LOGE("Failed to set x509 version");
215 return false;
216 }
217 if (!SetSerialNumber(x509)) {
218 NETSTACK_LOGE("Failed to set serial number");
219 return false;
220 }
221 if (!SetNotValidTime(x509)) {
222 NETSTACK_LOGE("Failed to set not valid time");
223 return false;
224 }
225 if (!SetSignatureAlgorithm(x509)) {
226 NETSTACK_LOGE("Failed to set signature algorithm");
227 return false;
228 }
229 return true;
230 }
231
CaCertToString(X509 * x509)232 bool TLSCertificate::CaCertToString(X509 *x509)
233 {
234 if (!x509) {
235 NETSTACK_LOGE("x509 is null");
236 return false;
237 }
238 BIO *bio = BIO_new(BIO_s_mem());
239 X509_print(bio, x509);
240 char data[FILE_READ_CERT_LEN] = {};
241 if (!BIO_read(bio, data, FILE_READ_CERT_LEN)) {
242 NETSTACK_LOGE("Ca certificate to string BIO_read is false");
243 BIO_free(bio);
244 return false;
245 }
246 caCertString_ = std::string(data);
247 BIO_free(bio);
248 return true;
249 }
250
LocalCertToString(X509 * x509)251 bool TLSCertificate::LocalCertToString(X509 *x509)
252 {
253 if (!x509) {
254 NETSTACK_LOGE("x509 is null");
255 return false;
256 }
257 BIO *bio = BIO_new(BIO_s_mem());
258 if (!bio) {
259 NETSTACK_LOGE("bio is null");
260 return false;
261 }
262 X509_print(bio, x509);
263 char data[FILE_READ_CERT_LEN] = {};
264 if (!BIO_read(bio, data, FILE_READ_CERT_LEN)) {
265 NETSTACK_LOGE("Local certificate to string BIO_read is false");
266 BIO_free(bio);
267 return false;
268 }
269 localCertString_ = std::string(data);
270 BIO_free(bio);
271 return true;
272 }
273
SetX509Version(X509 * x509)274 bool TLSCertificate::SetX509Version(X509 *x509)
275 {
276 if (!x509) {
277 NETSTACK_LOGE("x509 is null");
278 return false;
279 }
280 auto ver = X509_get_version(x509) + 1;
281 version_ = CERT_VERSION_FLAG + std::to_string(ver);
282 NETSTACK_LOGI("tls version_ %{public}s", version_.c_str());
283 return true;
284 }
285
SetSerialNumber(X509 * x509)286 bool TLSCertificate::SetSerialNumber(X509 *x509)
287 {
288 if (!x509) {
289 NETSTACK_LOGE("x509 is null");
290 return false;
291 }
292 ASN1_INTEGER *serial = X509_get_serialNumber(x509);
293 if (!serial) {
294 NETSTACK_LOGE("Failed to get serial number");
295 return false;
296 }
297 if (!serial->length) {
298 NETSTACK_LOGE("Serial length error");
299 return false;
300 }
301 BIGNUM *bn = ASN1_INTEGER_to_BN(serial, nullptr);
302 if (!bn) {
303 NETSTACK_LOGE("Unable to convert ASN1INTEGER to BN");
304 return false;
305 }
306 serialNumber_ = BN_bn2hex(bn);
307 BN_free(bn);
308 return true;
309 }
310
SetNotValidTime(X509 * x509)311 bool TLSCertificate::SetNotValidTime(X509 *x509)
312 {
313 if (!x509) {
314 NETSTACK_LOGE("x509 is null");
315 return false;
316 }
317 ASN1_TIME *before = X509_get_notBefore(x509);
318 if (!before) {
319 NETSTACK_LOGE("before is null");
320 return false;
321 }
322 tm tmBefore = {0};
323 if (!ASN1_TIME_to_tm(before, &tmBefore)) {
324 NETSTACK_LOGE("ASN1_TIME_to_tm before is false");
325 return false;
326 }
327
328 ASN1_TIME *after = X509_get_notAfter(x509);
329 if (!after) {
330 NETSTACK_LOGE("after is null");
331 return false;
332 }
333 tm tmAfter;
334 if (!ASN1_TIME_to_tm(after, &tmAfter)) {
335 NETSTACK_LOGE("ASN1_TIME_to_tm before is false");
336 return false;
337 }
338 return true;
339 }
340
SetSignatureAlgorithm(X509 * x509)341 bool TLSCertificate::SetSignatureAlgorithm(X509 *x509)
342 {
343 if (!x509) {
344 NETSTACK_LOGE("x509 is null");
345 return false;
346 }
347 int signNid = X509_get_signature_nid(x509);
348 const char *sign = OBJ_nid2sn(signNid);
349 if (!sign) {
350 NETSTACK_LOGE("OBJ_nid2sn is null");
351 return false;
352 }
353 signatureAlgorithm_ = sign;
354 return true;
355 }
356
SetLocalCertRawData(X509 * x509)357 bool TLSCertificate::SetLocalCertRawData(X509 *x509)
358 {
359 if (!x509) {
360 NETSTACK_LOGE("x509 is null");
361 return false;
362 }
363 int32_t length = i2d_X509(x509, nullptr);
364 if (length <= 0) {
365 NETSTACK_LOGE("Failed to convert x509 to der format, length is %{public}d", length);
366 return false;
367 }
368 unsigned char *der = nullptr;
369 (void)i2d_X509(x509, &der);
370 SecureData data(der, length);
371 rawData_.data = data;
372 OPENSSL_free(der);
373 rawData_.encodingFormat = DER;
374 return true;
375 }
376
GetSignatureAlgorithm() const377 std::string TLSCertificate::GetSignatureAlgorithm() const
378 {
379 return signatureAlgorithm_;
380 }
GetLocalCertString() const381 std::string TLSCertificate::GetLocalCertString() const
382 {
383 return localCertString_;
384 }
385
handle() const386 Handle TLSCertificate::handle() const
387 {
388 return Handle(x509_);
389 }
390
GetLocalCertRawData() const391 const X509CertRawData &TLSCertificate::GetLocalCertRawData() const
392 {
393 return rawData_;
394 }
395 } // namespace TlsSocket
396 } // namespace NetStack
397 } // namespace OHOS
398