2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 // Licensed under the Apache License, Version 2.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
18 * @file FSecCert_CertChain.cpp
19 * @brief This file contains implementation of X509 Certificate Chains.
30 #include <openssl/x509.h>
31 #include <openssl/x509_vfy.h>
32 #include <FBaseSysLog.h>
33 #include <FBaseByteBuffer.h>
34 #include <FBaseResult.h>
35 #include "FSecCert_CertChain.h"
36 #include "FSecCert_CertDbManager.h"
38 namespace Tizen { namespace Security { namespace Cert
41 _CertChain::_CertChain(void)
44 , __certFormat(_CERT_X509)
45 , __rootCertType(_CERT_TYPE_NOT_BOUNDED)
46 , __contextType(_CERT_CONTEXT_CERT)
47 , __checkValidity(true)
49 __certChain.Construct();
52 _CertChain::~_CertChain(void)
58 _CertChain::Clear(void)
60 __certChain.RemoveAll(true);
64 _CertChain::AddCertificate(_CertFormat certFormat, char* pFileName) //added pCert format
68 SysTryReturnResult(NID_SEC_CERT, pFileName != null, E_INVALID_ARG, "Input file path is null.");
69 SysTryReturnResult(NID_SEC_CERT, certFormat == _CERT_X509, E_INVALID_ARG, "Input cert format is not X509.");
71 std::unique_ptr< _X509Certificate > pCert(new (std::nothrow) _X509Certificate());
72 SysTryReturnResult(NID_SEC_CERT, pCert != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
74 r = pCert->Parse(pFileName);
75 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Parsing of certificate failed.", GetErrorMessage(r));
77 r = __certChain.Add(*pCert.release());
78 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[r] Failed to add certificate in chain.", GetErrorMessage(r));
79 __certFormat = certFormat;
85 _CertChain::AddCertificate(_CertFormat certFormat, byte* pBuf, int bufSize) //added certFormat
89 SysTryReturnResult(NID_SEC_CERT, pBuf != null, E_INVALID_ARG, "Invalid input certificate buffer, input buffer must not be null.");
91 SysTryReturnResult(NID_SEC_CERT, certFormat == _CERT_X509, E_INVALID_ARG, "Input cert format is not X509.");
93 std::unique_ptr< _X509Certificate > pCert(new (std::nothrow) _X509Certificate());
94 SysTryReturnResult(NID_SEC_CERT, pCert != null, E_OUT_OF_MEMORY, "Failed to allocate memory");
96 r = pCert->Parse(pBuf, bufSize);
97 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Parsing of certificate failed.", GetErrorMessage(r));
99 r = __certChain.Add(*pCert.release());
100 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[r] Failed to add certificatein chain.", GetErrorMessage(r));
102 __certFormat = certFormat;
108 _CertChain::AddCertificate(_X509Certificate* pCert)
110 result r = E_SUCCESS;
112 SysTryReturnResult(NID_SEC_CERT, pCert != null, E_INVALID_ARG, "Invalid input certificate buffer, input buffer must not be null.");
114 r = __certChain.Add(*pCert);
115 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to add certificate in chain.", GetErrorMessage(r));
117 __certFormat = _CERT_X509;
123 _CertChain::AddPrivateKey(char* pPKeyPath)
125 SysTryReturnResult(NID_SEC_CERT, pPKeyPath != null, E_INVALID_ARG, "Input key buffer is null.");
127 __pPrivateKey.reset(null);
129 __pPrivateKey = std::unique_ptr< _CertPrivateKeyInfo >(new (std::nothrow) _CertPrivateKeyInfo(pPKeyPath));
130 SysTryReturnResult(NID_SEC_CERT, __pPrivateKey != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
136 _CertChain::AddPrivateKey(byte* pBuf, int bufSize)
138 SysTryReturnResult(NID_SEC_CERT, pBuf != null, E_INVALID_ARG, "Input parameters are not correct.");
139 SysTryReturnResult(NID_SEC_CERT, bufSize > 0, E_INVALID_ARG, "Input buffer size must be greater than zero.");
141 __pPrivateKey.reset(null);
143 __pPrivateKey = std::unique_ptr< _CertPrivateKeyInfo >(new (std::nothrow) _CertPrivateKeyInfo(pBuf, bufSize));
144 SysTryReturnResult(NID_SEC_CERT, __pPrivateKey != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
150 _CertChain::GetPrivateKey(void)
152 return __pPrivateKey.get();
156 _CertChain::MoveNext(void)
158 SysTryReturnResult(NID_SEC_CERT, __certChain.GetCount() > 0, E_SYSTEM, "No certificate is present in chain, failed to move to tail of certificate chain.");
159 SysTryReturnResult(NID_SEC_CERT, __pos < (__certChain.GetCount() - 1), E_SYSTEM, "Position is at last certificate, failed to move to next certificate in chain.");
166 _CertChain::MovePrev(void)
168 SysTryReturnResult(NID_SEC_CERT, __pos > 0, E_SYSTEM, "Position is already at zero, failed to move to previous certificate in chain.");
174 _CertChain::MoveHead(void)
181 _CertChain::MoveTail(void)
183 SysTryReturnResult(NID_SEC_CERT, __certChain.GetCount() > 0, E_SYSTEM, "No certificate is present in chain, failed to move to tail of certificate chain.");
184 __pos = __certChain.GetCount() - 1;
190 _CertChain::GetCertTypeByDomain(void)
194 switch (__rootCertType)
196 case _CERT_TYPE_SIM_ROOT_DOMAIN1:
198 case _CERT_TYPE_ROOT_DOMAIN1:
200 case _CERT_TYPE_DEV_ROOT_DOMAIN1:
201 r = _CERT_DOMAIN1_TRUSTED;
204 case _CERT_TYPE_ROOT_DOMAIN2:
206 case _CERT_TYPE_DEV_ROOT_DOMAIN2:
207 r = _CERT_DOMAIN2_TRUSTED;
210 case _CERT_TYPE_ROOT_DOMAIN3:
212 case _CERT_TYPE_SIM_ROOT_DOMAIN3:
214 case _CERT_TYPE_DEV_ROOT_DOMAIN3:
215 r = _CERT_DOMAIN3_TRUSTED;
219 r = _CERT_WRT_TRUSTED;
223 r = _CERT_INVALID_DOMAIN;
231 _CertChain::GetCurrentCertificate(void)
233 SysTryReturn(NID_SEC_CERT, __certChain.GetCount() > 0, null, E_SYSTEM, "[E_SYSTEM] There is no certifcate present in chain.");
234 SysTryReturn(NID_SEC_CERT, __pos >= 0, null, E_SYSTEM, "[E_SYSTEM] Failed to get certificate object from chain.");
235 return reinterpret_cast< _X509Certificate* >(__certChain.GetAt(__pos));
240 _CertChain::Verify(void)
242 result r = E_SUCCESS;
243 const unsigned char* pCertContent = null;
245 int certCount = __certChain.GetCount();
246 STACK_OF(X509)* pTrustedChain = null;
247 STACK_OF(X509)* pInterimChain = null;
248 X509_STORE_CTX* pStoreCtx = NULL;
249 byte* pCertBuffer = null;
250 _X509Certificate* pCert = null;
251 X509** ppInterimCerts = null;
252 X509* pX509UserCert = null;
254 SysTryReturnResult(NID_SEC_CERT, certCount > 0, E_SYSTEM, "No certificates are present in certificate chain.");
255 SysTryReturnResult(NID_SEC_CERT, __certFormat == _CERT_X509, E_SYSTEM, "Certificate chain is not of type X509.");
257 pCert = reinterpret_cast< _X509Certificate* >(__certChain.GetAt(0));
258 SysTryReturnResult(NID_SEC_CERT, pCert != null, E_SYSTEM, "Failed to get first certificate in chain.");
260 certCount--; //user certificate is added.
262 if (certCount == 0) //only root cert to verify
264 SysTryReturnResult(NID_SEC_CERT, pCert->IsSelfSigned(), E_DATA_NOT_FOUND, "Failed to get root certificate in chain.");
265 return pCert->VerifySignature(null, 0);
268 pCert->GetCertBuffer(pCertBuffer, certSize);
269 SysTryReturnResult(NID_SEC_CERT, pCertBuffer != null, E_SYSTEM, "Failed to get encoded buffer of first certificate.");
271 pCertContent = const_cast< const unsigned char* >(pCertBuffer);
273 d2i_X509(&pX509UserCert, &pCertContent, certSize);
274 SysTryReturnResult(NID_SEC_CERT, pX509UserCert != null, E_SYSTEM, "Failed to parse user certificate.");
276 pTrustedChain = sk_X509_new_null();
277 SysTryCatch(NID_SEC_CERT, pTrustedChain != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY]Failed to allocate trusted root ca certificate chain.");
279 pInterimChain = sk_X509_new_null();
280 SysTryCatch(NID_SEC_CERT, pInterimChain != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY]Failed to allocate intermediate ca certificate chain.");
282 ppInterimCerts = (X509**) new X509*[certCount];
283 memset(ppInterimCerts, 0, (sizeof(X509*) * certCount));
285 for (int i = 0; i < certCount; i++)
291 pCert = reinterpret_cast< _X509Certificate* >(__certChain.GetAt(i + 1));
292 SysTryCatch(NID_SEC_CERT, pCert != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to get certificate at index (%d).", i + 1);
294 pCert->GetCertBuffer(pCertBuffer, certSize);
295 SysTryCatch(NID_SEC_CERT, pCertBuffer != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to get buffer of certificate at index (%d).", i + 1);
297 pCertContent = const_cast< const unsigned char* >(pCertBuffer);
299 d2i_X509(&ppInterimCerts[i], &pCertContent, certSize);
300 SysTryCatch(NID_SEC_CERT, ppInterimCerts[i] != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to parse certificate at index (%d).", i + 1);
302 if (pCert->IsSelfSigned())
305 // insert root certificate into trusted chain
306 if (!(sk_X509_push(pTrustedChain, ppInterimCerts[i])))
308 SysLog(NID_SEC_CERT, "Fail to push root ca certificate into openssl stack.");
315 if (!(sk_X509_push(pInterimChain, ppInterimCerts[i])))
317 SysLog(NID_SEC_CERT, "Fail to push intermediate ca certificate into openssl stack.");
325 SysTryCatch(NID_SEC_CERT, sk_X509_num(pTrustedChain) > 0, r = E_DATA_NOT_FOUND, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] Failed to get root certificate in chain.");
327 // initialize store and store context
328 pStoreCtx = X509_STORE_CTX_new();
330 // construct store context
331 if (!X509_STORE_CTX_init(pStoreCtx, 0, pX509UserCert, pInterimChain))
333 SysLog(NID_SEC_CERT, "Fail to initialize X509 store context.");
338 X509_STORE_CTX_trusted_stack(pStoreCtx, pTrustedChain);
341 if (X509_verify_cert(pStoreCtx) != 1)
343 SysLog(NID_SEC_CERT, "Fail to verify certificate chain.");
344 switch (X509_STORE_CTX_get_error(pStoreCtx))
346 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
347 r = E_DATA_NOT_FOUND;
350 case X509_V_ERR_CERT_HAS_EXPIRED:
352 case X509_V_ERR_CERT_NOT_YET_VALID:
353 r = E_INVALID_CERTIFICATE;
356 case X509_V_ERR_CERT_SIGNATURE_FAILURE:
357 r = E_CERTIFICATE_VERIFICATION_FAILED;
364 SysLog(NID_SEC_CERT, "error number = %d", X509_STORE_CTX_get_error(pStoreCtx));
371 if (ppInterimCerts != null)
373 for (int i = 0; i < certCount; i++)
375 if (ppInterimCerts[i] != null)
377 X509_free(ppInterimCerts[i]);
381 delete[] ppInterimCerts;
384 if (pX509UserCert != null)
386 X509_free(pX509UserCert);
389 if (pStoreCtx != null)
391 X509_STORE_CTX_free(pStoreCtx);
394 if (pTrustedChain != null)
396 sk_X509_free(pTrustedChain);
399 if (pInterimChain != null)
401 sk_X509_free(pInterimChain);
408 _CertChain::VerifyUsingOpenSsl(void)
410 result r = E_SUCCESS;
415 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "No certificate is present in certificate chain, failed to validate certificate chain.");
417 if (__certFormat == _CERT_X509)
419 _X509Certificate* pCert = null;
420 _X509Certificate* pPrevCert = null;
421 _X509TbsCert* pTbsCert = null;
422 _X509TbsCert* pPrevTbsCert = null;
426 pPrevCert = GetCurrentCertificate();
427 SysTryReturnResult(NID_SEC_CERT, pPrevCert != null, E_SYSTEM, "Failed to get root certificate from chain, broken certificate chain.");
429 if (pPrevCert->IsSelfSigned())
431 // rootCA self verify
434 pPrevTbsCert = pPrevCert->GetTbsCertInstance();
435 SysTryReturnResult(NID_SEC_CERT, pPrevTbsCert != null, E_SYSTEM, "Failed to get root certificate to be signed instance.");
437 r = pPrevTbsCert->GetValidity();
438 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_INVALID_CERTIFICATE, "Root certificate validation failed (subject name: %s).", pPrevTbsCert->GetSubjectName());
441 r = pPrevCert->VerifySignature(null, 0);
442 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_CERTIFICATE_VERIFICATION_FAILED, "Root certificate signature verification failed (subject name: %s).", pPrevTbsCert->GetSubjectName());
446 if (MoveNext() == E_SUCCESS)
448 pPrevCert = GetCurrentCertificate();
454 while (MovePrev() == E_SUCCESS);
456 while (MovePrev() == E_SUCCESS)
461 pCert = GetCurrentCertificate();
462 SysTryReturnResult(NID_SEC_CERT, pCert != null, E_SYSTEM, "Failed to get certificate from chain, broken certificate chain.");
464 pPrevTbsCert = pPrevCert->GetTbsCertInstance();
465 SysTryReturnResult(NID_SEC_CERT, pPrevTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
467 pTbsCert = pCert->GetTbsCertInstance();
468 SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
472 r = pPrevTbsCert->GetValidity();
473 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_INVALID_CERTIFICATE, "Certificate validation failed (subject name: %s).", pPrevTbsCert->GetSubjectName());
477 SysTryReturnResult(NID_SEC_CERT, pCert->IsIssuer(pPrevCert), E_SYSTEM, "Certificate is not in sorted order or parent certificate is missing in chain, certificate chain is broken (subject name: %s).", pPrevTbsCert->GetSubjectName());
479 r = pPrevTbsCert->GetPublicKeyInfoN(keyLen, &pKey);
480 SysTryReturnResult(NID_SEC_CERT, pKey != null, E_SYSTEM, "Failed to public key from certificate (subject name: %s).", pPrevTbsCert->GetSubjectName());
482 std::unique_ptr< byte[] > pKeyAuto(pKey);
484 r = pCert->VerifySignature(pKey, keyLen);
486 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_CERTIFICATE_VERIFICATION_FAILED, "Certificate signature verification failed (subject name: %s).", pTbsCert->GetSubjectName());
496 _CertChain::VerifyCertChainWithDb(void)
498 result r = E_SUCCESS;
499 _CertDbManager* pCertDb = null;
502 _CaCertType certType = _CERT_TYPE_NOT_BOUNDED;
505 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "No certificate is present in certificate chain, failed to validate certificate chain.");
507 pCertDb = _CertDbManager::GetInstance();
508 SysTryReturnResult(NID_SEC_CERT, pCertDb != null, E_SYSTEM, "Failed to get instance of certificate database manager.");
510 if (__certFormat == _CERT_X509)
512 _X509Certificate* pLastCert = null;
513 _X509TbsCert* pTbsCert = null;
514 pLastCert = GetCurrentCertificate();
515 SysTryReturnResult(NID_SEC_CERT, pLastCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
517 if (pLastCert->IsSelfSigned())
519 pCertDb = _CertDbManager::GetInstance();
520 SysTryReturnResult(NID_SEC_CERT, pCertDb != null, E_SYSTEM, "Failed to get instance of certificate database manager.");
522 pTbsCert = pLastCert->GetTbsCertInstance();
523 SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get root certificate to be signed instance.");
525 if (GetContextType() == _CERT_CONTEXT_SSL)
527 certType = _CERT_TYPE_ROOT_CA;
528 __checkValidity = true;
530 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
532 certType = _CERT_TYPE_ROOT_CA_BY_USER;
533 __checkValidity = true;
535 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
536 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetSubjectName());
539 else if (GetContextType() == _CERT_CONTEXT_MIDP || GetContextType() == _CERT_CONTEXT_DOMAIN || GetContextType() == _CERT_CONTEXT_DOMAIN_NO_VALIDITY)
541 if (GetContextType() == _CERT_CONTEXT_DOMAIN_NO_VALIDITY)
543 __checkValidity = false;
547 __checkValidity = true;
550 certType = _CERT_TYPE_ROOT_DOMAIN1;
551 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
553 certType = _CERT_TYPE_ROOT_DOMAIN2;
554 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
556 certType = _CERT_TYPE_ROOT_DOMAIN3;
557 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
559 certType = _CERT_TYPE_DEV_ROOT_DOMAIN1;
560 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
562 certType = _CERT_TYPE_DEV_ROOT_DOMAIN3;
563 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
564 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetSubjectName());
570 else if (GetContextType() == _CERT_CONTEXT_CERT || GetContextType() == _CERT_CONTEXT_CERT_NO_VALIDITY)
572 if (GetContextType() == _CERT_CONTEXT_CERT)
574 __checkValidity = true;
576 else if (GetContextType() == _CERT_CONTEXT_CERT_NO_VALIDITY)
578 __checkValidity = false;
581 certType = _CERT_TYPE_TRUSTED_CA;
583 else if (GetContextType() == _CERT_CONTEXT_OSP_USER || GetContextType() == _CERT_CONTEXT_OSP_USER_NO_VALIDITY)
585 if (GetContextType() == _CERT_CONTEXT_OSP_USER)
587 __checkValidity = true;
589 else if (GetContextType() == _CERT_CONTEXT_OSP_USER_NO_VALIDITY)
591 __checkValidity = false;
594 certType = _CERT_TYPE_ROOT_CA_BY_USER;
596 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
597 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
599 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL1 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL1_NO_VALIDITY)
601 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL1)
603 __checkValidity = true;
605 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL1_NO_VALIDITY)
607 __checkValidity = false;
610 certType = _CERT_TYPE_OSP_CRITICAL1;
612 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
613 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
615 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL2 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL2_NO_VALIDITY)
617 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL2)
619 __checkValidity = true;
621 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL2_NO_VALIDITY)
623 __checkValidity = false;
626 certType = _CERT_TYPE_OSP_CRITICAL2;
627 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
628 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
630 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL3 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL3_NO_VALIDITY)
632 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL3)
634 __checkValidity = true;
636 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL3_NO_VALIDITY)
638 __checkValidity = false;
640 certType = _CERT_TYPE_OSP_CRITICAL3;
642 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
643 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
645 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL4 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL4_NO_VALIDITY)
647 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL4)
649 __checkValidity = true;
651 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL4_NO_VALIDITY)
653 __checkValidity = false;
655 certType = _CERT_TYPE_OSP_CRITICAL4;
657 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
658 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
660 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL5 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL5_NO_VALIDITY)
662 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL5)
664 __checkValidity = true;
666 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL5_NO_VALIDITY)
668 __checkValidity = false;
670 certType = _CERT_TYPE_OSP_CRITICAL5;
672 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
673 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
675 else if (GetContextType() == _CERT_CONTEXT_OSP_PRELOAD_APP || GetContextType() == _CERT_CONTEXT_OSP_PRELOAD_APP_NO_VALIDITY)
677 if (GetContextType() == _CERT_CONTEXT_OSP_PRELOAD_APP)
679 __checkValidity = true;
681 else if (GetContextType() == _CERT_CONTEXT_OSP_PRELOAD_APP_NO_VALIDITY)
683 __checkValidity = false;
685 certType = _CERT_TYPE_OSP_PRELOAD_APP;
687 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
688 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
690 else if (GetContextType() == _CERT_CONTEXT_WRT)
692 __checkValidity = true;
693 certType = _CERT_TYPE_WRT;
695 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
696 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
698 else if (GetContextType() == _CERT_CONTEXT_TK)
700 certType = _CERT_TYPE_ROOT_DOMAIN2;
701 __checkValidity = true;
702 if (!strcmp(_CERT_TK_ISSUER_NAME, reinterpret_cast< const char* >(pTbsCert->GetIssuerName())))
704 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
705 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
709 //if the issuerName of this certificate is not _CERT_TK_ISSUER_NAME then we should return some error
710 SysTryReturnResult(NID_SEC_CERT, false, E_INACCESSIBLE_PATH, "Failed to access specified Path.");
715 SysTryReturnResult(NID_SEC_CERT, false, E_SYSTEM, "Invalid context type.");
719 //Set the format of root certificate
720 __rootCertType = certType;
728 //Otherwise extract root certificate from Db and add in tail and then verify.
729 pTbsCert = pLastCert->GetTbsCertInstance();
730 SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get to be signed object from cerificate.");
733 //If the conetxt type is SSL then root certiifcate should be searched in DefaultROOCACert directory.
734 //It should not search in any other directory
735 //Similarily, if context type is MIDP then root certificate should be searched in Domain1, Domain2 & Domain3 directory.
736 //If not found report error.
737 if (GetContextType() == _CERT_CONTEXT_SSL)
739 certType = _CERT_TYPE_ROOT_CA;
740 __checkValidity = true;
741 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
743 certType = _CERT_TYPE_ROOT_CA_BY_USER;
744 __checkValidity = true;
746 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
747 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
750 else if (GetContextType() == _CERT_CONTEXT_MIDP || GetContextType() == _CERT_CONTEXT_DOMAIN || GetContextType() == _CERT_CONTEXT_DOMAIN_NO_VALIDITY)
752 if (GetContextType() == _CERT_CONTEXT_DOMAIN_NO_VALIDITY)
754 __checkValidity = false;
758 __checkValidity = true;
760 certType = _CERT_TYPE_ROOT_DOMAIN1;
761 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
763 certType = _CERT_TYPE_ROOT_DOMAIN2;
764 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
766 certType = _CERT_TYPE_ROOT_DOMAIN3;
767 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
769 certType = _CERT_TYPE_DEV_ROOT_DOMAIN1;
770 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
772 certType = _CERT_TYPE_DEV_ROOT_DOMAIN3;
774 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
775 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
781 else if (GetContextType() == _CERT_CONTEXT_CERT || GetContextType() == _CERT_CONTEXT_CERT_NO_VALIDITY)
783 if (GetContextType() == _CERT_CONTEXT_CERT)
785 __checkValidity = true;
787 else if (GetContextType() == _CERT_CONTEXT_CERT_NO_VALIDITY)
789 __checkValidity = false;
792 r = pCertDb->FindIssuerCertificateAndTypeN(_CERT_X509, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen, certType);
793 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
795 else if (GetContextType() == _CERT_CONTEXT_OSP_USER || GetContextType() == _CERT_CONTEXT_OSP_USER_NO_VALIDITY)
797 if (GetContextType() == _CERT_CONTEXT_OSP_USER)
799 __checkValidity = true;
801 else if (GetContextType() == _CERT_CONTEXT_OSP_USER_NO_VALIDITY)
803 __checkValidity = false;
805 certType = _CERT_TYPE_ROOT_CA_BY_USER;
807 r = (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen));
808 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
810 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL1 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL1_NO_VALIDITY)
812 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL1)
814 __checkValidity = true;
816 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL1_NO_VALIDITY)
818 __checkValidity = false;
820 certType = _CERT_TYPE_OSP_CRITICAL1;
822 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
823 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
825 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL2 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL2_NO_VALIDITY)
827 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL2)
829 __checkValidity = true;
831 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL2_NO_VALIDITY)
833 __checkValidity = false;
835 certType = _CERT_TYPE_OSP_CRITICAL2;
837 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
838 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
840 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL3 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL3_NO_VALIDITY)
842 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL3)
844 __checkValidity = true;
846 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL3_NO_VALIDITY)
848 __checkValidity = false;
850 certType = _CERT_TYPE_OSP_CRITICAL3;
852 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
853 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
855 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL4 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL4_NO_VALIDITY)
857 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL4)
859 __checkValidity = true;
861 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL4_NO_VALIDITY)
863 __checkValidity = false;
865 certType = _CERT_TYPE_OSP_CRITICAL4;
867 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
868 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
870 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL5 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL5_NO_VALIDITY)
872 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL5)
874 __checkValidity = true;
876 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL5_NO_VALIDITY)
878 __checkValidity = false;
880 certType = _CERT_TYPE_OSP_CRITICAL5;
882 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
883 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
885 else if (GetContextType() == _CERT_CONTEXT_OSP_PRELOAD_APP || GetContextType() == _CERT_CONTEXT_OSP_PRELOAD_APP_NO_VALIDITY)
887 if (GetContextType() == _CERT_CONTEXT_OSP_PRELOAD_APP)
889 __checkValidity = true;
891 else if (GetContextType() == _CERT_CONTEXT_OSP_PRELOAD_APP_NO_VALIDITY)
893 __checkValidity = false;
895 certType = _CERT_TYPE_OSP_PRELOAD_APP;
897 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
898 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
900 else if (GetContextType() == _CERT_CONTEXT_WRT)
902 __checkValidity = true;
903 certType = _CERT_TYPE_WRT;
905 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
906 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
908 else if (GetContextType() == _CERT_CONTEXT_TK)
910 certType = _CERT_TYPE_ROOT_DOMAIN2;
911 __checkValidity = true;
913 if (!strcmp(_CERT_TK_ISSUER_NAME, reinterpret_cast< const char* >(pTbsCert->GetIssuerName())))
915 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
916 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
920 SysTryReturnResult(NID_SEC_CERT, false, E_INACCESSIBLE_PATH, "Failed to access specified certificate path.");
925 SysTryReturnResult(NID_SEC_CERT, false, E_SYSTEM, "Invalid context type.");
930 std::unique_ptr< byte[] > pCertAuto(pCert);
932 //Add newly found root certificate in chain for verification.
933 r = AddCertificate(__certFormat, reinterpret_cast< byte* >(pCert), certLen);
935 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to add parent certificate in chain.");
936 //Verify certificate chain and return result to application
938 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to verify certificate chain.", GetErrorMessage(r));
942 SysTryReturnResult(NID_SEC_CERT, false, E_DATA_NOT_FOUND, "Parent certificate not found in certificate database.");
947 //Set the format of root certificate
948 __rootCertType = certType;
957 _CertChain::GetCount(void)
959 return __certChain.GetCount();
963 _CertChain::SetContextType(_CertContextType type)
965 __contextType = type;
969 _CertChain::GetContextType(void)
971 return __contextType;
975 _CertChain::GetCertFormat(void)
981 _CertChain::RemoveHead(bool freeFlag)
983 __certChain.RemoveAt(0, freeFlag);
987 _CertChain::RemoveTail(bool freeFlag)
989 if (__certChain.GetCount() > 0)
991 __certChain.RemoveAt(__certChain.GetCount() - 1, freeFlag);
995 } } } //Tizen::Security::Cert