• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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