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;
350 case X509_V_ERR_CERT_HAS_EXPIRED:
352 case X509_V_ERR_CERT_NOT_YET_VALID:
353 r = E_INVALID_CERTIFICATE;
355 case X509_V_ERR_CERT_SIGNATURE_FAILURE:
356 r = E_CERTIFICATE_VERIFICATION_FAILED;
362 SysLog(NID_SEC_CERT, "error number = %d", X509_STORE_CTX_get_error(pStoreCtx));
369 if (ppInterimCerts != null)
371 for(int i = 0; i < certCount; i++)
373 if (ppInterimCerts[i] != null)
375 X509_free(ppInterimCerts[i]);
379 delete[] ppInterimCerts;
382 if (pX509UserCert != null)
384 X509_free(pX509UserCert);
387 if (pStoreCtx != null)
389 X509_STORE_CTX_free(pStoreCtx);
392 if (pTrustedChain != null)
394 sk_X509_free(pTrustedChain);
397 if (pInterimChain != null)
399 sk_X509_free(pInterimChain);
406 _CertChain::VerifyUsingOpenSsl(void)
408 result r = E_SUCCESS;
413 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "No certificate is present in certificate chain, failed to validate certificate chain.");
415 if (__certFormat == _CERT_X509)
417 _X509Certificate* pCert = null;
418 _X509Certificate* pPrevCert = null;
419 _X509TbsCert* pTbsCert = null;
420 _X509TbsCert* pPrevTbsCert = null;
424 pPrevCert = GetCurrentCertificate();
425 SysTryReturnResult(NID_SEC_CERT, pPrevCert != null, E_SYSTEM, "Failed to get root certificate from chain, broken certificate chain.");
427 if (pPrevCert->IsSelfSigned())
429 // rootCA self verify
432 pPrevTbsCert = pPrevCert->GetTbsCertInstance();
433 SysTryReturnResult(NID_SEC_CERT, pPrevTbsCert != null, E_SYSTEM, "Failed to get root certificate to be signed instance.");
435 r = pPrevTbsCert->GetValidity();
436 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_INVALID_CERTIFICATE, "Root certificate validation failed (subject name: %s).", pPrevTbsCert->GetSubjectName());
439 r = pPrevCert->VerifySignature(null, 0);
440 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_CERTIFICATE_VERIFICATION_FAILED, "Root certificate signature verification failed (subject name: %s).", pPrevTbsCert->GetSubjectName());
444 if (MoveNext() == E_SUCCESS)
446 pPrevCert = GetCurrentCertificate();
452 while (MovePrev() == E_SUCCESS);
454 while (MovePrev() == E_SUCCESS)
459 pCert = GetCurrentCertificate();
460 SysTryReturnResult(NID_SEC_CERT, pCert != null, E_SYSTEM, "Failed to get certificate from chain, broken certificate chain.");
462 pPrevTbsCert = pPrevCert->GetTbsCertInstance();
463 SysTryReturnResult(NID_SEC_CERT, pPrevTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
465 pTbsCert = pCert->GetTbsCertInstance();
466 SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
470 r = pPrevTbsCert->GetValidity();
471 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_INVALID_CERTIFICATE, "Certificate validation failed (subject name: %s).", pPrevTbsCert->GetSubjectName());
475 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());
477 r = pPrevTbsCert->GetPublicKeyInfoN(keyLen, &pKey);
478 SysTryReturnResult(NID_SEC_CERT, pKey != null, E_SYSTEM, "Failed to public key from certificate (subject name: %s).", pPrevTbsCert->GetSubjectName());
480 std::unique_ptr<byte[]> pKeyAuto(pKey);
482 r = pCert->VerifySignature(pKey, keyLen);
484 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_CERTIFICATE_VERIFICATION_FAILED, "Certificate signature verification failed (subject name: %s).", pTbsCert->GetSubjectName());
494 _CertChain::VerifyCertChainWithDb(void)
496 result r = E_SUCCESS;
497 _CertDbManager* pCertDb = null;
500 _CaCertType certType = _CERT_TYPE_NOT_BOUNDED;
503 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "No certificate is present in certificate chain, failed to validate certificate chain.");
505 pCertDb = _CertDbManager::GetInstance();
506 SysTryReturnResult(NID_SEC_CERT, pCertDb != null, E_SYSTEM, "Failed to get instance of certificate database manager.");
508 if (__certFormat == _CERT_X509)
510 _X509Certificate* pLastCert = null;
511 _X509TbsCert* pTbsCert = null;
512 pLastCert = GetCurrentCertificate();
513 SysTryReturnResult(NID_SEC_CERT, pLastCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
515 if (pLastCert->IsSelfSigned())
517 pCertDb = _CertDbManager::GetInstance();
518 SysTryReturnResult(NID_SEC_CERT, pCertDb != null, E_SYSTEM, "Failed to get instance of certificate database manager.");
520 pTbsCert = pLastCert->GetTbsCertInstance();
521 SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get root certificate to be signed instance.");
523 if (GetContextType() == _CERT_CONTEXT_SSL)
525 certType = _CERT_TYPE_ROOT_CA;
526 __checkValidity = true;
528 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
530 certType = _CERT_TYPE_ROOT_CA_BY_USER;
531 __checkValidity = true;
533 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
534 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetSubjectName());
537 else if (GetContextType() == _CERT_CONTEXT_MIDP || GetContextType() == _CERT_CONTEXT_DOMAIN || GetContextType() == _CERT_CONTEXT_DOMAIN_NO_VALIDITY)
539 if (GetContextType() == _CERT_CONTEXT_DOMAIN_NO_VALIDITY)
541 __checkValidity = false;
545 __checkValidity = true;
548 certType = _CERT_TYPE_ROOT_DOMAIN1;
549 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
551 certType = _CERT_TYPE_ROOT_DOMAIN2;
552 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
554 certType = _CERT_TYPE_ROOT_DOMAIN3;
555 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
557 certType = _CERT_TYPE_DEV_ROOT_DOMAIN1;
558 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
560 certType = _CERT_TYPE_DEV_ROOT_DOMAIN3;
561 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
562 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetSubjectName());
568 else if (GetContextType() == _CERT_CONTEXT_CERT || GetContextType() == _CERT_CONTEXT_CERT_NO_VALIDITY)
570 if (GetContextType() == _CERT_CONTEXT_CERT)
572 __checkValidity = true;
574 else if (GetContextType() == _CERT_CONTEXT_CERT_NO_VALIDITY)
576 __checkValidity = false;
579 certType = _CERT_TYPE_TRUSTED_CA;
581 else if (GetContextType() == _CERT_CONTEXT_OSP_USER || GetContextType() == _CERT_CONTEXT_OSP_USER_NO_VALIDITY)
583 if (GetContextType() == _CERT_CONTEXT_OSP_USER)
585 __checkValidity = true;
587 else if (GetContextType() == _CERT_CONTEXT_OSP_USER_NO_VALIDITY)
589 __checkValidity = false;
592 certType = _CERT_TYPE_ROOT_CA_BY_USER;
594 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
595 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
597 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL1 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL1_NO_VALIDITY)
599 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL1)
601 __checkValidity = true;
603 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL1_NO_VALIDITY)
605 __checkValidity = false;
608 certType = _CERT_TYPE_OSP_CRITICAL1;
610 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
611 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
613 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL2 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL2_NO_VALIDITY)
615 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL2)
617 __checkValidity = true;
619 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL2_NO_VALIDITY)
621 __checkValidity = false;
624 certType = _CERT_TYPE_OSP_CRITICAL2;
625 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
626 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
628 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL3 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL3_NO_VALIDITY)
630 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL3)
632 __checkValidity = true;
634 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL3_NO_VALIDITY)
636 __checkValidity = false;
638 certType = _CERT_TYPE_OSP_CRITICAL3;
640 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
641 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
643 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL4 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL4_NO_VALIDITY)
645 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL4)
647 __checkValidity = true;
649 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL4_NO_VALIDITY)
651 __checkValidity = false;
653 certType = _CERT_TYPE_OSP_CRITICAL4;
655 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
656 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
658 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL5 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL5_NO_VALIDITY)
660 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL5)
662 __checkValidity = true;
664 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL5_NO_VALIDITY)
666 __checkValidity = false;
668 certType = _CERT_TYPE_OSP_CRITICAL5;
670 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
671 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
673 else if (GetContextType() == _CERT_CONTEXT_OSP_PRELOAD_APP || GetContextType() == _CERT_CONTEXT_OSP_PRELOAD_APP_NO_VALIDITY)
675 if (GetContextType() == _CERT_CONTEXT_OSP_PRELOAD_APP)
677 __checkValidity = true;
679 else if (GetContextType() == _CERT_CONTEXT_OSP_PRELOAD_APP_NO_VALIDITY)
681 __checkValidity = false;
683 certType = _CERT_TYPE_OSP_PRELOAD_APP;
685 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
686 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
688 else if (GetContextType() == _CERT_CONTEXT_WRT)
690 __checkValidity = true;
691 certType = _CERT_TYPE_WRT;
693 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
694 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
696 else if (GetContextType() == _CERT_CONTEXT_TK)
698 certType = _CERT_TYPE_ROOT_DOMAIN2;
699 __checkValidity = true;
700 if (!strcmp(_CERT_TK_ISSUER_NAME, reinterpret_cast< const char* >(pTbsCert->GetIssuerName())))
702 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
703 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
707 //if the issuerName of this certificate is not _CERT_TK_ISSUER_NAME then we should return some error
708 SysTryReturnResult(NID_SEC_CERT, false, E_INACCESSIBLE_PATH, "Failed to access specified Path.");
713 SysTryReturnResult(NID_SEC_CERT, false, E_SYSTEM, "Invalid context type.");
717 //Set the format of root certificate
718 __rootCertType = certType;
726 //Otherwise extract root certificate from Db and add in tail and then verify.
727 pTbsCert = pLastCert->GetTbsCertInstance();
728 SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get to be signed object from cerificate.");
731 //If the conetxt type is SSL then root certiifcate should be searched in DefaultROOCACert directory.
732 //It should not search in any other directory
733 //Similarily, if context type is MIDP then root certificate should be searched in Domain1, Domain2 & Domain3 directory.
734 //If not found report error.
735 if (GetContextType() == _CERT_CONTEXT_SSL)
737 certType = _CERT_TYPE_ROOT_CA;
738 __checkValidity = true;
739 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
741 certType = _CERT_TYPE_ROOT_CA_BY_USER;
742 __checkValidity = true;
744 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
745 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
748 else if (GetContextType() == _CERT_CONTEXT_MIDP || GetContextType() == _CERT_CONTEXT_DOMAIN || GetContextType() == _CERT_CONTEXT_DOMAIN_NO_VALIDITY)
750 if (GetContextType() == _CERT_CONTEXT_DOMAIN_NO_VALIDITY)
752 __checkValidity = false;
756 __checkValidity = true;
758 certType = _CERT_TYPE_ROOT_DOMAIN1;
759 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
761 certType = _CERT_TYPE_ROOT_DOMAIN2;
762 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
764 certType = _CERT_TYPE_ROOT_DOMAIN3;
765 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
767 certType = _CERT_TYPE_DEV_ROOT_DOMAIN1;
768 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
770 certType = _CERT_TYPE_DEV_ROOT_DOMAIN3;
772 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
773 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
779 else if (GetContextType() == _CERT_CONTEXT_CERT || GetContextType() == _CERT_CONTEXT_CERT_NO_VALIDITY)
781 if (GetContextType() == _CERT_CONTEXT_CERT)
783 __checkValidity = true;
785 else if (GetContextType() == _CERT_CONTEXT_CERT_NO_VALIDITY)
787 __checkValidity = false;
790 r = pCertDb->FindIssuerCertificateAndTypeN(_CERT_X509, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen, certType);
791 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
793 else if (GetContextType() == _CERT_CONTEXT_OSP_USER || GetContextType() == _CERT_CONTEXT_OSP_USER_NO_VALIDITY)
795 if (GetContextType() == _CERT_CONTEXT_OSP_USER)
797 __checkValidity = true;
799 else if (GetContextType() == _CERT_CONTEXT_OSP_USER_NO_VALIDITY)
801 __checkValidity = false;
803 certType = _CERT_TYPE_ROOT_CA_BY_USER;
805 r = (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen));
806 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
808 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL1 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL1_NO_VALIDITY)
810 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL1)
812 __checkValidity = true;
814 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL1_NO_VALIDITY)
816 __checkValidity = false;
818 certType = _CERT_TYPE_OSP_CRITICAL1;
820 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
821 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
823 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL2 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL2_NO_VALIDITY)
825 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL2)
827 __checkValidity = true;
829 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL2_NO_VALIDITY)
831 __checkValidity = false;
833 certType = _CERT_TYPE_OSP_CRITICAL2;
835 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
836 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
838 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL3 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL3_NO_VALIDITY)
840 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL3)
842 __checkValidity = true;
844 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL3_NO_VALIDITY)
846 __checkValidity = false;
848 certType = _CERT_TYPE_OSP_CRITICAL3;
850 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
851 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
853 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL4 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL4_NO_VALIDITY)
855 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL4)
857 __checkValidity = true;
859 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL4_NO_VALIDITY)
861 __checkValidity = false;
863 certType = _CERT_TYPE_OSP_CRITICAL4;
865 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
866 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
868 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL5 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL5_NO_VALIDITY)
870 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL5)
872 __checkValidity = true;
874 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL5_NO_VALIDITY)
876 __checkValidity = false;
878 certType = _CERT_TYPE_OSP_CRITICAL5;
880 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
881 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
883 else if (GetContextType() == _CERT_CONTEXT_OSP_PRELOAD_APP || GetContextType() == _CERT_CONTEXT_OSP_PRELOAD_APP_NO_VALIDITY)
885 if (GetContextType() == _CERT_CONTEXT_OSP_PRELOAD_APP)
887 __checkValidity = true;
889 else if (GetContextType() == _CERT_CONTEXT_OSP_PRELOAD_APP_NO_VALIDITY)
891 __checkValidity = false;
893 certType = _CERT_TYPE_OSP_PRELOAD_APP;
895 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
896 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
898 else if (GetContextType() == _CERT_CONTEXT_WRT)
900 __checkValidity = true;
901 certType = _CERT_TYPE_WRT;
903 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
904 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
906 else if (GetContextType() == _CERT_CONTEXT_TK)
908 certType = _CERT_TYPE_ROOT_DOMAIN2;
909 __checkValidity = true;
911 if (!strcmp(_CERT_TK_ISSUER_NAME, reinterpret_cast< const char* >(pTbsCert->GetIssuerName())))
913 r = pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen);
914 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to find certificate in database (subject name: %s).", GetErrorMessage(r), pTbsCert->GetIssuerName());
918 SysTryReturnResult(NID_SEC_CERT, false, E_INACCESSIBLE_PATH, "Failed to access specified certificate path.");
923 SysTryReturnResult(NID_SEC_CERT, false, E_SYSTEM, "Invalid context type.");
928 std::unique_ptr<byte[]> pCertAuto(pCert);
930 //Add newly found root certificate in chain for verification.
931 r = AddCertificate(__certFormat, reinterpret_cast< byte* >(pCert), certLen);
933 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to add parent certificate in chain.");
934 //Verify certificate chain and return result to application
936 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to verify certificate chain.", GetErrorMessage(r));
940 SysTryReturnResult(NID_SEC_CERT, false, E_DATA_NOT_FOUND, "Parent certificate not found in certificate database.");
945 //Set the format of root certificate
946 __rootCertType = certType;
955 _CertChain::GetCount(void)
957 return __certChain.GetCount();
961 _CertChain::SetContextType(_CertContextType type)
963 __contextType = type;
967 _CertChain::GetContextType(void)
969 return __contextType;
973 _CertChain::GetCertFormat(void)
979 _CertChain::RemoveHead(bool freeFlag)
981 __certChain.RemoveAt(0, freeFlag);
985 _CertChain::RemoveTail(bool freeFlag)
987 if (__certChain.GetCount() > 0)
989 __certChain.RemoveAt(__certChain.GetCount() - 1, freeFlag);
993 } } } //Tizen::Security::Cert