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 "x509_cert_chain_openssl.h"
17 #include "x509_cert_chain_openssl_ex.h"
18
19 #include <openssl/crypto.h>
20 #include <openssl/err.h>
21 #include <openssl/evp.h>
22 #include <openssl/obj_mac.h>
23 #include <openssl/ocsp.h>
24 #include <openssl/ossl_typ.h>
25 #include <openssl/pem.h>
26 #include <openssl/pkcs12.h>
27 #include <openssl/ssl.h>
28 #include <openssl/x509.h>
29 #include <openssl/x509_vfy.h>
30 #include <openssl/x509v3.h>
31 #include <securec.h>
32
33 #include "cert_crl_common.h"
34 #include "certificate_openssl_class.h"
35 #include "certificate_openssl_common.h"
36 #include "cf_blob.h"
37 #include "cf_log.h"
38 #include "cf_memory.h"
39 #include "cf_result.h"
40 #include "config.h"
41 #include "fwk_class.h"
42 #include "utils.h"
43 #include "x509_cert_chain_spi.h"
44
45 #define MAX_CERT_NUM 256 /* max certs number of a certchain */
46 #define TIMET_NUM 6
47 #define TIMET_YEAR_START 1900
48 #define TIMET_YEAR_OFFSET 100 // start time year from 1900 + 100
49 #define HTTP_TIMEOUT 10
50 #define TRY_CONNECT_TIMES 3
51 #define OCSP_CONN_MILLISECOND 5000 // millisecond
52 #define OCSP_CONN_TIMEOUT (-1) // timeout == 0 means no timeout, < 0 means exactly one try.
53 #define HTTP_PORT "80"
54 #define HTTPS_PORT "443"
55
56 // helper functions
57 typedef struct {
58 int32_t errCode;
59 CfResult result;
60 } OpensslErrorToResult;
61
62 typedef struct {
63 const EVP_MD *md;
64 X509 *subjectCert;
65 X509 *issuerCert;
66 } OcspCertIdInfo;
67
68 typedef struct {
69 OCSP_REQUEST *req;
70 OCSP_RESPONSE *resp;
71 OcspCertIdInfo *certIdInfo;
72 } OcspLocalParam;
73
74 typedef struct {
75 X509 *leafCert;
76 HcfRevocationCheckParam *revo;
77 char **host;
78 char **port;
79 char **path;
80 int *ssl;
81 } GetOcspUrlParams;
82
83 static const OpensslErrorToResult ERROR_TO_RESULT_MAP[] = {
84 { X509_V_OK, CF_SUCCESS },
85 { X509_V_ERR_CERT_SIGNATURE_FAILURE, CF_ERR_CERT_SIGNATURE_FAILURE },
86 { X509_V_ERR_CERT_NOT_YET_VALID, CF_ERR_CERT_NOT_YET_VALID },
87 { X509_V_ERR_CERT_HAS_EXPIRED, CF_ERR_CERT_HAS_EXPIRED },
88 { X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, CF_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY },
89 { X509_V_ERR_KEYUSAGE_NO_CERTSIGN, CF_ERR_KEYUSAGE_NO_CERTSIGN },
90 { X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE, CF_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE },
91 };
92
ConvertOpensslErrorMsg(int32_t errCode)93 static CfResult ConvertOpensslErrorMsg(int32_t errCode)
94 {
95 for (uint32_t i = 0; i < sizeof(ERROR_TO_RESULT_MAP) / sizeof(OpensslErrorToResult); ++i) {
96 if (ERROR_TO_RESULT_MAP[i].errCode == errCode) {
97 return ERROR_TO_RESULT_MAP[i].result;
98 }
99 }
100 return CF_ERR_CRYPTO_OPERATION;
101 }
102
DestroyX509CertChain(CfObjectBase * self)103 static void DestroyX509CertChain(CfObjectBase *self)
104 {
105 if (self == NULL || !CfIsClassMatch(self, GetX509CertChainClass())) {
106 LOGE("Invalid params!");
107 return;
108 }
109 HcfX509CertChainOpensslImpl *impl = (HcfX509CertChainOpensslImpl *)self;
110 if (impl->x509CertChain != NULL) {
111 sk_X509_pop_free(impl->x509CertChain, X509_free);
112 impl->x509CertChain = NULL;
113 }
114
115 CfFree(impl);
116 }
117
X509ToHcfX509Certificate(X509 * cert,HcfX509Certificate ** returnObj)118 static CfResult X509ToHcfX509Certificate(X509 *cert, HcfX509Certificate **returnObj)
119 {
120 if (cert == NULL) {
121 LOGE("The input params invalid.");
122 return CF_INVALID_PARAMS;
123 }
124
125 int dataLength = 0;
126 uint8_t *certData = GetX509EncodedDataStream(cert, &dataLength);
127 if (certData == NULL) {
128 LOGE("Falied to get certificate data!");
129 return CF_ERR_CRYPTO_OPERATION;
130 }
131
132 HcfX509Certificate *x509cert = NULL;
133 CfEncodingBlob encodingBlob = { certData, dataLength, CF_FORMAT_DER };
134 CfResult res = HcfX509CertificateCreate(&encodingBlob, &x509cert);
135 if (res != CF_SUCCESS) {
136 LOGE("HcfX509CertificateCreate fail, res : %d!", res);
137 CfFree(certData);
138 return CF_ERR_MALLOC;
139 }
140
141 *returnObj = x509cert;
142 CfFree(certData);
143 return res;
144 }
145
GetCertlist(HcfX509CertChainSpi * self,HcfX509CertificateArray * certsList)146 static CfResult GetCertlist(HcfX509CertChainSpi *self, HcfX509CertificateArray *certsList)
147 {
148 if ((self == NULL) || (certsList == NULL)) {
149 LOGE("[GetCertlist openssl] The input data is null!");
150 return CF_INVALID_PARAMS;
151 }
152 if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertChainClass())) {
153 LOGE("[GetCertlist openssl] Input wrong class type!");
154 return CF_INVALID_PARAMS;
155 }
156
157 CfResult res = CF_SUCCESS;
158 HcfX509CertChainOpensslImpl *certChain = (HcfX509CertChainOpensslImpl *)self;
159 STACK_OF(X509) *x509CertChain = certChain->x509CertChain;
160
161 int32_t certsNum = sk_X509_num(x509CertChain);
162 if (certsNum <= 0) {
163 LOGE("sk X509 num : 0, failed!");
164 CfPrintOpensslError();
165 return CF_ERR_CRYPTO_OPERATION;
166 }
167 /* the list count has checked when create cert chain */
168 certsList->data = (HcfX509Certificate **)CfMalloc(certsNum * sizeof(HcfX509Certificate *), 0);
169 if (certsList->data == NULL) {
170 LOGE("malloc failed");
171 return CF_ERR_MALLOC;
172 }
173
174 certsList->count = (uint32_t)certsNum;
175 for (int32_t i = 0; i < certsNum; ++i) {
176 X509 *cert = sk_X509_value(x509CertChain, i);
177 if (cert == NULL) {
178 LOGE("sk X509 value is null, failed!");
179 CfPrintOpensslError();
180 FreeCertArrayData(certsList);
181 return CF_ERR_CRYPTO_OPERATION;
182 }
183 HcfX509Certificate *x509Cert = NULL;
184 res = X509ToHcfX509Certificate(cert, &x509Cert);
185 if (res != CF_SUCCESS) {
186 LOGE("convert x509 to HcfX509Certificate failed!");
187 FreeCertArrayData(certsList);
188 return res;
189 }
190 certsList->data[i] = x509Cert;
191 }
192
193 return res;
194 }
195
CheckCertChainIsRevoked(const STACK_OF (X509_CRL)* crlStack,const STACK_OF (X509)* certChain)196 static CfResult CheckCertChainIsRevoked(const STACK_OF(X509_CRL) *crlStack, const STACK_OF(X509) *certChain)
197 {
198 int cerNum = sk_X509_num(certChain);
199 if (cerNum == 0) {
200 LOGE("sk X509 num : 0, failed!");
201 CfPrintOpensslError();
202 return CF_ERR_CRYPTO_OPERATION;
203 }
204
205 int crlNum = sk_X509_CRL_num(crlStack); // allow crlNum : 0, no crl
206 for (int i = 0; i < crlNum; ++i) {
207 X509_CRL *crl = sk_X509_CRL_value(crlStack, i);
208 if (crl == NULL) {
209 LOGE("sk X509 CRL value is null, failed!");
210 CfPrintOpensslError();
211 return CF_ERR_CRYPTO_OPERATION;
212 }
213
214 /* crl in certcrlcollection object is not null. */
215 for (int j = 0; j < cerNum; ++j) {
216 X509 *cert = sk_X509_value(certChain, j);
217 if (cert == NULL) {
218 LOGE("sk X509 value is null, failed!");
219 CfPrintOpensslError();
220 return CF_ERR_CRYPTO_OPERATION;
221 }
222
223 X509_REVOKED *rev = NULL;
224 int32_t res = X509_CRL_get0_by_cert(crl, &rev, cert);
225 if (res != 0) {
226 LOGE("cert is revoked.");
227 return CF_ERR_CRYPTO_OPERATION;
228 }
229 }
230 }
231
232 return CF_SUCCESS;
233 }
234
SetVerifyParams(X509_STORE * store,X509 * mostTrustCert)235 static CfResult SetVerifyParams(X509_STORE *store, X509 *mostTrustCert)
236 {
237 if (X509_STORE_add_cert(store, mostTrustCert) != CF_OPENSSL_SUCCESS) {
238 LOGE("add cert to store failed!");
239 CfPrintOpensslError();
240 return CF_ERR_CRYPTO_OPERATION;
241 }
242
243 unsigned long flags = 0;
244 if (!CheckIsSelfSigned(mostTrustCert)) {
245 flags |= X509_V_FLAG_PARTIAL_CHAIN; // is not self signed
246 LOGI("SetVerifyFlag() is a partitial chain, not self signed!");
247 }
248
249 /* date has verified before. */
250 flags |= X509_V_FLAG_NO_CHECK_TIME;
251 X509_STORE_set_flags(store, flags);
252
253 return CF_SUCCESS;
254 }
255
VerifyCertChain(X509 * mostTrustCert,STACK_OF (X509)* x509CertChain)256 static CfResult VerifyCertChain(X509 *mostTrustCert, STACK_OF(X509) *x509CertChain)
257 {
258 if (mostTrustCert == NULL || x509CertChain == NULL) {
259 LOGE("invalid params!");
260 return CF_INVALID_PARAMS;
261 }
262
263 X509 *cert = sk_X509_value(x509CertChain, 0); // leaf cert
264 if (cert == NULL) {
265 CfPrintOpensslError();
266 return CF_ERR_CRYPTO_OPERATION;
267 }
268
269 X509_STORE_CTX *ctx = X509_STORE_CTX_new();
270 if (ctx == NULL) {
271 CfPrintOpensslError();
272 return CF_ERR_CRYPTO_OPERATION;
273 }
274
275 X509_STORE *store = X509_STORE_new();
276 if (store == NULL) {
277 LOGE("verify cert chain malloc failed!");
278 X509_STORE_CTX_free(ctx);
279 CfPrintOpensslError();
280 return CF_ERR_CRYPTO_OPERATION;
281 }
282
283 CfResult res = SetVerifyParams(store, mostTrustCert);
284 if (res == CF_SUCCESS) {
285 if (X509_STORE_CTX_init(ctx, store, cert, x509CertChain) != CF_OPENSSL_SUCCESS) {
286 LOGE("init verify ctx failed!");
287 X509_STORE_CTX_free(ctx);
288 X509_STORE_free(store);
289 CfPrintOpensslError();
290 return CF_ERR_CRYPTO_OPERATION;
291 }
292
293 if (X509_verify_cert(ctx) == CF_OPENSSL_SUCCESS) {
294 res = CF_SUCCESS;
295 } else {
296 int32_t errCode = X509_STORE_CTX_get_error(ctx);
297 const char *pChError = X509_verify_cert_error_string(errCode);
298 LOGE("Failed to verify cert, openssl openssl error code = %d, error msg:%s.", errCode, pChError);
299 res = ConvertOpensslErrorMsg(errCode);
300 }
301 }
302
303 X509_STORE_CTX_free(ctx); // Cleanup: Free the allocated memory and release resources.
304 X509_STORE_free(store);
305 return res;
306 }
307
ConvertByteArrayToPubKey(const uint8_t * pubKeyBytes,size_t len)308 static EVP_PKEY *ConvertByteArrayToPubKey(const uint8_t *pubKeyBytes, size_t len)
309 {
310 if (pubKeyBytes == NULL) {
311 LOGE("ConvertByteArrayToPubkey invalid params.");
312 return NULL;
313 }
314 EVP_PKEY *pubKey = d2i_PUBKEY(NULL, &pubKeyBytes, len); // pubkey DER format.
315 if (pubKey == NULL) {
316 LOGE("d2i_PUBKEY() failed!");
317 CfPrintOpensslError();
318 return NULL;
319 }
320
321 return pubKey;
322 }
323
CheckOthersInTrustAnchor(const HcfX509TrustAnchor * anchor,X509 * rootCert,bool * checkResult)324 static CfResult CheckOthersInTrustAnchor(const HcfX509TrustAnchor *anchor, X509 *rootCert, bool *checkResult)
325 {
326 *checkResult = false;
327 if (anchor->CAPubKey == NULL) {
328 return CF_SUCCESS;
329 }
330
331 // 1. validate public key of the root CA.
332 EVP_PKEY *pubKey = ConvertByteArrayToPubKey(anchor->CAPubKey->data, anchor->CAPubKey->size);
333 if (pubKey == NULL) {
334 LOGE("ConvertByteArrayToPubKey failed!");
335 return CF_ERR_CRYPTO_OPERATION;
336 }
337 /* pubkey in trust anchor may be the pubkey of self or of its upper level cert. */
338 bool matchUpperPubKey = false;
339 if (CheckSelfPubkey(rootCert, pubKey) != CF_SUCCESS) {
340 matchUpperPubKey = (X509_verify(rootCert, pubKey) == CF_OPENSSL_SUCCESS);
341 if (!matchUpperPubKey) {
342 LOGE("verify pubkey in trust anchor failed!");
343 CfPrintOpensslError();
344 EVP_PKEY_free(pubKey);
345 return CF_SUCCESS;
346 }
347 }
348
349 /* If pubkey is of self cert, the subject should be of self cert.
350 * If pubkey is of upper level cert, the subject should be of uppoer level cert (i.e. the issuer of self cert).
351 */
352 if (anchor->CASubject != NULL) {
353 // 2. compare subject name of root CA.
354 X509NameType nameType = NAME_TYPE_SUBJECT;
355 if (matchUpperPubKey) {
356 nameType = NAME_TYPE_ISSUER;
357 }
358 bool compareSubjectFlag = false;
359 CfResult res = CompareNameObject(rootCert, anchor->CASubject, nameType, &compareSubjectFlag);
360 if (res != CF_SUCCESS) {
361 LOGE("verify subject in trust anchor failed!");
362 EVP_PKEY_free(pubKey);
363 return res;
364 }
365 LOGI("verify subject in trust anchor result: %d", compareSubjectFlag);
366 *checkResult = compareSubjectFlag;
367 } else {
368 *checkResult = true;
369 }
370 EVP_PKEY_free(pubKey);
371 return CF_SUCCESS;
372 }
373
GetTrustAnchor(const HcfX509TrustAnchor * trustAnchors,X509 * rootCert,X509 ** mostTrustCertOut)374 static CfResult GetTrustAnchor(const HcfX509TrustAnchor *trustAnchors, X509 *rootCert, X509 **mostTrustCertOut)
375 {
376 if (trustAnchors == NULL || rootCert == NULL || mostTrustCertOut == NULL) {
377 LOGE("GetTrustAnchorCert() invalid params!");
378 return CF_INVALID_PARAMS;
379 }
380
381 if (trustAnchors->CACert != NULL) {
382 X509 *cert = GetX509FromHcfX509Certificate((HcfCertificate *)trustAnchors->CACert);
383 if (cert == NULL) {
384 LOGE("GetTrustAnchorCert() cert is null.");
385 return CF_INVALID_PARAMS;
386 }
387
388 X509_NAME *subjectName = X509_get_subject_name(cert);
389 if (subjectName == NULL) {
390 CfPrintOpensslError();
391 return CF_ERR_CRYPTO_OPERATION;
392 }
393 X509_NAME *subjectRoot = X509_get_subject_name(rootCert);
394 if (subjectRoot == NULL) {
395 CfPrintOpensslError();
396 return CF_ERR_CRYPTO_OPERATION;
397 }
398 EVP_PKEY *pubKey = X509_get_pubkey(cert); // validate public key of the trustAnchor CACert. X509_check_issued
399 if (pubKey == NULL) {
400 LOGE("X509_get_pubkey() failed!");
401 CfPrintOpensslError();
402 return CF_ERR_CRYPTO_OPERATION;
403 }
404 if (X509_verify(rootCert, pubKey) != CF_OPENSSL_SUCCESS && X509_NAME_cmp(subjectName, subjectRoot)) {
405 LOGE("X509_verify() failed!");
406 CfPrintOpensslError();
407 EVP_PKEY_free(pubKey);
408 return CF_SUCCESS; // continue to try next trustAnchor
409 }
410 EVP_PKEY_free(pubKey);
411 *mostTrustCertOut = cert;
412 return CF_SUCCESS;
413 }
414
415 bool checkResult = false;
416 CfResult res = CheckOthersInTrustAnchor(trustAnchors, rootCert, &checkResult);
417 if (res != CF_SUCCESS) {
418 LOGE("CheckOthersInTrustAnchor failed.");
419 return res;
420 }
421
422 if (checkResult) {
423 *mostTrustCertOut = rootCert;
424 }
425 return CF_SUCCESS;
426 }
427
FreeTrustAnchorData(HcfX509TrustAnchor * trustAnchor)428 static void FreeTrustAnchorData(HcfX509TrustAnchor *trustAnchor)
429 {
430 if (trustAnchor == NULL) {
431 return;
432 }
433 CfBlobFree(&trustAnchor->CAPubKey);
434 CfBlobFree(&trustAnchor->CASubject);
435 CfObjDestroy(trustAnchor->CACert);
436 trustAnchor->CACert = NULL;
437 }
438
CopyHcfX509TrustAnchor(const HcfX509TrustAnchor * inputAnchor,HcfX509TrustAnchor * outAnchor)439 static CfResult CopyHcfX509TrustAnchor(const HcfX509TrustAnchor *inputAnchor, HcfX509TrustAnchor *outAnchor)
440 {
441 HcfX509Certificate *CACert = inputAnchor->CACert;
442 CfBlob *CAPubKey = inputAnchor->CAPubKey;
443 CfBlob *CASubject = inputAnchor->CASubject;
444 CfBlob *nameConstraints = inputAnchor->nameConstraints;
445 CfResult res = CF_SUCCESS;
446 if (CACert != NULL) {
447 CfEncodingBlob encodedByte = { NULL, 0, CF_FORMAT_DER };
448 CACert->base.getEncoded((HcfCertificate *)CACert, &encodedByte);
449 res = HcfX509CertificateCreate(&encodedByte, &outAnchor->CACert);
450 if (res != CF_SUCCESS) {
451 LOGE("HcfX509CertificateCreate fail, res : %d!", res);
452 CfFree(encodedByte.data);
453 return CF_ERR_MALLOC;
454 }
455 CfFree(encodedByte.data);
456 }
457 if (CAPubKey != NULL) {
458 res = DeepCopyBlobToBlob(CAPubKey, &outAnchor->CAPubKey);
459 if (res != CF_SUCCESS) {
460 LOGE("DeepCopyDataToBlob failed");
461 CfObjDestroy(outAnchor->CACert);
462 return res;
463 }
464 }
465 if (CASubject != NULL) {
466 res = DeepCopyBlobToBlob(CASubject, &outAnchor->CASubject);
467 if (res != CF_SUCCESS) {
468 LOGE("DeepCopyDataToBlob failed");
469 CfObjDestroy(outAnchor->CACert);
470 CfBlobFree(&outAnchor->CAPubKey);
471 return res;
472 }
473 }
474 if (nameConstraints != NULL) {
475 res = DeepCopyBlobToBlob(nameConstraints, &outAnchor->nameConstraints);
476 if (res != CF_SUCCESS) {
477 LOGE("DeepCopyDataToBlob failed");
478 CfObjDestroy(outAnchor->CACert);
479 CfBlobFree(&outAnchor->CAPubKey);
480 CfBlobFree(&outAnchor->CASubject);
481 return res;
482 }
483 }
484
485 return res;
486 }
487
FillValidateResult(HcfX509TrustAnchor * inputAnchor,X509 * cert,HcfX509CertChainValidateResult * result)488 static CfResult FillValidateResult(HcfX509TrustAnchor *inputAnchor, X509 *cert, HcfX509CertChainValidateResult *result)
489 {
490 if (inputAnchor == NULL || cert == NULL) {
491 LOGE("FillValidateResult() invalidate params!");
492 return CF_INVALID_PARAMS;
493 }
494 CfResult res = CF_SUCCESS;
495 HcfX509TrustAnchor *validateTrustAnchors = (HcfX509TrustAnchor *)CfMalloc(sizeof(HcfX509TrustAnchor), 0);
496 if (validateTrustAnchors == NULL) {
497 LOGE("FillValidateResult() malloc failed");
498 return CF_ERR_MALLOC;
499 }
500 res = CopyHcfX509TrustAnchor(inputAnchor, validateTrustAnchors);
501 if (res != CF_SUCCESS) {
502 LOGE("CopyHcfX509TrustAnchor() failed!");
503 CfFree(validateTrustAnchors);
504 return res;
505 }
506
507 result->trustAnchor = validateTrustAnchors;
508 HcfX509Certificate *entityCert = NULL;
509 res = X509ToHcfX509Certificate(cert, &entityCert);
510 if (res != CF_SUCCESS) {
511 LOGE("X509ToHcfX509Certificate() failed!");
512 FreeTrustAnchorData(result->trustAnchor);
513 CF_FREE_PTR(result->trustAnchor);
514 return res;
515 }
516
517 result->entityCert = entityCert;
518 return res;
519 }
520
ParseX509CRL(const CfEncodingBlob * inStream)521 static X509_CRL *ParseX509CRL(const CfEncodingBlob *inStream)
522 {
523 if ((inStream->data == NULL) || (inStream->len <= 0)) {
524 LOGE("Invalid params!");
525 return NULL;
526 }
527 BIO *bio = BIO_new_mem_buf(inStream->data, inStream->len);
528 if (bio == NULL) {
529 LOGE("bio get null!");
530 CfPrintOpensslError();
531 return NULL;
532 }
533 X509_CRL *crlOut = NULL;
534 switch (inStream->encodingFormat) {
535 case CF_FORMAT_DER:
536 crlOut = d2i_X509_CRL_bio(bio, NULL);
537 break;
538 case CF_FORMAT_PEM:
539 crlOut = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL);
540 break;
541 default:
542 LOGE("Not support format!");
543 break;
544 }
545 BIO_free_all(bio);
546 if (crlOut == NULL) {
547 LOGE("Parse X509 CRL fail!");
548 CfPrintOpensslError();
549 return NULL;
550 }
551 return crlOut;
552 }
553
PushCrl2Stack(HcfX509CrlArray * crlArray,STACK_OF (X509_CRL)* outCrls)554 static CfResult PushCrl2Stack(HcfX509CrlArray *crlArray, STACK_OF(X509_CRL) *outCrls)
555 {
556 CfResult res = CF_SUCCESS;
557 HcfX509Crl *x509Crl = NULL;
558 X509_CRL *crl = NULL;
559 for (uint32_t i = 0; i < crlArray->count; i++) {
560 CfEncodingBlob encodedBlob = { 0 };
561 x509Crl = crlArray->data[i];
562 res = x509Crl->getEncoded(x509Crl, &encodedBlob);
563 if (res != CF_SUCCESS) {
564 LOGE("Failed to getEncoded of crl!");
565 return res;
566 }
567
568 crl = ParseX509CRL(&encodedBlob);
569 CfFree(encodedBlob.data);
570 if (crl == NULL) {
571 LOGE("Failed to Parse x509 CRL!");
572 return CF_INVALID_PARAMS;
573 }
574 if (sk_X509_CRL_push(outCrls, crl) == 0) {
575 LOGE("sk_X509_CRL_push failed!");
576 X509_CRL_free(crl);
577 return CF_ERR_CRYPTO_OPERATION;
578 }
579 }
580 return res;
581 }
582
GetX509Crls(const HcfCertCRLCollectionArray * certCRLCollections,STACK_OF (X509_CRL)* outCrls)583 static CfResult GetX509Crls(const HcfCertCRLCollectionArray *certCRLCollections, STACK_OF(X509_CRL) *outCrls)
584 {
585 if (certCRLCollections == NULL) { // certCRLCollection is not force params for verify certchain
586 LOGI("certcrlcollections is null!");
587 return CF_SUCCESS;
588 }
589
590 CfResult res = CF_SUCCESS;
591 HcfX509CrlArray *crlArray = NULL;
592 HcfCertCrlCollection *crlCollection = NULL;
593 for (uint32_t i = 0; i < certCRLCollections->count; i++) {
594 crlCollection = certCRLCollections->data[i];
595 res = crlCollection->getCRLs(crlCollection, &crlArray);
596 if (res != CF_SUCCESS) {
597 LOGE("getCRLs() from CertCrlCollection failed!");
598 /* Warning: free outCrls in outside */
599 return res;
600 }
601 if (crlArray->count == 0) {
602 LOGI("crls array is empty.");
603 continue;
604 }
605 res = PushCrl2Stack(crlArray, outCrls);
606 if (res != CF_SUCCESS) {
607 LOGE("push crls to stack failed!");
608 /* Warning: free outCrls in outside */
609 return res;
610 }
611 }
612
613 return res;
614 }
615
ValidateCrlLocal(const HcfCertCRLCollectionArray * collectionArr,STACK_OF (X509)* x509CertChain)616 static CfResult ValidateCrlLocal(const HcfCertCRLCollectionArray *collectionArr, STACK_OF(X509) *x509CertChain)
617 {
618 STACK_OF(X509_CRL) *crlStack = sk_X509_CRL_new_null();
619 if (crlStack == NULL) {
620 LOGE("sk X509 CRL new null failed!");
621 CfPrintOpensslError();
622 return CF_ERR_CRYPTO_OPERATION;
623 }
624
625 CfResult res = GetX509Crls(collectionArr, crlStack);
626 if (res != CF_SUCCESS) {
627 LOGE("GetX509Crls failed");
628 sk_X509_CRL_pop_free(crlStack, X509_CRL_free);
629 return res;
630 }
631
632 if (sk_X509_CRL_num(crlStack) == 0) {
633 LOGI("crls count is 0");
634 sk_X509_CRL_free(crlStack);
635 return CF_SUCCESS;
636 }
637 res = CheckCertChainIsRevoked(crlStack, x509CertChain);
638 sk_X509_CRL_pop_free(crlStack, X509_CRL_free);
639 return res;
640 }
641
ValidateNC(STACK_OF (X509)* x509CertChain,CfBlob * nameConstraints)642 static CfResult ValidateNC(STACK_OF(X509) *x509CertChain, CfBlob *nameConstraints)
643 {
644 if (nameConstraints == NULL) {
645 LOGI("NameConstraints from js is null!");
646 return CF_SUCCESS;
647 }
648
649 const unsigned char *p = nameConstraints->data;
650 NAME_CONSTRAINTS *nc =
651 (NAME_CONSTRAINTS *)ASN1_item_d2i(NULL, &p, nameConstraints->size, ASN1_ITEM_rptr(NAME_CONSTRAINTS));
652 if (nc == NULL) {
653 LOGE("Get nameConstraints from js failed!");
654 return CF_INVALID_PARAMS;
655 }
656
657 CfResult res = CF_SUCCESS;
658 for (int i = 0; i < sk_X509_num(x509CertChain); i++) {
659 X509 *cert = sk_X509_value(x509CertChain, i);
660 if (cert == NULL) {
661 LOGE("Get cert from stack to check nameConstraints failed!");
662 res = CF_INVALID_PARAMS;
663 break;
664 }
665 if (CheckIsLeafCert(cert) && !CheckIsSelfSigned(cert)) {
666 if (NAME_CONSTRAINTS_check(cert, nc) != X509_V_OK) {
667 LOGE("Check nameConstraints failed!");
668 res = CF_INVALID_PARAMS;
669 break;
670 }
671 }
672 }
673
674 NAME_CONSTRAINTS_free(nc);
675 return res;
676 }
677
ValidateTrustAnchor(const HcfX509TrustAnchorArray * trustAnchorsArray,X509 * rootCert,STACK_OF (X509)* x509CertChain,HcfX509TrustAnchor ** trustAnchorResult)678 static CfResult ValidateTrustAnchor(const HcfX509TrustAnchorArray *trustAnchorsArray, X509 *rootCert,
679 STACK_OF(X509) *x509CertChain, HcfX509TrustAnchor **trustAnchorResult)
680 {
681 CfResult res = CF_SUCCESS;
682 for (uint32_t i = 0; i < trustAnchorsArray->count; ++i) {
683 X509 *mostTrustAnchorCert = NULL;
684 HcfX509TrustAnchor *trustAnchor = trustAnchorsArray->data[i];
685 res = GetTrustAnchor(trustAnchor, rootCert, &mostTrustAnchorCert);
686 if (res != CF_SUCCESS) {
687 LOGE("Get trust anchor cert failed, try next trustAnchor.");
688 return res;
689 }
690 if (mostTrustAnchorCert == NULL) {
691 LOGE("most trust anchor cert is null.");
692 res = CF_INVALID_PARAMS; /* if validate trust anchor list failed, return the last error. */
693 continue;
694 }
695
696 res = VerifyCertChain(mostTrustAnchorCert, x509CertChain);
697 if (res != CF_SUCCESS) { // verify the data & crl list of certchain
698 LOGI("verify one trustanchor failed, try next trustAnchor.");
699 continue;
700 }
701
702 res = ValidateNC(x509CertChain, trustAnchor->nameConstraints);
703 if (res != CF_SUCCESS) {
704 LOGI("verify nameConstraints failed, try next trustAnchor.");
705 continue;
706 }
707 *trustAnchorResult = trustAnchor;
708 break;
709 }
710
711 return res;
712 }
713
GetDpUrl(DIST_POINT * dp)714 static const char *GetDpUrl(DIST_POINT *dp)
715 {
716 GENERAL_NAMES *gens = NULL;
717 GENERAL_NAME *gen = NULL;
718 ASN1_STRING *url = NULL;
719
720 if (dp == NULL || dp->distpoint == NULL || dp->distpoint->type != 0) {
721 return NULL;
722 }
723 gens = dp->distpoint->name.fullname;
724 if (gens == NULL) {
725 return NULL;
726 }
727 for (int32_t i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
728 gen = sk_GENERAL_NAME_value(gens, i);
729 if (gen == NULL) {
730 continue;
731 }
732 int gtype;
733 url = GENERAL_NAME_get0_value(gen, >ype);
734 if (url == NULL) {
735 continue;
736 }
737 if (gtype == GEN_URI && ASN1_STRING_length(url) > GEN_URI) {
738 const char *uptr = (const char *)ASN1_STRING_get0_data(url);
739 if (CfIsHttp(uptr)) {
740 // can/should not use HTTPS here
741 return uptr;
742 }
743 }
744 }
745 return NULL;
746 }
747
LoadCrlDp(STACK_OF (DIST_POINT)* crldp)748 static X509_CRL *LoadCrlDp(STACK_OF(DIST_POINT) *crldp)
749 {
750 const char *urlptr = NULL;
751 for (int i = 0; i < sk_DIST_POINT_num(crldp); i++) {
752 DIST_POINT *dp = sk_DIST_POINT_value(crldp, i);
753 urlptr = GetDpUrl(dp);
754 if (urlptr != NULL) {
755 return X509_CRL_load_http(urlptr, NULL, NULL, HTTP_TIMEOUT);
756 }
757 }
758 return NULL;
759 }
760
GetCrlFromCert(const HcfX509CertChainValidateParams * params,X509 * x509)761 static X509_CRL *GetCrlFromCert(const HcfX509CertChainValidateParams *params, X509 *x509)
762 {
763 STACK_OF(DIST_POINT) *crlStack = X509_get_ext_d2i(x509, NID_crl_distribution_points, NULL, NULL);
764 if (crlStack != NULL) {
765 X509_CRL *crl = LoadCrlDp(crlStack);
766 sk_DIST_POINT_pop_free(crlStack, DIST_POINT_free);
767 if (crl != NULL) {
768 return crl;
769 }
770 }
771
772 if (params->revocationCheckParam->crlDownloadURI != NULL &&
773 params->revocationCheckParam->crlDownloadURI->data != NULL) {
774 char *url = (char *)params->revocationCheckParam->crlDownloadURI->data;
775 if (CfIsUrlValid(url)) {
776 return X509_CRL_load_http(url, NULL, NULL, HTTP_TIMEOUT);
777 }
778 }
779
780 return NULL;
781 }
782
ValidateCrlOnline(const HcfX509CertChainValidateParams * params,STACK_OF (X509)* x509CertChain)783 static CfResult ValidateCrlOnline(const HcfX509CertChainValidateParams *params, STACK_OF(X509) *x509CertChain)
784 {
785 X509 *x509 = sk_X509_value(x509CertChain, 0);
786 if (x509 == NULL) {
787 LOGE("Get leaf cert failed!");
788 return CF_INVALID_PARAMS;
789 }
790 X509_CRL *crl = GetCrlFromCert(params, x509);
791 if (crl == NULL) {
792 LOGE("Get crl online is null!");
793 return CF_ERR_CRYPTO_OPERATION;
794 }
795
796 STACK_OF(X509_CRL) *crlStack = sk_X509_CRL_new_null();
797 if (crlStack == NULL) {
798 LOGE("Create crl stack failed!");
799 return CF_ERR_CRYPTO_OPERATION;
800 }
801 if (sk_X509_CRL_push(crlStack, crl) == 0) {
802 LOGE("Push crl stack failed!");
803 sk_X509_CRL_pop_free(crlStack, X509_CRL_free);
804 return CF_ERR_CRYPTO_OPERATION;
805 }
806 if (CheckCertChainIsRevoked(crlStack, x509CertChain) != CF_SUCCESS) {
807 LOGE("Certchain is revoked, verify failed!");
808 sk_X509_CRL_pop_free(crlStack, X509_CRL_free);
809 return CF_ERR_CRYPTO_OPERATION;
810 }
811
812 sk_X509_CRL_pop_free(crlStack, X509_CRL_free);
813 return CF_SUCCESS;
814 }
815
ContainsOption(HcfRevChkOpArray * options,HcfRevChkOption op)816 static bool ContainsOption(HcfRevChkOpArray *options, HcfRevChkOption op)
817 {
818 if (options == NULL || options->data == NULL) {
819 return false;
820 }
821
822 for (uint32_t i = 0; i < options->count; i++) {
823 if (options->data[i] == op) {
824 return true;
825 }
826 }
827 return false;
828 }
829
VerifyOcspSigner(OCSP_BASICRESP * bs,STACK_OF (X509)* certChain,X509 * cert)830 static CfResult VerifyOcspSigner(OCSP_BASICRESP *bs, STACK_OF(X509) *certChain, X509 *cert)
831 {
832 if (cert == NULL) {
833 LOGE("Input data cert is null!");
834 return CF_INVALID_PARAMS;
835 }
836 X509_STORE *store = X509_STORE_new();
837 if (store == NULL) {
838 LOGE("New x509 store failed!");
839 return CF_ERR_CRYPTO_OPERATION;
840 }
841 CfResult res = SetVerifyParams(store, cert);
842 if (res != CF_SUCCESS) {
843 LOGE("Set verify params failed!");
844 X509_STORE_free(store);
845 return res;
846 }
847
848 if (OCSP_basic_verify(bs, certChain, store, 0) != 1) {
849 LOGE("OCSP basic verify failed!");
850 res = CF_ERR_CERT_SIGNATURE_FAILURE;
851 }
852 X509_STORE_free(store);
853
854 return res;
855 }
856
ParseResp(OCSP_BASICRESP * bs,OcspCertIdInfo * certIdInfo)857 static CfResult ParseResp(OCSP_BASICRESP *bs, OcspCertIdInfo *certIdInfo)
858 {
859 int ocspStatus;
860 ASN1_GENERALIZEDTIME *thisUpdate = NULL;
861 ASN1_GENERALIZEDTIME *nextUpdate = NULL;
862 CfResult res = CF_ERR_CRYPTO_OPERATION;
863
864 OCSP_CERTID *certId = OCSP_cert_to_id(certIdInfo->md, certIdInfo->subjectCert, certIdInfo->issuerCert);
865 if (certId == NULL) {
866 LOGE("Unable to create certId.");
867 return CF_ERR_CRYPTO_OPERATION;
868 }
869
870 if (OCSP_resp_find_status(bs, certId, &ocspStatus, NULL, NULL, &thisUpdate, &nextUpdate) == 1) {
871 switch (ocspStatus) {
872 case V_OCSP_CERTSTATUS_GOOD:
873 LOGI("The OCSP status is [V_OCSP_CERTSTATUS_GOOD]!");
874 res = CF_SUCCESS;
875 break;
876 case V_OCSP_CERTSTATUS_REVOKED:
877 LOGE("The OCSP status is [V_OCSP_CERTSTATUS_REVOKED]!");
878 break;
879 case V_OCSP_CERTSTATUS_UNKNOWN:
880 default:
881 LOGE("!The OCSP status is [UNKNOWN]!");
882 break;
883 }
884 }
885 OCSP_CERTID_free(certId);
886 return res;
887 }
888
ValidateOcspLocalGetTrustCert(STACK_OF (X509)* x509CertChain,HcfX509TrustAnchor * trustAnchor,const HcfX509CertChainValidateParams * params,HcfRevocationCheckParam * revo,X509 ** trustCert)889 static void ValidateOcspLocalGetTrustCert(STACK_OF(X509) *x509CertChain, HcfX509TrustAnchor *trustAnchor,
890 const HcfX509CertChainValidateParams *params, HcfRevocationCheckParam *revo, X509 **trustCert)
891 {
892 if (revo->ocspResponderCert != NULL) {
893 *trustCert = GetX509FromHcfX509Certificate((HcfCertificate *)(params->revocationCheckParam->ocspResponderCert));
894 } else if (trustAnchor->CACert != NULL) {
895 *trustCert = GetX509FromHcfX509Certificate((HcfCertificate *)(trustAnchor->CACert));
896 } else {
897 *trustCert = sk_X509_value(x509CertChain, sk_X509_num(x509CertChain) - 1);
898 }
899 }
900
ValidateOcspLocal(OcspLocalParam localParam,STACK_OF (X509)* x509CertChain,HcfX509TrustAnchor * trustAnchor,const HcfX509CertChainValidateParams * params)901 static CfResult ValidateOcspLocal(OcspLocalParam localParam, STACK_OF(X509) *x509CertChain,
902 HcfX509TrustAnchor *trustAnchor, const HcfX509CertChainValidateParams *params)
903 {
904 int i;
905 X509 *trustCert = NULL;
906 OCSP_RESPONSE *rsp = NULL;
907 if (localParam.certIdInfo == NULL) {
908 LOGE("The input data is null!");
909 return CF_INVALID_PARAMS;
910 }
911 HcfRevocationCheckParam *revo = params->revocationCheckParam;
912 if (localParam.resp == NULL && revo->ocspResponses != NULL) {
913 const unsigned char *p = revo->ocspResponses->data;
914 rsp = d2i_OCSP_RESPONSE(NULL, &p, revo->ocspResponses->size);
915 localParam.resp = rsp;
916 }
917 if (localParam.resp == NULL) {
918 LOGE("The input data is null!");
919 return CF_ERR_CRYPTO_OPERATION;
920 }
921 if (OCSP_response_status(localParam.resp) != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
922 LOGE("The resp status is not success!");
923 OCSP_RESPONSE_free(rsp);
924 return CF_ERR_CRYPTO_OPERATION;
925 }
926 OCSP_BASICRESP *bs = OCSP_response_get1_basic(localParam.resp);
927 OCSP_RESPONSE_free(rsp);
928 if (bs == NULL) {
929 LOGE("Error parsing response!");
930 return CF_ERR_CRYPTO_OPERATION;
931 }
932 if (localParam.req != NULL && ((i = OCSP_check_nonce(localParam.req, bs)) <= 0)) {
933 if (i == -1) {
934 LOGW("No nonce in response!");
935 } else {
936 LOGE("Nonce Verify error!");
937 OCSP_BASICRESP_free(bs);
938 return CF_ERR_CRYPTO_OPERATION;
939 }
940 }
941
942 ValidateOcspLocalGetTrustCert(x509CertChain, trustAnchor, params, revo, &trustCert);
943 CfResult res = VerifyOcspSigner(bs, x509CertChain, trustCert);
944 if (res != CF_SUCCESS) {
945 LOGE("VerifySinger failed!");
946 OCSP_BASICRESP_free(bs);
947 return res;
948 }
949 res = ParseResp(bs, localParam.certIdInfo);
950 OCSP_BASICRESP_free(bs);
951 return res;
952 }
953
SendReqBioCustom(BIO * bio,const char * host,const char * path,OCSP_REQUEST * req)954 static OCSP_RESPONSE *SendReqBioCustom(BIO *bio, const char *host, const char *path, OCSP_REQUEST *req)
955 {
956 OCSP_RESPONSE *resp = NULL;
957 OCSP_REQ_CTX *ctx;
958
959 ctx = OCSP_sendreq_new(bio, path, NULL, -1);
960 if (ctx == NULL) {
961 LOGE("Create ocsp req ctx failed!");
962 return NULL;
963 }
964 if (!OCSP_REQ_CTX_add1_header(ctx, "Accept", "application/ocsp-response")) {
965 OCSP_REQ_CTX_free(ctx);
966 return NULL;
967 }
968 if (!OCSP_REQ_CTX_add1_header(ctx, "Host", host)) {
969 OCSP_REQ_CTX_free(ctx);
970 return NULL;
971 }
972 if (!OCSP_REQ_CTX_set1_req(ctx, req)) {
973 OCSP_REQ_CTX_free(ctx);
974 return NULL;
975 }
976 int ret;
977 int tryNum = TRY_CONNECT_TIMES;
978 do {
979 ret = OCSP_sendreq_nbio(&resp, ctx);
980 tryNum--;
981 } while ((ret == -1) && BIO_should_retry(bio) && tryNum != 0);
982 OCSP_REQ_CTX_free(ctx);
983 if (ret) {
984 return resp;
985 }
986 return NULL;
987 }
988
ConnectToServer(BIO * bio,int tryNum)989 static bool ConnectToServer(BIO *bio, int tryNum)
990 {
991 int ret = 0;
992 int num = tryNum;
993 do {
994 ret = BIO_do_connect_retry(bio, OCSP_CONN_TIMEOUT, OCSP_CONN_MILLISECOND);
995 if (ret == 1) {
996 break;
997 } else if (ret <= 0) {
998 LOGE("OCSP connecte service failed.");
999 CfPrintOpensslError();
1000 if (BIO_should_retry(bio)) {
1001 LOGI("Try to connect service again, [%d]st.", num);
1002 num--;
1003 } else {
1004 break;
1005 }
1006 }
1007 } while (ret <= 0 && num != 0);
1008 return (ret == 1 ? true : false);
1009 }
1010
GetOcspUrl(GetOcspUrlParams * params)1011 static CfResult GetOcspUrl(GetOcspUrlParams *params)
1012 {
1013 char *url = NULL;
1014
1015 if (params->leafCert == NULL) {
1016 LOGE("The input param invalid.");
1017 return CF_INVALID_PARAMS;
1018 }
1019 STACK_OF(OPENSSL_STRING) *ocspList = X509_get1_ocsp(params->leafCert);
1020 if (ocspList != NULL && sk_OPENSSL_STRING_num(ocspList) > 0) {
1021 url = sk_OPENSSL_STRING_value(ocspList, 0);
1022 }
1023
1024 if (url == NULL) {
1025 if (params->revo->ocspResponderURI == NULL || params->revo->ocspResponderURI->data == NULL) {
1026 LOGE("Unable to get url.");
1027 return CF_ERR_CRYPTO_OPERATION;
1028 }
1029 }
1030 char *urlValiable = (url == NULL) ? (char *)(params->revo->ocspResponderURI->data) : url;
1031 if (!CfIsUrlValid(urlValiable)) {
1032 LOGE("Invalid url.");
1033 return CF_INVALID_PARAMS;
1034 }
1035 if (!OCSP_parse_url(urlValiable, params->host, params->port, params->path, params->ssl)) {
1036 LOGE("Unable to parse url.");
1037 return CF_ERR_CRYPTO_OPERATION;
1038 }
1039 return CF_SUCCESS;
1040 }
1041
SetRequestData(HcfRevocationCheckParam * revo,OCSP_REQUEST * req,OcspCertIdInfo * certIdInfo)1042 static CfResult SetRequestData(HcfRevocationCheckParam *revo, OCSP_REQUEST *req, OcspCertIdInfo *certIdInfo)
1043 {
1044 OCSP_CERTID *certId = OCSP_cert_to_id(certIdInfo->md, certIdInfo->subjectCert, certIdInfo->issuerCert);
1045 if (certId == NULL) {
1046 LOGE("Unable to create certId.");
1047 return CF_ERR_CRYPTO_OPERATION;
1048 }
1049
1050 if (OCSP_request_add0_id(req, certId) == NULL) {
1051 LOGE("Unable to add certId to req.");
1052 OCSP_CERTID_free(certId);
1053 return CF_INVALID_PARAMS;
1054 }
1055
1056 if (revo->ocspRequestExtension != NULL) {
1057 for (size_t i = 0; i < revo->ocspRequestExtension->count; i++) {
1058 const unsigned char *p = revo->ocspRequestExtension->data[i].data;
1059 X509_EXTENSION *ext = d2i_X509_EXTENSION(NULL, &p, revo->ocspRequestExtension->data[i].size);
1060 if (ext == NULL) {
1061 return CF_INVALID_PARAMS;
1062 }
1063 if (!OCSP_REQUEST_add_ext(req, ext, -1)) {
1064 X509_EXTENSION_free(ext);
1065 return CF_ERR_CRYPTO_OPERATION;
1066 }
1067 X509_EXTENSION_free(ext);
1068 ext = NULL;
1069 }
1070 }
1071
1072 return CF_SUCCESS;
1073 }
1074
CreateConnectBio(char * host,char * port,int ssl)1075 static BIO *CreateConnectBio(char *host, char *port, int ssl)
1076 {
1077 BIO *bio = NULL;
1078 if (ssl == 1) {
1079 SSL_library_init();
1080 SSL_load_error_strings();
1081 OpenSSL_add_all_algorithms();
1082
1083 SSL_CTX *sslCtx = SSL_CTX_new(TLS_client_method());
1084 if (sslCtx == NULL) {
1085 return NULL;
1086 }
1087 bio = BIO_new_ssl_connect(sslCtx);
1088 if (bio == NULL) {
1089 LOGE("bio is null.");
1090 SSL_CTX_free(sslCtx);
1091 return NULL;
1092 }
1093 if (BIO_set_conn_hostname(bio, host) != 1) {
1094 LOGE("Set host name failed.");
1095 BIO_free_all(bio);
1096 SSL_CTX_free(sslCtx);
1097 return NULL;
1098 }
1099 } else {
1100 bio = BIO_new_connect(host);
1101 }
1102
1103 if (bio == NULL) {
1104 LOGE("Create connect bio failed.");
1105 return bio;
1106 }
1107
1108 if (port != NULL) {
1109 if (BIO_set_conn_port(bio, port) != 1) {
1110 LOGE("Set port failed.");
1111 BIO_free_all(bio);
1112 return NULL;
1113 }
1114 } else if (ssl) {
1115 if (BIO_set_conn_port(bio, HTTPS_PORT) != 1) {
1116 LOGE("Set port failed.");
1117 BIO_free_all(bio);
1118 return NULL;
1119 }
1120 } else {
1121 if (BIO_set_conn_port(bio, HTTP_PORT) != 1) {
1122 LOGE("Set port failed.");
1123 BIO_free_all(bio);
1124 return NULL;
1125 }
1126 }
1127 return bio;
1128 }
1129
ValidateOcspOnline(STACK_OF (X509)* x509CertChain,OcspCertIdInfo * certIdInfo,HcfX509TrustAnchor * trustAnchor,const HcfX509CertChainValidateParams * params)1130 static CfResult ValidateOcspOnline(STACK_OF(X509) *x509CertChain, OcspCertIdInfo *certIdInfo,
1131 HcfX509TrustAnchor *trustAnchor, const HcfX509CertChainValidateParams *params)
1132 {
1133 char *host = NULL;
1134 char *port = NULL;
1135 char *path = NULL;
1136 int ssl = 0;
1137
1138 HcfRevocationCheckParam *revo = params->revocationCheckParam;
1139
1140 CfResult res = GetOcspUrl(&(GetOcspUrlParams) { .leafCert = sk_X509_value(x509CertChain, 0),
1141 .revo = revo, .host = &host, .port = &port, .path = &path, .ssl = &ssl });
1142 if (res != CF_SUCCESS) {
1143 LOGE("Unable to get ocps url.");
1144 return res;
1145 }
1146
1147 BIO *cbio = CreateConnectBio(host, port, ssl);
1148 if (cbio == NULL) {
1149 LOGE("Unable to create connection.");
1150 return CF_ERR_CRYPTO_OPERATION;
1151 }
1152 if (!ConnectToServer(cbio, TRY_CONNECT_TIMES)) {
1153 LOGE("Unable to connect service.");
1154 BIO_free_all(cbio);
1155 return CF_ERR_CRYPTO_OPERATION;
1156 }
1157 OCSP_REQUEST *req = OCSP_REQUEST_new();
1158 if (req == NULL) {
1159 LOGE("Unable to create req.");
1160 BIO_free_all(cbio);
1161 return CF_ERR_CRYPTO_OPERATION;
1162 }
1163 res = SetRequestData(revo, req, certIdInfo);
1164 if (res != CF_SUCCESS) {
1165 LOGE("Unable to set request data.");
1166 OCSP_REQUEST_free(req);
1167 BIO_free_all(cbio);
1168 return res;
1169 }
1170
1171 /* Send OCSP request and wait for response */
1172 OCSP_RESPONSE *resp = SendReqBioCustom(cbio, host, path, req);
1173 if (resp == NULL) {
1174 LOGE("Unable to send request.");
1175 OCSP_REQUEST_free(req);
1176 BIO_free_all(cbio);
1177 return CF_ERR_CRYPTO_OPERATION;
1178 }
1179 res = ValidateOcspLocal(
1180 (OcspLocalParam) { .req = req, .resp = resp, .certIdInfo = certIdInfo }, x509CertChain, trustAnchor, params);
1181 OCSP_REQUEST_free(req);
1182 BIO_free_all(cbio);
1183 OCSP_RESPONSE_free(resp);
1184 return res;
1185 }
1186
GetHashDigest(const CfBlob * ocspDigest)1187 static const EVP_MD *GetHashDigest(const CfBlob *ocspDigest)
1188 {
1189 if (ocspDigest == NULL || ocspDigest->data == NULL) {
1190 return EVP_sha256();
1191 }
1192 char *mdName = (char *)ocspDigest->data;
1193 if (strcmp(mdName, "SHA1") == 0) {
1194 return EVP_sha1();
1195 } else if (strcmp(mdName, "SHA224") == 0) {
1196 return EVP_sha224();
1197 } else if (strcmp(mdName, "SHA256") == 0) {
1198 return EVP_sha256();
1199 } else if (strcmp(mdName, "SHA384") == 0) {
1200 return EVP_sha384();
1201 } else if (strcmp(mdName, "SHA512") == 0) {
1202 return EVP_sha512();
1203 } else if (strcmp(mdName, "MD5") == 0) {
1204 return EVP_md5();
1205 }
1206 return EVP_sha256();
1207 }
1208
GetCertIssuerFromChain(STACK_OF (X509)* x509CertChain,X509 * leafCert,X509 ** issuerCert)1209 static CfResult GetCertIssuerFromChain(STACK_OF(X509) *x509CertChain, X509 *leafCert, X509 **issuerCert)
1210 {
1211 X509_STORE *store = NULL;
1212 X509_STORE_CTX *storeCtx = NULL;
1213 CfResult ret = CF_SUCCESS;
1214
1215 store = X509_STORE_new();
1216 if (store == NULL) {
1217 LOGE("Unable to create store.");
1218 return CF_ERR_MALLOC;
1219 }
1220
1221 for (int i = 1; i < sk_X509_num(x509CertChain); i++) {
1222 X509 *tmpCert = sk_X509_value(x509CertChain, i);
1223 if (X509_STORE_add_cert(store, tmpCert) != 1) {
1224 LOGE("Add cert to store failed.");
1225 X509_STORE_free(store);
1226 return CF_ERR_CRYPTO_OPERATION;
1227 }
1228 }
1229
1230 storeCtx = X509_STORE_CTX_new();
1231 if (storeCtx == NULL) {
1232 LOGE("Unable to create storeCtx.");
1233 X509_STORE_free(store);
1234 return CF_ERR_MALLOC;
1235 }
1236
1237 if (X509_STORE_CTX_init(storeCtx, store, NULL, NULL) == 0) {
1238 LOGE("Unable to init STORE_CTX.");
1239 ret = CF_ERR_CRYPTO_OPERATION;
1240 goto end;
1241 }
1242
1243 if (X509_STORE_CTX_get1_issuer(issuerCert, storeCtx, leafCert) == -1) {
1244 LOGE("Some other error occurred when getting issuer.");
1245 ret = CF_ERR_CRYPTO_OPERATION;
1246 goto end;
1247 }
1248
1249 end:
1250 X509_STORE_free(store);
1251 X509_STORE_CTX_free(storeCtx);
1252 return ret;
1253 }
1254
GetCertIdInfo(STACK_OF (X509)* x509CertChain,const CfBlob * ocspDigest,OcspCertIdInfo * certIdInfo)1255 static CfResult GetCertIdInfo(STACK_OF(X509) *x509CertChain, const CfBlob *ocspDigest, OcspCertIdInfo *certIdInfo)
1256 {
1257 X509 *issuerCert = NULL;
1258 X509 *leafCert = NULL;
1259 CfResult ret = CF_INVALID_PARAMS;
1260
1261 leafCert = sk_X509_value(x509CertChain, 0);
1262 if (leafCert == NULL) {
1263 LOGE("Get the leaf cert is null.");
1264 return CF_INVALID_PARAMS;
1265 }
1266
1267 ret = GetCertIssuerFromChain(x509CertChain, leafCert, &issuerCert);
1268 if (ret != CF_SUCCESS) {
1269 LOGE("Get cert issuer from chain failed.");
1270 return ret;
1271 }
1272
1273 if (X509_up_ref(leafCert) != 1) {
1274 LOGE("Unable to up ref leaf cert.");
1275 X509_free(issuerCert);
1276 return CF_ERR_CRYPTO_OPERATION;
1277 }
1278
1279 certIdInfo->md = GetHashDigest(ocspDigest);
1280 certIdInfo->subjectCert = leafCert;
1281 certIdInfo->issuerCert = issuerCert;
1282 return CF_SUCCESS;
1283 }
1284
ValidateRevocationOnLine(const HcfX509CertChainValidateParams * params,STACK_OF (X509)* x509CertChain,HcfX509TrustAnchor * trustAnchor,OcspCertIdInfo * certIdInfo)1285 static CfResult ValidateRevocationOnLine(const HcfX509CertChainValidateParams *params, STACK_OF(X509) *x509CertChain,
1286 HcfX509TrustAnchor *trustAnchor, OcspCertIdInfo *certIdInfo)
1287 {
1288 CfResult res = CF_INVALID_PARAMS;
1289 if (ContainsOption(params->revocationCheckParam->options, REVOCATION_CHECK_OPTION_PREFER_OCSP)) {
1290 if ((res = ValidateOcspOnline(x509CertChain, certIdInfo, trustAnchor, params)) == CF_SUCCESS) {
1291 return res;
1292 }
1293 if (ContainsOption(params->revocationCheckParam->options, REVOCATION_CHECK_OPTION_FALLBACK_NO_PREFER)) {
1294 if ((res = ValidateCrlOnline(params, x509CertChain)) == CF_SUCCESS) {
1295 return res;
1296 }
1297 }
1298 if (ContainsOption(params->revocationCheckParam->options, REVOCATION_CHECK_OPTION_FALLBACK_LOCAL)) {
1299 if ((res = ValidateOcspLocal((OcspLocalParam) { .req = NULL, .resp = NULL, .certIdInfo = certIdInfo },
1300 x509CertChain, trustAnchor, params)) == CF_SUCCESS) {
1301 return res;
1302 }
1303 return ValidateCrlLocal(params->certCRLCollections, x509CertChain);
1304 }
1305 } else {
1306 if ((res = ValidateCrlOnline(params, x509CertChain)) == CF_SUCCESS) {
1307 return res;
1308 }
1309 if (ContainsOption(params->revocationCheckParam->options, REVOCATION_CHECK_OPTION_FALLBACK_NO_PREFER)) {
1310 if ((res = ValidateOcspOnline(x509CertChain, certIdInfo, trustAnchor, params)) == CF_SUCCESS) {
1311 return res;
1312 }
1313 }
1314 if (ContainsOption(params->revocationCheckParam->options, REVOCATION_CHECK_OPTION_FALLBACK_LOCAL)) {
1315 if ((res = ValidateCrlLocal(params->certCRLCollections, x509CertChain)) == CF_SUCCESS) {
1316 return res;
1317 }
1318 return ValidateOcspLocal((OcspLocalParam) { .req = NULL, .resp = NULL, .certIdInfo = certIdInfo },
1319 x509CertChain, trustAnchor, params);
1320 }
1321 }
1322 return res;
1323 }
1324
ValidateRevocationLocal(const HcfX509CertChainValidateParams * params,STACK_OF (X509)* x509CertChain,HcfX509TrustAnchor * trustAnchor,OcspCertIdInfo * certIdInfo)1325 static CfResult ValidateRevocationLocal(const HcfX509CertChainValidateParams *params, STACK_OF(X509) *x509CertChain,
1326 HcfX509TrustAnchor *trustAnchor, OcspCertIdInfo *certIdInfo)
1327 {
1328 CfResult res = CF_INVALID_PARAMS;
1329 if (ContainsOption(params->revocationCheckParam->options, REVOCATION_CHECK_OPTION_PREFER_OCSP)) {
1330 if ((res = ValidateOcspLocal((OcspLocalParam) { .req = NULL, .resp = NULL, .certIdInfo = certIdInfo },
1331 x509CertChain, trustAnchor, params)) == CF_SUCCESS) {
1332 return res;
1333 }
1334 } else {
1335 if ((res = ValidateCrlLocal(params->certCRLCollections, x509CertChain)) == CF_SUCCESS) {
1336 return res;
1337 }
1338 }
1339 return CF_INVALID_PARAMS;
1340 }
1341
FreeCertIdInfo(OcspCertIdInfo * certIdInfo)1342 static void FreeCertIdInfo(OcspCertIdInfo *certIdInfo)
1343 {
1344 if (certIdInfo->subjectCert != NULL) {
1345 X509_free(certIdInfo->subjectCert);
1346 }
1347 if (certIdInfo->issuerCert != NULL) {
1348 X509_free(certIdInfo->issuerCert);
1349 }
1350 }
1351
ValidateRevocation(STACK_OF (X509)* x509CertChain,HcfX509TrustAnchor * trustAnchor,const HcfX509CertChainValidateParams * params)1352 static CfResult ValidateRevocation(
1353 STACK_OF(X509) *x509CertChain, HcfX509TrustAnchor *trustAnchor, const HcfX509CertChainValidateParams *params)
1354 {
1355 if (x509CertChain == NULL || params == NULL) {
1356 LOGE("The input data is null!");
1357 return CF_INVALID_PARAMS;
1358 }
1359
1360 if (params->revocationCheckParam && params->revocationCheckParam->options) {
1361 CfResult res = CF_INVALID_PARAMS;
1362 OcspCertIdInfo certIdInfo = {0};
1363 res = GetCertIdInfo(x509CertChain, params->revocationCheckParam->ocspDigest, &certIdInfo);
1364 if (res != CF_SUCCESS) {
1365 LOGE("Get cert id info failed.");
1366 return res;
1367 }
1368 if (ContainsOption(params->revocationCheckParam->options, REVOCATION_CHECK_OPTION_ACCESS_NETWORK)) {
1369 res = ValidateRevocationOnLine(params, x509CertChain, trustAnchor, &certIdInfo);
1370 if (res != CF_SUCCESS) {
1371 LOGE("Try to validate revocation online failed.");
1372 }
1373 } else {
1374 res = ValidateRevocationLocal(params, x509CertChain, trustAnchor, &certIdInfo);
1375 if (res != CF_SUCCESS) {
1376 LOGE("Try to validate revocation local failed.");
1377 }
1378 }
1379 FreeCertIdInfo(&certIdInfo);
1380 return res;
1381 } else {
1382 return ValidateCrlLocal(params->certCRLCollections, x509CertChain);
1383 }
1384 }
1385
ValidateDate(const STACK_OF (X509)* x509CertChain,CfBlob * date)1386 static CfResult ValidateDate(const STACK_OF(X509) *x509CertChain, CfBlob *date)
1387 {
1388 if (date == NULL) {
1389 LOGI("date is null");
1390 return CF_SUCCESS;
1391 }
1392 if (!CfBlobIsStr(date)) {
1393 LOGE("time format is invalid");
1394 return CF_INVALID_PARAMS;
1395 }
1396 ASN1_TIME *asn1InputDate = ASN1_TIME_new();
1397 if (asn1InputDate == NULL) {
1398 LOGE("Failed to malloc for asn1 time.");
1399 return CF_ERR_MALLOC;
1400 }
1401 if (ASN1_TIME_set_string(asn1InputDate, (const char *)date->data) != CF_OPENSSL_SUCCESS) {
1402 LOGE("Failed to set time for asn1 time.");
1403 CfPrintOpensslError();
1404 ASN1_TIME_free(asn1InputDate);
1405 return CF_INVALID_PARAMS;
1406 }
1407 CfResult res = CF_SUCCESS;
1408 int certsNum = sk_X509_num(x509CertChain);
1409 for (int i = 0; i < certsNum; ++i) {
1410 X509 *cert = sk_X509_value(x509CertChain, i);
1411 if (cert == NULL) {
1412 LOGE("sk X509 value is null, failed!");
1413 CfPrintOpensslError();
1414 ASN1_TIME_free(asn1InputDate);
1415 return CF_ERR_CRYPTO_OPERATION;
1416 }
1417 res = CompareDateWithCertTime(cert, asn1InputDate);
1418 if (res != CF_SUCCESS) {
1419 LOGE("check validate failed.");
1420 ASN1_TIME_free(asn1InputDate);
1421 return res;
1422 }
1423 }
1424 ASN1_TIME_free(asn1InputDate);
1425 return res;
1426 }
1427
ValidatePolicy(const STACK_OF (X509)* x509CertChain,HcfValPolicyType policy,CfBlob * sslHostname)1428 static CfResult ValidatePolicy(const STACK_OF(X509) *x509CertChain, HcfValPolicyType policy, CfBlob *sslHostname)
1429 {
1430 CfResult res = CF_SUCCESS;
1431 switch (policy) {
1432 case VALIDATION_POLICY_TYPE_SSL:
1433 if (sslHostname == NULL) {
1434 LOGE("The specified policy is SSL, but sslHostname is null!");
1435 return CF_INVALID_PARAMS;
1436 }
1437 if (!X509_check_host(
1438 sk_X509_value(x509CertChain, 0), (const char *)(sslHostname->data), sslHostname->size, 0, NULL)) {
1439 LOGE("Validate SSL policy failed!");
1440 return CF_ERR_CRYPTO_OPERATION;
1441 }
1442 break;
1443 case VALIDATION_POLICY_TYPE_X509:
1444 res = CF_SUCCESS;
1445 break;
1446 default:
1447 LOGE("Unknown policy type!");
1448 res = CF_INVALID_PARAMS;
1449 break;
1450 }
1451 return res;
1452 }
1453
ValidateUseage(const STACK_OF (X509)* x509CertChain,HcfKuArray * keyUsage)1454 static CfResult ValidateUseage(const STACK_OF(X509) *x509CertChain, HcfKuArray *keyUsage)
1455 {
1456 CfResult res = CF_SUCCESS;
1457 if (keyUsage != NULL) {
1458 X509 *cert = sk_X509_value(x509CertChain, 0);
1459 if (cert == NULL) {
1460 return CF_INVALID_PARAMS;
1461 }
1462 uint32_t count = 0;
1463 for (size_t i = 0; i < keyUsage->count; i++) {
1464 HcfKeyUsageType kuType = keyUsage->data[i];
1465 uint32_t usageFlag = 0;
1466 switch (kuType) {
1467 case KEYUSAGE_DIGITAL_SIGNATURE:
1468 usageFlag = X509v3_KU_DIGITAL_SIGNATURE;
1469 break;
1470 case KEYUSAGE_NON_REPUDIATION:
1471 usageFlag = X509v3_KU_NON_REPUDIATION;
1472 break;
1473 case KEYUSAGE_KEY_ENCIPHERMENT:
1474 usageFlag = X509v3_KU_KEY_ENCIPHERMENT;
1475 break;
1476 case KEYUSAGE_DATA_ENCIPHERMENT:
1477 usageFlag = X509v3_KU_DATA_ENCIPHERMENT;
1478 break;
1479 case KEYUSAGE_KEY_AGREEMENT:
1480 usageFlag = X509v3_KU_KEY_AGREEMENT;
1481 break;
1482 case KEYUSAGE_KEY_CERT_SIGN:
1483 usageFlag = X509v3_KU_KEY_CERT_SIGN;
1484 break;
1485 case KEYUSAGE_CRL_SIGN:
1486 usageFlag = X509v3_KU_CRL_SIGN;
1487 break;
1488 case KEYUSAGE_ENCIPHER_ONLY:
1489 usageFlag = X509v3_KU_ENCIPHER_ONLY;
1490 break;
1491 case KEYUSAGE_DECIPHER_ONLY:
1492 usageFlag = X509v3_KU_DECIPHER_ONLY;
1493 break;
1494 default:
1495 return CF_INVALID_PARAMS;
1496 }
1497 if ((X509_get_key_usage(cert) & usageFlag)) {
1498 count++;
1499 }
1500 }
1501 res = (count == keyUsage->count) ? CF_SUCCESS : CF_ERR_CRYPTO_OPERATION;
1502 }
1503 return res;
1504 }
1505
ValidateStrategies(const HcfX509CertChainValidateParams * params,STACK_OF (X509)* x509CertChain)1506 static CfResult ValidateStrategies(const HcfX509CertChainValidateParams *params, STACK_OF(X509) *x509CertChain)
1507 {
1508 CfResult res = ValidateDate(x509CertChain, params->date);
1509 if (res != CF_SUCCESS) {
1510 LOGE("Validate date failed.");
1511 return res;
1512 }
1513 res = ValidatePolicy(x509CertChain, params->policy, params->sslHostname);
1514 if (res != CF_SUCCESS) {
1515 LOGE("Validate policy failed.");
1516 return res;
1517 }
1518 res = ValidateUseage(x509CertChain, params->keyUsage);
1519 if (res != CF_SUCCESS) {
1520 LOGE("Validate usage failed.");
1521 return res;
1522 }
1523 return res;
1524 }
1525
ValidateOther(const HcfX509CertChainValidateParams * params,STACK_OF (X509)* x509CertChain,HcfX509TrustAnchor ** trustAnchorResult)1526 static CfResult ValidateOther(const HcfX509CertChainValidateParams *params, STACK_OF(X509) *x509CertChain,
1527 HcfX509TrustAnchor **trustAnchorResult)
1528 {
1529 if (sk_X509_num(x509CertChain) < 1) {
1530 LOGE("No cert in the certchain!");
1531 return CF_INVALID_PARAMS;
1532 }
1533 X509 *rootCert = sk_X509_value(x509CertChain, sk_X509_num(x509CertChain) - 1);
1534 if (rootCert == NULL) {
1535 LOGE("Sk X509 value failed!");
1536 CfPrintOpensslError();
1537 return CF_ERR_CRYPTO_OPERATION;
1538 }
1539
1540 CfResult res = ValidateTrustAnchor(params->trustAnchors, rootCert, x509CertChain, trustAnchorResult);
1541 if (res != CF_SUCCESS) {
1542 LOGE("ValidateTrustAnchor failed!");
1543 return res;
1544 }
1545 res = ValidateRevocation(x509CertChain, *trustAnchorResult, params);
1546 if (res != CF_SUCCESS) {
1547 return res;
1548 }
1549 return res;
1550 }
1551
Validate(HcfX509CertChainSpi * self,const HcfX509CertChainValidateParams * params,HcfX509CertChainValidateResult * result)1552 static CfResult Validate(
1553 HcfX509CertChainSpi *self, const HcfX509CertChainValidateParams *params, HcfX509CertChainValidateResult *result)
1554 {
1555 if ((self == NULL) || (params == NULL) || (params->trustAnchors == NULL) || (params->trustAnchors->data == NULL) ||
1556 (params->trustAnchors->count == 0) || (result == NULL)) {
1557 LOGE("The input data is null!");
1558 return CF_INVALID_PARAMS;
1559 }
1560 if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertChainClass())) {
1561 LOGE("Input wrong class type!");
1562 return CF_INVALID_PARAMS;
1563 }
1564 if (!((HcfX509CertChainOpensslImpl *)self)->isOrder) {
1565 LOGE("MisOrder certs chain, verify failed!");
1566 return CF_INVALID_PARAMS;
1567 }
1568
1569 STACK_OF(X509) *x509CertChain = ((HcfX509CertChainOpensslImpl *)self)->x509CertChain;
1570 /* when check time with X509_STORE_CTX_set_time, the noAfter of cert is exclusive, but in RFC5280, it is inclusive,
1571 * so check manually here.
1572 */
1573 CfResult res = ValidateStrategies(params, x509CertChain);
1574 if (res != CF_SUCCESS) {
1575 LOGE("Validate part1 failed!");
1576 return res;
1577 }
1578
1579 HcfX509TrustAnchor *trustAnchorResult = NULL;
1580 res = ValidateOther(params, x509CertChain, &trustAnchorResult);
1581 if (res != CF_SUCCESS) {
1582 LOGE("Validate part2 failed!");
1583 return res;
1584 }
1585 X509 *entityCert = sk_X509_value(x509CertChain, 0);
1586 if (entityCert == NULL) {
1587 CfPrintOpensslError();
1588 return CF_ERR_CRYPTO_OPERATION;
1589 }
1590
1591 return FillValidateResult(trustAnchorResult, entityCert, result);
1592 }
1593
CreateX509CertChainPEM(const CfEncodingBlob * inData,STACK_OF (X509)** certchainObj)1594 static int32_t CreateX509CertChainPEM(const CfEncodingBlob *inData, STACK_OF(X509) **certchainObj)
1595 {
1596 STACK_OF(X509) *certsChain = NULL;
1597 X509 *cert = NULL;
1598
1599 BIO *bio = BIO_new_mem_buf(inData->data, inData->len);
1600 if (bio == NULL) {
1601 LOGE("BIO new mem buf failed!");
1602 CfPrintOpensslError();
1603 return CF_ERR_CRYPTO_OPERATION;
1604 }
1605
1606 /* Create cert chain object */
1607 certsChain = sk_X509_new_null();
1608 if (certsChain == NULL) {
1609 BIO_free(bio);
1610 LOGE("Error creating certificate chain.");
1611 CfPrintOpensslError();
1612 return CF_ERR_CRYPTO_OPERATION;
1613 }
1614
1615 /* Add cert to cert chain object */
1616 while ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) && cert != NULL) {
1617 if (sk_X509_push(certsChain, cert) <= 0) {
1618 LOGE("Memory allocation failure!");
1619 X509_free(cert);
1620 BIO_free(bio);
1621 sk_X509_pop_free(certsChain, X509_free);
1622 return CF_ERR_CRYPTO_OPERATION;
1623 }
1624 LOGI("push cert to certsChain.");
1625 }
1626
1627 if (sk_X509_num(certsChain) == 0) {
1628 LOGE("cert chain size = 0.");
1629 CfPrintOpensslError();
1630 BIO_free(bio);
1631 sk_X509_free(certsChain);
1632 return CF_ERR_CRYPTO_OPERATION;
1633 }
1634
1635 *certchainObj = certsChain;
1636 BIO_free(bio);
1637 return CF_SUCCESS;
1638 }
1639
1640 /*
1641 * create x509 certchain from DER format streams
1642 * input params: inData
1643 * output params: certchainObj
1644 */
CreateX509CertChainDER(const CfEncodingBlob * inData,STACK_OF (X509)** certchainObj)1645 static int32_t CreateX509CertChainDER(const CfEncodingBlob *inData, STACK_OF(X509) **certchainObj)
1646 {
1647 STACK_OF(X509) *certsChain = NULL;
1648 X509 *cert = NULL;
1649 const unsigned char *p = inData->data; // DER data
1650 size_t length = inData->len;
1651
1652 certsChain = sk_X509_new_null();
1653 if (certsChain == NULL) {
1654 LOGE("Error creating certificate chain.");
1655 return CF_ERR_MALLOC;
1656 }
1657
1658 while (p < inData->data + length) {
1659 size_t lengthLeft = (inData->data + length - p);
1660 cert = d2i_X509(NULL, &p, lengthLeft);
1661 if (cert == NULL) {
1662 LOGE("Failed to parse certificate.");
1663 CfPrintOpensslError();
1664 sk_X509_pop_free(certsChain, X509_free);
1665 return CF_ERR_CRYPTO_OPERATION;
1666 }
1667 if (sk_X509_push(certsChain, cert) <= 0) {
1668 LOGE("Memory allocation failure!");
1669 X509_free(cert);
1670 sk_X509_pop_free(certsChain, X509_free);
1671 return CF_ERR_MALLOC;
1672 }
1673 LOGI("push cert to certsChain.");
1674 }
1675
1676 if (sk_X509_num(certsChain) == 0) {
1677 sk_X509_free(certsChain);
1678 LOGE("sk_X509_num failed.");
1679 return CF_INVALID_PARAMS;
1680 }
1681 *certchainObj = certsChain;
1682 return CF_SUCCESS;
1683 }
1684
1685 /*
1686 * create x509 certchain from pkcs#7 streams
1687 * input params: inData
1688 * output params: certchainObj
1689 */
CreateX509CertChainPKCS7(const CfEncodingBlob * inData,STACK_OF (X509)** certchainObj)1690 static CfResult CreateX509CertChainPKCS7(const CfEncodingBlob *inData, STACK_OF(X509) **certchainObj)
1691 {
1692 size_t dataLength = inData->len;
1693 uint8_t *data = inData->data;
1694 BIO *bio = BIO_new_mem_buf(data, dataLength);
1695 if (bio == NULL) {
1696 LOGE("malloc failed");
1697 CfPrintOpensslError();
1698 return CF_ERR_MALLOC;
1699 }
1700
1701 PKCS7 *pkcs7 = d2i_PKCS7_bio(bio, NULL); // DER format .p7b file
1702 if (pkcs7 == NULL) {
1703 LOGE("Failed to parse PKCS7 data.");
1704 BIO_free(bio);
1705 CfPrintOpensslError();
1706 return CF_ERR_CRYPTO_OPERATION;
1707 }
1708
1709 /* Get cert chain from pkcs7 object */
1710 STACK_OF(X509) *oriCertsChain = NULL;
1711 int i = OBJ_obj2nid(pkcs7->type);
1712 if (i == NID_pkcs7_signed && pkcs7->d.sign != NULL) {
1713 oriCertsChain = pkcs7->d.sign->cert;
1714 } else if (i == NID_pkcs7_signedAndEnveloped && pkcs7->d.signed_and_enveloped != NULL) {
1715 oriCertsChain = pkcs7->d.signed_and_enveloped->cert;
1716 }
1717
1718 if (oriCertsChain == NULL || sk_X509_num(oriCertsChain) == 0) {
1719 LOGE("Failed to get certchain object.");
1720 PKCS7_free(pkcs7);
1721 BIO_free(bio);
1722 return CF_ERR_CRYPTO_OPERATION;
1723 }
1724
1725 /* Clone a cert chain object for free pkcs7 object */
1726 STACK_OF(X509) *certsChain = sk_X509_deep_copy(oriCertsChain, X509_dup, X509_free);
1727 if (certsChain == NULL) {
1728 PKCS7_free(pkcs7);
1729 BIO_free(bio);
1730 LOGE("deep clone cert chain failed.");
1731 CfPrintOpensslError();
1732 return CF_ERR_CRYPTO_OPERATION;
1733 }
1734 *certchainObj = certsChain;
1735 PKCS7_free(pkcs7);
1736 BIO_free(bio);
1737 return CF_SUCCESS;
1738 }
1739
CreateX509CertChainInner(const CfEncodingBlob * inData,STACK_OF (X509)** certchainObj)1740 static int32_t CreateX509CertChainInner(const CfEncodingBlob *inData, STACK_OF(X509) **certchainObj)
1741 {
1742 int32_t ret = CF_SUCCESS;
1743 if (inData->encodingFormat == CF_FORMAT_PKCS7) {
1744 ret = CreateX509CertChainPKCS7(inData, certchainObj);
1745 } else if (inData->encodingFormat == CF_FORMAT_DER) {
1746 // create certchain from CF_FORMAT_DER
1747 ret = CreateX509CertChainDER(inData, certchainObj);
1748 } else if (inData->encodingFormat == CF_FORMAT_PEM) {
1749 // create certchain from CF_FORMAT_PEM
1750 ret = CreateX509CertChainPEM(inData, certchainObj);
1751 } else {
1752 LOGE("invalid input params");
1753 return CF_INVALID_PARAMS;
1754 }
1755
1756 if (ret != CF_SUCCESS) {
1757 LOGE("error happened");
1758 return ret;
1759 }
1760
1761 int num = sk_X509_num(*certchainObj);
1762 if (num > MAX_CERT_NUM || num == 0) {
1763 LOGE("certchain certs number :%d invalid. create certChain failed! ", num);
1764 sk_X509_pop_free(*certchainObj, X509_free);
1765 *certchainObj = NULL;
1766 return CF_INVALID_PARAMS;
1767 }
1768
1769 return CF_SUCCESS;
1770 }
1771
HcfX509CertChainByEncSpiCreate(const CfEncodingBlob * inStream,HcfX509CertChainSpi ** spi)1772 CfResult HcfX509CertChainByEncSpiCreate(const CfEncodingBlob *inStream, HcfX509CertChainSpi **spi)
1773 {
1774 int32_t ret = CF_SUCCESS;
1775 if (inStream == NULL || inStream->data == NULL || inStream->len == 0 || spi == NULL) {
1776 LOGE("HcfX509CertChainByEncSpiCreate(), Invalid params!");
1777 return CF_INVALID_PARAMS;
1778 }
1779 HcfX509CertChainOpensslImpl *certChain =
1780 (HcfX509CertChainOpensslImpl *)CfMalloc(sizeof(HcfX509CertChainOpensslImpl), 0);
1781 if (certChain == NULL) {
1782 LOGE("Failed to allocate certChain spi object memory!");
1783 return CF_ERR_MALLOC;
1784 }
1785
1786 ret = CreateX509CertChainInner(inStream, &(certChain->x509CertChain));
1787 if (ret != CF_SUCCESS || certChain->x509CertChain == NULL) {
1788 CfFree(certChain);
1789 LOGE("Failed to create x509 cert chain");
1790 return CF_INVALID_PARAMS;
1791 }
1792 bool isOrder = true;
1793 ret = IsOrderCertChain(certChain->x509CertChain, &isOrder);
1794 if (ret != CF_SUCCESS) {
1795 LOGE("cert chain isOrder failed!");
1796 sk_X509_pop_free(certChain->x509CertChain, X509_free);
1797 CfFree(certChain);
1798 return ret;
1799 }
1800
1801 certChain->isOrder = isOrder;
1802 certChain->base.base.getClass = GetX509CertChainClass;
1803 certChain->base.base.destroy = DestroyX509CertChain;
1804 certChain->base.engineGetCertList = GetCertlist;
1805 certChain->base.engineValidate = Validate;
1806 certChain->base.engineToString = CfToString;
1807 certChain->base.engineHashCode = CfHashCode;
1808 *spi = (HcfX509CertChainSpi *)certChain;
1809 return CF_SUCCESS;
1810 }
1811
GetCertsStack(const HcfX509CertificateArray * inCerts,STACK_OF (X509)* certsStack)1812 static CfResult GetCertsStack(const HcfX509CertificateArray *inCerts, STACK_OF(X509) *certsStack)
1813 {
1814 for (uint32_t i = 0; i < inCerts->count; ++i) {
1815 X509 *cert = GetX509FromHcfX509Certificate((HcfCertificate *)inCerts->data[i]);
1816 if (cert == NULL) {
1817 LOGE("GetX509Cert from encodedBlob failed!");
1818 return CF_INVALID_PARAMS;
1819 }
1820
1821 X509 *certDup = X509_dup(cert);
1822 if (certDup == NULL) {
1823 LOGE("Memory allocation failure!");
1824 return CF_ERR_MALLOC;
1825 }
1826
1827 if (sk_X509_push(certsStack, certDup) <= 0) {
1828 LOGE("Memory allocation failure!");
1829 X509_free(certDup);
1830 return CF_ERR_MALLOC;
1831 }
1832 }
1833
1834 return CF_SUCCESS;
1835 }
1836
HcfX509CertChainByArrSpiCreate(const HcfX509CertificateArray * inCerts,HcfX509CertChainSpi ** spi)1837 CfResult HcfX509CertChainByArrSpiCreate(const HcfX509CertificateArray *inCerts, HcfX509CertChainSpi **spi)
1838 {
1839 if (spi == NULL || inCerts == NULL || inCerts->data == NULL || inCerts->count == 0 ||
1840 inCerts->count > MAX_CERT_NUM) {
1841 LOGE("Invalid params, is null!");
1842 return CF_INVALID_PARAMS;
1843 }
1844
1845 HcfX509CertChainOpensslImpl *certChain =
1846 (HcfX509CertChainOpensslImpl *)CfMalloc(sizeof(HcfX509CertChainOpensslImpl), 0);
1847 if (certChain == NULL) {
1848 LOGE("Failed to allocate certChain spi object memory!");
1849 return CF_ERR_MALLOC;
1850 }
1851
1852 STACK_OF(X509) *certsStack = sk_X509_new_null();
1853 if (certsStack == NULL) {
1854 LOGE("Error creating certificate chain.");
1855 CfFree(certChain);
1856 return CF_ERR_MALLOC;
1857 }
1858
1859 CfResult res = GetCertsStack(inCerts, certsStack);
1860 if (res != CF_SUCCESS) {
1861 LOGE("Get Certs Stack failed!");
1862 sk_X509_pop_free(certsStack, X509_free);
1863 CfFree(certChain);
1864 return res;
1865 }
1866
1867 bool isOrder = true;
1868 res = IsOrderCertChain(certsStack, &isOrder);
1869 if (res != CF_SUCCESS) {
1870 LOGE("cert chain isOrder failed!");
1871 sk_X509_pop_free(certsStack, X509_free);
1872 CfFree(certChain);
1873 return res;
1874 }
1875
1876 certChain->isOrder = isOrder;
1877 certChain->x509CertChain = certsStack;
1878 certChain->base.base.getClass = GetX509CertChainClass;
1879 certChain->base.base.destroy = DestroyX509CertChain;
1880 certChain->base.engineGetCertList = GetCertlist;
1881 certChain->base.engineValidate = Validate;
1882 certChain->base.engineToString = CfToString;
1883 certChain->base.engineHashCode = CfHashCode;
1884 *spi = (HcfX509CertChainSpi *)certChain;
1885
1886 return CF_SUCCESS;
1887 }
1888
ValidatCertChainX509(STACK_OF (X509)* x509CertChain,HcfX509CertChainValidateParams params)1889 bool ValidatCertChainX509(STACK_OF(X509) * x509CertChain, HcfX509CertChainValidateParams params)
1890 {
1891 CfResult res = ValidateDate(x509CertChain, params.date);
1892 if (res != CF_SUCCESS) {
1893 return false;
1894 }
1895 X509 *rootCert = sk_X509_value(x509CertChain, sk_X509_num(x509CertChain) - 1);
1896 if (rootCert == NULL) {
1897 return false;
1898 }
1899 HcfX509TrustAnchor *trustAnchorResult = NULL;
1900 if (ValidateTrustAnchor(params.trustAnchors, rootCert, x509CertChain, &trustAnchorResult) != CF_SUCCESS) {
1901 return false;
1902 }
1903 if (ValidateCrlLocal(params.certCRLCollections, x509CertChain) != CF_SUCCESS) {
1904 return false;
1905 }
1906 return true;
1907 }
1908
PopFreeCerts(STACK_OF (X509)* allCerts,STACK_OF (X509)* leafCerts)1909 static void PopFreeCerts(STACK_OF(X509) *allCerts, STACK_OF(X509) *leafCerts)
1910 {
1911 sk_X509_pop_free(allCerts, X509_free);
1912 sk_X509_pop_free(leafCerts, X509_free);
1913 }
1914
PackCertChain(const HcfX509CertChainBuildParameters * inParams,STACK_OF (X509)* out)1915 static CfResult PackCertChain(const HcfX509CertChainBuildParameters *inParams, STACK_OF(X509) * out)
1916 {
1917 STACK_OF(X509) *allCerts = sk_X509_new_null();
1918 STACK_OF(X509) *leafCerts = sk_X509_new_null();
1919 if (allCerts == NULL || leafCerts == NULL) {
1920 sk_X509_free(allCerts);
1921 sk_X509_free(leafCerts);
1922 return CF_ERR_CRYPTO_OPERATION;
1923 }
1924 CfResult res = GetLeafCertsFromCertStack(inParams, allCerts, leafCerts);
1925 if (res != CF_SUCCESS) {
1926 PopFreeCerts(allCerts, leafCerts);
1927 return res;
1928 }
1929
1930 int allCertsLen = sk_X509_num(allCerts);
1931 int leafCertsLen = sk_X509_num(leafCerts);
1932
1933 for (int i = 0; i < leafCertsLen; i++) {
1934 X509 *leafCert = sk_X509_value(leafCerts, i);
1935 if (CheckIsSelfSigned(leafCert)) {
1936 sk_X509_push(out, X509_dup(leafCert));
1937 if (ValidatCertChainX509(out, inParams->validateParameters)) {
1938 PopFreeCerts(allCerts, leafCerts);
1939 return CF_SUCCESS;
1940 }
1941 } else {
1942 sk_X509_push(out, X509_dup(leafCert));
1943 X509_NAME *issuerName = X509_get_issuer_name(leafCert);
1944 X509 *ca = FindCertificateBySubject(allCerts, issuerName);
1945
1946 int depth = 0;
1947 int maxdepth = inParams->maxlength < 0 ? allCertsLen : inParams->maxlength;
1948 while (ca && (depth < maxdepth)) {
1949 sk_X509_push(out, X509_dup(ca));
1950 issuerName = X509_get_issuer_name(ca);
1951 ca = FindCertificateBySubject(allCerts, issuerName);
1952 depth++;
1953 }
1954 if (ValidatCertChainX509(out, inParams->validateParameters)) {
1955 PopFreeCerts(allCerts, leafCerts);
1956 return CF_SUCCESS;
1957 }
1958 }
1959
1960 while (sk_X509_num(out) > 0) {
1961 X509_free(sk_X509_pop(out));
1962 }
1963 }
1964 PopFreeCerts(allCerts, leafCerts);
1965 return CF_INVALID_PARAMS;
1966 }
1967
HcfX509CertChainByParamsSpiCreate(const HcfX509CertChainBuildParameters * inParams,HcfX509CertChainSpi ** spi)1968 CfResult HcfX509CertChainByParamsSpiCreate(const HcfX509CertChainBuildParameters *inParams, HcfX509CertChainSpi **spi)
1969 {
1970 if (inParams == NULL || spi == NULL) {
1971 LOGE("Get certchain from js error, the input is null!");
1972 return CF_INVALID_PARAMS;
1973 }
1974
1975 STACK_OF(X509) *certStack = sk_X509_new_null();
1976 if (certStack == NULL) {
1977 LOGE("Failed to new certificate stack.");
1978 return CF_ERR_MALLOC;
1979 }
1980
1981 CfResult res = PackCertChain(inParams, certStack);
1982 if (res != CF_SUCCESS) {
1983 LOGE("Failed to pack certificate chain.");
1984 sk_X509_pop_free(certStack, X509_free);
1985 return res;
1986 }
1987
1988 if (sk_X509_num(certStack) == 0) {
1989 sk_X509_free(certStack);
1990 LOGE("certs chain count = 0.");
1991 return CF_ERR_CERT_HAS_EXPIRED;
1992 }
1993
1994 bool isOrder = true;
1995 res = IsOrderCertChain(certStack, &isOrder);
1996 if (res != CF_SUCCESS) {
1997 LOGE("cert chain isOrder failed!");
1998 sk_X509_pop_free(certStack, X509_free);
1999 return res;
2000 }
2001
2002 HcfX509CertChainOpensslImpl *certChain =
2003 (HcfX509CertChainOpensslImpl *)CfMalloc(sizeof(HcfX509CertChainOpensslImpl), 0);
2004 if (certChain == NULL) {
2005 LOGE("Failed to allocate certChain spi object memory!");
2006 return CF_ERR_MALLOC;
2007 }
2008 certChain->isOrder = isOrder;
2009 certChain->x509CertChain = certStack;
2010 certChain->base.base.getClass = GetX509CertChainClass;
2011 certChain->base.base.destroy = DestroyX509CertChain;
2012 certChain->base.engineGetCertList = GetCertlist;
2013 certChain->base.engineValidate = Validate;
2014 *spi = (HcfX509CertChainSpi *)certChain;
2015
2016 return res;
2017 }
2018
ProcessP12Data(STACK_OF (X509)* ca,HcfX509TrustAnchorArray * result)2019 static void ProcessP12Data(STACK_OF(X509) *ca, HcfX509TrustAnchorArray *result)
2020 {
2021 for (int i = 0; i < sk_X509_num(ca); i++) {
2022 X509 *x509 = sk_X509_value(ca, i);
2023 // CACert
2024 if (X509ToHcfX509Certificate(x509, &(result->data[i]->CACert)) != CF_SUCCESS) {
2025 LOGD("Failed to get %d CACert!", i);
2026 }
2027
2028 // CAPubKey
2029 if (GetPubKeyDataFromX509(x509, &(result->data[i]->CAPubKey)) != CF_SUCCESS) {
2030 LOGD("Failed to get %d CAPubKey!", i);
2031 }
2032
2033 // CASubject
2034 if (GetSubjectNameFromX509(x509, &(result->data[i]->CASubject)) != CF_SUCCESS) {
2035 LOGD("Failed to get %d CASubject!", i);
2036 }
2037
2038 // nameConstraints
2039 if (GetNameConstraintsFromX509(x509, &(result->data[i]->nameConstraints)) != CF_SUCCESS) {
2040 LOGD("Failed to get %d nameConstraints!", i);
2041 }
2042 }
2043 }
2044
FreeHcfX509TrustAnchorArrayInner(HcfX509TrustAnchorArray * trustAnchorArray)2045 static void FreeHcfX509TrustAnchorArrayInner(HcfX509TrustAnchorArray *trustAnchorArray)
2046 {
2047 if (trustAnchorArray == NULL) {
2048 return;
2049 }
2050 if (trustAnchorArray->data != NULL) {
2051 for (uint32_t i = 0; i < trustAnchorArray->count; i++) {
2052 if (trustAnchorArray->data[i] != NULL) {
2053 CfObjDestroy(trustAnchorArray->data[i]->CACert);
2054 trustAnchorArray->data[i]->CACert = NULL;
2055 CfBlobFree(&trustAnchorArray->data[i]->CAPubKey);
2056 CfBlobFree(&trustAnchorArray->data[i]->CASubject);
2057 CfBlobFree(&trustAnchorArray->data[i]->nameConstraints);
2058 CfFree(trustAnchorArray->data[i]);
2059 trustAnchorArray->data[i] = NULL;
2060 }
2061 }
2062 CfFree(trustAnchorArray->data);
2063 }
2064 }
2065
STACK_OF(X509)2066 static STACK_OF(X509) *GetCaFromP12(const CfBlob *keyStore, const CfBlob *pwd)
2067 {
2068 X509 *cert = NULL;
2069 EVP_PKEY *pkey = NULL;
2070 STACK_OF(X509) *caStack = NULL;
2071 PKCS12 *p12 = NULL;
2072 const unsigned char *in = (const unsigned char *)(keyStore->data);
2073
2074 p12 = d2i_PKCS12(NULL, &in, keyStore->size);
2075 if (p12 == NULL) {
2076 LOGE("Error convert pkcs12 data to inner struct!");
2077 CfPrintOpensslError();
2078 return NULL;
2079 }
2080
2081 int ret = PKCS12_parse(p12, (const char *)pwd->data, &pkey, &cert, &caStack);
2082 PKCS12_free(p12);
2083 if (ret != 1) {
2084 LOGE("PKCS12_parse failed!");
2085 CfPrintOpensslError();
2086 return NULL;
2087 }
2088
2089 EVP_PKEY_free(pkey);
2090 if (cert == NULL) {
2091 LOGE("P12 dose not have a cert!");
2092 sk_X509_pop_free(caStack, X509_free);
2093 return NULL;
2094 }
2095 X509_free(cert);
2096
2097 if (caStack == NULL) {
2098 LOGE("P12 dose not have ca!");
2099 }
2100 return caStack;
2101 }
2102
MallocTrustAnchorArray(int32_t count)2103 static HcfX509TrustAnchorArray *MallocTrustAnchorArray(int32_t count)
2104 {
2105 HcfX509TrustAnchorArray *anchor = (HcfX509TrustAnchorArray *)(CfMalloc(sizeof(HcfX509TrustAnchorArray), 0));
2106 if (anchor == NULL) {
2107 LOGE("Failed to allocate trustAnchorArray memory!");
2108 return NULL;
2109 }
2110
2111 anchor->count = count;
2112 anchor->data = (HcfX509TrustAnchor **)(CfMalloc(anchor->count * sizeof(HcfX509TrustAnchor *), 0));
2113 if (anchor->data == NULL) {
2114 LOGE("Failed to allocate data memory!");
2115 CfFree(anchor);
2116 return NULL;
2117 }
2118
2119 for (uint32_t i = 0; i < anchor->count; i++) {
2120 anchor->data[i] = (HcfX509TrustAnchor *)(CfMalloc(sizeof(HcfX509TrustAnchor), 0));
2121 if (anchor->data[i] == NULL) {
2122 LOGE("Failed to allocate data memory!");
2123 FreeHcfX509TrustAnchorArrayInner(anchor);
2124 CfFree(anchor);
2125 return NULL;
2126 }
2127 }
2128 return anchor;
2129 }
2130
HcfX509CreateTrustAnchorWithKeyStoreFunc(const CfBlob * keyStore,const CfBlob * pwd,HcfX509TrustAnchorArray ** trustAnchorArray)2131 CfResult HcfX509CreateTrustAnchorWithKeyStoreFunc(
2132 const CfBlob *keyStore, const CfBlob *pwd, HcfX509TrustAnchorArray **trustAnchorArray)
2133 {
2134 if (keyStore == NULL || pwd == NULL || trustAnchorArray == NULL) {
2135 LOGE("Invalid params!");
2136 return CF_INVALID_PARAMS;
2137 }
2138
2139 STACK_OF(X509) *ca = GetCaFromP12(keyStore, pwd);
2140 if (ca == NULL) {
2141 return CF_ERR_CRYPTO_OPERATION;
2142 }
2143
2144 int32_t count = sk_X509_num(ca);
2145 if (count <= 0) {
2146 LOGE("P12 ca num is 0!");
2147 sk_X509_pop_free(ca, X509_free);
2148 return CF_ERR_CRYPTO_OPERATION;
2149 }
2150
2151 HcfX509TrustAnchorArray *anchor = MallocTrustAnchorArray(count);
2152 if (anchor == NULL) {
2153 sk_X509_pop_free(ca, X509_free);
2154 return CF_ERR_MALLOC;
2155 }
2156
2157 ProcessP12Data(ca, anchor);
2158 *trustAnchorArray = anchor;
2159 anchor = NULL;
2160 sk_X509_pop_free(ca, X509_free);
2161 return CF_SUCCESS;
2162 }
2163