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 "x509_certificate_openssl.h"
17
18 #include <securec.h>
19 #include <openssl/x509.h>
20 #include <openssl/x509v3.h>
21 #include <openssl/evp.h>
22 #include <openssl/pem.h>
23
24 #include "config.h"
25 #include "cf_log.h"
26 #include "cf_memory.h"
27 #include "cf_result.h"
28 #include "result.h"
29 #include "utils.h"
30 #include "x509_certificate.h"
31 #include "certificate_openssl_class.h"
32 #include "certificate_openssl_common.h"
33
34 #define X509_CERT_PUBLIC_KEY_OPENSSL_CLASS "X509CertPublicKeyOpensslClass"
35 #define OID_STR_MAX_LEN 128
36 #define CHAR_TO_BIT_LEN 8
37 #define MAX_DATE_STR_LEN 128
38 #define FLAG_BIT_LEFT_NUM 0x07
39
40 typedef struct {
41 HcfPubKey base;
42 EVP_PKEY *pubKey;
43 } X509PubKeyOpensslImpl;
44
45 static CfResult GetSubjectDNX509Openssl(HcfX509CertificateSpi *self, CfBlob *out);
46 static CfResult GetIssuerDNX509Openssl(HcfX509CertificateSpi *self, CfBlob *out);
47 static CfResult GetKeyUsageX509Openssl(HcfX509CertificateSpi *self, CfBlob *boolArr);
48 static CfResult GetSerialNumberX509Openssl(HcfX509CertificateSpi *self, CfBlob *out);
49 static CfResult GetSigAlgOidX509Openssl(HcfX509CertificateSpi *self, CfBlob *out);
50 static CfResult GetSubjectPubKeyAlgOidX509Openssl(HcfX509CertificateSpi *self, CfBlob *out);
51
DeepCopyDataToOut(const char * data,uint32_t len,CfBlob * out)52 static CfResult DeepCopyDataToOut(const char *data, uint32_t len, CfBlob *out)
53 {
54 out->data = (uint8_t *)HcfMalloc(len, 0);
55 if (out->data == NULL) {
56 LOGE("Failed to malloc for sig algorithm params!");
57 return CF_ERR_MALLOC;
58 }
59 (void)memcpy_s(out->data, len, data, len);
60 out->size = len;
61 return CF_SUCCESS;
62 }
63
GetX509CertClass(void)64 static const char *GetX509CertClass(void)
65 {
66 return X509_CERT_OPENSSL_CLASS;
67 }
68
DestroyX509Openssl(CfObjectBase * self)69 static void DestroyX509Openssl(CfObjectBase *self)
70 {
71 if (self == NULL) {
72 return;
73 }
74 if (!IsClassMatch(self, GetX509CertClass())) {
75 LOGE("Input wrong class type!");
76 return;
77 }
78 HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
79 X509_free(realCert->x509);
80 realCert->x509 = NULL;
81 CfFree(realCert);
82 }
83
GetX509CertPubKeyClass(void)84 static const char *GetX509CertPubKeyClass(void)
85 {
86 return X509_CERT_PUBLIC_KEY_OPENSSL_CLASS;
87 }
88
DestroyX509PubKeyOpenssl(HcfObjectBase * self)89 static void DestroyX509PubKeyOpenssl(HcfObjectBase *self)
90 {
91 if (self == NULL) {
92 return;
93 }
94 if (!IsPubKeyClassMatch(self, GetX509CertPubKeyClass())) {
95 LOGE("Input wrong class type!");
96 return;
97 }
98 X509PubKeyOpensslImpl *impl = (X509PubKeyOpensslImpl *)self;
99 if (impl->pubKey != NULL) {
100 EVP_PKEY_free(impl->pubKey);
101 impl->pubKey = NULL;
102 }
103 CfFree(impl);
104 }
105
GetPubKeyAlgorithm(HcfKey * self)106 static const char *GetPubKeyAlgorithm(HcfKey *self)
107 {
108 (void)self;
109 LOGD("Not supported!");
110 return NULL;
111 }
112
GetPubKeyEncoded(HcfKey * self,HcfBlob * returnBlob)113 static HcfResult GetPubKeyEncoded(HcfKey *self, HcfBlob *returnBlob)
114 {
115 if (self == NULL || returnBlob == NULL) {
116 LOGE("Input params is invalid.");
117 return HCF_INVALID_PARAMS;
118 }
119 if (!IsPubKeyClassMatch((HcfObjectBase *)self, GetX509CertPubKeyClass())) {
120 LOGE("Input wrong class type!");
121 return HCF_INVALID_PARAMS;
122 }
123 X509PubKeyOpensslImpl *impl = (X509PubKeyOpensslImpl *)self;
124
125 unsigned char *pkBytes = NULL;
126 int32_t pkLen = i2d_PUBKEY(impl->pubKey, &pkBytes);
127 if (pkLen <= 0) {
128 CfPrintOpensslError();
129 LOGE("Failed to convert internal pubkey to der format!");
130 return HCF_ERR_CRYPTO_OPERATION;
131 }
132
133 returnBlob->data = (uint8_t *)HcfMalloc(pkLen, 0);
134 if (returnBlob->data == NULL) {
135 LOGE("Failed to malloc for sig algorithm params!");
136 OPENSSL_free(pkBytes);
137 return HCF_ERR_MALLOC;
138 }
139 (void)memcpy_s(returnBlob->data, pkLen, pkBytes, pkLen);
140 returnBlob->len = (size_t)pkLen;
141
142 OPENSSL_free(pkBytes);
143 return HCF_SUCCESS;
144 }
145
GetPubKeyFormat(HcfKey * self)146 static const char *GetPubKeyFormat(HcfKey *self)
147 {
148 (void)self;
149 LOGD("Not supported!");
150 return NULL;
151 }
152
VerifyX509Openssl(HcfX509CertificateSpi * self,HcfPubKey * key)153 static CfResult VerifyX509Openssl(HcfX509CertificateSpi *self, HcfPubKey *key)
154 {
155 if ((self == NULL) || (key == NULL)) {
156 LOGE("The input data is null!");
157 return CF_INVALID_PARAMS;
158 }
159 if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass()) ||
160 (!IsPubKeyClassMatch((HcfObjectBase *)key, GetX509CertPubKeyClass()))) {
161 LOGE("Input wrong class type!");
162 return CF_INVALID_PARAMS;
163 }
164 HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
165 X509 *x509 = realCert->x509;
166 X509PubKeyOpensslImpl *keyImpl = (X509PubKeyOpensslImpl *)key;
167 EVP_PKEY *pubKey = keyImpl->pubKey;
168 if (X509_verify(x509, pubKey) != CF_OPENSSL_SUCCESS) {
169 LOGE("Failed to verify x509 cert's signature.");
170 CfPrintOpensslError();
171 return CF_ERR_CRYPTO_OPERATION;
172 }
173 return CF_SUCCESS;
174 }
175
GetEncodedX509Openssl(HcfX509CertificateSpi * self,CfEncodingBlob * encodedByte)176 static CfResult GetEncodedX509Openssl(HcfX509CertificateSpi *self, CfEncodingBlob *encodedByte)
177 {
178 if ((self == NULL) || (encodedByte == NULL)) {
179 LOGE("The input data is null!");
180 return CF_INVALID_PARAMS;
181 }
182 if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
183 LOGE("Input wrong class type!");
184 return CF_INVALID_PARAMS;
185 }
186 HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
187 X509 *x509 = realCert->x509;
188 int32_t length = i2d_X509(x509, NULL);
189 if ((length <= 0) || (x509 == NULL)) {
190 LOGE("Failed to convert internal x509 to der format!");
191 CfPrintOpensslError();
192 return CF_ERR_CRYPTO_OPERATION;
193 }
194 unsigned char *der = NULL;
195 (void)i2d_X509(x509, &der);
196 encodedByte->data = (uint8_t *)HcfMalloc(length, 0);
197 if (encodedByte->data == NULL) {
198 LOGE("Failed to malloc for x509 der data!");
199 OPENSSL_free(der);
200 return CF_ERR_MALLOC;
201 }
202 (void)memcpy_s(encodedByte->data, length, der, length);
203 OPENSSL_free(der);
204 encodedByte->len = length;
205 encodedByte->encodingFormat = CF_FORMAT_DER;
206 return CF_SUCCESS;
207 }
208
GetPublicKeyX509Openssl(HcfX509CertificateSpi * self,HcfPubKey ** keyOut)209 static CfResult GetPublicKeyX509Openssl(HcfX509CertificateSpi *self, HcfPubKey **keyOut)
210 {
211 if ((self == NULL) || (keyOut == NULL)) {
212 LOGE("The input data is null!");
213 return CF_INVALID_PARAMS;
214 }
215 if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
216 LOGE("Input wrong class type!");
217 return CF_INVALID_PARAMS;
218 }
219 HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
220 X509 *x509 = realCert->x509;
221 EVP_PKEY *pubKey = X509_get_pubkey(x509);
222 if (pubKey == NULL) {
223 LOGE("Failed to get publick key from x509 cert.");
224 CfPrintOpensslError();
225 return CF_ERR_CRYPTO_OPERATION;
226 }
227 X509PubKeyOpensslImpl *keyImpl = (X509PubKeyOpensslImpl *)HcfMalloc(sizeof(X509PubKeyOpensslImpl), 0);
228 if (keyImpl == NULL) {
229 LOGE("Failed to malloc for public key obj!");
230 EVP_PKEY_free(pubKey);
231 return CF_ERR_MALLOC;
232 }
233 keyImpl->pubKey = pubKey;
234 keyImpl->base.base.base.destroy = DestroyX509PubKeyOpenssl;
235 keyImpl->base.base.base.getClass = GetX509CertPubKeyClass;
236 keyImpl->base.base.getEncoded = GetPubKeyEncoded;
237 keyImpl->base.base.getAlgorithm = GetPubKeyAlgorithm;
238 keyImpl->base.base.getFormat = GetPubKeyFormat;
239 *keyOut = (HcfPubKey *)keyImpl;
240 return CF_SUCCESS;
241 }
242
CompareCertBlobX509Openssl(HcfX509CertificateSpi * self,HcfCertificate * x509Cert,bool * out)243 static CfResult CompareCertBlobX509Openssl(HcfX509CertificateSpi *self, HcfCertificate *x509Cert, bool *out)
244 {
245 CfResult res = CF_SUCCESS;
246 CfEncodingBlob encodedBlobSelf = { NULL, 0, CF_FORMAT_DER };
247 CfEncodingBlob encodedBlobParam = { NULL, 0, CF_FORMAT_DER };
248 if (x509Cert != NULL) {
249 res = x509Cert->getEncoded(x509Cert, &encodedBlobParam);
250 if (res != CF_SUCCESS) {
251 LOGE("x509Cert getEncoded failed!");
252 return res;
253 }
254 res = GetEncodedX509Openssl(self, &encodedBlobSelf);
255 if (res != CF_SUCCESS) {
256 LOGE("x509Cert GetEncodedX509Openssl failed!");
257 CfFree(encodedBlobParam.data);
258 return res;
259 }
260 if ((encodedBlobSelf.len != encodedBlobParam.len) ||
261 (memcmp(encodedBlobSelf.data, encodedBlobParam.data, encodedBlobSelf.len) != 0)) {
262 *out = false;
263 }
264
265 CfFree(encodedBlobParam.data);
266 CfFree(encodedBlobSelf.data);
267 }
268
269 return res;
270 }
271
CompareNameObjectX509Openssl(HcfX509CertificateSpi * self,const CfBlob * blobObj,X509NameType nameType,bool * out)272 static CfResult CompareNameObjectX509Openssl(
273 HcfX509CertificateSpi *self, const CfBlob *blobObj, X509NameType nameType, bool *out)
274 {
275 CfResult res = CF_SUCCESS;
276 if (blobObj != NULL) {
277 HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
278 X509 *x509 = realCert->x509;
279 res = CompareNameObject(x509, blobObj, nameType, out);
280 }
281 return res;
282 }
283
CheckValidityWithDateX509Openssl(HcfX509CertificateSpi * self,const char * date)284 static CfResult CheckValidityWithDateX509Openssl(HcfX509CertificateSpi *self, const char *date)
285 {
286 if ((self == NULL) || (date == NULL)) {
287 LOGE("The input data is null!");
288 return CF_INVALID_PARAMS;
289 }
290 if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
291 LOGE("Input wrong class type!");
292 return CF_INVALID_PARAMS;
293 }
294 HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
295 X509 *x509 = realCert->x509;
296 ASN1_TIME *asn1InputDate = ASN1_TIME_new();
297 if (asn1InputDate == NULL) {
298 LOGE("Failed to malloc for asn1 time.");
299 return CF_ERR_MALLOC;
300 }
301 if (ASN1_TIME_set_string(asn1InputDate, date) != CF_OPENSSL_SUCCESS) {
302 LOGE("Failed to set time for asn1 time.");
303 CfPrintOpensslError();
304 ASN1_TIME_free(asn1InputDate);
305 return CF_ERR_CRYPTO_OPERATION;
306 }
307 CfResult res = CompareDateWithCertTime(x509, asn1InputDate);
308 ASN1_TIME_free(asn1InputDate);
309 return res;
310 }
311
CompareKeyUsageX509Openssl(HcfX509CertificateSpi * self,const CfBlob * keyUsage,bool * out)312 static CfResult CompareKeyUsageX509Openssl(HcfX509CertificateSpi *self, const CfBlob *keyUsage, bool *out)
313 {
314 if (keyUsage == NULL) {
315 return CF_SUCCESS;
316 }
317 if (keyUsage->size == 0 || keyUsage->data == NULL) {
318 LOGE("invalid param!");
319 return CF_INVALID_PARAMS;
320 }
321 CfBlob cfBlobDataSelf = { 0 };
322 CfResult res = GetKeyUsageX509Openssl(self, &cfBlobDataSelf);
323 if ((res != CF_SUCCESS) && (res != CF_ERR_CRYPTO_OPERATION)) {
324 LOGE("x509Cert GetKeyUsageX509Openssl failed!");
325 return res;
326 }
327 /*
328 * Check If the position of the true value in both arrays is the same.
329 * When two array is in different length, it is considered as match success if the values of the over size part are
330 * false.
331 */
332 uint32_t index = 0;
333 for (; index < keyUsage->size && index < cfBlobDataSelf.size; ++index) {
334 if ((keyUsage->data[index] & 0x01) != (cfBlobDataSelf.data[index] & 0x01)) {
335 *out = false;
336 break;
337 }
338 }
339 if (!(*out)) {
340 CfFree(cfBlobDataSelf.data);
341 return CF_SUCCESS;
342 }
343 for (; index < cfBlobDataSelf.size; ++index) {
344 if (cfBlobDataSelf.data[index] != 0) {
345 *out = false;
346 break;
347 }
348 }
349 for (; index < keyUsage->size; ++index) {
350 if (keyUsage->data[index] != 0) {
351 *out = false;
352 break;
353 }
354 }
355 CfFree(cfBlobDataSelf.data);
356 return CF_SUCCESS;
357 }
358
CompareSerialNumberX509Openssl(HcfX509CertificateSpi * self,const CfBlob * serialNumber,bool * out)359 static CfResult CompareSerialNumberX509Openssl(HcfX509CertificateSpi *self, const CfBlob *serialNumber, bool *out)
360 {
361 CfResult res = CF_SUCCESS;
362 CfBlob cfBlobDataSelf = { 0 };
363
364 if (serialNumber != NULL) {
365 if (serialNumber->size == 0 || serialNumber->data == NULL) {
366 LOGE("invalid param!");
367 return CF_INVALID_PARAMS;
368 }
369
370 res = GetSerialNumberX509Openssl(self, &cfBlobDataSelf);
371 if (res != CF_SUCCESS) {
372 LOGE("x509Cert GetSerialNumberX509Openssl failed!");
373 return res;
374 }
375 do {
376 if (cfBlobDataSelf.size != serialNumber->size) {
377 *out = false;
378 break;
379 }
380 int ret = 0;
381 res = CompareBigNum(&cfBlobDataSelf, serialNumber, &ret);
382 if (res != CF_SUCCESS) {
383 LOGE("x509Cert CompareBigNum failed!");
384 break;
385 }
386 if (ret != 0) {
387 *out = false;
388 break;
389 }
390 } while (0);
391
392 CfFree(cfBlobDataSelf.data);
393 }
394
395 return res;
396 }
397
GetCertPubKey(HcfX509CertificateSpi * self,CfBlob * outBlob)398 static CfResult GetCertPubKey(HcfX509CertificateSpi *self, CfBlob *outBlob)
399 {
400 HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
401 X509 *x509 = realCert->x509;
402 EVP_PKEY *pubKey = X509_get_pubkey(x509);
403 if (pubKey == NULL) {
404 CfPrintOpensslError();
405 LOGE("the x509 cert data is error!");
406 return CF_ERR_CRYPTO_OPERATION;
407 }
408
409 unsigned char *pubKeyBytes = NULL;
410 int32_t pubKeyLen = i2d_PUBKEY(pubKey, &pubKeyBytes);
411 if (pubKeyLen <= 0) {
412 EVP_PKEY_free(pubKey);
413 CfPrintOpensslError();
414 LOGE("Failed to convert internal pubkey to der format!");
415 return CF_ERR_CRYPTO_OPERATION;
416 }
417
418 int32_t ret = DeepCopyDataToBlob(pubKeyBytes, (uint32_t)pubKeyLen, outBlob);
419 EVP_PKEY_free(pubKey);
420 OPENSSL_free(pubKeyBytes);
421 return ret;
422 }
423
ComparePublicKeyX509Openssl(HcfX509CertificateSpi * self,const CfBlob * pubKey,bool * out)424 static CfResult ComparePublicKeyX509Openssl(HcfX509CertificateSpi *self, const CfBlob *pubKey, bool *out)
425 {
426 CfResult res = CF_SUCCESS;
427 CfBlob cfBlobDataSelf = { 0, NULL };
428
429 if (pubKey != NULL) {
430 if (pubKey->size == 0 || pubKey->data == NULL) {
431 LOGE("invalid param!");
432 return CF_INVALID_PARAMS;
433 }
434 res = GetCertPubKey(self, &cfBlobDataSelf);
435 if (res != CF_SUCCESS) {
436 LOGE("x509Cert GetCertPubKey failed!");
437 return CF_ERR_CRYPTO_OPERATION;
438 }
439
440 if (cfBlobDataSelf.size != pubKey->size) {
441 *out = false;
442 CfBlobDataFree(&cfBlobDataSelf);
443 return res;
444 }
445 if (memcmp(cfBlobDataSelf.data, pubKey->data, cfBlobDataSelf.size) != 0) {
446 *out = false;
447 }
448 CfBlobDataFree(&cfBlobDataSelf);
449 }
450
451 return res;
452 }
453
ComparePublicKeyAlgOidX509Openssl(HcfX509CertificateSpi * self,const CfBlob * publicKeyAlgOid,bool * out)454 static CfResult ComparePublicKeyAlgOidX509Openssl(HcfX509CertificateSpi *self, const CfBlob *publicKeyAlgOid, bool *out)
455 {
456 CfResult res = CF_SUCCESS;
457 CfBlob cfBlobDataSelf = { 0 };
458
459 if (publicKeyAlgOid != NULL) {
460 if (!CfBlobIsStr(publicKeyAlgOid)) {
461 LOGE("publicKeyAlgOid is not string!");
462 return CF_INVALID_PARAMS;
463 }
464 res = GetSubjectPubKeyAlgOidX509Openssl(self, &cfBlobDataSelf);
465 if (res != CF_SUCCESS) {
466 LOGE("x509Cert ComparePublicKeyAlgOidX509Openssl failed!");
467 return res;
468 }
469
470 if (cfBlobDataSelf.size != publicKeyAlgOid->size ||
471 strncmp((const char *)cfBlobDataSelf.data, (const char *)publicKeyAlgOid->data, cfBlobDataSelf.size) != 0) {
472 *out = false;
473 }
474 CfFree(cfBlobDataSelf.data);
475 }
476
477 return res;
478 }
479
GetVersionX509Openssl(HcfX509CertificateSpi * self)480 static long GetVersionX509Openssl(HcfX509CertificateSpi *self)
481 {
482 if (self == NULL) {
483 LOGE("The input data is null!");
484 return INVALID_VERSION;
485 }
486 if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
487 LOGE("Input wrong class type!");
488 return INVALID_VERSION;
489 }
490 HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
491 X509 *x509 = realCert->x509;
492 return X509_get_version(x509) + 1;
493 }
494
GetSerialNumberX509Openssl(HcfX509CertificateSpi * self,CfBlob * out)495 static CfResult GetSerialNumberX509Openssl(HcfX509CertificateSpi *self, CfBlob *out)
496 {
497 if ((self == NULL) || (out == NULL)) {
498 LOGE("The input data is null!");
499 return CF_INVALID_PARAMS;
500 }
501 if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
502 LOGE("Input wrong class type!");
503 return CF_INVALID_PARAMS;
504 }
505
506 HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
507 X509 *x509 = realCert->x509;
508 const ASN1_INTEGER *serial = X509_get0_serialNumber(x509);
509 if (serial == NULL) {
510 LOGE("Failed to get serial number!");
511 return CF_ERR_CRYPTO_OPERATION;
512 }
513
514 unsigned char *serialNumBytes = NULL;
515 int serialNumLen = i2d_ASN1_INTEGER((ASN1_INTEGER *)serial, &serialNumBytes);
516 if (serialNumLen <= SERIAL_NUMBER_HEDER_SIZE) {
517 CfPrintOpensslError();
518 LOGE("Failed to get serialNumLen!");
519 return CF_ERR_CRYPTO_OPERATION;
520 }
521
522 CfResult ret = DeepCopyDataToOut((const char *)(serialNumBytes + SERIAL_NUMBER_HEDER_SIZE),
523 (uint32_t)(serialNumLen - SERIAL_NUMBER_HEDER_SIZE), out);
524 OPENSSL_free(serialNumBytes);
525 return ret;
526 }
527
GetIssuerDNX509Openssl(HcfX509CertificateSpi * self,CfBlob * out)528 static CfResult GetIssuerDNX509Openssl(HcfX509CertificateSpi *self, CfBlob *out)
529 {
530 if ((self == NULL) || (out == NULL)) {
531 LOGE("[Get issuerDN openssl] The input data is null!");
532 return CF_INVALID_PARAMS;
533 }
534 if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
535 LOGE("Input wrong class type!");
536 return CF_INVALID_PARAMS;
537 }
538 HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
539 X509 *x509 = realCert->x509;
540 X509_NAME *issuerName = X509_get_issuer_name(x509);
541 if (issuerName == NULL) {
542 LOGE("Failed to get x509 issuerName in openssl!");
543 CfPrintOpensslError();
544 return CF_ERR_CRYPTO_OPERATION;
545 }
546 char *issuer = (char *)HcfMalloc(HCF_MAX_STR_LEN + 1, 0);
547 if (issuer == NULL) {
548 LOGE("Failed to malloc for issuer buffer!");
549 return CF_ERR_MALLOC;
550 }
551
552 CfResult res = CF_SUCCESS;
553 do {
554 X509_NAME_oneline(issuerName, issuer, HCF_MAX_STR_LEN);
555 size_t length = strlen(issuer) + 1;
556 if (length == 1) {
557 LOGE("Failed to get oneline issuerName in openssl!");
558 res = CF_ERR_CRYPTO_OPERATION;
559 CfPrintOpensslError();
560 break;
561 }
562 res = DeepCopyDataToOut(issuer, length, out);
563 } while (0);
564 CfFree(issuer);
565 return res;
566 }
567
GetSubjectDNX509Openssl(HcfX509CertificateSpi * self,CfBlob * out)568 static CfResult GetSubjectDNX509Openssl(HcfX509CertificateSpi *self, CfBlob *out)
569 {
570 if ((self == NULL) || (out == NULL)) {
571 LOGE("[Get subjectDN openssl]The input data is null!");
572 return CF_INVALID_PARAMS;
573 }
574 if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
575 LOGE("Input wrong class type!");
576 return CF_INVALID_PARAMS;
577 }
578 HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
579 X509 *x509 = realCert->x509;
580 X509_NAME *subjectName = X509_get_subject_name(x509);
581 if (subjectName == NULL) {
582 LOGE("Failed to get x509 subjectName in openssl!");
583 CfPrintOpensslError();
584 return CF_ERR_CRYPTO_OPERATION;
585 }
586 char *subject = (char *)HcfMalloc(HCF_MAX_STR_LEN + 1, 0);
587 if (subject == NULL) {
588 LOGE("Failed to malloc for subject buffer!");
589 return CF_ERR_MALLOC;
590 }
591
592 CfResult res = CF_SUCCESS;
593 do {
594 X509_NAME_oneline(subjectName, subject, HCF_MAX_STR_LEN);
595 size_t length = strlen(subject) + 1;
596 if (length == 1) {
597 LOGE("Failed to get oneline subjectName in openssl!");
598 CfPrintOpensslError();
599 res = CF_ERR_CRYPTO_OPERATION;
600 break;
601 }
602 res = DeepCopyDataToOut(subject, length, out);
603 } while (0);
604 CfFree(subject);
605 return res;
606 }
607
GetNotBeforeX509Openssl(HcfX509CertificateSpi * self,CfBlob * outDate)608 static CfResult GetNotBeforeX509Openssl(HcfX509CertificateSpi *self, CfBlob *outDate)
609 {
610 if ((self == NULL) || (outDate == NULL)) {
611 LOGE("Get not before, input is null!");
612 return CF_INVALID_PARAMS;
613 }
614 if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
615 LOGE("Get not before, input wrong class type!");
616 return CF_INVALID_PARAMS;
617 }
618 HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
619 X509 *x509 = realCert->x509;
620 ASN1_TIME *notBeforeDate = X509_get_notBefore(x509);
621 if (notBeforeDate == NULL) {
622 LOGE("NotBeforeDate is null in x509 cert!");
623 CfPrintOpensslError();
624 return CF_ERR_CRYPTO_OPERATION;
625 }
626 if (ASN1_TIME_normalize(notBeforeDate) != CF_OPENSSL_SUCCESS) {
627 LOGE("Failed to normalize notBeforeDate!");
628 CfPrintOpensslError();
629 return CF_ERR_CRYPTO_OPERATION;
630 }
631 const char *date = (const char *)(notBeforeDate->data);
632 if ((date == NULL) || (strlen(date) > HCF_MAX_STR_LEN)) {
633 LOGE("Failed to get notBeforeDate data!");
634 return CF_ERR_CRYPTO_OPERATION;
635 }
636 uint32_t length = strlen(date) + 1;
637 return DeepCopyDataToOut(date, length, outDate);
638 }
639
GetNotAfterX509Openssl(HcfX509CertificateSpi * self,CfBlob * outDate)640 static CfResult GetNotAfterX509Openssl(HcfX509CertificateSpi *self, CfBlob *outDate)
641 {
642 if ((self == NULL) || (outDate == NULL)) {
643 LOGE("Get not after, input data is null!");
644 return CF_INVALID_PARAMS;
645 }
646 if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
647 LOGE("Get not after, input wrong class type!");
648 return CF_INVALID_PARAMS;
649 }
650 HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
651 X509 *x509 = realCert->x509;
652 ASN1_TIME *notAfterDate = X509_get_notAfter(x509);
653 if (notAfterDate == NULL) {
654 LOGE("NotAfterDate is null in x509 cert!");
655 CfPrintOpensslError();
656 return CF_ERR_CRYPTO_OPERATION;
657 }
658 if (ASN1_TIME_normalize(notAfterDate) != CF_OPENSSL_SUCCESS) {
659 LOGE("Failed to normalize notAfterDate!");
660 CfPrintOpensslError();
661 return CF_ERR_CRYPTO_OPERATION;
662 }
663 const char *date = (const char *)(notAfterDate->data);
664 if ((date == NULL) || (strlen(date) > HCF_MAX_STR_LEN)) {
665 LOGE("Failed to get notAfterDate data!");
666 return CF_ERR_CRYPTO_OPERATION;
667 }
668 uint32_t length = strlen(date) + 1;
669 return DeepCopyDataToOut(date, length, outDate);
670 }
671
GetSignatureX509Openssl(HcfX509CertificateSpi * self,CfBlob * sigOut)672 static CfResult GetSignatureX509Openssl(HcfX509CertificateSpi *self, CfBlob *sigOut)
673 {
674 if ((self == NULL) || (sigOut == NULL)) {
675 LOGE("The input data is null!");
676 return CF_INVALID_PARAMS;
677 }
678 if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
679 LOGE("Input wrong class type!");
680 return CF_INVALID_PARAMS;
681 }
682 HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
683 X509 *x509 = realCert->x509;
684 const ASN1_BIT_STRING *signature;
685 X509_get0_signature(&signature, NULL, x509);
686 if ((signature == NULL) || (signature->length == 0) || (signature->length > HCF_MAX_BUFFER_LEN)) {
687 LOGE("Failed to get x509 signature in openssl!");
688 CfPrintOpensslError();
689 return CF_ERR_CRYPTO_OPERATION;
690 }
691 sigOut->data = (uint8_t *)HcfMalloc(signature->length, 0);
692 if (sigOut->data == NULL) {
693 LOGE("Failed to malloc for signature data!");
694 return CF_ERR_MALLOC;
695 }
696 (void)memcpy_s(sigOut->data, signature->length, signature->data, signature->length);
697 sigOut->size = signature->length;
698 return CF_SUCCESS;
699 }
700
GetSigAlgNameX509Openssl(HcfX509CertificateSpi * self,CfBlob * outName)701 static CfResult GetSigAlgNameX509Openssl(HcfX509CertificateSpi *self, CfBlob *outName)
702 {
703 if ((self == NULL) || (outName == NULL)) {
704 LOGE("[GetSigAlgName openssl] The input data is null!");
705 return CF_INVALID_PARAMS;
706 }
707 if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
708 LOGE("[GetSigAlgName openssl] Input wrong class type!");
709 return CF_INVALID_PARAMS;
710 }
711 HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
712 X509 *x509 = realCert->x509;
713 const X509_ALGOR *alg;
714 X509_get0_signature(NULL, &alg, x509);
715 const ASN1_OBJECT *oidObj;
716 X509_ALGOR_get0(&oidObj, NULL, NULL, alg);
717 char oidStr[OID_STR_MAX_LEN] = { 0 };
718 int32_t resLen = OBJ_obj2txt(oidStr, OID_STR_MAX_LEN, oidObj, 1);
719 if ((resLen < 0) || (resLen >= OID_STR_MAX_LEN)) {
720 LOGE("Failed to convert x509 object to text!");
721 CfPrintOpensslError();
722 return CF_ERR_CRYPTO_OPERATION;
723 }
724 const char *algName = GetAlgorithmName(oidStr);
725 if (algName == NULL) {
726 return CF_ERR_CRYPTO_OPERATION;
727 }
728 uint32_t len = strlen(algName) + 1;
729 return DeepCopyDataToOut(algName, len, outName);
730 }
731
GetSigAlgOidX509Openssl(HcfX509CertificateSpi * self,CfBlob * out)732 static CfResult GetSigAlgOidX509Openssl(HcfX509CertificateSpi *self, CfBlob *out)
733 {
734 if ((self == NULL) || (out == NULL)) {
735 LOGE("[GetSigAlgOID openssl] The input data is null!");
736 return CF_INVALID_PARAMS;
737 }
738 if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
739 LOGE("[GetSigAlgOID openssl] Input wrong class type!");
740 return CF_INVALID_PARAMS;
741 }
742 HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
743 X509 *x509 = realCert->x509;
744 const X509_ALGOR *alg;
745 X509_get0_signature(NULL, &alg, x509);
746 const ASN1_OBJECT *oid;
747 X509_ALGOR_get0(&oid, NULL, NULL, alg);
748 char algOid[OID_STR_MAX_LEN] = { 0 };
749 int32_t resLen = OBJ_obj2txt(algOid, OID_STR_MAX_LEN, oid, 1);
750 if ((resLen < 0) || (resLen >= OID_STR_MAX_LEN)) {
751 LOGE("Failed to convert x509 object to text!");
752 CfPrintOpensslError();
753 return CF_ERR_CRYPTO_OPERATION;
754 }
755 uint32_t len = strlen(algOid) + 1;
756 return DeepCopyDataToOut(algOid, len, out);
757 }
758
GetSigAlgParamsX509Openssl(HcfX509CertificateSpi * self,CfBlob * sigAlgParamsOut)759 static CfResult GetSigAlgParamsX509Openssl(HcfX509CertificateSpi *self, CfBlob *sigAlgParamsOut)
760 {
761 if ((self == NULL) || (sigAlgParamsOut == NULL)) {
762 LOGE("[GetSigAlgParams openssl] The input data is null!");
763 return CF_INVALID_PARAMS;
764 }
765 if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
766 LOGE("[GetSigAlgParams openssl] Input wrong class type!");
767 return CF_INVALID_PARAMS;
768 }
769 HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
770 X509 *x509 = realCert->x509;
771 const X509_ALGOR *alg;
772 X509_get0_signature(NULL, &alg, x509);
773 int32_t paramType = 0;
774 const void *paramValue = NULL;
775 X509_ALGOR_get0(NULL, ¶mType, ¶mValue, alg);
776 if (paramType == V_ASN1_UNDEF) {
777 LOGE("get_X509_ALGOR_parameter, no parameters!");
778 return CF_NOT_SUPPORT;
779 }
780 ASN1_TYPE *param = ASN1_TYPE_new();
781 if (param == NULL) {
782 LOGE("Failed to malloc for asn1 type data!");
783 return CF_ERR_MALLOC;
784 }
785 if (ASN1_TYPE_set1(param, paramType, paramValue) != CF_OPENSSL_SUCCESS) {
786 LOGE("Failed to set asn1 type in openssl!");
787 CfPrintOpensslError();
788 ASN1_TYPE_free(param);
789 return CF_ERR_CRYPTO_OPERATION;
790 }
791 unsigned char *out = NULL;
792 int32_t len = i2d_ASN1_TYPE(param, NULL);
793 if (len <= 0) {
794 LOGE("Failed to convert ASN1_TYPE!");
795 CfPrintOpensslError();
796 ASN1_TYPE_free(param);
797 return CF_ERR_CRYPTO_OPERATION;
798 }
799 (void)i2d_ASN1_TYPE(param, &out);
800 ASN1_TYPE_free(param);
801 CfResult res = DeepCopyDataToOut((const char *)out, len, sigAlgParamsOut);
802 OPENSSL_free(out);
803 return res;
804 }
805
ConvertAsn1String2BoolArray(const ASN1_BIT_STRING * string,CfBlob * boolArr)806 static CfResult ConvertAsn1String2BoolArray(const ASN1_BIT_STRING *string, CfBlob *boolArr)
807 {
808 uint32_t length = ASN1_STRING_length(string) * CHAR_TO_BIT_LEN;
809 if (string->flags & ASN1_STRING_FLAG_BITS_LEFT) {
810 length -= string->flags & FLAG_BIT_LEFT_NUM;
811 }
812 boolArr->data = (uint8_t *)HcfMalloc(length, 0);
813 if (boolArr->data == NULL) {
814 LOGE("Failed to malloc for bit array data!");
815 return CF_ERR_MALLOC;
816 }
817 for (uint32_t i = 0; i < length; i++) {
818 boolArr->data[i] = ASN1_BIT_STRING_get_bit(string, i);
819 }
820 boolArr->size = length;
821 return CF_SUCCESS;
822 }
823
GetKeyUsageX509Openssl(HcfX509CertificateSpi * self,CfBlob * boolArr)824 static CfResult GetKeyUsageX509Openssl(HcfX509CertificateSpi *self, CfBlob *boolArr)
825 {
826 if ((self == NULL) || (boolArr == NULL)) {
827 LOGE("[GetKeyUsage openssl] The input data is null!");
828 return CF_INVALID_PARAMS;
829 }
830 if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
831 LOGE("Input wrong class type!");
832 return CF_INVALID_PARAMS;
833 }
834 HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
835 X509 *x509 = realCert->x509;
836
837 ASN1_BIT_STRING *keyUsage = (ASN1_BIT_STRING *)X509_get_ext_d2i(x509, NID_key_usage, NULL, NULL);
838 if ((keyUsage == NULL) || (keyUsage->length <= 0)|| (keyUsage->length >= HCF_MAX_STR_LEN)) {
839 LOGE("Failed to get x509 keyUsage in openssl!");
840 CfPrintOpensslError();
841 return CF_ERR_CRYPTO_OPERATION;
842 }
843 CfResult res = ConvertAsn1String2BoolArray(keyUsage, boolArr);
844 ASN1_BIT_STRING_free(keyUsage);
845 return res;
846 }
847
DeepCopyExtendedKeyUsage(const STACK_OF (ASN1_OBJECT)* extUsage,int32_t i,CfArray * keyUsageOut)848 static CfResult DeepCopyExtendedKeyUsage(const STACK_OF(ASN1_OBJECT) *extUsage,
849 int32_t i, CfArray *keyUsageOut)
850 {
851 char usage[OID_STR_MAX_LEN] = { 0 };
852 int32_t resLen = OBJ_obj2txt(usage, OID_STR_MAX_LEN, sk_ASN1_OBJECT_value(extUsage, i), 1);
853 if ((resLen < 0) || (resLen >= OID_STR_MAX_LEN)) {
854 LOGE("Failed to convert x509 object to text!");
855 CfPrintOpensslError();
856 return CF_ERR_CRYPTO_OPERATION;
857 }
858 uint32_t len = strlen(usage) + 1;
859 keyUsageOut->data[i].data = (uint8_t *)HcfMalloc(len, 0);
860 if (keyUsageOut->data[i].data == NULL) {
861 LOGE("Failed to malloc for key usage!");
862 return CF_ERR_MALLOC;
863 }
864 (void)memcpy_s(keyUsageOut->data[i].data, len, usage, len);
865 keyUsageOut->data[i].size = len;
866 return CF_SUCCESS;
867 }
868
GetExtendedKeyUsageX509Openssl(HcfX509CertificateSpi * self,CfArray * keyUsageOut)869 static CfResult GetExtendedKeyUsageX509Openssl(HcfX509CertificateSpi *self, CfArray *keyUsageOut)
870 {
871 if ((self == NULL) || (keyUsageOut == NULL)) {
872 LOGE("The input data is null!");
873 return CF_INVALID_PARAMS;
874 }
875 if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
876 LOGE("Input wrong class type!");
877 return CF_INVALID_PARAMS;
878 }
879 HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
880 X509 *x509 = realCert->x509;
881 STACK_OF(ASN1_OBJECT) *extUsage = X509_get_ext_d2i(x509, NID_ext_key_usage, NULL, NULL);
882 if (extUsage == NULL) {
883 LOGE("Failed to get x509 extended keyUsage in openssl!");
884 return CF_ERR_CRYPTO_OPERATION;
885 }
886 CfResult res = CF_SUCCESS;
887 do {
888 int32_t size = sk_ASN1_OBJECT_num(extUsage);
889 if (size <= 0) {
890 LOGE("The extended key usage size in openssl is invalid!");
891 CfPrintOpensslError();
892 res = CF_ERR_CRYPTO_OPERATION;
893 break;
894 }
895 int32_t blobSize = sizeof(CfBlob) * size;
896 keyUsageOut->data = (CfBlob *)HcfMalloc(blobSize, 0);
897 if (keyUsageOut->data == NULL) {
898 LOGE("Failed to malloc for keyUsageOut array!");
899 res = CF_ERR_MALLOC;
900 break;
901 }
902 keyUsageOut->count = (uint32_t)size;
903 for (int32_t i = 0; i < size; ++i) {
904 res = DeepCopyExtendedKeyUsage(extUsage, i, keyUsageOut);
905 if (res != CF_SUCCESS) {
906 LOGE("Falied to copy extended key usage!");
907 break;
908 }
909 }
910 } while (0);
911 if (res != CF_SUCCESS) {
912 CfArrayDataClearAndFree(keyUsageOut);
913 }
914 sk_ASN1_OBJECT_pop_free(extUsage, ASN1_OBJECT_free);
915 return res;
916 }
917
GetBasicConstraintsX509Openssl(HcfX509CertificateSpi * self)918 static int32_t GetBasicConstraintsX509Openssl(HcfX509CertificateSpi *self)
919 {
920 if (self == NULL) {
921 LOGE("The input data is null!");
922 return INVALID_CONSTRAINTS_LEN;
923 }
924 if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
925 LOGE("Input wrong class type!");
926 return INVALID_CONSTRAINTS_LEN;
927 }
928 HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
929 X509 *x509 = realCert->x509;
930 BASIC_CONSTRAINTS *constraints = (BASIC_CONSTRAINTS *)X509_get_ext_d2i(x509, NID_basic_constraints, NULL, NULL);
931 if (constraints == NULL) {
932 LOGE("Failed to get basic constraints in openssl!");
933 return INVALID_CONSTRAINTS_LEN;
934 }
935 /* Path len is only valid for CA cert. */
936 if (!constraints->ca) {
937 BASIC_CONSTRAINTS_free(constraints);
938 LOGI("The cert in not a CA!");
939 return INVALID_CONSTRAINTS_LEN;
940 }
941 if ((constraints->pathlen == NULL) || (constraints->pathlen->type == V_ASN1_NEG_INTEGER)) {
942 BASIC_CONSTRAINTS_free(constraints);
943 LOGE("The cert path len is negative in openssl!");
944 return INVALID_CONSTRAINTS_LEN;
945 }
946 long pathLen = ASN1_INTEGER_get(constraints->pathlen);
947 if ((pathLen < 0) || (pathLen > INT_MAX)) {
948 BASIC_CONSTRAINTS_free(constraints);
949 LOGE("Get the overflow path length in openssl!");
950 return INVALID_CONSTRAINTS_LEN;
951 }
952 BASIC_CONSTRAINTS_free(constraints);
953 return (int32_t)pathLen;
954 }
955
DeepCopyAlternativeNames(const STACK_OF (GENERAL_NAME)* altNames,int32_t i,CfArray * outName)956 static CfResult DeepCopyAlternativeNames(const STACK_OF(GENERAL_NAME) *altNames, int32_t i, CfArray *outName)
957 {
958 GENERAL_NAME *general = sk_GENERAL_NAME_value(altNames, i);
959 int32_t generalType = 0;
960 ASN1_STRING *ans1Str = GENERAL_NAME_get0_value(general, &generalType);
961 const char *str = (const char *)ASN1_STRING_get0_data(ans1Str);
962 if ((str == NULL) || (strlen(str) > HCF_MAX_STR_LEN)) {
963 LOGE("Failed to get x509 altNames string in openssl!");
964 CfPrintOpensslError();
965 return CF_ERR_CRYPTO_OPERATION;
966 }
967 uint32_t nameLen = strlen(str) + 1;
968 outName->data[i].data = (uint8_t *)HcfMalloc(nameLen, 0);
969 if (outName->data[i].data == NULL) {
970 LOGE("Failed to malloc for outName!");
971 return CF_ERR_MALLOC;
972 }
973 (void)memcpy_s(outName->data[i].data, nameLen, str, nameLen);
974 outName->data[i].size = nameLen;
975 return CF_SUCCESS;
976 }
977
GetSubjectAltNamesX509Openssl(HcfX509CertificateSpi * self,CfArray * outName)978 static CfResult GetSubjectAltNamesX509Openssl(HcfX509CertificateSpi *self, CfArray *outName)
979 {
980 if ((self == NULL) || (outName == NULL)) {
981 LOGE("[GetSubjectAltNames openssl] The input data is null!");
982 return CF_INVALID_PARAMS;
983 }
984 if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
985 LOGE("Input wrong class type!");
986 return CF_INVALID_PARAMS;
987 }
988 HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
989 X509 *x509 = realCert->x509;
990 STACK_OF(GENERAL_NAME) *subjectAltName = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL);
991 if (subjectAltName == NULL) {
992 LOGE("Failed to get subjectAltName in openssl!");
993 CfPrintOpensslError();
994 return CF_ERR_CRYPTO_OPERATION;
995 }
996 CfResult res = CF_SUCCESS;
997 do {
998 int32_t size = sk_GENERAL_NAME_num(subjectAltName);
999 if (size <= 0) {
1000 LOGE("The subjectAltName number in openssl is invalid!");
1001 CfPrintOpensslError();
1002 res = CF_ERR_CRYPTO_OPERATION;
1003 break;
1004 }
1005 int32_t blobSize = sizeof(CfBlob) * size;
1006 outName->data = (CfBlob *)HcfMalloc(blobSize, 0);
1007 if (outName->data == NULL) {
1008 LOGE("Failed to malloc for subjectAltName array!");
1009 res = CF_ERR_MALLOC;
1010 break;
1011 }
1012 outName->count = (uint32_t)size;
1013 for (int32_t i = 0; i < size; ++i) {
1014 res = DeepCopyAlternativeNames(subjectAltName, i, outName);
1015 if (res != CF_SUCCESS) {
1016 LOGE("Falied to copy subjectAltName!");
1017 break;
1018 }
1019 }
1020 } while (0);
1021 if (res != CF_SUCCESS) {
1022 CfArrayDataClearAndFree(outName);
1023 }
1024 GENERAL_NAMES_free(subjectAltName);
1025 return res;
1026 }
1027
GetIssuerAltNamesX509Openssl(HcfX509CertificateSpi * self,CfArray * outName)1028 static CfResult GetIssuerAltNamesX509Openssl(HcfX509CertificateSpi *self, CfArray *outName)
1029 {
1030 if ((self == NULL) || (outName == NULL)) {
1031 LOGE("[GetIssuerAltNames openssl] The input data is null!");
1032 return CF_INVALID_PARAMS;
1033 }
1034 if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
1035 LOGE("Input wrong class type!");
1036 return CF_INVALID_PARAMS;
1037 }
1038 HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
1039 X509 *x509 = realCert->x509;
1040 STACK_OF(GENERAL_NAME) *issuerAltName = X509_get_ext_d2i(x509, NID_issuer_alt_name, NULL, NULL);
1041 if (issuerAltName == NULL) {
1042 LOGE("Failed to get issuerAltName in openssl!");
1043 CfPrintOpensslError();
1044 return CF_ERR_CRYPTO_OPERATION;
1045 }
1046 CfResult res = CF_SUCCESS;
1047 do {
1048 int32_t size = sk_GENERAL_NAME_num(issuerAltName);
1049 if (size <= 0) {
1050 LOGE("The issuerAltName number in openssl is invalid!");
1051 CfPrintOpensslError();
1052 res = CF_ERR_CRYPTO_OPERATION;
1053 break;
1054 }
1055 int32_t blobSize = sizeof(CfBlob) * size;
1056 outName->data = (CfBlob *)HcfMalloc(blobSize, 0);
1057 if (outName->data == NULL) {
1058 LOGE("Failed to malloc for issuerAltName array!");
1059 res = CF_ERR_MALLOC;
1060 break;
1061 }
1062 outName->count = (uint32_t)size;
1063 for (int32_t i = 0; i < size; ++i) {
1064 res = DeepCopyAlternativeNames(issuerAltName, i, outName);
1065 if (res != CF_SUCCESS) {
1066 LOGE("Falied to copy issuerAltName!");
1067 break;
1068 }
1069 }
1070 } while (0);
1071 if (res != CF_SUCCESS) {
1072 CfArrayDataClearAndFree(outName);
1073 }
1074 GENERAL_NAMES_free(issuerAltName);
1075 return res;
1076 }
1077
MatchPart1(HcfX509CertificateSpi * self,const HcfX509CertMatchParams * matchParams,bool * out)1078 static CfResult MatchPart1(HcfX509CertificateSpi *self, const HcfX509CertMatchParams *matchParams, bool *out)
1079 {
1080 CfResult res = CF_SUCCESS;
1081 *out = true;
1082
1083 // x509Cert
1084 res = CompareCertBlobX509Openssl(self, matchParams->x509Cert, out);
1085 if (res != CF_SUCCESS || (*out == false)) {
1086 LOGE("Failed to CompareCertBlob!");
1087 return res;
1088 }
1089 // subject
1090 res = CompareNameObjectX509Openssl(self, matchParams->subject, NAME_TYPE_SUBECT, out);
1091 if (res != CF_SUCCESS || (*out == false)) {
1092 LOGE("Failed to CompareSubject!");
1093 return res;
1094 }
1095 // validDate
1096 if (matchParams->validDate != NULL) {
1097 if (!CfBlobIsStr(matchParams->validDate)) {
1098 LOGE("Invalid param!");
1099 return CF_INVALID_PARAMS;
1100 }
1101 res = CheckValidityWithDateX509Openssl(self, (const char *)matchParams->validDate->data);
1102 if ((res == CF_ERR_CERT_NOT_YET_VALID) || (res == CF_ERR_CERT_HAS_EXPIRED)) {
1103 *out = false;
1104 return CF_SUCCESS;
1105 }
1106 if (res != CF_SUCCESS) {
1107 LOGE("Failed to CheckValidityWithDate!");
1108 return res;
1109 }
1110 }
1111 // issuer
1112 res = CompareNameObjectX509Openssl(self, matchParams->issuer, NAME_TYPE_ISSUER, out);
1113 if (res != CF_SUCCESS || (*out == false)) {
1114 LOGE("Failed to CompareIssuer!");
1115 return res;
1116 }
1117 return res;
1118 }
1119
MatchPart2(HcfX509CertificateSpi * self,const HcfX509CertMatchParams * matchParams,bool * out)1120 static CfResult MatchPart2(HcfX509CertificateSpi *self, const HcfX509CertMatchParams *matchParams, bool *out)
1121 {
1122 CfResult res = CF_SUCCESS;
1123 *out = true;
1124
1125 // keyUsage
1126 res = CompareKeyUsageX509Openssl(self, matchParams->keyUsage, out);
1127 if (res != CF_SUCCESS || (*out == false)) {
1128 LOGE("Failed to CompareKeyUsage!");
1129 return res;
1130 }
1131 // serialNumber
1132 res = CompareSerialNumberX509Openssl(self, matchParams->serialNumber, out);
1133 if (res != CF_SUCCESS || (*out == false)) {
1134 LOGE("Failed to CompareSerialNumber!");
1135 return res;
1136 }
1137 // publicKey
1138 res = ComparePublicKeyX509Openssl(self, matchParams->publicKey, out);
1139 if (res != CF_SUCCESS || (*out == false)) {
1140 LOGE("Failed to ComparePublicKey!");
1141 return res;
1142 }
1143 // publicKeyAlgID
1144 res = ComparePublicKeyAlgOidX509Openssl(self, matchParams->publicKeyAlgID, out);
1145 if (res != CF_SUCCESS || (*out == false)) {
1146 LOGE("Failed to ComparePublicKeyAlgOid!");
1147 return res;
1148 }
1149
1150 return CF_SUCCESS;
1151 }
1152
MatchX509Openssl(HcfX509CertificateSpi * self,const HcfX509CertMatchParams * matchParams,bool * out)1153 static CfResult MatchX509Openssl(HcfX509CertificateSpi *self, const HcfX509CertMatchParams *matchParams, bool *out)
1154 {
1155 LOGI("enter MatchX509Openssl!");
1156 if ((self == NULL) || (matchParams == NULL) || (out == NULL)) {
1157 LOGE("[GetIssuerAltNames openssl] The input data is null!");
1158 return CF_INVALID_PARAMS;
1159 }
1160 if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
1161 LOGE("Input wrong class type!");
1162 return CF_INVALID_PARAMS;
1163 }
1164 CfResult res = CF_SUCCESS;
1165 *out = true;
1166 res = MatchPart1(self, matchParams, out);
1167 if (res != CF_SUCCESS || (*out == false)) {
1168 LOGE("Failed to Match Part1!");
1169 return res;
1170 }
1171
1172 res = MatchPart2(self, matchParams, out);
1173 if (res != CF_SUCCESS || (*out == false)) {
1174 LOGE("Failed to Match Part2!");
1175 return res;
1176 }
1177 return CF_SUCCESS;
1178 }
1179
DeepCopyURIs(ASN1_STRING * uri,uint32_t index,CfArray * outURI)1180 static CfResult DeepCopyURIs(ASN1_STRING *uri, uint32_t index, CfArray *outURI)
1181 {
1182 if (index >= outURI->count) { /* exceed the maximum memory capacity. */
1183 LOGE("exceed the maximum memory capacity, uriCount = %u, malloc count = %u", index, outURI->count);
1184 return CF_ERR_CRYPTO_OPERATION;
1185 }
1186
1187 const char *str = (const char *)ASN1_STRING_get0_data(uri);
1188 if ((str == NULL) || (strlen(str) > HCF_MAX_STR_LEN)) {
1189 LOGE("Failed to get CRL DP URI string in openssl!");
1190 return CF_ERR_CRYPTO_OPERATION;
1191 }
1192
1193 uint32_t uriLen = strlen(str) + 1;
1194 outURI->data[index].data = (uint8_t *)HcfMalloc(uriLen, 0);
1195 if (outURI->data[index].data == NULL) {
1196 LOGE("Failed to malloc for outURI[%u]!", index);
1197 return CF_ERR_MALLOC;
1198 }
1199 (void)memcpy_s(outURI->data[index].data, uriLen, str, uriLen);
1200 outURI->data[index].size = uriLen;
1201 return CF_SUCCESS;
1202 }
1203
GetDpURIFromGenName(GENERAL_NAME * genName,bool isFormatOutURI,uint32_t * uriCount,CfArray * outURI)1204 static CfResult GetDpURIFromGenName(GENERAL_NAME *genName, bool isFormatOutURI, uint32_t *uriCount, CfArray *outURI)
1205 {
1206 int type = 0;
1207 ASN1_STRING *uri = GENERAL_NAME_get0_value(genName, &type);
1208 if (uri == NULL) {
1209 LOGE("get uri asn1 string failed");
1210 return CF_ERR_CRYPTO_OPERATION;
1211 }
1212
1213 if (type != GEN_URI) {
1214 LOGI("not URI type, type is %d", type);
1215 return CF_SUCCESS;
1216 }
1217
1218 if (isFormatOutURI) {
1219 CfResult ret = DeepCopyURIs(uri, *uriCount, outURI);
1220 if (ret != CF_SUCCESS) {
1221 LOGE("copy URI[%u] failed", *uriCount);
1222 return ret;
1223 }
1224 }
1225 *uriCount += 1;
1226 return CF_SUCCESS;
1227 }
1228
GetDpURIFromGenNames(GENERAL_NAMES * genNames,bool isFormatOutURI,uint32_t * uriCount,CfArray * outURI)1229 static CfResult GetDpURIFromGenNames(GENERAL_NAMES *genNames, bool isFormatOutURI, uint32_t *uriCount,
1230 CfArray *outURI)
1231 {
1232 CfResult ret = CF_SUCCESS;
1233 int genNameNum = sk_GENERAL_NAME_num(genNames);
1234 for (int i = 0; i < genNameNum; ++i) {
1235 GENERAL_NAME *genName = sk_GENERAL_NAME_value(genNames, i);
1236 if (genName == NULL) {
1237 LOGE("get gen name failed!");
1238 ret = CF_ERR_CRYPTO_OPERATION;
1239 break;
1240 }
1241
1242 ret = GetDpURIFromGenName(genName, isFormatOutURI, uriCount, outURI);
1243 if (ret != CF_SUCCESS) {
1244 LOGE("get gen name failed!");
1245 break;
1246 }
1247 }
1248 return ret;
1249 }
1250
GetDpURI(STACK_OF (DIST_POINT)* crlDp,int32_t dpNumber,bool isFormatOutURI,uint32_t * uriCount,CfArray * outURI)1251 static CfResult GetDpURI(STACK_OF(DIST_POINT) *crlDp, int32_t dpNumber, bool isFormatOutURI,
1252 uint32_t *uriCount, CfArray *outURI)
1253 {
1254 CfResult ret = CF_SUCCESS;
1255 for (int i = 0; i < dpNumber; ++i) {
1256 DIST_POINT *dp = sk_DIST_POINT_value(crlDp, i);
1257 if (dp == NULL) {
1258 LOGE("get distribution point failed!");
1259 ret = CF_ERR_CRYPTO_OPERATION;
1260 break;
1261 }
1262
1263 if (dp->distpoint == NULL || dp->distpoint->type != 0) {
1264 LOGI("not fullnames, continue!");
1265 continue;
1266 }
1267
1268 ret = GetDpURIFromGenNames(dp->distpoint->name.fullname, isFormatOutURI, uriCount, outURI);
1269 if (ret != CF_SUCCESS) {
1270 LOGE("get dp uri from general names failed");
1271 break;
1272 }
1273 }
1274 if (ret == CF_SUCCESS && isFormatOutURI) {
1275 outURI->count = *uriCount;
1276 }
1277 return ret;
1278 }
1279
GetCRLDpURI(STACK_OF (DIST_POINT)* crlDp,CfArray * outURI)1280 static CfResult GetCRLDpURI(STACK_OF(DIST_POINT) *crlDp, CfArray *outURI)
1281 {
1282 /* 1. get CRL distribution point URI count */
1283 int32_t dpNumber = sk_DIST_POINT_num(crlDp);
1284 uint32_t uriCount = 0;
1285 CfResult ret = GetDpURI(crlDp, dpNumber, false, &uriCount, outURI);
1286 if (ret != CF_SUCCESS) {
1287 LOGE("get dp URI count failed, ret = %d", ret);
1288 return ret;
1289 }
1290 if (uriCount == 0) {
1291 LOGE("CRL DP URI not exist");
1292 return CF_NOT_EXIST;
1293 }
1294 if (uriCount > CF_MAX_URI_COUNT) {
1295 LOGE("uriCount[%u] exceed max count", uriCount);
1296 return CF_ERR_CRYPTO_OPERATION;
1297 }
1298 LOGI("get uriCount success, uriCount = %u", uriCount);
1299
1300 /* 2. malloc outArray buffer */
1301 uint32_t blobSize = sizeof(CfBlob) * uriCount;
1302 outURI->data = (CfBlob *)HcfMalloc(blobSize, 0);
1303 if (outURI->data == NULL) {
1304 LOGE("Failed to malloc for outURI array!");
1305 return CF_ERR_MALLOC;
1306 }
1307 outURI->count = uriCount;
1308
1309 /* 2. copy CRL distribution point URIs */
1310 uriCount = 0;
1311 ret = GetDpURI(crlDp, dpNumber, true, &uriCount, outURI);
1312 if (ret != CF_SUCCESS) {
1313 LOGE("get dp URI format failed, ret = %d", ret);
1314 CfArrayDataClearAndFree(outURI);
1315 return ret;
1316 }
1317
1318 LOGI("get CRL dp URI success, count = %u", outURI->count);
1319 return ret;
1320 }
1321
GetCRLDistributionPointsURIX509Openssl(HcfX509CertificateSpi * self,CfArray * outURI)1322 static CfResult GetCRLDistributionPointsURIX509Openssl(HcfX509CertificateSpi *self, CfArray *outURI)
1323 {
1324 if ((self == NULL) || (outURI == NULL)) {
1325 LOGE("[GetCRLDistributionPointsURI openssl] The input data is null!");
1326 return CF_INVALID_PARAMS;
1327 }
1328 if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
1329 LOGE("[GetCRLDistributionPointsURI openssl] Input wrong class type!");
1330 return CF_INVALID_PARAMS;
1331 }
1332
1333 HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
1334 X509 *x509 = realCert->x509;
1335 STACK_OF(DIST_POINT) *crlDp = X509_get_ext_d2i(x509, NID_crl_distribution_points, NULL, NULL);
1336 if (crlDp == NULL) {
1337 LOGE("Failed to get crl distribution point in openssl!");
1338 CfPrintOpensslError();
1339 return CF_NOT_EXIST;
1340 }
1341
1342 CfResult ret = GetCRLDpURI(crlDp, outURI);
1343 sk_DIST_POINT_pop_free(crlDp, DIST_POINT_free);
1344 return ret;
1345 }
1346
GetSubjectPubKeyAlgOidX509Openssl(HcfX509CertificateSpi * self,CfBlob * out)1347 static CfResult GetSubjectPubKeyAlgOidX509Openssl(HcfX509CertificateSpi *self, CfBlob *out)
1348 {
1349 CfResult res = CF_SUCCESS;
1350 HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
1351 X509 *x509 = realCert->x509;
1352 EVP_PKEY *pubkey = X509_get_pubkey(x509);
1353 if (NULL == pubkey) {
1354 LOGE("Failed to get public key from x509 cert.");
1355 CfPrintOpensslError();
1356 return CF_ERR_CRYPTO_OPERATION;
1357 }
1358 int nId = EVP_PKEY_get_base_id(pubkey);
1359 ASN1_OBJECT *obj = OBJ_nid2obj(nId);
1360 if (NULL == obj) {
1361 LOGE("Failed to get algObj from pubkey.");
1362 CfPrintOpensslError();
1363 EVP_PKEY_free(pubkey);
1364 return CF_ERR_CRYPTO_OPERATION;
1365 }
1366
1367 char algOid[OID_STR_MAX_LEN] = { 0 };
1368 int32_t resLen = OBJ_obj2txt(algOid, OID_STR_MAX_LEN, obj, 1);
1369 if ((resLen < 0) || (resLen >= OID_STR_MAX_LEN)) {
1370 LOGE("Failed to convert x509 object to text!");
1371 CfPrintOpensslError();
1372 EVP_PKEY_free(pubkey);
1373 ASN1_OBJECT_free(obj);
1374 return CF_ERR_CRYPTO_OPERATION;
1375 }
1376 uint32_t len = strlen(algOid) + 1;
1377 res = DeepCopyDataToOut(algOid, len, out);
1378 EVP_PKEY_free(pubkey);
1379 ASN1_OBJECT_free(obj);
1380 return res;
1381 }
1382
CreateX509CertInner(const CfEncodingBlob * encodingBlob)1383 static X509 *CreateX509CertInner(const CfEncodingBlob *encodingBlob)
1384 {
1385 X509 *x509 = NULL;
1386 BIO *bio = BIO_new_mem_buf(encodingBlob->data, encodingBlob->len);
1387 if (bio == NULL) {
1388 LOGE("Openssl bio new buf failed.");
1389 return NULL;
1390 }
1391 LOGD("The input cert format is: %d.", encodingBlob->encodingFormat);
1392 if (encodingBlob->encodingFormat == CF_FORMAT_DER) {
1393 x509 = d2i_X509_bio(bio, NULL);
1394 } else if (encodingBlob->encodingFormat == CF_FORMAT_PEM) {
1395 x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
1396 }
1397 BIO_free(bio);
1398 return x509;
1399 }
1400
OpensslX509CertSpiCreate(const CfEncodingBlob * inStream,HcfX509CertificateSpi ** spi)1401 CfResult OpensslX509CertSpiCreate(const CfEncodingBlob *inStream, HcfX509CertificateSpi **spi)
1402 {
1403 if ((inStream == NULL) || (inStream->data == NULL) || (spi == NULL)) {
1404 LOGE("The input data blob is null!");
1405 return CF_INVALID_PARAMS;
1406 }
1407 HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)HcfMalloc(sizeof(HcfOpensslX509Cert), 0);
1408 if (realCert == NULL) {
1409 LOGE("Failed to malloc for x509 instance!");
1410 return CF_ERR_MALLOC;
1411 }
1412 realCert->x509 = CreateX509CertInner(inStream);
1413 if (realCert->x509 == NULL) {
1414 CfFree(realCert);
1415 LOGE("Failed to create x509 cert from input data!");
1416 return CF_INVALID_PARAMS;
1417 }
1418 realCert->base.base.getClass = GetX509CertClass;
1419 realCert->base.base.destroy = DestroyX509Openssl;
1420 realCert->base.engineVerify = VerifyX509Openssl;
1421 realCert->base.engineGetEncoded = GetEncodedX509Openssl;
1422 realCert->base.engineGetPublicKey = GetPublicKeyX509Openssl;
1423 realCert->base.engineCheckValidityWithDate = CheckValidityWithDateX509Openssl;
1424 realCert->base.engineGetVersion = GetVersionX509Openssl;
1425 realCert->base.engineGetSerialNumber = GetSerialNumberX509Openssl;
1426 realCert->base.engineGetIssuerName = GetIssuerDNX509Openssl;
1427 realCert->base.engineGetSubjectName = GetSubjectDNX509Openssl;
1428 realCert->base.engineGetNotBeforeTime = GetNotBeforeX509Openssl;
1429 realCert->base.engineGetNotAfterTime = GetNotAfterX509Openssl;
1430 realCert->base.engineGetSignature = GetSignatureX509Openssl;
1431 realCert->base.engineGetSignatureAlgName = GetSigAlgNameX509Openssl;
1432 realCert->base.engineGetSignatureAlgOid = GetSigAlgOidX509Openssl;
1433 realCert->base.engineGetSignatureAlgParams = GetSigAlgParamsX509Openssl;
1434 realCert->base.engineGetKeyUsage = GetKeyUsageX509Openssl;
1435 realCert->base.engineGetExtKeyUsage = GetExtendedKeyUsageX509Openssl;
1436 realCert->base.engineGetBasicConstraints = GetBasicConstraintsX509Openssl;
1437 realCert->base.engineGetSubjectAltNames = GetSubjectAltNamesX509Openssl;
1438 realCert->base.engineGetIssuerAltNames = GetIssuerAltNamesX509Openssl;
1439 realCert->base.engineGetCRLDistributionPointsURI = GetCRLDistributionPointsURIX509Openssl;
1440 realCert->base.engineMatch = MatchX509Openssl;
1441
1442 *spi = (HcfX509CertificateSpi *)realCert;
1443 return CF_SUCCESS;
1444 }
1445