Merge changes I279bb901,If101a133 into tizen_2.1
[platform/framework/native/appfw.git] / src / security / cert / FSecCert_CertChain.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
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
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
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.
16 //
17
18 /**
19  * @file                FSecCert_CertChain.cpp
20  * @brief               This file contains implementation of X509 Certificate Chains.
21 */
22
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include <error.h>
27 #include <new>
28 #include <sys/stat.h>
29 #include <assert.h>
30 #include <dirent.h>
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"
38
39 namespace Tizen { namespace Security { namespace Cert
40 {
41
42 _CertChain::_CertChain(void)
43         : __pos(0)
44         , __pPrivateKey(null)
45         , __certFormat(_CERT_X509)
46         , __rootCertType(_CERT_TYPE_NOT_BOUNDED)
47         , __contextType(_CERT_CONTEXT_CERT)
48         , __checkValidity(true)
49 {
50         __certChain.Construct();
51 }
52
53 _CertChain::~_CertChain(void)
54 {
55         Clear();
56 }
57
58 void
59 _CertChain::Clear(void)
60 {
61         __certChain.RemoveAll(true);
62 }
63
64 result
65 _CertChain::AddCertificate(_CertFormat certFormat, char* pFileName)      //added pCert format
66 {
67         result r = E_SUCCESS;
68
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.");
71
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.");
74
75         r = pCert->Parse(pFileName);
76         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Parsing of certificate failed.", GetErrorMessage(r));
77
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;
81
82         return r;
83 }
84
85 result
86 _CertChain::AddCertificate(_CertFormat certFormat, byte* pBuf, int bufSize) //added certFormat
87 {
88         result r = E_SUCCESS;
89
90         SysTryReturnResult(NID_SEC_CERT, pBuf != null, E_INVALID_ARG, "Invalid input certificate buffer, input buffer must not be null.");
91
92         SysTryReturnResult(NID_SEC_CERT, certFormat == _CERT_X509, E_INVALID_ARG, "Input cert format is not X509.");
93
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");
96
97         r = pCert->Parse(pBuf, bufSize);
98         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Parsing of certificate failed.", GetErrorMessage(r));
99
100         r = __certChain.Add(*pCert.release());
101         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[r] Failed to add certificatein chain.", GetErrorMessage(r));
102
103         __certFormat = certFormat;
104
105         return r;
106 }
107
108 result
109 _CertChain::AddCertificate(_X509Certificate* pCert)
110 {
111         result r = E_SUCCESS;
112
113         SysTryReturnResult(NID_SEC_CERT, pCert != null, E_INVALID_ARG, "Invalid input certificate buffer, input buffer must not be null.");
114
115         r = __certChain.Add(*pCert);
116         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to add certificate in chain.", GetErrorMessage(r));
117
118         __certFormat = _CERT_X509;
119
120         return r;
121 }
122
123 result
124 _CertChain::AddPrivateKey(char* pPKeyPath)
125 {
126         SysTryReturnResult(NID_SEC_CERT, pPKeyPath != null, E_INVALID_ARG, "Input key buffer is null.");
127
128         __pPrivateKey.reset(null);
129
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.");
132
133         return E_SUCCESS;
134 }
135
136 result
137 _CertChain::AddPrivateKey(byte* pBuf, int bufSize)
138 {
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.");
141
142         __pPrivateKey.reset(null);
143
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.");
146
147         return E_SUCCESS;
148 }
149
150 _CertPrivateKeyInfo*
151 _CertChain::GetPrivateKey(void)
152 {
153         return __pPrivateKey.get();
154 }
155
156 result
157 _CertChain::MoveNext(void)
158 {
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.");
161
162         __pos++;
163         return E_SUCCESS;
164 }
165
166 result
167 _CertChain::MovePrev(void)
168 {
169         SysTryReturnResult(NID_SEC_CERT, __pos > 0, E_SYSTEM, "Position is already at zero, failed to move to previous certificate in chain.");
170         __pos--;
171         return E_SUCCESS;
172 }
173
174 result
175 _CertChain::MoveHead(void)
176 {
177         __pos = 0;
178         return E_SUCCESS;
179 }
180
181 result
182 _CertChain::MoveTail(void)
183 {
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;
186
187         return E_SUCCESS;
188 }
189
190 _CertDomainType
191 _CertChain::GetCertTypeByDomain(void)
192 {
193         _CertDomainType r;
194
195         switch (__rootCertType)
196         {
197         case _CERT_TYPE_SIM_ROOT_DOMAIN1:
198         //fall through
199         case _CERT_TYPE_ROOT_DOMAIN1:
200         //fall through
201         case _CERT_TYPE_DEV_ROOT_DOMAIN1:
202                 r = _CERT_DOMAIN1_TRUSTED;
203                 break;
204
205         case _CERT_TYPE_ROOT_DOMAIN2:
206         //fall through
207         case _CERT_TYPE_DEV_ROOT_DOMAIN2:
208                 r = _CERT_DOMAIN2_TRUSTED;
209                 break;
210
211         case _CERT_TYPE_ROOT_DOMAIN3:
212         //fall through
213         case _CERT_TYPE_SIM_ROOT_DOMAIN3:
214         //fall through
215         case _CERT_TYPE_DEV_ROOT_DOMAIN3:
216                 r = _CERT_DOMAIN3_TRUSTED;
217                 break;
218
219         case _CERT_TYPE_WRT:
220                 r = _CERT_WRT_TRUSTED;
221                 break;
222
223         default:
224                 r = _CERT_INVALID_DOMAIN;
225                 break;
226         }
227
228         return r;
229 }
230
231 _X509Certificate*
232 _CertChain::GetCurrentCertificate(void)
233 {
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));
237 }
238
239
240 result
241 _CertChain::Verify(void)
242 {
243         result r = E_SUCCESS;
244         const unsigned char* pCertContent = null;
245         int certSize = 0;
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;
254
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.");
257
258         pCert = reinterpret_cast< _X509Certificate* >(__certChain.GetAt(0));
259         SysTryReturnResult(NID_SEC_CERT, pCert != null, E_SYSTEM, "Failed to get first certificate in chain.");
260
261         certCount--; //user certificate is added.
262
263         if (certCount == 0) //only root cert to verify
264         {
265                 SysTryReturnResult(NID_SEC_CERT, pCert->IsSelfSigned(), E_DATA_NOT_FOUND, "Failed to get root certificate in chain.");
266                 return pCert->VerifySignature(null, 0);
267         }
268
269         pCert->GetCertBuffer(pCertBuffer, certSize);
270         SysTryReturnResult(NID_SEC_CERT, pCertBuffer != null, E_SYSTEM, "Failed to get encoded buffer of first certificate.");
271
272         pCertContent = const_cast< const unsigned char* >(pCertBuffer);
273
274         d2i_X509(&pX509UserCert, &pCertContent, certSize);
275         SysTryReturnResult(NID_SEC_CERT, pX509UserCert != null, E_SYSTEM, "Failed to parse user certificate.");
276
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.");
279
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.");
282
283         ppInterimCerts = (X509**) new X509*[certCount];
284         memset(ppInterimCerts, 0, (sizeof(X509*) * certCount));
285
286         for (int i = 0; i < certCount; i++)
287         {
288                 certSize = 0;
289                 pCertContent = null;
290                 pCertBuffer = null;
291
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);
294
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);
297
298                 pCertContent = const_cast< const unsigned char* >(pCertBuffer);
299
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);
302
303                 if (pCert->IsSelfSigned())
304                 {
305                         /* verify */
306                         // insert root certificate into trusted chain
307                         if (!(sk_X509_push(pTrustedChain, ppInterimCerts[i])))
308                         {
309                                 SysLog(NID_SEC_CERT, "Fail to push root ca certificate into openssl stack.");
310                                 r = E_SYSTEM;
311                                 goto CATCH;
312                         }
313                 }
314                 else
315                 {
316                         if (!(sk_X509_push(pInterimChain, ppInterimCerts[i])))
317                         {
318                                 SysLog(NID_SEC_CERT, "Fail to push intermediate ca certificate into openssl stack.");
319                                 r = E_SYSTEM;
320                                 goto CATCH;
321                         }
322
323                 }
324         }
325
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.");
327
328         // initialize store and store context
329         pStoreCtx = X509_STORE_CTX_new();
330
331         // construct store context
332         if (!X509_STORE_CTX_init(pStoreCtx, 0, pX509UserCert, pInterimChain))
333         {
334                 SysLog(NID_SEC_CERT, "Fail to initialize X509 store context.");
335                 r = E_SYSTEM;
336                 goto CATCH;
337         }
338
339         X509_STORE_CTX_trusted_stack(pStoreCtx, pTrustedChain);
340
341         // verify
342         if (X509_verify_cert(pStoreCtx) != 1)
343         {
344                 SysLog(NID_SEC_CERT, "Fail to verify certificate chain.");
345                 switch (X509_STORE_CTX_get_error(pStoreCtx))
346                 {
347                 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
348                         r = E_DATA_NOT_FOUND;
349                         break;
350
351                 case X509_V_ERR_CERT_HAS_EXPIRED:
352                 //fall though
353                 case X509_V_ERR_CERT_NOT_YET_VALID:
354                         r = E_INVALID_CERTIFICATE;
355                         break;
356
357                 case X509_V_ERR_CERT_SIGNATURE_FAILURE:
358                         r = E_CERTIFICATE_VERIFICATION_FAILED;
359                         break;
360
361                 default:
362                         r = E_SYSTEM;
363                         break;
364                 }
365                 SysLog(NID_SEC_CERT, "error number = %d", X509_STORE_CTX_get_error(pStoreCtx));
366                 goto CATCH;
367
368         }
369
370 CATCH:
371
372         if (ppInterimCerts != null)
373         {
374                 for (int i = 0; i < certCount; i++)
375                 {
376                         if (ppInterimCerts[i] != null)
377                         {
378                                 X509_free(ppInterimCerts[i]);
379                         }
380                 }
381
382                 delete[] ppInterimCerts;
383         }
384
385         if (pX509UserCert != null)
386         {
387                 X509_free(pX509UserCert);
388         }
389
390         if (pStoreCtx != null)
391         {
392                 X509_STORE_CTX_free(pStoreCtx);
393         }
394
395         if (pTrustedChain != null)
396         {
397                 sk_X509_free(pTrustedChain);
398         }
399
400         if (pInterimChain != null)
401         {
402                 sk_X509_free(pInterimChain);
403         }
404         return r;
405 }
406
407
408 result
409 _CertChain::VerifyUsingOpenSsl(void)
410 {
411         result r = E_SUCCESS;
412         int keyLen = 0;
413         int count = 0;
414
415         r = MoveTail();
416         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "No certificate is present in certificate chain, failed to validate certificate chain.");
417
418         if (__certFormat == _CERT_X509)
419         {
420                 _X509Certificate* pCert = null;
421                 _X509Certificate* pPrevCert = null;
422                 _X509TbsCert* pTbsCert = null;
423                 _X509TbsCert* pPrevTbsCert = null;
424
425                 do
426                 {
427                         pPrevCert = GetCurrentCertificate();
428                         SysTryReturnResult(NID_SEC_CERT, pPrevCert != null, E_SYSTEM, "Failed to get root certificate from chain, broken certificate chain.");
429
430                         if (pPrevCert->IsSelfSigned())
431                         {
432                                 // rootCA self verify
433                                 if (__checkValidity)
434                                 {
435                                         pPrevTbsCert = pPrevCert->GetTbsCertInstance();
436                                         SysTryReturnResult(NID_SEC_CERT, pPrevTbsCert != null, E_SYSTEM, "Failed to get root certificate to be signed instance.");
437
438                                         r = pPrevTbsCert->GetValidity();
439                                         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_INVALID_CERTIFICATE, "Root certificate validation failed (subject name: %s).", pPrevTbsCert->GetSubjectName());
440                                 }
441
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());
444                         }
445                         else
446                         {
447                                 if (MoveNext() == E_SUCCESS)
448                                 {
449                                         pPrevCert = GetCurrentCertificate();
450                                 }
451                                 count++;
452                                 break;
453                         }
454                 }
455                 while (MovePrev() == E_SUCCESS);
456
457                 while (MovePrev() == E_SUCCESS)
458                 {
459                         byte* pKey = null;
460                         count++;
461
462                         pCert = GetCurrentCertificate();
463                         SysTryReturnResult(NID_SEC_CERT, pCert != null, E_SYSTEM, "Failed to get certificate from chain, broken certificate chain.");
464
465                         pPrevTbsCert = pPrevCert->GetTbsCertInstance();
466                         SysTryReturnResult(NID_SEC_CERT, pPrevTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
467
468                         pTbsCert = pCert->GetTbsCertInstance();
469                         SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
470
471                         if (__checkValidity)
472                         {
473                                 r = pPrevTbsCert->GetValidity();
474                                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_INVALID_CERTIFICATE, "Certificate validation failed (subject name: %s).", pPrevTbsCert->GetSubjectName());
475                         }
476
477
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());
479
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());
482
483                         std::unique_ptr< byte[] > pKeyAuto(pKey);
484
485                         r = pCert->VerifySignature(pKey, keyLen);
486
487                         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_CERTIFICATE_VERIFICATION_FAILED, "Certificate signature verification failed (subject name: %s).", pTbsCert->GetSubjectName());
488
489                         pPrevCert = pCert;
490                 }
491         }
492
493         return E_SUCCESS;
494 }
495
496 result
497 _CertChain::VerifyCertChainWithDb(void)
498 {
499         result r = E_SUCCESS;
500         _CertDbManager* pCertDb = null;
501         byte* pCert = null;
502         int certLen = 0;
503         _CaCertType certType = _CERT_TYPE_NOT_BOUNDED;
504
505         r = MoveTail();
506         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "No certificate is present in certificate chain, failed to validate certificate chain.");
507
508         pCertDb = _CertDbManager::GetInstance();
509         SysTryReturnResult(NID_SEC_CERT, pCertDb != null, E_SYSTEM, "Failed to get instance of certificate database manager.");
510
511         if (__certFormat == _CERT_X509)
512         {
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.");
517
518                 if (pLastCert->IsSelfSigned())
519                 {
520                         pCertDb = _CertDbManager::GetInstance();
521                         SysTryReturnResult(NID_SEC_CERT, pCertDb != null, E_SYSTEM, "Failed to get instance of certificate database manager.");
522
523                         pTbsCert = pLastCert->GetTbsCertInstance();
524                         SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get root certificate to be signed instance.");
525
526                         if (GetContextType() == _CERT_CONTEXT_SSL)
527                         {
528                                 certType = _CERT_TYPE_ROOT_CA;
529                                 __checkValidity = true;
530
531                                 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
532                                 {
533                                         certType = _CERT_TYPE_ROOT_CA_BY_USER;
534                                         __checkValidity = true;
535
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());
538                                 }
539                         }
540                         else if (GetContextType() == _CERT_CONTEXT_MIDP || GetContextType() == _CERT_CONTEXT_DOMAIN || GetContextType() == _CERT_CONTEXT_DOMAIN_NO_VALIDITY)
541                         {
542                                 if (GetContextType() == _CERT_CONTEXT_DOMAIN_NO_VALIDITY)
543                                 {
544                                         __checkValidity = false;
545                                 }
546                                 else
547                                 {
548                                         __checkValidity = true;
549                                 }
550
551                                 certType = _CERT_TYPE_ROOT_DOMAIN1;
552                                 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
553                                 {
554                                         certType = _CERT_TYPE_ROOT_DOMAIN2;
555                                         if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
556                                         {
557                                                 certType = _CERT_TYPE_ROOT_DOMAIN3;
558                                                 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
559                                                 {
560                                                         certType = _CERT_TYPE_DEV_ROOT_DOMAIN1;
561                                                         if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
562                                                         {
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());
566                                                         }
567                                                 }
568                                         }
569                                 }
570                         }
571                         else if (GetContextType() == _CERT_CONTEXT_CERT || GetContextType() == _CERT_CONTEXT_CERT_NO_VALIDITY)
572                         {
573                                 if (GetContextType() == _CERT_CONTEXT_CERT)
574                                 {
575                                         __checkValidity = true;
576                                 }
577                                 else if (GetContextType() == _CERT_CONTEXT_CERT_NO_VALIDITY)
578                                 {
579                                         __checkValidity = false;
580                                 }
581
582                                 certType = _CERT_TYPE_TRUSTED_CA;
583                         }
584                         else if (GetContextType() == _CERT_CONTEXT_OSP_USER || GetContextType() == _CERT_CONTEXT_OSP_USER_NO_VALIDITY)
585                         {
586                                 if (GetContextType() == _CERT_CONTEXT_OSP_USER)
587                                 {
588                                         __checkValidity = true;
589                                 }
590                                 else if (GetContextType() == _CERT_CONTEXT_OSP_USER_NO_VALIDITY)
591                                 {
592                                         __checkValidity = false;
593                                 }
594
595                                 certType = _CERT_TYPE_ROOT_CA_BY_USER;
596
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());
599                         }
600                         else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL1 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL1_NO_VALIDITY)
601                         {
602                                 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL1)
603                                 {
604                                         __checkValidity = true;
605                                 }
606                                 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL1_NO_VALIDITY)
607                                 {
608                                         __checkValidity = false;
609                                 }
610
611                                 certType = _CERT_TYPE_OSP_CRITICAL1;
612
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());
615                         }
616                         else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL2 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL2_NO_VALIDITY)
617                         {
618                                 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL2)
619                                 {
620                                         __checkValidity = true;
621                                 }
622                                 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL2_NO_VALIDITY)
623                                 {
624                                         __checkValidity = false;
625                                 }
626
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());
630                         }
631                         else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL3 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL3_NO_VALIDITY)
632                         {
633                                 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL3)
634                                 {
635                                         __checkValidity = true;
636                                 }
637                                 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL3_NO_VALIDITY)
638                                 {
639                                         __checkValidity = false;
640                                 }
641                                 certType = _CERT_TYPE_OSP_CRITICAL3;
642
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());
645                         }
646                         else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL4 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL4_NO_VALIDITY)
647                         {
648                                 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL4)
649                                 {
650                                         __checkValidity = true;
651                                 }
652                                 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL4_NO_VALIDITY)
653                                 {
654                                         __checkValidity = false;
655                                 }
656                                 certType = _CERT_TYPE_OSP_CRITICAL4;
657
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());
660                         }
661                         else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL5 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL5_NO_VALIDITY)
662                         {
663                                 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL5)
664                                 {
665                                         __checkValidity = true;
666                                 }
667                                 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL5_NO_VALIDITY)
668                                 {
669                                         __checkValidity = false;
670                                 }
671                                 certType = _CERT_TYPE_OSP_CRITICAL5;
672
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());
675                         }
676                         else if (GetContextType() == _CERT_CONTEXT_OSP_PRELOAD_APP || GetContextType() == _CERT_CONTEXT_OSP_PRELOAD_APP_NO_VALIDITY)
677                         {
678                                 if (GetContextType() == _CERT_CONTEXT_OSP_PRELOAD_APP)
679                                 {
680                                         __checkValidity = true;
681                                 }
682                                 else if (GetContextType() == _CERT_CONTEXT_OSP_PRELOAD_APP_NO_VALIDITY)
683                                 {
684                                         __checkValidity = false;
685                                 }
686                                 certType = _CERT_TYPE_OSP_PRELOAD_APP;
687
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());
690                         }
691                         else if (GetContextType() == _CERT_CONTEXT_WRT)
692                         {
693                                 __checkValidity = true;
694                                 certType = _CERT_TYPE_WRT;
695
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());
698                         }
699                         else if (GetContextType() == _CERT_CONTEXT_TK)
700                         {
701                                 certType = _CERT_TYPE_ROOT_DOMAIN2;
702                                 __checkValidity = true;
703                                 if (!strcmp(_CERT_TK_ISSUER_NAME, reinterpret_cast< const char* >(pTbsCert->GetIssuerName())))
704                                 {
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());
707                                 }
708                                 else
709                                 {
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.");
712                                 }
713                         }
714                         else
715                         {
716                                 SysTryReturnResult(NID_SEC_CERT, false, E_SYSTEM, "Invalid context type.");
717                         }
718                         if (!IsFailed(r))
719                         {
720                                 //Set the format of root certificate
721                                 __rootCertType = certType;
722                         }
723
724                         delete[] pCert;
725                         return Verify();
726                 }
727                 else
728                 {
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.");
732
733
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)
739                         {
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)
743                                 {
744                                         certType = _CERT_TYPE_ROOT_CA_BY_USER;
745                                         __checkValidity = true;
746
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());
749                                 }
750                         }
751                         else if (GetContextType() == _CERT_CONTEXT_MIDP || GetContextType() == _CERT_CONTEXT_DOMAIN || GetContextType() == _CERT_CONTEXT_DOMAIN_NO_VALIDITY)
752                         {
753                                 if (GetContextType() == _CERT_CONTEXT_DOMAIN_NO_VALIDITY)
754                                 {
755                                         __checkValidity = false;
756                                 }
757                                 else
758                                 {
759                                         __checkValidity = true;
760                                 }
761                                 certType = _CERT_TYPE_ROOT_DOMAIN1;
762                                 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
763                                 {
764                                         certType = _CERT_TYPE_ROOT_DOMAIN2;
765                                         if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
766                                         {
767                                                 certType = _CERT_TYPE_ROOT_DOMAIN3;
768                                                 if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
769                                                 {
770                                                         certType = _CERT_TYPE_DEV_ROOT_DOMAIN1;
771                                                         if (pCertDb->FindIssuerCertificateByTypeN(_CERT_X509, certType, reinterpret_cast< char* >(pTbsCert->GetIssuerName()), &pCert, certLen) != E_SUCCESS)
772                                                         {
773                                                                 certType = _CERT_TYPE_DEV_ROOT_DOMAIN3;
774
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());
777                                                         }
778                                                 }
779                                         }
780                                 }
781                         }
782                         else if (GetContextType() == _CERT_CONTEXT_CERT || GetContextType() == _CERT_CONTEXT_CERT_NO_VALIDITY)
783                         {
784                                 if (GetContextType() == _CERT_CONTEXT_CERT)
785                                 {
786                                         __checkValidity = true;
787                                 }
788                                 else if (GetContextType() == _CERT_CONTEXT_CERT_NO_VALIDITY)
789                                 {
790                                         __checkValidity = false;
791                                 }
792
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());
795                         }
796                         else if (GetContextType() == _CERT_CONTEXT_OSP_USER || GetContextType() == _CERT_CONTEXT_OSP_USER_NO_VALIDITY)
797                         {
798                                 if (GetContextType() == _CERT_CONTEXT_OSP_USER)
799                                 {
800                                         __checkValidity = true;
801                                 }
802                                 else if (GetContextType() == _CERT_CONTEXT_OSP_USER_NO_VALIDITY)
803                                 {
804                                         __checkValidity = false;
805                                 }
806                                 certType = _CERT_TYPE_ROOT_CA_BY_USER;
807
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());
810                         }
811                         else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL1 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL1_NO_VALIDITY)
812                         {
813                                 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL1)
814                                 {
815                                         __checkValidity = true;
816                                 }
817                                 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL1_NO_VALIDITY)
818                                 {
819                                         __checkValidity = false;
820                                 }
821                                 certType = _CERT_TYPE_OSP_CRITICAL1;
822
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());
825                         }
826                         else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL2 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL2_NO_VALIDITY)
827                         {
828                                 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL2)
829                                 {
830                                         __checkValidity = true;
831                                 }
832                                 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL2_NO_VALIDITY)
833                                 {
834                                         __checkValidity = false;
835                                 }
836                                 certType = _CERT_TYPE_OSP_CRITICAL2;
837
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());
840                         }
841                         else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL3 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL3_NO_VALIDITY)
842                         {
843                                 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL3)
844                                 {
845                                         __checkValidity = true;
846                                 }
847                                 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL3_NO_VALIDITY)
848                                 {
849                                         __checkValidity = false;
850                                 }
851                                 certType = _CERT_TYPE_OSP_CRITICAL3;
852
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());
855                         }
856                         else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL4 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL4_NO_VALIDITY)
857                         {
858                                 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL4)
859                                 {
860                                         __checkValidity = true;
861                                 }
862                                 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL4_NO_VALIDITY)
863                                 {
864                                         __checkValidity = false;
865                                 }
866                                 certType = _CERT_TYPE_OSP_CRITICAL4;
867
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());
870                         }
871                         else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL5 || GetContextType() == _CERT_CONTEXT_OSP_CRITICAL5_NO_VALIDITY)
872                         {
873                                 if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL5)
874                                 {
875                                         __checkValidity = true;
876                                 }
877                                 else if (GetContextType() == _CERT_CONTEXT_OSP_CRITICAL5_NO_VALIDITY)
878                                 {
879                                         __checkValidity = false;
880                                 }
881                                 certType = _CERT_TYPE_OSP_CRITICAL5;
882
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());
885                         }
886                         else if (GetContextType() == _CERT_CONTEXT_OSP_PRELOAD_APP || GetContextType() == _CERT_CONTEXT_OSP_PRELOAD_APP_NO_VALIDITY)
887                         {
888                                 if (GetContextType() == _CERT_CONTEXT_OSP_PRELOAD_APP)
889                                 {
890                                         __checkValidity = true;
891                                 }
892                                 else if (GetContextType() == _CERT_CONTEXT_OSP_PRELOAD_APP_NO_VALIDITY)
893                                 {
894                                         __checkValidity = false;
895                                 }
896                                 certType = _CERT_TYPE_OSP_PRELOAD_APP;
897
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());
900                         }
901                         else if (GetContextType() == _CERT_CONTEXT_WRT)
902                         {
903                                 __checkValidity = true;
904                                 certType = _CERT_TYPE_WRT;
905
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());
908                         }
909                         else if (GetContextType() == _CERT_CONTEXT_TK)
910                         {
911                                 certType = _CERT_TYPE_ROOT_DOMAIN2;
912                                 __checkValidity = true;
913
914                                 if (!strcmp(_CERT_TK_ISSUER_NAME, reinterpret_cast< const char* >(pTbsCert->GetIssuerName())))
915                                 {
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());
918                                 }
919                                 else
920                                 {
921                                         SysTryReturnResult(NID_SEC_CERT, false, E_INACCESSIBLE_PATH, "Failed to access specified certificate path.");
922                                 }
923                         }
924                         else
925                         {
926                                 SysTryReturnResult(NID_SEC_CERT, false, E_SYSTEM, "Invalid context type.");
927                         }
928
929                         if (pCert != null)
930                         {
931                                 std::unique_ptr< byte[] > pCertAuto(pCert);
932
933                                 //Add newly found root certificate in chain for verification.
934                                 r = AddCertificate(__certFormat, reinterpret_cast< byte* >(pCert), certLen);
935
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
938                                 r = Verify();
939                                 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to verify certificate chain.", GetErrorMessage(r));
940                         }
941                         else
942                         {
943                                 SysTryReturnResult(NID_SEC_CERT, false, E_DATA_NOT_FOUND, "Parent certificate not found in certificate database.");
944                         }
945
946                         if (!IsFailed(r))
947                         {
948                                 //Set the format of root certificate
949                                 __rootCertType = certType;
950                         }
951                 }
952         }
953
954         return r;
955 }
956
957 int
958 _CertChain::GetCount(void)
959 {
960         return __certChain.GetCount();
961 }
962
963 void
964 _CertChain::SetContextType(_CertContextType type)
965 {
966         __contextType = type;
967 }
968
969 _CertContextType
970 _CertChain::GetContextType(void)
971 {
972         return __contextType;
973 }
974
975 _CertFormat
976 _CertChain::GetCertFormat(void)
977 {
978         return __certFormat;
979 }
980
981 void
982 _CertChain::RemoveHead(bool freeFlag)
983 {
984         __certChain.RemoveAt(0, freeFlag);
985 }
986
987 void
988 _CertChain::RemoveTail(bool freeFlag)
989 {
990         if (__certChain.GetCount() > 0)
991         {
992                 __certChain.RemoveAt(__certChain.GetCount() - 1, freeFlag);
993         }
994 }
995
996 } } } //Tizen::Security::Cert