2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
19 * @file FSecCert_CertChain.cpp
20 * @brief This file contains implementation of X509 Certificate Chains.
31 #include <openssl/x509.h>
32 #include <openssl/x509_vfy.h>
33 #include <FBaseSysLog.h>
34 #include <FBaseByteBuffer.h>
35 #include <FBaseResult.h>
36 #include "FSecCert_CertChain.h"
37 #include "FSecCert_CertDbManager.h"
39 namespace Tizen { namespace Security { namespace Cert
42 _CertChain::_CertChain(void)
45 , __certFormat(_CERT_X509)
46 , __rootCertType(_CERT_TYPE_NOT_BOUNDED)
47 , __contextType(_CERT_CONTEXT_CERT)
48 , __checkValidity(true)
50 __certChain.Construct();
53 _CertChain::~_CertChain(void)
59 _CertChain::Clear(void)
61 __certChain.RemoveAll(true);
65 _CertChain::AddCertificate(_CertFormat certFormat, char* pFileName) //added pCert format
69 SysTryReturnResult(NID_SEC_CERT, pFileName != null, E_INVALID_ARG, "Input file path is null.");
70 SysTryReturnResult(NID_SEC_CERT, certFormat == _CERT_X509, E_INVALID_ARG, "Input cert format is not X509.");
72 std::unique_ptr< _X509Certificate > pCert(new (std::nothrow) _X509Certificate());
73 SysTryReturnResult(NID_SEC_CERT, pCert != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
75 r = pCert->Parse(pFileName);
76 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Parsing of certificate failed.", GetErrorMessage(r));
78 r = __certChain.Add(*pCert.release());
79 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[r] Failed to add certificate in chain.", GetErrorMessage(r));
80 __certFormat = certFormat;
86 _CertChain::AddCertificate(_CertFormat certFormat, byte* pBuf, int bufSize) //added certFormat
90 SysTryReturnResult(NID_SEC_CERT, pBuf != null, E_INVALID_ARG, "Invalid input certificate buffer, input buffer must not be null.");
92 SysTryReturnResult(NID_SEC_CERT, certFormat == _CERT_X509, E_INVALID_ARG, "Input cert format is not X509.");
94 std::unique_ptr< _X509Certificate > pCert(new (std::nothrow) _X509Certificate());
95 SysTryReturnResult(NID_SEC_CERT, pCert != null, E_OUT_OF_MEMORY, "Failed to allocate memory");
97 r = pCert->Parse(pBuf, bufSize);
98 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Parsing of certificate failed.", GetErrorMessage(r));
100 r = __certChain.Add(*pCert.release());
101 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[r] Failed to add certificatein chain.", GetErrorMessage(r));
103 __certFormat = certFormat;
109 _CertChain::AddCertificate(_X509Certificate* pCert)
111 result r = E_SUCCESS;
113 SysTryReturnResult(NID_SEC_CERT, pCert != null, E_INVALID_ARG, "Invalid input certificate buffer, input buffer must not be null.");
115 r = __certChain.Add(*pCert);
116 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to add certificate in chain.", GetErrorMessage(r));
118 __certFormat = _CERT_X509;
124 _CertChain::AddPrivateKey(char* pPKeyPath)
126 SysTryReturnResult(NID_SEC_CERT, pPKeyPath != null, E_INVALID_ARG, "Input key buffer is null.");
128 __pPrivateKey.reset(null);
130 __pPrivateKey = std::unique_ptr< _CertPrivateKeyInfo >(new (std::nothrow) _CertPrivateKeyInfo(pPKeyPath));
131 SysTryReturnResult(NID_SEC_CERT, __pPrivateKey != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
137 _CertChain::AddPrivateKey(byte* pBuf, int bufSize)
139 SysTryReturnResult(NID_SEC_CERT, pBuf != null, E_INVALID_ARG, "Input parameters are not correct.");
140 SysTryReturnResult(NID_SEC_CERT, bufSize > 0, E_INVALID_ARG, "Input buffer size must be greater than zero.");
142 __pPrivateKey.reset(null);
144 __pPrivateKey = std::unique_ptr< _CertPrivateKeyInfo >(new (std::nothrow) _CertPrivateKeyInfo(pBuf, bufSize));
145 SysTryReturnResult(NID_SEC_CERT, __pPrivateKey != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
151 _CertChain::GetPrivateKey(void)
153 return __pPrivateKey.get();
157 _CertChain::MoveNext(void)
159 SysTryReturnResult(NID_SEC_CERT, __certChain.GetCount() > 0, E_SYSTEM, "No certificate is present in chain, failed to move to tail of certificate chain.");
160 SysTryReturnResult(NID_SEC_CERT, __pos < (__certChain.GetCount() - 1), E_SYSTEM, "Position is at last certificate, failed to move to next certificate in chain.");
167 _CertChain::MovePrev(void)
169 SysTryReturnResult(NID_SEC_CERT, __pos > 0, E_SYSTEM, "Position is already at zero, failed to move to previous certificate in chain.");
175 _CertChain::MoveHead(void)
182 _CertChain::MoveTail(void)
184 SysTryReturnResult(NID_SEC_CERT, __certChain.GetCount() > 0, E_SYSTEM, "No certificate is present in chain, failed to move to tail of certificate chain.");
185 __pos = __certChain.GetCount() - 1;
191 _CertChain::GetCertTypeByDomain(void)
195 switch (__rootCertType)
197 case _CERT_TYPE_SIM_ROOT_DOMAIN1:
199 case _CERT_TYPE_ROOT_DOMAIN1:
201 case _CERT_TYPE_DEV_ROOT_DOMAIN1:
202 r = _CERT_DOMAIN1_TRUSTED;
205 case _CERT_TYPE_ROOT_DOMAIN2:
207 case _CERT_TYPE_DEV_ROOT_DOMAIN2:
208 r = _CERT_DOMAIN2_TRUSTED;
211 case _CERT_TYPE_ROOT_DOMAIN3:
213 case _CERT_TYPE_SIM_ROOT_DOMAIN3:
215 case _CERT_TYPE_DEV_ROOT_DOMAIN3:
216 r = _CERT_DOMAIN3_TRUSTED;
220 r = _CERT_WRT_TRUSTED;
224 r = _CERT_INVALID_DOMAIN;
232 _CertChain::GetCurrentCertificate(void)
234 SysTryReturn(NID_SEC_CERT, __certChain.GetCount() > 0, null, E_SYSTEM, "[E_SYSTEM] There is no certifcate present in chain.");
235 SysTryReturn(NID_SEC_CERT, __pos >= 0, null, E_SYSTEM, "[E_SYSTEM] Failed to get certificate object from chain.");
236 return reinterpret_cast< _X509Certificate* >(__certChain.GetAt(__pos));
241 _CertChain::Verify(void)
243 result r = E_SUCCESS;
244 const unsigned char* pCertContent = null;
246 int certCount = __certChain.GetCount();
247 STACK_OF(X509)* pTrustedChain = null;
248 STACK_OF(X509)* pInterimChain = null;
249 X509_STORE_CTX* pStoreCtx = NULL;
250 byte* pCertBuffer = null;
251 _X509Certificate* pCert = null;
252 X509** ppInterimCerts = null;
253 X509* pX509UserCert = null;
255 SysTryReturnResult(NID_SEC_CERT, certCount > 0, E_SYSTEM, "No certificates are present in certificate chain.");
256 SysTryReturnResult(NID_SEC_CERT, __certFormat == _CERT_X509, E_SYSTEM, "Certificate chain is not of type X509.");
258 pCert = reinterpret_cast< _X509Certificate* >(__certChain.GetAt(0));
259 SysTryReturnResult(NID_SEC_CERT, pCert != null, E_SYSTEM, "Failed to get first certificate in chain.");
261 certCount--; //user certificate is added.
263 if (certCount == 0) //only root cert to verify
265 SysTryReturnResult(NID_SEC_CERT, pCert->IsSelfSigned(), E_DATA_NOT_FOUND, "Failed to get root certificate in chain.");
266 return pCert->VerifySignature(null, 0);
269 pCert->GetCertBuffer(pCertBuffer, certSize);
270 SysTryReturnResult(NID_SEC_CERT, pCertBuffer != null, E_SYSTEM, "Failed to get encoded buffer of first certificate.");
272 pCertContent = const_cast< const unsigned char* >(pCertBuffer);
274 d2i_X509(&pX509UserCert, &pCertContent, certSize);
275 SysTryReturnResult(NID_SEC_CERT, pX509UserCert != null, E_SYSTEM, "Failed to parse user certificate.");
277 pTrustedChain = sk_X509_new_null();
278 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.");
280 pInterimChain = sk_X509_new_null();
281 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.");
283 ppInterimCerts = (X509**) new X509*[certCount];
284 memset(ppInterimCerts, 0, (sizeof(X509*) * certCount));
286 for (int i = 0; i < certCount; i++)
292 pCert = reinterpret_cast< _X509Certificate* >(__certChain.GetAt(i + 1));
293 SysTryCatch(NID_SEC_CERT, pCert != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to get certificate at index (%d).", i + 1);
295 pCert->GetCertBuffer(pCertBuffer, certSize);
296 SysTryCatch(NID_SEC_CERT, pCertBuffer != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to get buffer of certificate at index (%d).", i + 1);
298 pCertContent = const_cast< const unsigned char* >(pCertBuffer);
300 d2i_X509(&ppInterimCerts[i], &pCertContent, certSize);
301 SysTryCatch(NID_SEC_CERT, ppInterimCerts[i] != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to parse certificate at index (%d).", i + 1);
303 if (pCert->IsSelfSigned())
306 // insert root certificate into trusted chain
307 if (!(sk_X509_push(pTrustedChain, ppInterimCerts[i])))
309 SysLog(NID_SEC_CERT, "Fail to push root ca certificate into openssl stack.");
316 if (!(sk_X509_push(pInterimChain, ppInterimCerts[i])))
318 SysLog(NID_SEC_CERT, "Fail to push intermediate ca certificate into openssl stack.");
326 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.");
328 // initialize store and store context
329 pStoreCtx = X509_STORE_CTX_new();
331 // construct store context
332 if (!X509_STORE_CTX_init(pStoreCtx, 0, pX509UserCert, pInterimChain))
334 SysLog(NID_SEC_CERT, "Fail to initialize X509 store context.");
339 X509_STORE_CTX_trusted_stack(pStoreCtx, pTrustedChain);
342 if (X509_verify_cert(pStoreCtx) != 1)
344 SysLog(NID_SEC_CERT, "Fail to verify certificate chain.");
345 switch (X509_STORE_CTX_get_error(pStoreCtx))
347 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
348 r = E_DATA_NOT_FOUND;
351 case X509_V_ERR_CERT_HAS_EXPIRED:
353 case X509_V_ERR_CERT_NOT_YET_VALID:
354 r = E_INVALID_CERTIFICATE;
357 case X509_V_ERR_CERT_SIGNATURE_FAILURE:
358 r = E_CERTIFICATE_VERIFICATION_FAILED;
365 SysLog(NID_SEC_CERT, "error number = %d", X509_STORE_CTX_get_error(pStoreCtx));
372 if (ppInterimCerts != null)
374 for (int i = 0; i < certCount; i++)
376 if (ppInterimCerts[i] != null)
378 X509_free(ppInterimCerts[i]);
382 delete[] ppInterimCerts;
385 if (pX509UserCert != null)
387 X509_free(pX509UserCert);
390 if (pStoreCtx != null)
392 X509_STORE_CTX_free(pStoreCtx);
395 if (pTrustedChain != null)
397 sk_X509_free(pTrustedChain);
400 if (pInterimChain != null)
402 sk_X509_free(pInterimChain);
409 _CertChain::VerifyUsingOpenSsl(void)
411 result r = E_SUCCESS;
416 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "No certificate is present in certificate chain, failed to validate certificate chain.");
418 if (__certFormat == _CERT_X509)
420 _X509Certificate* pCert = null;
421 _X509Certificate* pPrevCert = null;
422 _X509TbsCert* pTbsCert = null;
423 _X509TbsCert* pPrevTbsCert = null;
427 pPrevCert = GetCurrentCertificate();
428 SysTryReturnResult(NID_SEC_CERT, pPrevCert != null, E_SYSTEM, "Failed to get root certificate from chain, broken certificate chain.");
430 if (pPrevCert->IsSelfSigned())
432 // rootCA self verify
435 pPrevTbsCert = pPrevCert->GetTbsCertInstance();
436 SysTryReturnResult(NID_SEC_CERT, pPrevTbsCert != null, E_SYSTEM, "Failed to get root certificate to be signed instance.");
438 r = pPrevTbsCert->GetValidity();
439 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_INVALID_CERTIFICATE, "Root certificate validation failed (subject name: %s).", pPrevTbsCert->GetSubjectName());
442 r = pPrevCert->VerifySignature(null, 0);
443 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_CERTIFICATE_VERIFICATION_FAILED, "Root certificate signature verification failed (subject name: %s).", pPrevTbsCert->GetSubjectName());
447 if (MoveNext() == E_SUCCESS)
449 pPrevCert = GetCurrentCertificate();
455 while (MovePrev() == E_SUCCESS);
457 while (MovePrev() == E_SUCCESS)
462 pCert = GetCurrentCertificate();
463 SysTryReturnResult(NID_SEC_CERT, pCert != null, E_SYSTEM, "Failed to get certificate from chain, broken certificate chain.");
465 pPrevTbsCert = pPrevCert->GetTbsCertInstance();
466 SysTryReturnResult(NID_SEC_CERT, pPrevTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
468 pTbsCert = pCert->GetTbsCertInstance();
469 SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
473 r = pPrevTbsCert->GetValidity();
474 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_INVALID_CERTIFICATE, "Certificate validation failed (subject name: %s).", pPrevTbsCert->GetSubjectName());
478 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());
480 r = pPrevTbsCert->GetPublicKeyInfoN(keyLen, &pKey);
481 SysTryReturnResult(NID_SEC_CERT, pKey != null, E_SYSTEM, "Failed to public key from certificate (subject name: %s).", pPrevTbsCert->GetSubjectName());
483 std::unique_ptr< byte[] > pKeyAuto(pKey);
485 r = pCert->VerifySignature(pKey, keyLen);
487 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_CERTIFICATE_VERIFICATION_FAILED, "Certificate signature verification failed (subject name: %s).", pTbsCert->GetSubjectName());
497 _CertChain::VerifyCertChainWithDb(void)
499 result r = E_SUCCESS;
500 _CertDbManager* pCertDb = null;
503 _CaCertType certType = _CERT_TYPE_NOT_BOUNDED;
506 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "No certificate is present in certificate chain, failed to validate certificate chain.");
508 pCertDb = _CertDbManager::GetInstance();
509 SysTryReturnResult(NID_SEC_CERT, pCertDb != null, E_SYSTEM, "Failed to get instance of certificate database manager.");
511 if (__certFormat == _CERT_X509)
513 _X509Certificate* pLastCert = null;
514 _X509TbsCert* pTbsCert = null;
515 pLastCert = GetCurrentCertificate();
516 SysTryReturnResult(NID_SEC_CERT, pLastCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
518 if (pLastCert->IsSelfSigned())
520 pCertDb = _CertDbManager::GetInstance();
521 SysTryReturnResult(NID_SEC_CERT, pCertDb != null, E_SYSTEM, "Failed to get instance of certificate database manager.");
523 pTbsCert = pLastCert->GetTbsCertInstance();
524 SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get root certificate to be signed instance.");
526 if (GetContextType() == _CERT_CONTEXT_SSL)
528 certType = _CERT_TYPE_ROOT_CA;
529 __checkValidity = true;
531 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
533 certType = _CERT_TYPE_ROOT_CA_BY_USER;
534 __checkValidity = true;
536 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
537 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetSubjectName());
540 else if (GetContextType() == _CERT_CONTEXT_MIDP || GetContextType() == _CERT_CONTEXT_DOMAIN || GetContextType() == _CERT_CONTEXT_DOMAIN_NO_VALIDITY)
542 if (GetContextType() == _CERT_CONTEXT_DOMAIN_NO_VALIDITY)
544 __checkValidity = false;
548 __checkValidity = true;
551 certType = _CERT_TYPE_ROOT_DOMAIN1;
552 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
554 certType = _CERT_TYPE_ROOT_DOMAIN2;
555 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
557 certType = _CERT_TYPE_ROOT_DOMAIN3;
558 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
560 certType = _CERT_TYPE_DEV_ROOT_DOMAIN1;
561 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
563 certType = _CERT_TYPE_DEV_ROOT_DOMAIN3;
564 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
565 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetSubjectName());
571 else if (GetContextType() == _CERT_CONTEXT_CERT || GetContextType() == _CERT_CONTEXT_CERT_NO_VALIDITY)
573 if (GetContextType() == _CERT_CONTEXT_CERT)
575 __checkValidity = true;
577 else if (GetContextType() == _CERT_CONTEXT_CERT_NO_VALIDITY)
579 __checkValidity = false;
582 certType = _CERT_TYPE_TRUSTED_CA;
584 else if (GetContextType() == _CERT_CONTEXT_OSP_USER || GetContextType() == _CERT_CONTEXT_OSP_USER_NO_VALIDITY)
586 if (GetContextType() == _CERT_CONTEXT_OSP_USER)
588 __checkValidity = true;
590 else if (GetContextType() == _CERT_CONTEXT_OSP_USER_NO_VALIDITY)
592 __checkValidity = false;
595 certType = _CERT_TYPE_ROOT_CA_BY_USER;
597 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
598 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
600 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL1 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL1_NO_VALIDITY)
602 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL1)
604 __checkValidity = true;
606 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL1_NO_VALIDITY)
608 __checkValidity = false;
611 certType = _CERT_TYPE_OSP_CRITICAL1;
613 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
614 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
616 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL2 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL2_NO_VALIDITY)
618 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL2)
620 __checkValidity = true;
622 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL2_NO_VALIDITY)
624 __checkValidity = false;
627 certType = _CERT_TYPE_OSP_CRITICAL2;
628 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
629 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
631 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL3 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL3_NO_VALIDITY)
633 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL3)
635 __checkValidity = true;
637 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL3_NO_VALIDITY)
639 __checkValidity = false;
641 certType = _CERT_TYPE_OSP_CRITICAL3;
643 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
644 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
646 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL4 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL4_NO_VALIDITY)
648 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL4)
650 __checkValidity = true;
652 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL4_NO_VALIDITY)
654 __checkValidity = false;
656 certType = _CERT_TYPE_OSP_CRITICAL4;
658 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
659 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
661 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL5 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL5_NO_VALIDITY)
663 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL5)
665 __checkValidity = true;
667 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL5_NO_VALIDITY)
669 __checkValidity = false;
671 certType = _CERT_TYPE_OSP_CRITICAL5;
673 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
674 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
676 else if (GetContextType() == _CERT_CONTEXT_OSP_PRELOAD_APP || GetContextType() == _CERT_CONTEXT_OSP_PRELOAD_APP_NO_VALIDITY)
678 if (GetContextType() == _CERT_CONTEXT_OSP_PRELOAD_APP)
680 __checkValidity = true;
682 else if (GetContextType() == _CERT_CONTEXT_OSP_PRELOAD_APP_NO_VALIDITY)
684 __checkValidity = false;
686 certType = _CERT_TYPE_OSP_PRELOAD_APP;
688 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
689 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
691 else if (GetContextType() == _CERT_CONTEXT_WRT)
693 __checkValidity = true;
694 certType = _CERT_TYPE_WRT;
696 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
697 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
699 else if (GetContextType() == _CERT_CONTEXT_TK)
701 certType = _CERT_TYPE_ROOT_DOMAIN2;
702 __checkValidity = true;
703 if (!strcmp(_CERT_TK_ISSUER_NAME, reinterpret_cast< const char* >(pTbsCert->GetIssuerName())))
705 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
706 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
710 //if the issuerName of this certificate is not _CERT_TK_ISSUER_NAME then we should return some error
711 SysTryReturnResult(NID_SEC_CERT, false, E_INACCESSIBLE_PATH, "Failed to access specified Path.");
716 SysTryReturnResult(NID_SEC_CERT, false, E_SYSTEM, "Invalid context type.");
720 //Set the format of root certificate
721 __rootCertType = certType;
729 //Otherwise extract root certificate from Db and add in tail and then verify.
730 pTbsCert = pLastCert->GetTbsCertInstance();
731 SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get to be signed object from cerificate.");
734 //If the conetxt type is SSL then root certiifcate should be searched in DefaultROOCACert directory.
735 //It should not search in any other directory
736 //Similarily, if context type is MIDP then root certificate should be searched in Domain1, Domain2 & Domain3 directory.
737 //If not found report error.
738 if (GetContextType() == _CERT_CONTEXT_SSL)
740 certType = _CERT_TYPE_ROOT_CA;
741 __checkValidity = true;
742 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
744 certType = _CERT_TYPE_ROOT_CA_BY_USER;
745 __checkValidity = true;
747 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
748 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
751 else if (GetContextType() == _CERT_CONTEXT_MIDP || GetContextType() == _CERT_CONTEXT_DOMAIN || GetContextType() == _CERT_CONTEXT_DOMAIN_NO_VALIDITY)
753 if (GetContextType() == _CERT_CONTEXT_DOMAIN_NO_VALIDITY)
755 __checkValidity = false;
759 __checkValidity = true;
761 certType = _CERT_TYPE_ROOT_DOMAIN1;
762 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
764 certType = _CERT_TYPE_ROOT_DOMAIN2;
765 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
767 certType = _CERT_TYPE_ROOT_DOMAIN3;
768 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
770 certType = _CERT_TYPE_DEV_ROOT_DOMAIN1;
771 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
773 certType = _CERT_TYPE_DEV_ROOT_DOMAIN3;
775 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
776 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
782 else if (GetContextType() == _CERT_CONTEXT_CERT || GetContextType() == _CERT_CONTEXT_CERT_NO_VALIDITY)
784 if (GetContextType() == _CERT_CONTEXT_CERT)
786 __checkValidity = true;
788 else if (GetContextType() == _CERT_CONTEXT_CERT_NO_VALIDITY)
790 __checkValidity = false;
793 r = pCertDb->FindIssuerCertificateAndTypeN(_CERT_X509, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen, certType);
794 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
796 else if (GetContextType() == _CERT_CONTEXT_OSP_USER || GetContextType() == _CERT_CONTEXT_OSP_USER_NO_VALIDITY)
798 if (GetContextType() == _CERT_CONTEXT_OSP_USER)
800 __checkValidity = true;
802 else if (GetContextType() == _CERT_CONTEXT_OSP_USER_NO_VALIDITY)
804 __checkValidity = false;
806 certType = _CERT_TYPE_ROOT_CA_BY_USER;
808 r = (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen));
809 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
811 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL1 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL1_NO_VALIDITY)
813 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL1)
815 __checkValidity = true;
817 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL1_NO_VALIDITY)
819 __checkValidity = false;
821 certType = _CERT_TYPE_OSP_CRITICAL1;
823 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
824 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
826 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL2 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL2_NO_VALIDITY)
828 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL2)
830 __checkValidity = true;
832 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL2_NO_VALIDITY)
834 __checkValidity = false;
836 certType = _CERT_TYPE_OSP_CRITICAL2;
838 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
839 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
841 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL3 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL3_NO_VALIDITY)
843 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL3)
845 __checkValidity = true;
847 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL3_NO_VALIDITY)
849 __checkValidity = false;
851 certType = _CERT_TYPE_OSP_CRITICAL3;
853 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
854 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
856 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL4 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL4_NO_VALIDITY)
858 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL4)
860 __checkValidity = true;
862 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL4_NO_VALIDITY)
864 __checkValidity = false;
866 certType = _CERT_TYPE_OSP_CRITICAL4;
868 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
869 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
871 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL5 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL5_NO_VALIDITY)
873 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL5)
875 __checkValidity = true;
877 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL5_NO_VALIDITY)
879 __checkValidity = false;
881 certType = _CERT_TYPE_OSP_CRITICAL5;
883 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
884 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
886 else if (GetContextType() == _CERT_CONTEXT_OSP_PRELOAD_APP || GetContextType() == _CERT_CONTEXT_OSP_PRELOAD_APP_NO_VALIDITY)
888 if (GetContextType() == _CERT_CONTEXT_OSP_PRELOAD_APP)
890 __checkValidity = true;
892 else if (GetContextType() == _CERT_CONTEXT_OSP_PRELOAD_APP_NO_VALIDITY)
894 __checkValidity = false;
896 certType = _CERT_TYPE_OSP_PRELOAD_APP;
898 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
899 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
901 else if (GetContextType() == _CERT_CONTEXT_WRT)
903 __checkValidity = true;
904 certType = _CERT_TYPE_WRT;
906 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
907 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
909 else if (GetContextType() == _CERT_CONTEXT_TK)
911 certType = _CERT_TYPE_ROOT_DOMAIN2;
912 __checkValidity = true;
914 if (!strcmp(_CERT_TK_ISSUER_NAME, reinterpret_cast< const char* >(pTbsCert->GetIssuerName())))
916 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
917 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
921 SysTryReturnResult(NID_SEC_CERT, false, E_INACCESSIBLE_PATH, "Failed to access specified certificate path.");
926 SysTryReturnResult(NID_SEC_CERT, false, E_SYSTEM, "Invalid context type.");
931 std::unique_ptr< byte[] > pCertAuto(pCert);
933 //Add newly found root certificate in chain for verification.
934 r = AddCertificate(__certFormat, reinterpret_cast< byte* >(pCert), certLen);
936 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to add parent certificate in chain.");
937 //Verify certificate chain and return result to application
939 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to verify certificate chain.", GetErrorMessage(r));
943 SysTryReturnResult(NID_SEC_CERT, false, E_DATA_NOT_FOUND, "Parent certificate not found in certificate database.");
948 //Set the format of root certificate
949 __rootCertType = certType;
958 _CertChain::GetCount(void)
960 return __certChain.GetCount();
964 _CertChain::SetContextType(_CertContextType type)
966 __contextType = type;
970 _CertChain::GetContextType(void)
972 return __contextType;
976 _CertChain::GetCertFormat(void)
982 _CertChain::RemoveHead(bool freeFlag)
984 __certChain.RemoveAt(0, freeFlag);
988 _CertChain::RemoveTail(bool freeFlag)
990 if (__certChain.GetCount() > 0)
992 __certChain.RemoveAt(__certChain.GetCount() - 1, freeFlag);
996 } } } //Tizen::Security::Cert