1 /*
2 * Copyright (c) 2023-2024 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 "certificate_openssl_common.h"
17
18 #include <openssl/err.h>
19 #include <openssl/x509v3.h>
20 #include <securec.h>
21 #include <string.h>
22
23 #include "cf_log.h"
24 #include "cf_memory.h"
25 #include "cf_result.h"
26 #include "config.h"
27
28 #define TIME_MON_LEN 2
29 #define TIME_HOUR_LEN 8
30 #define TIME_MIN_LEN 10
31 #define TIME_SEC_LEN 12
32
33 typedef struct {
34 char *oid;
35 char *algorithmName;
36 } OidToAlgorithmName;
37
38 static const OidToAlgorithmName g_oidToNameMap[] = {
39 { "1.2.840.113549.1.1.2", "MD2withRSA" },
40 { "1.2.840.113549.1.1.4", "MD5withRSA" },
41 { "1.2.840.113549.1.1.5", "SHA1withRSA" },
42 { "1.2.840.10040.4.3", "SHA1withDSA" },
43 { "1.2.840.10045.4.1", "SHA1withECDSA" },
44 { "1.2.840.113549.1.1.14", "SHA224withRSA" },
45 { "1.2.840.113549.1.1.11", "SHA256withRSA" },
46 { "1.2.840.113549.1.1.12", "SHA384withRSA" },
47 { "1.2.840.113549.1.1.13", "SHA512withRSA" },
48 { "2.16.840.1.101.3.4.3.1", "SHA224withDSA" },
49 { "2.16.840.1.101.3.4.3.2", "SHA256withDSA" },
50 { "1.2.840.10045.4.3.1", "SHA224withECDSA" },
51 { "1.2.840.10045.4.3.2", "SHA256withECDSA" },
52 { "1.2.840.10045.4.3.3", "SHA384withECDSA" },
53 { "1.2.840.10045.4.3.4", "SHA512withECDSA" }
54 };
55
GetAlgorithmName(const char * oid)56 const char *GetAlgorithmName(const char *oid)
57 {
58 if (oid == NULL) {
59 LOGE("Oid is null!");
60 return NULL;
61 }
62
63 uint32_t oidCount = sizeof(g_oidToNameMap) / sizeof(OidToAlgorithmName);
64 for (uint32_t i = 0; i < oidCount; i++) {
65 if (strcmp(g_oidToNameMap[i].oid, oid) == 0) {
66 return g_oidToNameMap[i].algorithmName;
67 }
68 }
69 LOGE("Can not find algorithmName! [oid]: %{public}s", oid);
70 return NULL;
71 }
72
CfPrintOpensslError(void)73 void CfPrintOpensslError(void)
74 {
75 char szErr[LOG_PRINT_MAX_LEN] = { 0 };
76 unsigned long errCode;
77
78 errCode = ERR_get_error();
79 ERR_error_string_n(errCode, szErr, LOG_PRINT_MAX_LEN);
80
81 LOGE("[Openssl]: engine fail, error code = %{public}lu, error string = %{public}s", errCode, szErr);
82 }
83
DeepCopyDataToBlob(const unsigned char * data,uint32_t len,CfBlob * outBlob)84 CfResult DeepCopyDataToBlob(const unsigned char *data, uint32_t len, CfBlob *outBlob)
85 {
86 if (data == NULL || outBlob == NULL) {
87 CF_LOG_E("The input params invalid.");
88 return CF_INVALID_PARAMS;
89 }
90 uint8_t *tmp = (uint8_t *)CfMalloc(len, 0);
91 if (tmp == NULL) {
92 CF_LOG_E("Failed to malloc.");
93 return CF_ERR_MALLOC;
94 }
95 (void)memcpy_s(tmp, len, data, len);
96
97 outBlob->data = tmp;
98 outBlob->size = len;
99 return CF_SUCCESS;
100 }
101
DeepCopyBlobToBlob(const CfBlob * inBlob,CfBlob ** outBlob)102 CfResult DeepCopyBlobToBlob(const CfBlob *inBlob, CfBlob **outBlob)
103 {
104 if (inBlob == NULL || outBlob == NULL) {
105 LOGE("The input params invalid!");
106 return CF_INVALID_PARAMS;
107 }
108
109 CfBlob *tmp = (CfBlob *)CfMalloc(sizeof(CfBlob), 0);
110 if (tmp == NULL) {
111 LOGE("malloc failed");
112 return CF_ERR_MALLOC;
113 }
114 CfResult res = DeepCopyDataToBlob((const unsigned char *)inBlob->data, inBlob->size, tmp);
115 if (res != CF_SUCCESS) {
116 LOGE("DeepCopyDataToBlob failed");
117 CfFree(tmp);
118 tmp = NULL;
119 return res;
120 }
121 *outBlob = tmp;
122 return CF_SUCCESS;
123 }
124
CopyExtensionsToBlob(const X509_EXTENSIONS * exts,CfBlob * outBlob)125 CfResult CopyExtensionsToBlob(const X509_EXTENSIONS *exts, CfBlob *outBlob)
126 {
127 if (exts == NULL) { /* if not exist extension, return success */
128 LOGD("No extension!");
129 return CF_SUCCESS;
130 }
131
132 if (sk_X509_EXTENSION_num(exts) <= 0) {
133 LOGD("exts number is smaller than 0");
134 return CF_SUCCESS;
135 }
136
137 unsigned char *extbytes = NULL;
138 int32_t extLen = i2d_X509_EXTENSIONS(exts, &extbytes);
139 if (extLen <= 0) {
140 CF_LOG_E("get extLen failed!");
141 CfPrintOpensslError();
142 return CF_ERR_CRYPTO_OPERATION;
143 }
144
145 CfResult ret = DeepCopyDataToBlob(extbytes, (uint32_t)extLen, outBlob);
146 OPENSSL_free(extbytes);
147 return ret;
148 }
149
CompareDateWithCertTime(const X509 * x509,const ASN1_TIME * inputDate)150 CfResult CompareDateWithCertTime(const X509 *x509, const ASN1_TIME *inputDate)
151 {
152 ASN1_TIME *startDate = X509_get_notBefore(x509);
153 ASN1_TIME *expirationDate = X509_get_notAfter(x509);
154 if ((startDate == NULL) || (expirationDate == NULL)) {
155 LOGE("Date is null in x509 cert!");
156 CfPrintOpensslError();
157 return CF_ERR_CRYPTO_OPERATION;
158 }
159 CfResult res = CF_SUCCESS;
160 /* 0: equal in ASN1_TIME_compare, -1: a < b, 1: a > b, -2: error. */
161 if (ASN1_TIME_compare(inputDate, startDate) < 0) {
162 LOGE("Date is not validate in x509 cert!");
163 res = CF_ERR_CERT_NOT_YET_VALID;
164 } else if (ASN1_TIME_compare(expirationDate, inputDate) < 0) {
165 LOGE("Date is expired in x509 cert!");
166 res = CF_ERR_CERT_HAS_EXPIRED;
167 }
168 return res;
169 }
170
ConvertNameDerDataToString(const unsigned char * data,uint32_t derLen,CfBlob * out)171 CfResult ConvertNameDerDataToString(const unsigned char *data, uint32_t derLen, CfBlob *out)
172 {
173 if (data == NULL || derLen == 0 || out == NULL) {
174 LOGE("The input params invalid!");
175 return CF_INVALID_PARAMS;
176 }
177 X509_NAME *x509Name = d2i_X509_NAME(NULL, &data, derLen);
178 if (x509Name == NULL) {
179 LOGE("x509Name is null!");
180 CfPrintOpensslError();
181 return CF_ERR_CRYPTO_OPERATION;
182 }
183 char *name = X509_NAME_oneline(x509Name, NULL, 0);
184 if (name == NULL) {
185 LOGE("name is null!");
186 CfPrintOpensslError();
187 X509_NAME_free(x509Name);
188 return CF_ERR_CRYPTO_OPERATION;
189 }
190 if (strlen(name) > HCF_MAX_STR_LEN) {
191 LOGE("name is to long!");
192 CfPrintOpensslError();
193 OPENSSL_free(name);
194 X509_NAME_free(x509Name);
195 return CF_ERR_CRYPTO_OPERATION;
196 }
197 CfResult res = DeepCopyDataToBlob((const unsigned char *)name, strlen(name) + 1, out);
198 OPENSSL_free(name);
199 X509_NAME_free(x509Name);
200 return res;
201 }
202
CompareNameObject(const X509 * cert,const CfBlob * derBlob,X509NameType type,bool * compareRes)203 CfResult CompareNameObject(const X509 *cert, const CfBlob *derBlob, X509NameType type, bool *compareRes)
204 {
205 X509_NAME *name = NULL;
206 if (type == NAME_TYPE_SUBJECT) {
207 name = X509_get_subject_name(cert);
208 } else if (type == NAME_TYPE_ISSUER) {
209 name = X509_get_issuer_name(cert);
210 }
211 if (name == NULL) {
212 LOGE("x509Cert get name failed!");
213 CfPrintOpensslError();
214 return CF_ERR_CRYPTO_OPERATION;
215 }
216 char *nameStr = X509_NAME_oneline(name, NULL, 0);
217 if (nameStr == NULL) {
218 LOGE("x509Cert name oneline failed!");
219 CfPrintOpensslError();
220 return CF_ERR_CRYPTO_OPERATION;
221 }
222
223 CfBlob nameBlob = { 0 };
224 CfResult res = ConvertNameDerDataToString(derBlob->data, derBlob->size, &nameBlob);
225 if (res != CF_SUCCESS) {
226 LOGE("x509Cert ConvertNameDerDataToString failed!");
227 OPENSSL_free(nameStr);
228 return res;
229 }
230 uint32_t len = strlen(nameStr) + 1;
231 if (len != nameBlob.size || strncmp((const char *)nameStr, (const char *)nameBlob.data, nameBlob.size) != 0) {
232 LOGE("name do not match!");
233 *compareRes = false;
234 } else {
235 *compareRes = true;
236 }
237 CfBlobDataFree(&nameBlob);
238 OPENSSL_free(nameStr);
239 return CF_SUCCESS;
240 }
241
CompareBigNum(const CfBlob * lhs,const CfBlob * rhs,int * out)242 CfResult CompareBigNum(const CfBlob *lhs, const CfBlob *rhs, int *out)
243 {
244 if ((lhs->data == NULL) || (lhs->size == 0) || (rhs->data == NULL) || (rhs->size == 0)) {
245 LOGE("Invalid params!");
246 return CF_INVALID_PARAMS;
247 }
248
249 BIGNUM *lhsBigNum = BN_bin2bn(lhs->data, lhs->size, NULL);
250 if (lhsBigNum == NULL) {
251 LOGE("bin to big number fail!");
252 CfPrintOpensslError();
253 return CF_INVALID_PARAMS;
254 }
255 BIGNUM *rhsBigNum = BN_bin2bn(rhs->data, rhs->size, NULL);
256 if (rhsBigNum == NULL) {
257 LOGE("bin to big number fail!");
258 CfPrintOpensslError();
259 BN_free(lhsBigNum);
260 return CF_INVALID_PARAMS;
261 }
262 *out = BN_cmp(lhsBigNum, rhsBigNum);
263 BN_free(lhsBigNum);
264 BN_free(rhsBigNum);
265 return CF_SUCCESS;
266 }
267
GetX509EncodedDataStream(const X509 * certificate,int * dataLength)268 uint8_t *GetX509EncodedDataStream(const X509 *certificate, int *dataLength)
269 {
270 if (certificate == NULL) {
271 LOGE("The input params null.");
272 return NULL;
273 }
274
275 unsigned char *der = NULL;
276 int32_t length = i2d_X509(certificate, &der);
277 if (length <= 0) {
278 LOGE("Failed to convert internal x509 to der format!");
279 CfPrintOpensslError();
280 return NULL;
281 }
282 uint8_t *data = (uint8_t *)CfMalloc(length, 0);
283 if (data == NULL) {
284 LOGE("Failed to malloc for x509 der data!");
285 OPENSSL_free(der);
286 return NULL;
287 }
288 (void)memcpy_s(data, length, der, length);
289 OPENSSL_free(der);
290 *dataLength = length;
291
292 return data;
293 }
294
Asn1TimeToStr(const ASN1_GENERALIZEDTIME * time)295 char *Asn1TimeToStr(const ASN1_GENERALIZEDTIME *time)
296 {
297 char buffer[24];
298 if (time == NULL || time->data == NULL) {
299 return NULL;
300 }
301
302 if (snprintf_s(buffer, sizeof(buffer), sizeof(buffer) - 1, "%.6s-", time->data + TIME_MON_LEN) < 0 ||
303 snprintf_s(buffer + strlen(buffer), sizeof(buffer) - strlen(buffer), sizeof(buffer) - strlen(buffer) - 1,
304 "%.2s:", time->data + TIME_HOUR_LEN) < 0 ||
305 snprintf_s(buffer + strlen(buffer), sizeof(buffer) - strlen(buffer), sizeof(buffer) - strlen(buffer) - 1,
306 "%.2s:", time->data + TIME_MIN_LEN) < 0 ||
307 snprintf_s(buffer + strlen(buffer), sizeof(buffer) - strlen(buffer), sizeof(buffer) - strlen(buffer) - 1,
308 "%.2sZ", time->data + TIME_SEC_LEN) < 0) {
309 return NULL;
310 }
311
312 char *result = strdup(buffer);
313 if (result == NULL) {
314 return NULL;
315 }
316
317 return result;
318 }
319
CfArrayContains(const CfArray * self,const CfArray * sub)320 bool CfArrayContains(const CfArray *self, const CfArray *sub)
321 {
322 for (uint32_t i = 0; i < self->count; ++i) {
323 bool found = false;
324 for (uint32_t j = 0; j < sub->count; ++j) {
325 if (self->data[i].size == sub->data[j].size &&
326 memcmp(self->data[i].data, sub->data[j].data, self->data[i].size) == 0) {
327 found = true;
328 break;
329 }
330 }
331 if (!found) {
332 return false;
333 }
334 }
335 return true;
336 }
337
DeepCopyDataToOut(const char * data,uint32_t len,CfBlob * out)338 CfResult DeepCopyDataToOut(const char *data, uint32_t len, CfBlob *out)
339 {
340 out->data = (uint8_t *)CfMalloc(len, 0);
341 if (out->data == NULL) {
342 LOGE("Failed to malloc for sig algorithm params!");
343 return CF_ERR_MALLOC;
344 }
345 if (memcpy_s(out->data, len, data, len) != EOK) {
346 CF_LOG_E("Failed to memcpy_s");
347 CfFree(out->data);
348 out->data = NULL;
349 return CF_ERR_COPY;
350 }
351 out->size = len;
352 return CF_SUCCESS;
353 }
354
CheckIsSelfSigned(const X509 * cert)355 bool CheckIsSelfSigned(const X509 *cert)
356 {
357 if (cert == NULL) {
358 return false;
359 }
360 bool ret = false;
361 X509_NAME *issuer = X509_get_issuer_name(cert);
362 if (issuer == NULL) {
363 LOGE("x509 get issuer name failed!");
364 CfPrintOpensslError();
365 return ret;
366 }
367
368 X509_NAME *subject = X509_get_subject_name(cert);
369 if (subject == NULL) {
370 LOGE("x509 get subject name failed!");
371 CfPrintOpensslError();
372 return ret;
373 }
374
375 ret = (X509_NAME_cmp(issuer, subject) == 0);
376 return ret;
377 }
378
CheckIsLeafCert(X509 * cert)379 bool CheckIsLeafCert(X509 *cert)
380 {
381 if (cert == NULL) {
382 return false;
383 }
384
385 if (X509_check_ca(cert)) {
386 return false;
387 }
388
389 return true;
390 }
391
IsOrderCertChain(STACK_OF (X509)* certsChain,bool * isOrder)392 CfResult IsOrderCertChain(STACK_OF(X509) *certsChain, bool *isOrder)
393 {
394 int num = sk_X509_num(certsChain);
395 if (num == 1) {
396 LOGI("1 certs is order chain.");
397 return CF_SUCCESS;
398 }
399
400 X509 *cert = NULL;
401 X509 *certNext = NULL;
402 X509_NAME *issuerName = NULL;
403 X509_NAME *subjectName = NULL;
404 for (int i = num - 1; i > 0; --i) {
405 cert = sk_X509_value(certsChain, i);
406 if (cert == NULL) {
407 LOGE("sk X509 value is null, failed!");
408 CfPrintOpensslError();
409 return CF_ERR_CRYPTO_OPERATION;
410 }
411 certNext = sk_X509_value(certsChain, i - 1);
412 if (certNext == NULL) {
413 LOGE("sk X509 value is null, failed!");
414 CfPrintOpensslError();
415 return CF_ERR_CRYPTO_OPERATION;
416 }
417
418 subjectName = X509_get_subject_name(cert);
419 if (subjectName == NULL) {
420 LOGE("x509 get subject name failed!");
421 CfPrintOpensslError();
422 return CF_ERR_CRYPTO_OPERATION;
423 }
424 issuerName = X509_get_issuer_name(certNext);
425 if (issuerName == NULL) {
426 LOGE("x509 get subject name failed!");
427 CfPrintOpensslError();
428 return CF_ERR_CRYPTO_OPERATION;
429 }
430
431 if (X509_NAME_cmp(subjectName, issuerName) != 0) {
432 *isOrder = false;
433 LOGI("is a misOrder chain.");
434 break;
435 }
436 }
437
438 return CF_SUCCESS;
439 }
440
CheckSelfPubkey(X509 * cert,const EVP_PKEY * pubKey)441 CfResult CheckSelfPubkey(X509 *cert, const EVP_PKEY *pubKey)
442 {
443 EVP_PKEY *certPublicKey = X509_get_pubkey(cert);
444 if (certPublicKey == NULL) {
445 LOGE("get cert public key failed!");
446 CfPrintOpensslError();
447 return CF_ERR_CRYPTO_OPERATION;
448 }
449
450 int isMatch = EVP_PKEY_cmp(certPublicKey, pubKey);
451 if (isMatch != CF_OPENSSL_SUCCESS) {
452 LOGE("cmp cert public key failed!");
453 CfPrintOpensslError();
454 EVP_PKEY_free(certPublicKey);
455 return CF_ERR_CRYPTO_OPERATION;
456 }
457
458 EVP_PKEY_free(certPublicKey);
459 return CF_SUCCESS;
460 }
461
FindCertificateBySubject(STACK_OF (X509)* certs,X509_NAME * subjectName)462 X509 *FindCertificateBySubject(STACK_OF(X509) *certs, X509_NAME *subjectName)
463 {
464 X509_STORE_CTX *ctx = NULL;
465 X509 *cert = NULL;
466 X509_OBJECT *obj = NULL;
467
468 X509_STORE *store = X509_STORE_new();
469 if (store == NULL) {
470 return NULL;
471 }
472 for (int i = 0; i < sk_X509_num(certs); i++) {
473 cert = sk_X509_value(certs, i);
474 if (X509_STORE_add_cert(store, cert) != 1) {
475 X509_STORE_free(store);
476 return NULL;
477 }
478 }
479
480 if (!(ctx = X509_STORE_CTX_new())) {
481 X509_STORE_free(store);
482 return NULL;
483 }
484 if (X509_STORE_CTX_init(ctx, store, NULL, NULL) != 1) {
485 X509_STORE_free(store);
486 X509_STORE_CTX_free(ctx);
487 return NULL;
488 }
489 obj = X509_STORE_CTX_get_obj_by_subject(ctx, X509_LU_X509, subjectName);
490 if (obj == NULL) {
491 X509_STORE_free(store);
492 X509_STORE_CTX_free(ctx);
493 return NULL;
494 }
495 cert = X509_OBJECT_get0_X509(obj);
496 X509_STORE_free(store);
497 X509_OBJECT_free(obj);
498 X509_STORE_CTX_free(ctx);
499
500 return cert;
501 }
502
SubAltNameArrayDataClearAndFree(SubAltNameArray * array)503 void SubAltNameArrayDataClearAndFree(SubAltNameArray *array)
504 {
505 if (array == NULL) {
506 LOGD("The input array is null, no need to free.");
507 return;
508 }
509 if (array->data != NULL) {
510 for (uint32_t i = 0; i < array->count; ++i) {
511 CF_FREE_BLOB(array->data[i].name);
512 }
513 CfFree(array->data);
514 array->data = NULL;
515 array->count = 0;
516 }
517 }
518
GetPubKeyDataFromX509(X509 * x509,CfBlob ** pub)519 CfResult GetPubKeyDataFromX509(X509 *x509, CfBlob **pub)
520 {
521 EVP_PKEY *pkey = X509_get0_pubkey(x509);
522 if (pkey == NULL) {
523 return CF_ERR_CRYPTO_OPERATION;
524 }
525
526 *pub = (CfBlob *)CfMalloc(sizeof(CfBlob), 0);
527 if (*pub == NULL) {
528 LOGE("Failed to malloc pub key!");
529 return CF_ERR_MALLOC;
530 }
531
532 int32_t size = i2d_PUBKEY(pkey, &((*pub)->data));
533 if (size <= 0) {
534 LOGE("Failed to convert public key to DER format");
535 CfFree(*pub);
536 *pub = NULL;
537 return CF_INVALID_PARAMS;
538 }
539 (*pub)->size = (uint32_t)size;
540 return CF_SUCCESS;
541 }
542
GetSubjectNameFromX509(X509 * cert,CfBlob ** sub)543 CfResult GetSubjectNameFromX509(X509 *cert, CfBlob **sub)
544 {
545 if (cert == NULL) {
546 LOGE("No certificate found in when get subject name");
547 return CF_INVALID_PARAMS;
548 }
549 X509_NAME *name = X509_get_subject_name(cert);
550 if (!name) {
551 LOGE("Failed to get subject name!");
552 return CF_INVALID_PARAMS;
553 }
554 *sub = (CfBlob *)CfMalloc(sizeof(CfBlob), 0);
555 if (*sub == NULL) {
556 LOGE("Failed to malloc pub key!");
557 return CF_ERR_MALLOC;
558 }
559
560 int32_t size = i2d_X509_NAME(name, &((*sub)->data));
561 if (size <= 0) {
562 LOGE("Failed to get subject DER data!");
563 CfFree(*sub);
564 *sub = NULL;
565 return CF_ERR_CRYPTO_OPERATION;
566 }
567 (*sub)->size = (uint32_t)size;
568 return CF_SUCCESS;
569 }
570
GetNameConstraintsFromX509(X509 * cert,CfBlob ** name)571 CfResult GetNameConstraintsFromX509(X509 *cert, CfBlob **name)
572 {
573 if (cert == NULL) {
574 LOGE("No certificate found in when get name constraints");
575 return CF_INVALID_PARAMS;
576 }
577 ASN1_BIT_STRING *nc = X509_get_ext_d2i(cert, NID_name_constraints, NULL, NULL);
578 if (!nc) {
579 LOGE("No nameConstraints found in certificate");
580 return CF_INVALID_PARAMS;
581 }
582 *name = (CfBlob *)CfMalloc(sizeof(CfBlob), 0);
583 if (*name == NULL) {
584 LOGE("Failed to malloc pub key!");
585 return CF_ERR_MALLOC;
586 }
587 int32_t size = i2d_ASN1_BIT_STRING(nc, &((*name)->data));
588 ASN1_BIT_STRING_free(nc);
589 if (size < 0) {
590 LOGE("Failed to get name DER data!");
591 CfFree(*name);
592 *name = NULL;
593 return CF_ERR_CRYPTO_OPERATION;
594 }
595 (*name)->size = (uint32_t)size;
596 return CF_SUCCESS;
597 }
598
CopyMemFromBIO(BIO * bio,CfBlob * outBlob)599 CfResult CopyMemFromBIO(BIO *bio, CfBlob *outBlob)
600 {
601 if (bio == NULL || outBlob == NULL) {
602 LOGE("Invalid input.");
603 return CF_ERR_INTERNAL;
604 }
605 int len = BIO_pending(bio);
606 if (len <= 0) {
607 LOGE("Bio len less than or equal to 0.");
608 return CF_ERR_INTERNAL;
609 }
610 uint8_t *buff = (uint8_t *)CfMalloc(len, 0);
611 if (buff == NULL) {
612 LOGE("Malloc mem for buff fail.");
613 return CF_ERR_MALLOC;
614 }
615 if (BIO_read(bio, buff, len) <= 0) {
616 LOGE("Bio read fail.");
617 CfPrintOpensslError();
618 CfFree(buff);
619 buff = NULL;
620 return CF_ERR_CRYPTO_OPERATION;
621 }
622 outBlob->size = (uint32_t)len;
623 outBlob->data = buff;
624 return CF_SUCCESS;
625 }
626
CfDeepCopyExtendedKeyUsage(const STACK_OF (ASN1_OBJECT)* extUsage,int32_t index,CfArray * keyUsageOut)627 CfResult CfDeepCopyExtendedKeyUsage(const STACK_OF(ASN1_OBJECT) *extUsage,
628 int32_t index, CfArray *keyUsageOut)
629 {
630 if (extUsage == NULL || keyUsageOut == NULL) {
631 LOGE("Invalid input.");
632 return CF_ERR_INTERNAL;
633 }
634 char usage[OID_STR_MAX_LEN] = { 0 };
635 int32_t resLen = OBJ_obj2txt(usage, OID_STR_MAX_LEN, sk_ASN1_OBJECT_value(extUsage, index), 1);
636 if ((resLen <= 0) || (resLen >= OID_STR_MAX_LEN)) {
637 LOGE("Failed to convert x509 object to text!");
638 CfPrintOpensslError();
639 return CF_ERR_CRYPTO_OPERATION;
640 }
641 uint32_t len = strlen(usage) + 1;
642 keyUsageOut->data[index].data = (uint8_t *)CfMalloc(len, 0);
643 if (keyUsageOut->data[index].data == NULL) {
644 LOGE("Failed to malloc for key usage!");
645 return CF_ERR_MALLOC;
646 }
647 (void)memcpy_s(keyUsageOut->data[index].data, len, usage, len);
648 keyUsageOut->data[index].size = len;
649 return CF_SUCCESS;
650 }
651
CfDeepCopyAlternativeNames(const STACK_OF (GENERAL_NAME)* altNames,int32_t index,CfArray * outName)652 CfResult CfDeepCopyAlternativeNames(const STACK_OF(GENERAL_NAME) *altNames, int32_t index, CfArray *outName)
653 {
654 if (altNames == NULL || outName == NULL) {
655 LOGE("Invalid input.");
656 return CF_ERR_INTERNAL;
657 }
658 GENERAL_NAME *general = sk_GENERAL_NAME_value(altNames, index);
659 int32_t generalType = 0;
660 ASN1_STRING *ans1Str = GENERAL_NAME_get0_value(general, &generalType);
661 const char *str = (const char *)ASN1_STRING_get0_data(ans1Str);
662 if ((str == NULL) || (strlen(str) > HCF_MAX_STR_LEN)) {
663 LOGE("Failed to get x509 altNames string in openssl!");
664 CfPrintOpensslError();
665 return CF_ERR_CRYPTO_OPERATION;
666 }
667 uint32_t nameLen = strlen(str) + 1;
668 outName->data[index].data = (uint8_t *)CfMalloc(nameLen, 0);
669 if (outName->data[index].data == NULL) {
670 LOGE("Failed to malloc for outName!");
671 return CF_ERR_MALLOC;
672 }
673 (void)memcpy_s(outName->data[index].data, nameLen, str, nameLen);
674 outName->data[index].size = nameLen;
675 return CF_SUCCESS;
676 }
677
CfDeepCopySubAltName(const STACK_OF (GENERAL_NAME)* altname,int32_t index,const SubAltNameArray * subAltNameArrayOut)678 CfResult CfDeepCopySubAltName(
679 const STACK_OF(GENERAL_NAME) * altname, int32_t index, const SubAltNameArray *subAltNameArrayOut)
680 {
681 if (altname == NULL || subAltNameArrayOut == NULL) {
682 LOGE("Invalid input.");
683 return CF_ERR_INTERNAL;
684 }
685 GENERAL_NAME *generalName = sk_GENERAL_NAME_value(altname, index);
686 if (generalName == NULL) {
687 LOGE("Failed to get general name from altname!");
688 CfPrintOpensslError();
689 return CF_ERR_CRYPTO_OPERATION;
690 }
691 unsigned char *derData = NULL;
692 int derLength = i2d_GENERAL_NAME(generalName, &derData);
693 if (derLength <= 0 || derData == NULL) {
694 LOGE("Get generalName failed!");
695 return CF_ERR_CRYPTO_OPERATION;
696 }
697
698 SubjectAlternaiveNameData *subAltNameData = &(subAltNameArrayOut->data[index]);
699 subAltNameData->name.data = CfMalloc(derLength, 0);
700 if (subAltNameData->name.data == NULL) {
701 LOGE("Failed to malloc for sub alt name data!");
702 OPENSSL_free(derData);
703 return CF_ERR_MALLOC;
704 }
705 (void)memcpy_s(subAltNameData->name.data, derLength, derData, derLength);
706 subAltNameData->name.size = (uint32_t)derLength;
707 subAltNameData->type = generalName->type;
708 OPENSSL_free(derData);
709 return CF_SUCCESS;
710 }
711
CfDeepCopyCertPolices(const CERTIFICATEPOLICIES * certPolicesIn,int32_t index,CfArray * certPolices)712 CfResult CfDeepCopyCertPolices(const CERTIFICATEPOLICIES *certPolicesIn, int32_t index, CfArray *certPolices)
713 {
714 if (certPolicesIn == NULL || certPolices == NULL) {
715 LOGE("Invalid input.");
716 return CF_ERR_INTERNAL;
717 }
718 POLICYINFO *policy = sk_POLICYINFO_value(certPolicesIn, index);
719 if (policy == NULL) {
720 LOGE("Failed to get policy info from cert policies!");
721 CfPrintOpensslError();
722 return CF_ERR_CRYPTO_OPERATION;
723 }
724 ASN1_OBJECT *policyOid = policy->policyid;
725 char policyBuff[OID_STR_MAX_LEN] = { 0 };
726 int32_t resLen = OBJ_obj2txt(policyBuff, OID_STR_MAX_LEN, policyOid, 1);
727 if ((resLen <= 0) || (resLen >= OID_STR_MAX_LEN)) {
728 LOGE("Failed to convert x509 object to text!");
729 CfPrintOpensslError();
730 return CF_ERR_CRYPTO_OPERATION;
731 }
732 uint32_t len = strlen(policyBuff) + 1;
733 certPolices->data[index].data = (uint8_t *)CfMalloc(len, 0);
734 if (certPolices->data[index].data == NULL) {
735 LOGE("Failed to malloc for cert policies!");
736 return CF_ERR_MALLOC;
737 }
738 (void)memcpy_s(certPolices->data[index].data, len, policyBuff, len);
739 certPolices->data[index].size = len;
740 return CF_SUCCESS;
741 }
742
DeepCopyURIs(ASN1_STRING * uri,uint32_t index,CfArray * outURI)743 static CfResult DeepCopyURIs(ASN1_STRING *uri, uint32_t index, CfArray *outURI)
744 {
745 if (index >= outURI->count) { /* exceed the maximum memory capacity. */
746 LOGE("exceed the maximum memory capacity, uriCount = %{public}u, malloc count = %{public}u",
747 index, outURI->count);
748 return CF_ERR_CRYPTO_OPERATION;
749 }
750
751 const char *str = (const char *)ASN1_STRING_get0_data(uri);
752 if ((str == NULL) || (strlen(str) > HCF_MAX_STR_LEN)) {
753 LOGE("Failed to get CRL DP URI string in openssl!");
754 return CF_ERR_CRYPTO_OPERATION;
755 }
756
757 uint32_t uriLen = strlen(str) + 1;
758 outURI->data[index].data = (uint8_t *)CfMalloc(uriLen, 0);
759 if (outURI->data[index].data == NULL) {
760 LOGE("Failed to malloc for outURI[%{public}u]!", index);
761 return CF_ERR_MALLOC;
762 }
763 (void)memcpy_s(outURI->data[index].data, uriLen, str, uriLen);
764 outURI->data[index].size = uriLen;
765 return CF_SUCCESS;
766 }
767
CfConvertAsn1String2BoolArray(const ASN1_BIT_STRING * string,CfBlob * boolArr)768 CfResult CfConvertAsn1String2BoolArray(const ASN1_BIT_STRING *string, CfBlob *boolArr)
769 {
770 if (string == NULL || boolArr == NULL) {
771 LOGE("Invalid input.");
772 return CF_ERR_INTERNAL;
773 }
774 uint32_t length = (uint32_t)ASN1_STRING_length(string) * CHAR_TO_BIT_LEN;
775 if ((uint32_t)(string->flags) & ASN1_STRING_FLAG_BITS_LEFT) {
776 length -= (uint32_t)(string->flags) & FLAG_BIT_LEFT_NUM;
777 }
778 boolArr->data = (uint8_t *)CfMalloc(length, 0);
779 if (boolArr->data == NULL) {
780 LOGE("Failed to malloc for bit array data!");
781 return CF_ERR_MALLOC;
782 }
783 for (uint32_t i = 0; i < length; i++) {
784 boolArr->data[i] = ASN1_BIT_STRING_get_bit(string, i);
785 }
786 boolArr->size = length;
787 return CF_SUCCESS;
788 }
789
GetGeneralNameData(const GENERAL_NAME * gen,unsigned char ** bytes,unsigned char ** point)790 static int32_t GetGeneralNameData(const GENERAL_NAME *gen, unsigned char **bytes, unsigned char **point)
791 {
792 int32_t len = 0;
793 switch (gen->type) {
794 case GEN_X400:
795 len = sizeof(uint8_t) * (gen->d.x400Address->length);
796 *bytes = (unsigned char *)gen->d.x400Address->data;
797 break;
798 case GEN_EDIPARTY:
799 len = i2d_EDIPARTYNAME(gen->d.ediPartyName, bytes);
800 *point = *bytes;
801 break;
802 case GEN_OTHERNAME:
803 len = i2d_OTHERNAME(gen->d.otherName, bytes);
804 *point = *bytes;
805 break;
806 case GEN_EMAIL:
807 case GEN_DNS:
808 case GEN_URI:
809 len = i2d_ASN1_IA5STRING(gen->d.ia5, bytes);
810 *point = *bytes;
811 break;
812 case GEN_DIRNAME:
813 len = i2d_X509_NAME(gen->d.dirn, bytes);
814 *point = *bytes;
815 break;
816 case GEN_IPADD:
817 len = i2d_ASN1_OCTET_STRING(gen->d.ip, bytes);
818 *point = *bytes;
819 break;
820 case GEN_RID:
821 len = i2d_ASN1_OBJECT(gen->d.rid, bytes);
822 *point = *bytes;
823 break;
824 default:
825 LOGE("Unknown type.");
826 break;
827 }
828 return len;
829 }
830
CfCompareGN2Blob(const GENERAL_NAME * gen,CfBlob * nc)831 bool CfCompareGN2Blob(const GENERAL_NAME *gen, CfBlob *nc)
832 {
833 if (gen == NULL || nc == NULL) {
834 LOGE("Invalid input.");
835 return CF_ERR_INTERNAL;
836 }
837 unsigned char *bytes = NULL;
838 unsigned char *point = NULL;
839 int32_t len = GetGeneralNameData(gen, &bytes, &point);
840 bool ret = false;
841 if (bytes != NULL && len > 0) {
842 ret = (len == (int32_t)(nc->size)) && (strncmp((const char *)bytes, (const char *)nc->data, len) == 0);
843 }
844 if (point != NULL) {
845 OPENSSL_free(point);
846 }
847
848 return ret;
849 }
850
GetDpURIFromGenName(GENERAL_NAME * genName,bool isFormatOutURI,uint32_t * uriCount,CfArray * outURI)851 static CfResult GetDpURIFromGenName(GENERAL_NAME *genName, bool isFormatOutURI, uint32_t *uriCount, CfArray *outURI)
852 {
853 int type = 0;
854 ASN1_STRING *uri = GENERAL_NAME_get0_value(genName, &type);
855 if (uri == NULL) {
856 LOGE("get uri asn1 string failed");
857 return CF_ERR_CRYPTO_OPERATION;
858 }
859
860 if (type != GEN_URI) {
861 LOGI("not URI type, type is %{public}d", type);
862 return CF_SUCCESS;
863 }
864
865 if (isFormatOutURI) {
866 CfResult ret = DeepCopyURIs(uri, *uriCount, outURI);
867 if (ret != CF_SUCCESS) {
868 LOGE("copy URI[%{public}u] failed", *uriCount);
869 return ret;
870 }
871 }
872 *uriCount += 1;
873 return CF_SUCCESS;
874 }
875
GetDpURIFromGenNames(GENERAL_NAMES * genNames,bool isFormatOutURI,uint32_t * uriCount,CfArray * outURI)876 static CfResult GetDpURIFromGenNames(GENERAL_NAMES *genNames, bool isFormatOutURI, uint32_t *uriCount,
877 CfArray *outURI)
878 {
879 CfResult ret = CF_SUCCESS;
880 int genNameNum = sk_GENERAL_NAME_num(genNames);
881 for (int i = 0; i < genNameNum; ++i) {
882 GENERAL_NAME *genName = sk_GENERAL_NAME_value(genNames, i);
883 if (genName == NULL) {
884 LOGE("get gen name failed!");
885 ret = CF_ERR_CRYPTO_OPERATION;
886 break;
887 }
888
889 ret = GetDpURIFromGenName(genName, isFormatOutURI, uriCount, outURI);
890 if (ret != CF_SUCCESS) {
891 LOGE("get gen name failed!");
892 break;
893 }
894 }
895 return ret;
896 }
897
GetDpURI(STACK_OF (DIST_POINT)* crlDp,int32_t dpNumber,bool isFormatOutURI,uint32_t * uriCount,CfArray * outURI)898 static CfResult GetDpURI(STACK_OF(DIST_POINT) *crlDp, int32_t dpNumber, bool isFormatOutURI,
899 uint32_t *uriCount, CfArray *outURI)
900 {
901 CfResult ret = CF_SUCCESS;
902 for (int i = 0; i < dpNumber; ++i) {
903 DIST_POINT *dp = sk_DIST_POINT_value(crlDp, i);
904 if (dp == NULL) {
905 LOGE("get distribution point failed!");
906 ret = CF_ERR_CRYPTO_OPERATION;
907 break;
908 }
909
910 if (dp->distpoint == NULL || dp->distpoint->type != 0) {
911 LOGI("not fullnames, continue!");
912 continue;
913 }
914
915 ret = GetDpURIFromGenNames(dp->distpoint->name.fullname, isFormatOutURI, uriCount, outURI);
916 if (ret != CF_SUCCESS) {
917 LOGE("get dp uri from general names failed");
918 break;
919 }
920 }
921 if (ret == CF_SUCCESS && isFormatOutURI) {
922 outURI->count = *uriCount;
923 }
924 return ret;
925 }
926
CfGetCRLDpURI(STACK_OF (DIST_POINT)* crlDp,CfArray * outURI)927 CfResult CfGetCRLDpURI(STACK_OF(DIST_POINT) *crlDp, CfArray *outURI)
928 {
929 if (crlDp == NULL || outURI == NULL) {
930 LOGE("Invalid input.");
931 return CF_ERR_INTERNAL;
932 }
933 /* 1. get CRL distribution point URI count */
934 int32_t dpNumber = sk_DIST_POINT_num(crlDp);
935 uint32_t uriCount = 0;
936 CfResult ret = GetDpURI(crlDp, dpNumber, false, &uriCount, outURI);
937 if (ret != CF_SUCCESS) {
938 LOGE("get dp URI count failed, ret = %{public}d", ret);
939 return ret;
940 }
941 if (uriCount == 0) {
942 LOGE("CRL DP URI not exist");
943 return CF_NOT_EXIST;
944 }
945 if (uriCount > CF_MAX_URI_COUNT) {
946 LOGE("uriCount[%{public}u] exceed max count", uriCount);
947 return CF_ERR_CRYPTO_OPERATION;
948 }
949
950 /* 2. malloc outArray buffer */
951 int32_t blobSize = (int32_t)(sizeof(CfBlob) * uriCount);
952 outURI->data = (CfBlob *)CfMalloc(blobSize, 0);
953 if (outURI->data == NULL) {
954 LOGE("Failed to malloc for outURI array!");
955 return CF_ERR_MALLOC;
956 }
957 outURI->count = uriCount;
958
959 /* 2. copy CRL distribution point URIs */
960 uriCount = 0;
961 ret = GetDpURI(crlDp, dpNumber, true, &uriCount, outURI);
962 if (ret != CF_SUCCESS) {
963 LOGE("get dp URI format failed, ret = %{public}d", ret);
964 CfArrayDataClearAndFree(outURI);
965 return ret;
966 }
967
968 return ret;
969 }
970