71ddfe273b9da2c1c212e7db78f1534a7b96566f
[platform/framework/native/appfw.git] / src / security / cert / FSecCert_CertDbManager.cpp
1 //
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Apache License, Version 2.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 /**
18  * @file                FSecCert_CertDbManager.cpp
19  * @brief               This file contains implementation of X509 Certificate Db Manager APIs.
20 */
21
22 #include <stdio.h>
23 #include <string.h>
24 #include <stdlib.h>
25 #include <error.h>
26 #include <new>
27 #include <sys/stat.h>
28 #include <assert.h>
29 #include <dirent.h>
30 #include <openssl/evp.h>
31 #include <openssl/pem.h>
32 #include <unique_ptr.h>
33 #include <pthread.h>
34 #include <FIoFile.h>
35 #include <FBaseSysLog.h>
36 #include <FBaseByteBuffer.h>
37 #include <FBaseResult.h>
38 #include <FBase_StringConverter.h>
39 #include "FSecCert_CertDbStore.h"
40 #include "FSecCert_CertFileStore.h"
41 #include "FSecCert_CertDbManager.h"
42 #include "FSecCert_Base64.h"
43 #include "FSecCert_CertService.h"
44 #include "FSecCert_CertManager.h"
45
46 using namespace Tizen::Base;
47 using namespace Tizen::Io;
48
49 namespace
50 {
51 struct ByteDeleter
52 {
53         void operator ()(byte* c)
54         {
55                 free(c);
56         }
57 };
58 }
59
60 namespace Tizen { namespace Security { namespace Cert
61 {
62 _CertDbManager* _CertDbManager::__pCertDb = null;
63
64 _CertDbManager::_CertDbManager(void)
65 {
66 }
67
68 _CertDbManager::~_CertDbManager(void)
69 {
70 }
71
72 void
73 _CertDbManager::Construct(void)
74 {
75         static _CertDbManager certDb;
76         __pCertDb = &certDb;
77 }
78
79
80 _CertDbManager*
81 _CertDbManager::GetInstance(void)
82 {
83         static pthread_once_t once_block = PTHREAD_ONCE_INIT;
84         if (__pCertDb == null)
85         {
86                 pthread_once(&once_block, Construct);
87         }
88
89         return __pCertDb;
90 }
91
92 result
93 _CertDbManager::CreateCertificateTables(void)
94 {
95         result r = E_SUCCESS;
96
97         r = __caCertDbStore.CreateCertificateTables();
98         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to create certificate tables in database.");
99
100         return E_SUCCESS;
101 }
102
103 bool
104 _CertDbManager::IsCertificateTablesCreated(void)
105 {
106         result r = E_SUCCESS;
107
108         r = __caCertDbStore.IsRootCaCertTableCreated();
109         if (r != E_SUCCESS)
110         {
111                 SetLastResult(E_SYSTEM);
112                 return false;
113         }
114
115         r = __userCertDbStore.IsUserCertTableCreated();
116         if (r != E_SUCCESS)
117         {
118                 SetLastResult(E_SYSTEM);
119                 return false;
120         }
121
122         return true;
123 }
124
125 result
126 _CertDbManager::ResetCertificateTables(void)
127 {
128         result r = E_SUCCESS;
129
130         r = __caCertDbStore.DropCertificateTables();
131         SysTryReturn(NID_SEC_CERT, !IsFailed(r), false, E_SYSTEM, "[E_SYSTEM] Failed to drop certificate tables in database.");
132
133         r = __caCertDbStore.CreateCertificateTables();
134         SysTryReturn(NID_SEC_CERT, !IsFailed(r), false, E_SYSTEM, "[E_SYSTEM] Failed to create certificate tables in database.");
135
136         return E_SUCCESS;
137 }
138
139 result
140 _CertDbManager::RemoveCertificateTables(void)
141 {
142         result r = E_SUCCESS;
143         r = __caCertDbStore.DropCertificateTables();
144         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to delete all the certificate tables in database.");
145         return E_SUCCESS;
146 }
147
148 result
149 _CertDbManager::RemoveCaCertificateByType(_CaCertType certType)
150 {
151         result r = E_SUCCESS;
152         char condition[_MAX_TYPE_CONST_SIZE] = {0, };
153         char installed[_MAX_TYPE_RECORD_SIZE] = "T\0";
154
155         snprintf(condition, _MAX_TYPE_CONST_SIZE, "certType = %d and installed = '%s'", certType, installed);
156
157         r = __caCertDbStore.RemoveAllCertificateByCondition(reinterpret_cast< byte* >(condition));
158         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to delete all the certificate tables in database.");
159
160         return E_SUCCESS;
161 }
162
163 result
164 _CertDbManager::RemoveUserCaCertificateByCertId(int certId)
165 {
166         result r = E_SUCCESS;
167         char condition[_MAX_TYPE_CONST_SIZE] = {0, };
168         char installed[_MAX_TYPE_RECORD_SIZE] = "T\0";
169
170         snprintf(condition, _MAX_TYPE_CONST_SIZE, "certId = %d and certType = %d and installed = '%s'", certId, _CERT_TYPE_ROOT_CA_BY_USER, installed);
171         r = __caCertDbStore.RemoveAllCertificateByCondition(reinterpret_cast< byte* >(condition));
172         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to delete all the certificate tables in database.");
173
174         return E_SUCCESS;
175 }
176
177 result
178 _CertDbManager::InsertDefaultCaCertificateFromBuffer(_CaCertType certType, _CertFormat certFormat, byte* pCertBuf, int certLen)
179 {
180         return InsertCaCertificateFromBuffer(certType, certFormat, pCertBuf, certLen, false);
181 }
182
183 result
184 _CertDbManager::InsertCaCertificateFromBuffer(_CaCertType certType, _CertFormat certFormat, byte* pCertBuf, int certLen, bool checkValidity)
185 {
186         result r = E_SUCCESS;
187         String tempFileName;
188         CaCertRecord certRecord = {0, };
189         _CertFileStore fileStore;
190         _CertFormat certBufFormat = _CERT_UNKNOWN;
191         _CertEncodingType encodingType = _CERT_ENC_TYPE_UNKNOWN;
192         int lenSubjectName = 0;
193         int lenIssuerName = 0;
194         int lenSerialNo = 0;
195         int certId = 0;
196         int derCertBufferLength = 0;
197         char serialName[_MAX_SERIAL_NUMBER_SIZE] = {0, };
198         char installed[_MAX_TYPE_RECORD_SIZE] = "T\0";
199         char subjectName[_MAX_ISSUER_SUBJECT_NAME_SIZE] = {0, };
200         char issuerName[_MAX_ISSUER_SUBJECT_NAME_SIZE] = {0, };
201         byte* pDerCert = null;
202         byte* pSerial = null;
203         _X509TbsCert* pTbsCert = null;
204
205         r = __caCertDbStore.IsRootCaCertTableCreated();
206         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Root certificate tables are not created in database.");
207
208         std::unique_ptr< _X509Certificate > pCert(new (std::nothrow) _X509Certificate());
209         SysTryReturnResult(NID_SEC_CERT, pCert != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
210
211         certBufFormat = _CertManager::GetEncodedCertBuffer(pCertBuf, certLen, &pDerCert, &derCertBufferLength, &encodingType);
212         std::unique_ptr< byte, ByteDeleter > pDerCertBuffer(pDerCert);
213         pDerCert = null;
214         SysTryReturnResult(NID_SEC_CERT, pDerCertBuffer != null, E_INVALID_CONDITION, "Input certificate buffer.");
215         SysTryReturnResult(NID_SEC_CERT, certBufFormat == _CERT_X509, E_INVALID_CONDITION, "Unsupported certificate format.");
216         SysTryReturnResult(NID_SEC_CERT, derCertBufferLength > 0, E_INVALID_CONDITION, "Invalid certificate length.");
217
218         r = pCert->Parse(pDerCertBuffer.get(), derCertBufferLength);
219         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_DECODING_FAILED, "Decoding failed.");
220
221         pTbsCert = pCert->GetTbsCertInstance();
222         SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
223
224         lenSubjectName = strlen(reinterpret_cast< const char* >(pTbsCert->GetSubjectName()));
225         lenIssuerName = strlen(reinterpret_cast< const char* >(pTbsCert->GetIssuerName()));
226
227         SysTryReturnResult(NID_SEC_CERT, lenSubjectName < _MAX_ISSUER_SUBJECT_NAME_SIZE, E_SYSTEM, "Subject name is more then maximum specified length.");
228         SysTryReturnResult(NID_SEC_CERT, lenIssuerName < _MAX_ISSUER_SUBJECT_NAME_SIZE, E_SYSTEM, "Subject name is more then maximum specified length.");
229
230         strncpy(subjectName, reinterpret_cast< const char* >(pTbsCert->GetSubjectName()),lenSubjectName);
231         strncpy(issuerName, reinterpret_cast< const char* >(pTbsCert->GetIssuerName()),lenIssuerName);
232
233         pTbsCert->GetSerialNumber(pSerial, reinterpret_cast< int& >(lenSerialNo));
234         if ((lenSerialNo <= 0) || (lenSerialNo > _MAX_SERIAL_NUMBER_SIZE))
235         {
236                 memset(pSerial, 0, _MAX_SERIAL_NUMBER_SIZE);
237                 lenSerialNo = 1;
238         }
239         else
240         {
241                 memcpy(serialName, pSerial, lenSerialNo);
242         }
243
244         if (checkValidity)
245         {
246                 if (pCert->IsSelfSigned())
247                 {
248                         r = pCert->VerifySignature(null, 0);
249                         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_INVALID_CONTENT, "Invalid data.");
250                 }
251 #ifdef _CERT_VERIFY_AND_INSTALL_CERTIFICATE
252                 //Open this code - if u want to support installation of Intermediate CA Certificate with verification using this API.(ideally it should check if installing intermediate CA) (09082011)
253                 else if (pCert->IsCaCertificate())
254                 {
255                         std::unique_ptr< _CertChain > pCertChain(new (std::nothrow) _CertChain());
256                         SysTryReturnResult(NID_SEC_CERT, pCertChain != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
257
258                         r = pCertChain->AddCertificate(certFormat, pDerCertBuffer.get(), derCertBufferLength);
259                         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_INVALID_CONTENT, "AddCertificate failed.");
260
261                         r = pCertChain->MoveHead();
262                         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_INVALID_CONTENT, "MoveHead failed.");
263
264
265                         // It support only RSA, For ECC Certificate if you want to omit this, block this call or check as per algo id
266                         //(there are ECC certificate installation which we support for china model. hence these comments)
267                         r = pCertChain->VerifyCertChainWithDb();
268                         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to verify certificate chain.");
269                 }
270 #endif
271
272 #ifdef _CERT_INSTALL_ONLY_CA_CERTIFICATE
273                 //Open this code - if u want to support only CA Certificate installation using this API.(ideally it should check)
274                 else
275                 {
276                         return E_UNSUPPORTED_OPERATION;
277                 }
278 #endif
279
280         }
281
282         r = __caCertDbStore.CheckDuplicateCertificate(certType, reinterpret_cast< byte* >(subjectName), lenSubjectName);
283         if (!IsFailed(r))
284         {
285                 return E_FILE_ALREADY_EXIST;
286         }
287
288         SysTryReturnResult(NID_SEC_CERT, r == E_DATA_NOT_FOUND, r, "Failed to check duplicate");
289
290
291         //Get the last installed certificate id from db table
292         __caCertDbStore.GetCurrentCertId(certId);
293         //Calculate the new (std::nothrow) certificate id for installation
294         certId = certId + 1;
295         fileStore.GetFileNameFromHandle(certId, _CERT_PATH_CA_CERT, tempFileName);
296
297         memset(&certRecord, 0, sizeof(certRecord));
298         certRecord.certType = static_cast< int >(certType);
299         certRecord.certFormat = static_cast< int >(certFormat);
300
301         std::unique_ptr< char[] > pFileName(Tizen::Base::_StringConverter::CopyToCharArrayN(tempFileName));
302         SysTryReturnResult(NID_SEC_CERT, pFileName != null, E_SYSTEM, "Failed to get file attributes.");
303
304         int len = strlen(pFileName.get());
305         strncpy(certRecord.fileName, pFileName.get(), len);
306
307         certRecord.subjectNameLen = lenSubjectName;
308         memcpy(certRecord.subjectName, subjectName, lenSubjectName);
309         certRecord.issuerNameLen = lenIssuerName;
310         memcpy(certRecord.issuerName, issuerName, lenIssuerName);
311         certRecord.parentCa = certId;
312         strcpy(certRecord.installed, installed);
313         memcpy(certRecord.serialNo, serialName, lenSerialNo);
314         certRecord.serialNoLen = lenSerialNo;
315
316         r = __caCertDbStore.InsertCaCertificate(&certRecord);
317         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Certificate record insertion failed.", GetErrorMessage(r));
318
319         fileStore.SetFilePath(tempFileName);
320
321         r = fileStore.WriteToFile(pDerCertBuffer.get(), derCertBufferLength);
322         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_INACCESSIBLE_PATH, "Path inaccessible.");
323
324         return r;
325
326 }
327
328 result
329 _CertDbManager::UpdateCaCertificateFromBuffer(_CaCertType certType, _CertFormat certFormat, byte* pCurCertBuf, int curCertLen, byte* pNewCertBuf, int newCertLen)
330 {
331         result r = E_SUCCESS;
332         String tempFileName;
333         CaCertRecord certRecord = {0, };
334         CaCertRecord certRecord1 = {0, };
335         _CertFileStore fileStore;
336         _X509TbsCert* pTbsCert = null;
337         _X509TbsCert* pNewTbsCert = null;
338         int lenSubjectName = 0;
339         int lenNewSubjectName = 0;
340         int lenIssuerName = 0;
341         int lenNewIssuerName = 0;
342         int lenNewSerialNo = 0;
343         int certId = 0;
344         int subjNameB64len = 0;
345         char subjectNameBase64[_MAX_ISSUER_SUBJECT_NAME_SIZE] = {0, };
346         char newSubjectName[_MAX_ISSUER_SUBJECT_NAME_SIZE] = {0, };
347         char newIssuerName[_MAX_ISSUER_SUBJECT_NAME_SIZE] = {0, };
348         char newSerialName[_MAX_SERIAL_NUMBER_SIZE] = {0, };
349         char installed[_MAX_TYPE_RECORD_SIZE] = "T\0";
350         char condition[_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_SUBJECT_OFFSET_SIZE] = {0, };
351         byte* pNewSerial = null;
352
353         r = __caCertDbStore.IsRootCaCertTableCreated();
354         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Root certificate tables are not created in database.");
355
356         std::unique_ptr< _X509Certificate > pCert(new (std::nothrow) _X509Certificate());
357         SysTryReturnResult(NID_SEC_CERT, pCert != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
358
359         r = pCert->Parse(pCurCertBuf, curCertLen);
360         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_DECODING_FAILED, "Parse failed.");
361
362         pTbsCert = pCert->GetTbsCertInstance();
363         SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
364
365         lenSubjectName = strlen(reinterpret_cast< char* >(pTbsCert->GetSubjectName()));
366         lenIssuerName = strlen(reinterpret_cast< char* >(pTbsCert->GetIssuerName()));
367
368         SysTryReturnResult(NID_SEC_CERT, lenSubjectName < _MAX_ISSUER_SUBJECT_NAME_SIZE, E_SYSTEM, "Subject name exceeds allowable length.");
369         SysTryReturnResult(NID_SEC_CERT, lenIssuerName < _MAX_ISSUER_SUBJECT_NAME_SIZE, E_SYSTEM, "Subject name exceeds allowable length.");
370
371         r = __caCertDbStore.CheckDuplicateCertificate(certType, pTbsCert->GetSubjectName(), lenSubjectName);
372         if (!IsFailed(r)) //checkit
373         {
374                 subjNameB64len = _Base64::GetEncodedSize(lenSubjectName);
375                 SysTryReturnResult(NID_SEC_CERT, subjNameB64len >= 0, E_ENCODING_FAILED, "Failed to encode data in base 64 encoding.");
376
377                 memset(subjectNameBase64, 0, sizeof(subjectNameBase64));
378
379                 r = _Base64::Encode(pTbsCert->GetSubjectName(), lenSubjectName, subjectNameBase64, subjNameB64len);
380                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_ENCODING_FAILED, "Failed to encode data in base 64 encoding.");
381
382                 snprintf(condition, (_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_SUBJECT_OFFSET_SIZE), "subjectName = '%s' and certType = %d and installed = '%s'", subjectNameBase64, certType, installed);
383                 r = __caCertDbStore.GetFirstRecordByConditions(reinterpret_cast< byte* >(condition), &certRecord);
384                 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to get certificates record.", GetErrorMessage(r));
385
386                 certId = certRecord.parentCa;
387
388                 fileStore.GetFileNameFromHandle(certId, _CERT_PATH_CA_CERT, tempFileName);
389                 fileStore.SetFilePath(tempFileName);
390
391                 if (certFormat == _CERT_X509)
392                 {
393                         std::unique_ptr< _X509Certificate > pNewCert(new (std::nothrow) _X509Certificate());
394                         SysTryReturnResult(NID_SEC_CERT, pNewCert != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
395
396                         r = pNewCert->Parse(pNewCertBuf, newCertLen);
397                         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_DECODING_FAILED, "Decoding failed.");
398
399                         pNewTbsCert = pNewCert->GetTbsCertInstance();
400                         SysTryReturnResult(NID_SEC_CERT, pNewTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
401
402                         lenSubjectName = strlen(reinterpret_cast< char* >(pNewTbsCert->GetSubjectName()));
403                         lenIssuerName = strlen(reinterpret_cast< char* >(pNewTbsCert->GetIssuerName()));
404
405                         strncpy(newSubjectName, reinterpret_cast< const char* >(pNewTbsCert->GetSubjectName()),lenSubjectName);
406                         strncpy(newIssuerName, reinterpret_cast< const char* >(pNewTbsCert->GetIssuerName()),lenIssuerName);
407
408                         lenNewSubjectName = strlen(newSubjectName);
409                         lenNewIssuerName = strlen(newIssuerName);
410
411                         pNewTbsCert->GetSerialNumber(pNewSerial, reinterpret_cast< int& >(lenNewSerialNo));
412                         if ((lenNewSerialNo <= 0) || (lenNewSerialNo > _MAX_SERIAL_NUMBER_SIZE))
413                         {
414                                 memset(pNewSerial, 0, _MAX_SERIAL_NUMBER_SIZE);
415                                 lenNewSerialNo = 1;
416
417                         }
418                         else
419                         {
420                                 memcpy(newSerialName, pNewSerial, lenNewSerialNo);
421                         }
422
423                         SysTryReturnResult(NID_SEC_CERT, lenNewSubjectName < _MAX_ISSUER_SUBJECT_NAME_SIZE, E_SYSTEM, "Subject name length exceeds specified length.");
424                         SysTryReturnResult(NID_SEC_CERT, lenNewIssuerName < _MAX_ISSUER_SUBJECT_NAME_SIZE, E_SYSTEM, "Subject name length exceeds specified length.");
425                 }
426                 certRecord1.certType = static_cast< int >(certType);
427                 certRecord1.certFormat = static_cast< int >(certFormat);
428
429                 std::unique_ptr< char[] > pFileName(Tizen::Base::_StringConverter::CopyToCharArrayN(tempFileName));
430                 SysTryReturnResult(NID_SEC_CERT, pFileName != null, E_OPERATION_FAILED, "Failed to get file name.");
431
432                 int len = strlen(pFileName.get());
433                 strncpy(certRecord1.fileName, pFileName.get(), len);
434
435                 certRecord1.subjectNameLen = lenNewSubjectName;
436                 memcpy(certRecord1.subjectName, newSubjectName, lenNewSubjectName);
437                 certRecord1.issuerNameLen = lenIssuerName;
438                 memcpy(certRecord1.issuerName, newIssuerName, lenNewIssuerName);
439                 certRecord1.parentCa = certId;
440                 strcpy(certRecord1.installed, certRecord.installed);
441                 memcpy(certRecord1.serialNo, newSerialName, lenNewSerialNo);
442                 certRecord1.serialNoLen = lenNewSerialNo;
443
444                 r = __caCertDbStore.UpdateCaCertificate(&certRecord, &certRecord1);
445                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_OPERATION_FAILED, "Failed to update ca certificate.");
446
447                 fileStore.DeleteFile();
448
449                 r = fileStore.WriteToFile(pNewCertBuf, newCertLen);
450                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_INACCESSIBLE_PATH, "Path does not exist.");
451                 //No need to update record as only file data changed.
452                 return E_SUCCESS;
453         }
454
455         return r;
456 }
457
458 result
459 _CertDbManager::RemoveCaCertificateFromBuffer(_CaCertType certType, _CertFormat certFormat, byte* pCertBuf, int certLen)
460 {
461         result r = E_SUCCESS;
462         _X509TbsCert* pTbsCert = null;
463         String fileName;
464         _CertFileStore fileStore;
465         int certId = 0;
466
467         //Check certType missing
468
469         r = __caCertDbStore.IsRootCaCertTableCreated();
470         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_OBJ_NOT_FOUND, "No root certificate tables are create in databased.");
471
472         std::unique_ptr< _X509Certificate > pCert(new (std::nothrow) _X509Certificate());
473         SysTryReturnResult(NID_SEC_CERT, pCert != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
474
475         r = pCert->Parse(pCertBuf, certLen);
476         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Parsing failed.");
477
478         pTbsCert = pCert->GetTbsCertInstance();
479         SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
480
481         r = __caCertDbStore.CheckDuplicateCertificate(certType, pTbsCert->GetSubjectName(), strlen(reinterpret_cast< char* >(pTbsCert->GetSubjectName())));
482         SysTryReturnResult(NID_SEC_CERT, r != E_DATA_NOT_FOUND, E_OBJ_NOT_FOUND, "Certificate not found in db.");
483         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), r, "Propagated.");
484
485         r = GetCaCertificateId(pTbsCert->GetSubjectName(), strlen(reinterpret_cast< char* >(pTbsCert->GetSubjectName())),
486                                                    pTbsCert->GetIssuerName(), strlen(reinterpret_cast< char* >(pTbsCert->GetIssuerName())),
487                                                    certId, certType);
488         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed get ca certificate id.", GetErrorMessage(r));
489
490
491         r = __caCertDbStore.RemoveCertificateById(certId);
492         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to delete certificate with certificate id (%d).", certId);
493
494         //Delete File
495         fileStore.GetFileNameFromHandle(certId, _CERT_PATH_CA_CERT, fileName);
496         Tizen::Io::File::Remove(fileName);
497
498         return r;
499 }
500
501
502 result
503 _CertDbManager::RemoveCertificateChainByCertId(int certId)
504 {
505         result r = E_SUCCESS;
506         char condition[_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_SUBJECT_OFFSET_SIZE] = {0, };
507         UserCertRecord userCertRecord = {0, };
508
509         memset(&userCertRecord, 0, sizeof(userCertRecord));
510         memset(condition, 0, _MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_SUBJECT_OFFSET_SIZE);
511
512         snprintf(condition, (_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_SUBJECT_OFFSET_SIZE), "certId = %d", certId);
513         r = __userCertDbStore.GetFirstRecordByConditions(reinterpret_cast< byte* >(condition), &userCertRecord);
514         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r) || r == E_DATA_NOT_FOUND, E_SYSTEM, "Failed to get certificate record.");
515         SysTryReturnResult(NID_SEC_CERT, r != E_DATA_NOT_FOUND, E_SUCCESS, "No such record found.");
516
517         r = DeleteCertificateChain(userCertRecord.certId, userCertRecord.parentCa);
518         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "File deletion failed for certificate Id (%d).", certId);
519
520         return r;
521 }
522
523
524 result
525 _CertDbManager::GetCaCertificateId(byte* pSubjectName, int subjectNameSize, byte* pIssuerName, int issuerNameSize, int& certId, _CaCertType certType)
526 {
527         result r = E_SUCCESS;
528         int subjNameB64len = 0;
529         int issuerB64len = 0;
530         char subjectNameBase64[_MAX_ISSUER_SUBJECT_NAME_SIZE] = {0, };
531         char issuerNameBase64[_MAX_ISSUER_SUBJECT_NAME_SIZE] = {0, };
532         char condition[_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_SUBJECT_OFFSET_SIZE] = {0, };
533         char installed[_MAX_TYPE_RECORD_SIZE] = "T\0";
534         CaCertRecord caCertRecord = {0, };
535
536         SysTryReturnResult(NID_SEC_CERT, pSubjectName != null, E_INVALID_ARG, "Invalid subject name.");
537         SysTryReturnResult(NID_SEC_CERT, subjectNameSize > 0, E_INVALID_ARG, "Invalid subject name length.");
538
539         subjNameB64len = _Base64::GetEncodedSize(subjectNameSize);
540         memset(subjectNameBase64, 0, sizeof(subjectNameBase64));
541
542         r = _Base64::Encode(pSubjectName, subjectNameSize, subjectNameBase64, subjNameB64len);
543         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_ENCODING_FAILED, "Failed to encode data in base 64 encoding.");
544
545         memset(condition, 0, sizeof(condition));
546
547         if (pIssuerName != null && issuerNameSize > 0)
548         {
549                 issuerB64len = _Base64::GetEncodedSize(issuerNameSize);
550                 memset(issuerNameBase64, 0, sizeof(issuerNameBase64));
551
552                 r = _Base64::Encode(pIssuerName, issuerNameSize, issuerNameBase64, issuerB64len);
553                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_ENCODING_FAILED, "Failed to encode data in base 64 encoding.");
554
555                 if (certType == _CERT_TYPE_NOT_BOUNDED)
556                 {
557                         snprintf(condition, (_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_SUBJECT_OFFSET_SIZE), "subjectName = '%s' and issuerName = '%s' and installed = '%s'", subjectNameBase64, issuerNameBase64, installed);
558                 }
559                 else
560                 {
561                         snprintf(condition, (_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_SUBJECT_OFFSET_SIZE), "subjectName = '%s' and issuerName = '%s' and certType = %d and installed = '%s'", subjectNameBase64, issuerNameBase64, certType, installed);
562                 }
563         }
564         else
565         {
566                 if (certType == _CERT_TYPE_NOT_BOUNDED)
567                 {
568                         snprintf(condition, (_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_SUBJECT_OFFSET_SIZE), "subjectName = '%s' and installed = '%s'", subjectNameBase64, installed);
569                 }
570                 else
571                 {
572                         snprintf(condition, (_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_SUBJECT_OFFSET_SIZE), "subjectName = '%s' and certType = %d and installed = '%s'", subjectNameBase64, certType, installed);
573                 }
574         }
575
576         r = __caCertDbStore.GetFirstRecordByConditions(reinterpret_cast< byte* >(condition), &caCertRecord);
577         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to get certificates record.", GetErrorMessage(r));
578
579         certId = caCertRecord.certId;
580
581         return E_SUCCESS;
582 }
583
584 result
585 _CertDbManager::GetUserCertificateId(byte* pSubjectName, int subjectNameSize, byte* pIssuerName, int issuerNameSize, int& certId)
586 {
587         result r = E_SUCCESS;
588         int subjNameB64len = 0;
589         int issuerB64len = 0;
590         char subjectNameBase64[_MAX_ISSUER_SUBJECT_NAME_SIZE] = {0, };
591         char issuerNameBase64[_MAX_ISSUER_SUBJECT_NAME_SIZE] = {0, };
592         char condition[_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_ISSUER_SUBJECT_NAME_SIZE] = {0, };
593         char installed[_MAX_TYPE_RECORD_SIZE] = "T\0";
594         UserCertRecord userCertRecord = {0, };
595
596         SysTryReturnResult(NID_SEC_CERT, pSubjectName != null, E_INVALID_ARG, "Invalid subject name.");
597         SysTryReturnResult(NID_SEC_CERT, subjectNameSize > 0, E_INVALID_ARG, "Invalid subject name length.");
598
599         subjNameB64len = _Base64::GetEncodedSize(subjectNameSize);
600         memset(subjectNameBase64, 0, sizeof(subjectNameBase64));
601
602         r = _Base64::Encode(reinterpret_cast< byte* >(pSubjectName), subjectNameSize, subjectNameBase64, subjNameB64len);
603         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_ENCODING_FAILED, "Failed to encode data in base 64 encoding.");
604
605         memset(condition, 0, sizeof(condition));
606
607         if (pIssuerName != null && issuerNameSize > 0)
608         {
609                 issuerB64len = _Base64::GetEncodedSize(issuerNameSize);
610                 memset(issuerNameBase64, 0, sizeof(issuerNameBase64));
611
612                 r = _Base64::Encode(reinterpret_cast< byte* >(pIssuerName), issuerNameSize, issuerNameBase64, issuerB64len);
613                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_ENCODING_FAILED, "Failed to encode data in base 64 encoding.");
614
615                 snprintf(condition, (_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_ISSUER_SUBJECT_NAME_SIZE), "subjectName = '%s' and issuerName = '%s' and installed = '%s'", subjectNameBase64, issuerNameBase64, installed);
616         }
617         else
618         {
619                 snprintf(condition, (_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_ISSUER_SUBJECT_NAME_SIZE), "subjectName = '%s' and installed = '%s'", subjectNameBase64, installed);
620         }
621
622         r = __userCertDbStore.GetFirstRecordByConditions(reinterpret_cast< byte* >(condition), &userCertRecord);
623         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to get certificate record.", GetErrorMessage(r));
624
625         certId = userCertRecord.certId;
626
627         return E_SUCCESS;
628 }
629
630 result
631 _CertDbManager::RemoveAllUserCertificate(void)
632 {
633         __userCertDbStore.DeleteUserCertFiles();
634
635         return E_SUCCESS;
636 }
637
638 result
639 _CertDbManager::DeleteCertificateChain(int devCertId, int devParentCA)
640 {
641         result r = E_SUCCESS;
642         CaCertRecord certRecord = {0, };
643         int recCount = 0;
644         int caCertId = 0;
645         int caParentCa = 0;
646         char installed[_MAX_TYPE_RECORD_SIZE] = "T\0";
647         char condition[_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_SUBJECT_OFFSET_SIZE] = {0, };
648         bool devCert = true;
649
650         SysTryReturnResult(NID_SEC_CERT, devCertId > 0, E_INVALID_ARG, "Invalid input argument.");
651         SysTryReturnResult(NID_SEC_CERT, devParentCA > 0, E_INVALID_ARG, "Invalid input argument.");
652
653         memset(condition, 0, _MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_SUBJECT_OFFSET_SIZE);
654
655         snprintf(condition, (_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_SUBJECT_OFFSET_SIZE), "parentCa = %d and installed = '%s'", devParentCA, installed);
656         //Check if any other device certificate has same parent as of referred device certificare. If it is yes then we
657         //delete only device certificate and return. We cannot disturb another chain.
658         __userCertDbStore.GetCountByCondition(reinterpret_cast< byte* >(&condition), recCount);
659         //More than one device certificate found which is referring same intermidiate CA or ROOT CA. So just delete device certificate and return.
660         if (recCount > 1)
661         {
662                 r = DeleteCertificateByIdNTableName(devCertId, _CERT_USER_CERT_TABLE);
663                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_OPERATION_FAILED, "Failed to delete certificate.");
664
665                 return E_SUCCESS;
666         }
667         //Now there is not two device certificate with same intermidiate CA,
668         //so go ahead to intermidiate CA and delete device certificate.
669         caParentCa = devParentCA;
670         caCertId = devCertId;
671         do
672         {
673                 if (__caCertDbStore.CheckIfSameParent(caParentCa) == E_SUCCESS)
674                 {
675                         if (devCert)
676                         {
677                                 r = DeleteCertificateByIdNTableName(caCertId, _CERT_USER_CERT_TABLE);
678                                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_OPERATION_FAILED, "Failed to delete certificate.");
679
680                                 devCert = false; //Device certificate is deleted here now go to CA certificate for deletion
681                                 SysLog(NID_SEC_CERT, "Device certificate is deleted here now go to CA certificate for deletion.");
682                                 break; // break here next certificate has dependency
683                         }
684                         else
685                         {
686                                 r = DeleteCertificateByIdNTableName(caCertId, _CERT_ROOT_CA_CERT_TABLE);
687                                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_OPERATION_FAILED, "Failed to delete certificate.");
688
689                                 break; // break here next certificate has dependency
690                         }
691                 }
692                 else // The caCertId's parent is no more parent of any other certificate so delete caCertId from Db.
693                 {
694                         if (devCert) //If it is device certificate
695                         {
696                                 r = DeleteCertificateByIdNTableName(caCertId, _CERT_USER_CERT_TABLE);
697                                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_OPERATION_FAILED, "Failed to delete certificate table.");
698
699                                 devCert = false; //Device certificate is deleted here now go to CA certificate for deletion
700                                 SysLog(NID_SEC_CERT, "Device certificate is deleted here now go to CA certificate for deletion.");
701                         }
702                         else //If it is CA certificate and there is no dependency
703                         {
704                                 r = DeleteCertificateByIdNTableName(caCertId, _CERT_ROOT_CA_CERT_TABLE);
705                                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to delete certificate table.");
706
707                                 SysLog(NID_SEC_CERT, "It is CA certificate and there is no dependency.");
708                         }
709                         caCertId = caParentCa; // Now look for next certificate in chain
710                         memset(condition, 0, _MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_SUBJECT_OFFSET_SIZE);
711                         snprintf(condition, (_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_SUBJECT_OFFSET_SIZE), "certId = %d and installed = '%s'", devParentCA, installed);
712                         memset(&certRecord, 0, sizeof(certRecord));
713                         r = __caCertDbStore.GetFirstRecordByConditions(reinterpret_cast< byte* >(condition), &certRecord);
714                         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r) || r == E_DATA_NOT_FOUND, E_SYSTEM, "Failed to get certificate record.");
715                         SysTryReturnResult(NID_SEC_CERT, r != E_DATA_NOT_FOUND, E_SUCCESS, "No such record found.");
716
717                         caParentCa = certRecord.parentCa;
718                 }
719         }
720         while (caCertId != caParentCa);
721
722         return E_SUCCESS;
723 }
724
725 result
726 _CertDbManager::GetCertificateListByFormat(_CertFormat certFormat, _CertificateListInfo** ppCertList, int& count)
727 {
728         result r = E_SUCCESS;
729         CaCertRecord certRecord = {0, };
730         _CertificateListInfo* pHoldList = null;
731         _CertFileStore fileStore;
732         int certCount = 0;
733         int certLength = 0;
734         char installed[_MAX_TYPE_RECORD_SIZE] = "T\0";
735         char condition[_MAX_TYPE_CONST_SIZE] = {0, };
736
737         snprintf(condition, _MAX_TYPE_CONST_SIZE, "certFormat = %d and certType != %d and installed = '%s'", certFormat, _CERT_TYPE_INTERMIDIATE_CA, installed);
738
739         r = __caCertDbStore.GetFirstRecordByConditions(reinterpret_cast< byte* >(condition), &certRecord);
740         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r) || r == E_DATA_NOT_FOUND, E_SYSTEM, "Failed to get certificate record.");
741         SysTryReturnResult(NID_SEC_CERT, r != E_DATA_NOT_FOUND, E_SUCCESS, "No such record found.");
742
743         std::unique_ptr< _CertificateListInfo > pCertList(new (std::nothrow) _CertificateListInfo);
744         SysTryReturnResult(NID_SEC_CERT, pCertList != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
745
746         memset(pCertList.get(), 0, sizeof(*pCertList.get()));
747         pCertList->pNext = null;
748         r = fileStore.SetFileHandle(certRecord.certId, _CERT_PATH_CA_CERT);
749         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to set file handle.");
750
751         r = fileStore.ReadFromFile(pCertList->certificate, certLength);
752         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to read from file.");
753
754         pCertList->length = certLength;
755         pCertList->certFileId = certRecord.certId;
756         pCertList->format = static_cast< _CertFormat >(certRecord.certFormat);
757         pCertList->certType = static_cast< _CaCertType >(certRecord.certType);
758         certCount++;
759
760         pHoldList = pCertList.release();
761         *ppCertList = pHoldList;
762
763         while (__caCertDbStore.GetNextRecordByCondition(reinterpret_cast< byte* >(condition), &certRecord, certRecord.certId) == E_SUCCESS)
764         {
765                 std::unique_ptr< _CertificateListInfo > pCertList(new (std::nothrow) _CertificateListInfo);
766                 SysTryReturnResult(NID_SEC_CERT, pCertList != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
767
768                 memset(pCertList.get(), 0, sizeof(*pCertList.get()));
769
770                 r = fileStore.SetFileHandle(certRecord.certId, _CERT_PATH_CA_CERT);
771                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to set file handle.");
772
773                 r = fileStore.ReadFromFile(pCertList->certificate, certLength);
774                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to read from file.");
775
776                 pCertList->pNext = null;
777                 pCertList->length = certLength;
778                 pCertList->certFileId = certRecord.certId;
779                 pCertList->format = (_CertFormat) certRecord.certFormat;
780                 pCertList->certType = static_cast< _CaCertType >(certRecord.certType);
781
782                 pHoldList->pNext = pCertList.release();
783                 pHoldList = pHoldList->pNext;
784
785                 certCount++;
786         }
787
788         count = certCount;
789
790
791         return r;
792 }
793
794 result
795 _CertDbManager::GetUserCertificateListByFormat(_CertFormat certFormat, _CertificateListInfo** ppCertList, int& count)
796 {
797         result r = E_SUCCESS;
798         UserCertRecord certRecord = {0, };
799         _CertificateListInfo* pHoldList = null;
800         _CertFileStore fileStore;
801         int certCount = 0;
802         int certLength = 0;
803         char installed[_MAX_TYPE_RECORD_SIZE] = "T\0";
804         char condition[_MAX_TYPE_CONST_SIZE] = {0, };
805
806         *ppCertList = null;
807
808         snprintf(condition, _MAX_TYPE_CONST_SIZE, "certFormat = %d and installed = '%s'", certFormat, installed);
809
810         r = __userCertDbStore.GetFirstRecordByConditions(reinterpret_cast< byte* >(condition), &certRecord);
811         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r) || r == E_DATA_NOT_FOUND, E_SYSTEM, "Failed to get certificate record.");
812         SysTryReturnResult(NID_SEC_CERT, r != E_DATA_NOT_FOUND, E_SUCCESS, "No such record found.");
813
814         std::unique_ptr< _CertificateListInfo > pCertList(new (std::nothrow) _CertificateListInfo);
815         SysTryReturnResult(NID_SEC_CERT, pCertList != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
816
817         memset(pCertList.get(), 0, sizeof(*pCertList.get()));
818         pCertList->pNext = null;
819
820         r = fileStore.SetFileHandle(certRecord.certId, _CERT_PATH_USER_CERT);
821         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to set file handle.");
822
823         r = fileStore.ReadFromFile(pCertList->certificate, certLength);
824         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to read from file.");
825
826         pCertList->length = certLength;
827         pCertList->certFileId = certRecord.certId;
828         pCertList->format = static_cast< _CertFormat >(certRecord.certFormat);
829         pCertList->certType = _CERT_TYPE_USER_CERT;
830         certCount++;
831
832         pHoldList = pCertList.release();
833         *ppCertList = pHoldList;
834
835         while (__userCertDbStore.GetNextRecordByCondition(reinterpret_cast< byte* >(condition), &certRecord, certRecord.certId) == E_SUCCESS)
836         {
837                 std::unique_ptr< _CertificateListInfo > pCertList(new (std::nothrow) _CertificateListInfo);
838                 SysTryReturnResult(NID_SEC_CERT, pCertList != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
839
840                 memset(pCertList.get(), 0, sizeof(*pCertList.get()));
841
842                 r = fileStore.SetFileHandle(certRecord.certId, _CERT_PATH_USER_CERT);
843                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to set file handle.");
844
845                 r = fileStore.ReadFromFile(pCertList->certificate, certLength);
846                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to read from file.");
847
848                 pCertList->pNext = null;
849                 pCertList->length = certLength;
850                 pCertList->certFileId = certRecord.certId;
851                 pCertList->format = static_cast< _CertFormat >(certRecord.certFormat);
852                 pCertList->certType = _CERT_TYPE_USER_CERT;
853
854                 pHoldList->pNext = pCertList.release();
855                 pHoldList = pHoldList->pNext;
856
857                 certCount++;
858         }
859
860         count = certCount;
861
862         return E_SUCCESS;
863 }
864
865 result
866 _CertDbManager::GetCaCertificateListByCertId(int certId, _CertificateListInfo** ppCertList)
867 {
868         result r = E_SUCCESS;
869         CaCertRecord certRecord = {0, };
870         _CertFileStore fileStore;
871         int certLength = 0;
872         char installed[_MAX_TYPE_RECORD_SIZE] = "T\0";
873         char condition[_MAX_TYPE_CONST_SIZE] = {0, };
874
875         *ppCertList = null;
876         snprintf(condition, _MAX_TYPE_CONST_SIZE, "certId = %d and certType != %d and installed = '%s'", certId, _CERT_TYPE_INTERMIDIATE_CA, installed);
877
878         r = __caCertDbStore.GetFirstRecordByConditions(reinterpret_cast< byte* >(condition), &certRecord);
879         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to get certificate record.", GetErrorMessage(r));
880
881         std::unique_ptr< _CertificateListInfo > pCertList(new (std::nothrow) _CertificateListInfo);
882         SysTryReturnResult(NID_SEC_CERT, pCertList != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
883
884         memset(pCertList.get(), 0, sizeof(*pCertList.get()));
885
886         pCertList->pNext = null;
887         r = fileStore.SetFileHandle(certRecord.certId, _CERT_PATH_CA_CERT);
888         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to set file handle.");
889
890         r = fileStore.ReadFromFile(pCertList->certificate, certLength);
891         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to read from file.");
892
893         pCertList->length = certLength;
894         pCertList->certFileId = certRecord.certId;
895         pCertList->format = static_cast< _CertFormat >(certRecord.certFormat);
896         pCertList->certType = static_cast< _CaCertType >(certRecord.certType);
897
898         *ppCertList = pCertList.release();
899
900         return r;
901 }
902
903 result
904 _CertDbManager::GetUserCertificateListByCertId(int certId, _CertificateListInfo** ppCertList)
905 {
906         result r = E_SUCCESS;
907         _CertFileStore fileStore;
908         UserCertRecord certRecord = {0, };
909         int priKeyLen = 0;
910         int certLength = 0;
911         char condition[_MAX_TYPE_CONST_SIZE] = {0, };
912         char installed[_MAX_TYPE_RECORD_SIZE] = "T\0";
913
914         *ppCertList = null;
915
916         SysTryReturnResult(NID_SEC_CERT, ppCertList != null, E_INVALID_ARG, "Invalid input arguments.");
917         SysTryReturnResult(NID_SEC_CERT, certId > 0, E_INVALID_ARG, "Invalid input arguments.");
918
919         snprintf(condition, _MAX_TYPE_CONST_SIZE, "certId = %d and installed = '%s'", certId, installed);
920         r = __userCertDbStore.GetFirstRecordByConditions(reinterpret_cast< byte* >(condition), &certRecord);
921         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to get certificate record.", GetErrorMessage(r));
922
923         std::unique_ptr< _CertificateListInfo > pCertList(new (std::nothrow) _CertificateListInfo);
924         SysTryReturnResult(NID_SEC_CERT, pCertList != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
925
926         memset(pCertList.get(), 0, sizeof(*pCertList.get()));
927
928         pCertList->pNext = null;
929
930         r = fileStore.SetFileHandle(certRecord.certId, _CERT_PATH_USER_CERT);
931         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to set file handle.");
932
933         r = fileStore.ReadFromFile(pCertList->certificate, certLength);
934         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to read from file.");
935
936         pCertList->length = certLength;
937         pCertList->certFileId = certRecord.certId;
938         pCertList->format = static_cast< _CertFormat >(certRecord.certFormat);
939         pCertList->certType = _CERT_TYPE_USER_CERT;
940
941         std::unique_ptr< _CertPrivateKeyInfo > pPriKey(new (std::nothrow) _CertPrivateKeyInfo());
942         SysTryReturnResult(NID_SEC_CERT, pPriKey != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
943
944         std::unique_ptr< byte[] > pPrivateKey(new (std::nothrow) byte[_MAX_CERT_PRIVATE_KEY_SIZE]);
945         SysTryReturnResult(NID_SEC_CERT, pPrivateKey != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
946
947         memset(pPrivateKey.get(), 0, _MAX_CERT_PRIVATE_KEY_SIZE);
948
949         r = fileStore.SetFileHandle(certRecord.certId, _CERT_PATH_PRIVATE_KEY);
950         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to set file handle.");
951
952         r = fileStore.ReadFromFile(pPrivateKey.get(), priKeyLen);
953         if (!IsFailed(r) && priKeyLen != 0)
954         {
955                 byte* pPrivateTempKey = null;
956                 pPriKey->SetPrivateKey(priKeyLen, pPrivateKey.get());
957
958                 pPrivateKey.reset(null);
959
960                 pPriKey->GetPkcs8EncDecKeyN(priKeyLen, &pPrivateTempKey, 0);
961                 SysTryReturnResult(NID_SEC_CERT, pPrivateTempKey != null, E_SYSTEM, "Failed to get private key buffer.");
962
963                 std::unique_ptr< byte[] > pPrivateKeyAuto(pPrivateTempKey);
964
965                 memcpy(pCertList->privatekey, pPrivateTempKey, priKeyLen);
966         }
967         pCertList->priKeyLen = priKeyLen;
968
969         *ppCertList = pCertList.release();
970
971         return r;
972 }
973
974 result
975 _CertDbManager::FindIssuerCertificateAndTypeN(_CertFormat certFormat, char* pIssuerName, byte** ppCert, int& certLen, _CaCertType& certType)
976 {
977         result r = E_SUCCESS;
978         CaCertRecord certRecord = {0, };
979         _CertFileStore fileStore;
980         String filePath;
981         int issuerNameB64len = 0;
982         char condition[_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_OFFSET_CONST_SIZE] = {0, };
983         char issuerNameBase64[_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_ISSUER_OFFSET_SIZE] = {0, };
984         char installed[_MAX_TYPE_RECORD_SIZE] = "T\0";
985
986         SysTryReturnResult(NID_SEC_CERT, certFormat == _CERT_X509, E_INVALID_ARG, "Invalid certificate format.");
987         SysTryReturnResult(NID_SEC_CERT, pIssuerName != null, E_INVALID_ARG, "Invalid input arguments.");
988         SysTryReturnResult(NID_SEC_CERT, ppCert != null, E_INVALID_ARG, "Invalid input arguments.");
989
990         issuerNameB64len = _Base64::GetEncodedSize(strlen(pIssuerName));
991         SysTryReturnResult(NID_SEC_CERT, issuerNameB64len >= 0, E_ENCODING_FAILED, "Failed to encode data in base 64 encoding.");
992
993         memset(issuerNameBase64, 0, sizeof(issuerNameBase64));
994
995         r = _Base64::Encode(reinterpret_cast< byte* >(pIssuerName), strlen(pIssuerName), issuerNameBase64, issuerNameB64len);
996         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_ENCODING_FAILED, "Failed to encode data in base 64 encoding.");
997
998         snprintf(condition, (_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_OFFSET_CONST_SIZE), "subjectName = '%s' and certFormat = %d and installed = '%s'", issuerNameBase64, certFormat, installed);
999
1000         r = __caCertDbStore.GetFirstRecordByConditions(reinterpret_cast< byte* >(condition), &certRecord);
1001         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to get certificate record.", GetErrorMessage(r));
1002
1003         filePath = reinterpret_cast< char* >(certRecord.fileName);
1004
1005         fileStore.SetFilePath(filePath);
1006
1007         *ppCert = new (std::nothrow) byte[_MAX_CERTIFICATE_SIZE];
1008         SysTryReturnResult(NID_SEC_CERT, *ppCert != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
1009
1010         r = fileStore.ReadFromFile(*ppCert, certLen);
1011         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to read from file.", GetErrorMessage(r));
1012
1013         certType = static_cast< _CaCertType >(certRecord.certType); //Get the type of certificate
1014
1015         return r;
1016 }
1017
1018 result
1019 _CertDbManager::FindIssuerCertificateByTypeN(_CertFormat certFormat, _CaCertType certType, char* pIssuerName, byte** ppCert, int& certLen)
1020 {
1021         result r = E_SUCCESS;
1022         String filePath;
1023         CaCertRecord certRecord = {0, };
1024         _CertFileStore fileStore;
1025         int issuerNameB64len = 0;
1026         char condition[_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_ISSUER_CONDITION_SIZE] = {0, };
1027         char issuerNameBase64[_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_ISSUER_NAME_OFFSET] = {0, };
1028         char installed[_MAX_TYPE_RECORD_SIZE] = "T\0";
1029
1030         SysTryReturnResult(NID_SEC_CERT, certType > _CERT_TYPE_NOT_BOUNDED, E_INVALID_ARG, "Invalid certificate type.");
1031         SysTryReturnResult(NID_SEC_CERT, certType < _CERT_TYPE_MAX, E_INVALID_ARG, "Invalid certificate type.");
1032         SysTryReturnResult(NID_SEC_CERT, certFormat == _CERT_X509, E_INVALID_ARG, "Invalid certificate format.");
1033         SysTryReturnResult(NID_SEC_CERT, pIssuerName != null, E_INVALID_ARG, "Invalid input arguments.");
1034         SysTryReturnResult(NID_SEC_CERT, ppCert != null, E_INVALID_ARG, "Invalid input arguments.");
1035
1036         issuerNameB64len = _Base64::GetEncodedSize(strlen(pIssuerName));
1037         SysTryReturnResult(NID_SEC_CERT, issuerNameB64len >= 0, E_ENCODING_FAILED, "Failed to get encoded size.");
1038
1039         memset(issuerNameBase64, 0, sizeof(issuerNameBase64));
1040
1041         r = _Base64::Encode(reinterpret_cast< byte* >(pIssuerName), strlen(pIssuerName), issuerNameBase64, issuerNameB64len);
1042         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_ENCODING_FAILED, "Failed to encode data in base 64 encoding.");
1043
1044         snprintf(condition, (_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_ISSUER_CONDITION_SIZE), "subjectName = '%s' and certFormat = %d and certType = %d and installed = '%s'", issuerNameBase64, certFormat, certType, installed);
1045         r = __caCertDbStore.GetFirstRecordByConditions(reinterpret_cast< byte* >(condition), &certRecord);
1046         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to get certificate record.", GetErrorMessage(r));
1047
1048         if (certRecord.certId == 0)
1049         {
1050                 return E_SUCCESS;
1051         }
1052
1053         filePath = static_cast< char* >(certRecord.fileName);
1054         fileStore.SetFilePath(filePath);
1055
1056         std::unique_ptr< byte[] > pCert(new (std::nothrow) byte[_MAX_CERTIFICATE_SIZE]);
1057         SysTryReturnResult(NID_SEC_CERT, pCert != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
1058
1059         r = fileStore.ReadFromFile(pCert.get(), certLen);
1060         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to read from file.", GetErrorMessage(r));
1061
1062         certType = static_cast< _CaCertType >(certRecord.certType); //Get the type of certificate
1063
1064         *ppCert = pCert.release();
1065
1066         return r;
1067 }
1068
1069 result
1070 _CertDbManager::FindCertType(_CertFormat certFormat, char* pIssuerName, char* pSubjectName, _CaCertType* pCertType)
1071 {
1072         result r = E_SUCCESS;
1073         CaCertRecord certRecord = {0, };
1074         _CertFileStore fileStore;
1075         int subjectNameB64len = 0;
1076         int issuerNameB64len = 0;
1077         char condition[_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_CONDITION_CONST_SIZE] = {0, };
1078         char subjectNameBase64[_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_ISSUER_OFFSET_SIZE] = {0, };
1079         char issuerNameBase64[_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_ISSUER_OFFSET_SIZE] = {0, };
1080         char installed[_MAX_TYPE_RECORD_SIZE] = "T\0";
1081
1082         SysTryReturnResult(NID_SEC_CERT, certFormat == _CERT_X509, E_INVALID_ARG, "Invalid certificate format.");
1083         SysTryReturnResult(NID_SEC_CERT, pIssuerName != null, E_INVALID_ARG, "Invalid input arguments.");
1084         SysTryReturnResult(NID_SEC_CERT, pSubjectName != null, E_INVALID_ARG, "Invalid input arguments.");
1085         SysTryReturnResult(NID_SEC_CERT, pCertType != null, E_INVALID_ARG, "Invalid input arguments.");
1086
1087         issuerNameB64len = _Base64::GetEncodedSize(strlen(pIssuerName));
1088         SysTryReturnResult(NID_SEC_CERT, issuerNameB64len >= 0, E_ENCODING_FAILED, "Failed to encode data in base 64 encoding.");
1089
1090         memset(issuerNameBase64, 0, sizeof(issuerNameBase64));
1091
1092         r = _Base64::Encode(reinterpret_cast< byte* >(pIssuerName), strlen(pIssuerName), issuerNameBase64, issuerNameB64len);
1093         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_ENCODING_FAILED, "Failed to encode data in base 64 encoding.");
1094
1095         subjectNameB64len = _Base64::GetEncodedSize(strlen(pSubjectName));
1096         SysTryReturnResult(NID_SEC_CERT, subjectNameB64len >= 0, E_ENCODING_FAILED, "Failed to encode data in base 64 encoding.");
1097
1098         memset(subjectNameBase64, 0, sizeof(subjectNameBase64));
1099         r = _Base64::Encode(reinterpret_cast< byte* >(pSubjectName), strlen(pSubjectName), subjectNameBase64, subjectNameB64len);
1100         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_ENCODING_FAILED, "Failed to encode data in base 64 encoding.");
1101
1102         snprintf(condition, (_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_CONDITION_CONST_SIZE), "certFormat = %d and issuerName = '%s' and subjectName = '%s' and installed = '%s'", certFormat, issuerNameBase64, subjectNameBase64, installed);
1103         r = __caCertDbStore.GetFirstRecordByConditions(reinterpret_cast< byte* >(condition), &certRecord);
1104         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to get certificate record.", GetErrorMessage(r));
1105
1106         *pCertType = static_cast< _CaCertType >(certRecord.certType);  //Get the type of certificate
1107         return E_SUCCESS;
1108 }
1109
1110 result
1111 _CertDbManager::DeleteCertificateByIdNTableName(int certId, String tableName)
1112 {
1113         result r = E_SUCCESS;
1114         _CertFileStore fileStore;
1115         String fileName;
1116
1117         SysTryReturnResult(NID_SEC_CERT, certId > 0, E_INVALID_ARG, "Invalid input argument.");
1118
1119         if (tableName.CompareTo(_CERT_USER_CERT_TABLE) == 0)
1120         {
1121                 String keyfileName;
1122
1123                 r = __userCertDbStore.RemoveCertificateById(certId);
1124                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Error in deleting certificate.");
1125
1126                 //Remove certificate file
1127                 fileStore.GetFileNameFromHandle(certId, _CERT_PATH_USER_CERT, fileName);
1128                 r = Tizen::Io::File::Remove(fileName);
1129                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_FILE_NOT_FOUND, "Error in deleting file.");
1130
1131                 //Remove private key file
1132                 //Don't check return type here as it is not necessary that private key is present.
1133                 fileStore.GetFileNameFromHandle(certId, _CERT_PATH_PRIVATE_KEY, keyfileName);
1134                 r = Tizen::Io::File::Remove(keyfileName);
1135         }
1136         else if (tableName.CompareTo(_CERT_ROOT_CA_CERT_TABLE) == 0)
1137         {
1138                 r = __caCertDbStore.RemoveCertificateById(certId);
1139                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Delete certificate failed.");
1140
1141                 //Remove certificate file
1142                 fileStore.GetFileNameFromHandle(certId, _CERT_PATH_CA_CERT, fileName);
1143                 r = Tizen::Io::File::Remove(fileName);
1144                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_FILE_NOT_FOUND, "Error in deleting file.");
1145         }
1146         return E_SUCCESS;
1147 }
1148
1149 result
1150 _CertDbManager::GetHashOfCertFile(byte* pFilePath, int* pLen, char* pBuf)
1151 {
1152         result r = E_SUCCESS;
1153         String fileName(reinterpret_cast< char* >(pFilePath));
1154         FileAttributes attr;
1155         File file;
1156         long fileSize = 0;
1157         int readCnt = 0;
1158         int certLen = 0;
1159         int outLen = _MAX_CERT_SHA1_DIGEST_SIZE;
1160         int resValue = 0;
1161
1162         SysTryReturnResult(NID_SEC_CERT, pFilePath != null, E_INVALID_ARG, "Invalid inpur arguments.");
1163         SysTryReturnResult(NID_SEC_CERT, pLen != null, E_INVALID_ARG, "Invalid inpur arguments.");
1164         SysTryReturnResult(NID_SEC_CERT, pBuf != null, E_INVALID_ARG, "Invalid inpur arguments.");
1165
1166         r = File::GetAttributes(fileName, attr);
1167         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to get attributes.");
1168
1169         fileSize = attr.GetFileSize();
1170         SysTryReturn(NID_SEC_CERT, fileSize >= 0, r, r, "[%s] Failed to get file attributes.", GetErrorMessage(r));
1171         SysTryReturn(NID_SEC_CERT, fileSize < _MAX_CERTIFICATE_SIZE, r, r, "[%s] File size exceeds maximum specified length.", GetErrorMessage(r));
1172
1173         // Open file
1174         r = file.Construct(fileName, L"r");
1175         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to construct file.");
1176
1177         std::unique_ptr< byte[] > pCertBuf(new (std::nothrow) byte[fileSize + 1]);
1178         SysTryReturnResult(NID_SEC_CERT, pCertBuf != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
1179
1180         memset(pCertBuf.get(), 0, fileSize + 1);
1181         readCnt = file.Read(pCertBuf.get(), fileSize);
1182         r = GetLastResult();
1183         SysTryReturn(NID_SEC_CERT, (readCnt == fileSize) || (!IsFailed(r)), r, r, "[%s] Failed to read file.", GetErrorMessage(r));
1184
1185         certLen = readCnt;
1186         std::unique_ptr< byte[] > pOutBuf(new (std::nothrow) byte[outLen]);
1187         SysTryReturnResult(NID_SEC_CERT, pOutBuf != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
1188
1189         memset(pOutBuf.get(), 0, outLen);
1190         //As per OpenSSL APIs, it takes input as unsigned data types
1191         resValue = EVP_Digest(pCertBuf.get(), static_cast< int >(certLen), pOutBuf.get(), reinterpret_cast< unsigned int* >(&outLen), EVP_sha1(), 0);
1192         SysTryReturnResult(NID_SEC_CERT, resValue == 1, E_SYSTEM, "Failed to create digest.");
1193
1194         memcpy(pBuf, pOutBuf.get(), outLen);
1195         *pLen = outLen;
1196
1197         return r;
1198 }
1199
1200 //User Certificate APIs
1201
1202 result
1203 _CertDbManager::InsertCertChain(_CertFormat certFormat, _CertChain* pCertChain)
1204 {
1205         result r = E_SUCCESS;
1206         _CaCertType certType = _CERT_TYPE_NOT_BOUNDED;
1207         int curCACertId = 0;
1208         int lastCACertId = 0;
1209         int curDevCertId = 0;
1210         bool updateUserParentCa = false;
1211
1212         SysTryReturnResult(NID_SEC_CERT, pCertChain != null, E_INVALID_ARG, "Invalid input parameter.");
1213         SysTryReturnResult(NID_SEC_CERT, certFormat == _CERT_X509, E_INVALID_ARG, "Invalid certificate format.");
1214
1215         //Check for CA certificate table creation
1216         r = __caCertDbStore.IsRootCaCertTableCreated();
1217         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Certificate table are not not created.");
1218
1219
1220         //Check if the chain is valid or not
1221         r = pCertChain->Verify();
1222         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_INVALID_ARG, "Invalid certificate chain.");
1223
1224         r = pCertChain->MoveHead();
1225         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to move head in certificate chain.");
1226
1227         if (certFormat == _CERT_X509)
1228         {
1229                 _X509Certificate* pCurCert = null;
1230                 _X509Certificate* pUserCert = null;
1231                 _X509TbsCert* pTbsCert = null;
1232                 byte* pX509Buff = null;
1233                 int x509BuffSize = 0;
1234
1235                 pUserCert = pCertChain->GetCurrentCertificate();
1236                 SysTryReturnResult(NID_SEC_CERT, pUserCert != null, E_SYSTEM, "Failed to get certificate from chain, broken certificate chain.");
1237
1238                 pTbsCert = pUserCert->GetTbsCertInstance();
1239                 SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
1240
1241                 pUserCert->GetCertBuffer(pX509Buff, x509BuffSize);
1242                 SysTryReturn(NID_SEC_CERT, pX509Buff != null, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to get certificate buffer.");
1243
1244                 r = InsertUserCertificateFromBuffer(certFormat, pX509Buff, x509BuffSize, null, 0);
1245                 SysTryReturn(NID_SEC_CERT, !(IsFailed(r) && (r != E_OBJ_ALREADY_EXIST) && (r != E_FILE_ALREADY_EXIST)), r, r, "[%s] Failed insert user certificate chain.", GetErrorMessage(r));
1246
1247                 updateUserParentCa = true;
1248
1249                 r = GetUserCertificateId(pTbsCert->GetSubjectName(), strlen(reinterpret_cast< char* >(pTbsCert->GetSubjectName())),
1250                                                                  pTbsCert->GetIssuerName(), strlen(reinterpret_cast< char* >(pTbsCert->GetIssuerName())),
1251                                                                  curDevCertId);
1252                 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed get user certificate id.", GetErrorMessage(r));
1253
1254                 //Insert certificate chain in CA certificate store
1255                 while (pCertChain->MoveNext() == E_SUCCESS)
1256                 {
1257
1258                         pCurCert = pCertChain->GetCurrentCertificate();
1259                         SysTryReturnResult(NID_SEC_CERT, pCurCert != null, E_SYSTEM, "Failed to get certificate from chain, broken certificate chain.");
1260
1261                         if (!pCurCert->IsSelfSigned())
1262                         {
1263                                 certType = _CERT_TYPE_INTERMIDIATE_CA;
1264                         }
1265                         else
1266                         {
1267                                 //This parameter need to pass from certificate manager about its type
1268                                 certType = _CERT_TYPE_ROOT_CA;
1269                         }
1270
1271                         pTbsCert = pCurCert->GetTbsCertInstance();
1272                         SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
1273
1274                         r = __caCertDbStore.CheckDuplicateCertificate(certType, reinterpret_cast< byte* >(pTbsCert->GetSubjectName()), strlen(reinterpret_cast< char* >(pTbsCert->GetSubjectName())));
1275                         if (r != E_SUCCESS)
1276                         {
1277                                 SysTryReturn(NID_SEC_CERT, r == E_DATA_NOT_FOUND, r, r, "[%s] Failed to check duplicate.", GetErrorMessage(r));
1278
1279                                 pX509Buff = null;
1280                                 x509BuffSize = 0;
1281
1282                                 pCurCert->GetCertBuffer(pX509Buff, x509BuffSize);
1283                                 SysTryReturnResult(NID_SEC_CERT, pX509Buff != null, E_SYSTEM, "Failed to get certificate buffer.");
1284
1285                                 r = InsertCaCertificateFromBuffer(certType, certFormat, pX509Buff, x509BuffSize);
1286                                 SysTryReturn(NID_SEC_CERT, !(IsFailed(r) && r != E_FILE_ALREADY_EXIST), r, r, "[E_SYSTEM] Failed to insert ca certificate.");
1287                         }
1288
1289                         // CA certificate already present or properly installed in CA certificate store,
1290                         // get the certificate id of certificate
1291                         r = GetCaCertificateId(pTbsCert->GetSubjectName(), strlen(reinterpret_cast< char* >(pTbsCert->GetSubjectName())),
1292                                                                    pTbsCert->GetIssuerName(), strlen(reinterpret_cast< char* >(pTbsCert->GetIssuerName())),
1293                                                                    curCACertId, certType);
1294                         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed get Ca certificate id.", GetErrorMessage(r));
1295
1296                         if (updateUserParentCa)
1297                         {
1298                                 __userCertDbStore.UpdateParentCa(curDevCertId, curCACertId);
1299                                 updateUserParentCa = false;
1300                                 lastCACertId = curCACertId;
1301                         }
1302                         else
1303                         {
1304                                 __caCertDbStore.UpdateParentCa(lastCACertId, curCACertId);
1305                                 lastCACertId = curCACertId;
1306                         }
1307
1308                         //If it is root certificate then its parent is itself
1309                         if (pCurCert->IsSelfSigned())
1310                         {
1311                                 __caCertDbStore.UpdateParentCa(curCACertId, curCACertId);
1312                         }
1313
1314                 } //end of while
1315
1316                 if (updateUserParentCa)
1317                 {
1318                         r = pCertChain->MoveHead();
1319                         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to move head in certificate chain.");
1320
1321                         pCurCert = pCertChain->GetCurrentCertificate();
1322                         SysTryReturnResult(NID_SEC_CERT, pCurCert != null, E_SYSTEM, "Failed to get certificate from chain, broken certificate chain.");
1323
1324                         pTbsCert = pCurCert->GetTbsCertInstance();
1325                         SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
1326
1327                         r = GetCaCertificateId(pTbsCert->GetIssuerName(), strlen(reinterpret_cast< char* >(pTbsCert->GetIssuerName())),
1328                                                                    null, 0, curCACertId);
1329                         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed get Ca certificate id.", GetErrorMessage(r));
1330
1331                         __userCertDbStore.UpdateParentCa(curDevCertId, curCACertId);
1332                         updateUserParentCa = false;
1333                         lastCACertId = curCACertId;
1334                 }
1335                 else if (!pCurCert->IsSelfSigned())
1336                 {
1337                         pTbsCert = pCurCert->GetTbsCertInstance();
1338                         SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
1339
1340                         r = GetCaCertificateId(pTbsCert->GetIssuerName(), strlen(reinterpret_cast< char* >(pTbsCert->GetIssuerName())),
1341                                                                    null, 0, curCACertId);
1342                         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed get Ca certificate id.", GetErrorMessage(r));
1343
1344                         __caCertDbStore.UpdateParentCa(lastCACertId, curCACertId);
1345                         lastCACertId = curCACertId;
1346                 }
1347         }
1348
1349         return r;
1350 }
1351
1352 result
1353 _CertDbManager::InsertCertificateChain(_CertFormat certFormat, _CertChain* pCertChain, _CertPrivateKeyInfo* pPrivateKeyInfo)
1354 {
1355         result r = E_SUCCESS;
1356         _CaCertType certType = _CERT_TYPE_NOT_BOUNDED;
1357         int prvKeyLen = 0;
1358         int curCACertId = 0;
1359         int lastCACertId = 0;
1360         int curDevCertId = 0;
1361
1362         bool updateUserParentCa = false;
1363         byte* pPrvKey = null;
1364         std::unique_ptr< byte[] > pPrvKeyBuffer;
1365
1366         SysTryReturnResult(NID_SEC_CERT, pCertChain != null, E_INVALID_ARG, "Invalid input parameter.");
1367         SysTryReturnResult(NID_SEC_CERT, certFormat == _CERT_X509, E_INVALID_ARG, "Invalid certificate format.");
1368
1369         r = __userCertDbStore.IsUserCertTableCreated();
1370         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to create certificate table.");
1371
1372         //Check for CA certificate table creation
1373         r = __caCertDbStore.IsRootCaCertTableCreated();
1374         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to create certificate table.");
1375
1376         //Check if the chain is valid or not
1377         r = pCertChain->Verify();
1378         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to verify certificate.", GetErrorMessage(r));
1379
1380         r = pCertChain->MoveHead();
1381         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to move head in certificate chain.");
1382
1383         if (certFormat == _CERT_X509)
1384         {
1385                 _X509Certificate* pCurCert = null;
1386                 _X509Certificate* pUserCert = null;
1387                 _X509TbsCert* pTbsCert = null;
1388                 byte* pX509Buff = null;
1389                 int x509BuffSize = 0;
1390
1391                 pUserCert = pCertChain->GetCurrentCertificate();
1392                 SysTryReturnResult(NID_SEC_CERT, pUserCert != null, E_SYSTEM, "Failed to get certificate from chain, broken certificate chain.");
1393
1394                 pTbsCert = pUserCert->GetTbsCertInstance();
1395                 SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
1396
1397                 byte* pSubjectName = pTbsCert->GetSubjectName();
1398                 SysTryReturn(NID_SEC_CERT, pSubjectName != null, E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] Subjectname not present.");
1399
1400                 int subjectNameLen = strlen(reinterpret_cast< char* >(pTbsCert->GetSubjectName()));
1401
1402                 r = __userCertDbStore.CheckDuplicateCertificate(pSubjectName, subjectNameLen);
1403                 if (r == E_DATA_NOT_FOUND)
1404                 {
1405                         if (pPrivateKeyInfo != null)
1406                         {
1407                                 pPrivateKeyInfo->GetPkcs8EncDecKeyN(prvKeyLen, &pPrvKey, 1);
1408                                 SysTryReturnResult(NID_SEC_CERT, prvKeyLen > 0, E_INVALID_KEY, "Invalid key length .");
1409
1410                                 pPrvKeyBuffer = std::unique_ptr< byte[] >(pPrvKey);
1411                                 pPrvKey = null;
1412
1413                         }
1414
1415                         pUserCert->GetCertBuffer(pX509Buff, x509BuffSize);
1416                         SysTryReturnResult(NID_SEC_CERT, pX509Buff != null, E_SYSTEM, "Failed to get certificate buffer.");
1417
1418                         r = _CertDbManager::InsertUserCertificateFromBuffer(certFormat, pX509Buff, x509BuffSize, pPrvKeyBuffer.get(), static_cast< int >(prvKeyLen));
1419                         if (IsFailed(r) && r != E_OBJ_ALREADY_EXIST && r != E_FILE_ALREADY_EXIST)
1420                         {
1421                                 return r;
1422                         }
1423                         else
1424                         {
1425                                 updateUserParentCa = true;
1426
1427                                 r = GetUserCertificateId(pTbsCert->GetSubjectName(), strlen(reinterpret_cast< char* >(pTbsCert->GetSubjectName())),
1428                                                                                  pTbsCert->GetIssuerName(), strlen(reinterpret_cast< char* >(pTbsCert->GetIssuerName())),
1429                                                                                  curDevCertId);
1430                                 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed get user certificate id.", GetErrorMessage(r));
1431
1432                                 if (pPrvKeyBuffer != null)
1433                                 {
1434                                         _CertFileStore fileStore;
1435                                         String privateKeyFile;
1436
1437                                         fileStore.GetFileNameFromHandle(curDevCertId, _CERT_PATH_PRIVATE_KEY, privateKeyFile);
1438                                         fileStore.SetFilePath(privateKeyFile);
1439
1440
1441                                         r = fileStore.WriteToFile(pPrvKeyBuffer.get(), prvKeyLen);
1442                                         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_INACCESSIBLE_PATH, "Failed to write in file.");
1443
1444                                 }
1445                         }
1446                 }
1447                 else
1448                 {
1449                         return r;
1450                 }
1451
1452                 if (pUserCert->IsSelfSigned())
1453                 {
1454                         __userCertDbStore.UpdateParentCa(curDevCertId, curDevCertId);
1455                         return r;
1456                 }
1457
1458                 //Insert certificate chain in CA certificate store
1459                 while (pCertChain->MoveNext() == E_SUCCESS)
1460                 {
1461                         pCurCert = pCertChain->GetCurrentCertificate();
1462                         SysTryReturnResult(NID_SEC_CERT, pCurCert != null, E_SYSTEM, "Failed to get certificate from chain, broken certificate chain.");
1463
1464                         if (!pCurCert->IsSelfSigned())
1465                         {
1466                                 certType = _CERT_TYPE_INTERMIDIATE_CA;
1467                         }
1468                         else
1469                         {
1470                                 //This parameter need to pass from certificate manager about its type
1471                                 certType = _CERT_TYPE_ROOT_CA;
1472                         }
1473
1474                         pTbsCert = pCurCert->GetTbsCertInstance();
1475                         SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
1476
1477                         r = __caCertDbStore.CheckDuplicateCertificate(certType, pTbsCert->GetSubjectName(), strlen(reinterpret_cast< char* >(pTbsCert->GetSubjectName())));
1478                         if (r != E_SUCCESS)
1479                         {
1480                                 SysTryReturnResult(NID_SEC_CERT, r == E_DATA_NOT_FOUND, r, "Failed to check duplicate.");
1481
1482                                 pX509Buff = null;
1483                                 x509BuffSize = 0;
1484
1485                                 pCurCert->GetCertBuffer(pX509Buff, x509BuffSize);
1486                                 SysTryReturnResult(NID_SEC_CERT, pX509Buff != null, E_SYSTEM, "Failed to get certificate buffer.");
1487
1488                                 r = _CertDbManager::InsertCaCertificateFromBuffer(certType, certFormat, pX509Buff, x509BuffSize);
1489                                 SysTryReturn(NID_SEC_CERT, !(IsFailed(r) && r != E_FILE_ALREADY_EXIST), r, r, "[E_SYSTEM] Failed to insert ca certificate.");
1490
1491                         }
1492                         // CA certificate already present or properly install in CA certificate store,
1493                         // get the certificate id of certificate
1494
1495                         r = GetCaCertificateId(pTbsCert->GetSubjectName(), strlen(reinterpret_cast< char* >(pTbsCert->GetSubjectName())),
1496                                                                    pTbsCert->GetIssuerName(), strlen(reinterpret_cast< char* >(pTbsCert->GetIssuerName())),
1497                                                                    curCACertId, certType);
1498                         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed get Ca certificate id.", GetErrorMessage(r));
1499
1500                         if (updateUserParentCa)
1501                         {
1502                                 __userCertDbStore.UpdateParentCa(curDevCertId, curCACertId);
1503                                 updateUserParentCa = false;
1504                                 lastCACertId = curCACertId;
1505                         }
1506                         else
1507                         {
1508                                 __caCertDbStore.UpdateParentCa(lastCACertId, curCACertId);
1509                                 lastCACertId = curCACertId;
1510                         }
1511
1512                         //If it is root certificate then its parent is itself
1513                         if (pCurCert->IsSelfSigned())
1514                         {
1515                                 __caCertDbStore.UpdateParentCa(curCACertId, curCACertId);
1516                         }
1517                 }
1518
1519                 if (updateUserParentCa)
1520                 {
1521                         r = pCertChain->MoveHead();
1522                         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to move head in certificate chain.");
1523
1524                         pCurCert = pCertChain->GetCurrentCertificate();
1525                         SysTryReturnResult(NID_SEC_CERT, pCurCert != null, E_SYSTEM, "Failed to get certificate from chain, broken certificate chain.");
1526
1527                         pTbsCert = pCurCert->GetTbsCertInstance();
1528                         SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
1529
1530                         r = GetCaCertificateId(pTbsCert->GetIssuerName(), strlen(reinterpret_cast< char* >(pTbsCert->GetIssuerName())),
1531                                                                    null, 0, curCACertId);
1532                         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed get Ca certificate id.", GetErrorMessage(r));
1533
1534                         __userCertDbStore.UpdateParentCa(curDevCertId, curCACertId);
1535                         updateUserParentCa = false;
1536                         lastCACertId = curCACertId;
1537                 }
1538                 else if (!pCurCert->IsSelfSigned())
1539                 {
1540                         pTbsCert = pCurCert->GetTbsCertInstance();
1541                         SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
1542
1543                         r = GetCaCertificateId(pTbsCert->GetIssuerName(), strlen(reinterpret_cast< char* >(pTbsCert->GetIssuerName())),
1544                                                                    null, 0, curCACertId);
1545                         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed get Ca certificate id.", GetErrorMessage(r));
1546
1547                         __caCertDbStore.UpdateParentCa(lastCACertId, curCACertId);
1548                         lastCACertId = curCACertId;
1549                 }
1550         }
1551
1552         return r;
1553 }
1554
1555 result
1556 _CertDbManager::InsertUserCertificateFromBuffer(_CertFormat certFormat, byte* pCertBuffer, int certLength, byte* pPrivateKey, int privateKeyLen, int parentCa)
1557 {
1558         result r = E_SUCCESS;
1559         _X509TbsCert* pTbsCert = null;
1560         _CertFileStore fileStore;
1561         UserCertRecord certRecord = {0, };
1562         String privateKeyFile;
1563         String tempFileName;
1564         int lenSubjectName = 0;
1565         int lenIssuerName = 0;
1566         int lenSerialNo = 0;
1567         int certId = 0;
1568         int keyIdB64Length = 0;
1569         char subjectNameBuffer[_MAX_ISSUER_SUBJECT_NAME_SIZE] = {0, };
1570         char szIssuerName[_MAX_ISSUER_SUBJECT_NAME_SIZE] = {0, };
1571         char serialName[_MAX_SERIAL_NUMBER_SIZE] = {0, };
1572         char installedRecord[_MAX_TYPE_RECORD_SIZE] = "T\0";
1573         byte* pKeyId = null;
1574         byte* pSerial = null;
1575
1576         //pPrivateKey, privateKeyLen, parentca are optional parameter, no need to sanity check for them.
1577         SysTryReturnResult(NID_SEC_CERT, pCertBuffer != null, E_INVALID_ARG, "Invalid input parameter.");
1578         SysTryReturnResult(NID_SEC_CERT, certFormat == _CERT_X509, E_INVALID_ARG, "Invalid certificate format.");
1579         SysTryReturnResult(NID_SEC_CERT, certLength > 0, E_INVALID_ARG, "Invalid input parameter.");
1580
1581         r = __userCertDbStore.IsUserCertTableCreated();
1582         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to create user certificate.");
1583
1584         std::unique_ptr< _X509Certificate > pCert(new (std::nothrow) _X509Certificate());
1585         SysTryReturnResult(NID_SEC_CERT, pCert != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
1586
1587         r = pCert->Parse(pCertBuffer, certLength);
1588         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Parsing failed.", GetErrorMessage(r));
1589
1590         pTbsCert = pCert->GetTbsCertInstance();
1591         SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
1592
1593         lenSubjectName = strlen(reinterpret_cast< char* >(pTbsCert->GetSubjectName()));
1594         lenIssuerName = strlen(reinterpret_cast< char* >(pTbsCert->GetIssuerName()));
1595
1596         SysTryReturnResult(NID_SEC_CERT, lenSubjectName < _MAX_ISSUER_SUBJECT_NAME_SIZE, E_DATABASE, "Length is greater than maximum allowed length.");
1597         SysTryReturnResult(NID_SEC_CERT, lenIssuerName < _MAX_ISSUER_SUBJECT_NAME_SIZE, E_DATABASE, "Length is greater than maximum allowed length.");
1598
1599         strncpy(subjectNameBuffer, reinterpret_cast< char* >(pTbsCert->GetSubjectName()),lenSubjectName);
1600         strncpy(szIssuerName, reinterpret_cast< char* >(pTbsCert->GetIssuerName()),lenIssuerName);
1601
1602         pTbsCert->GetSerialNumber(pSerial, static_cast< int& >(lenSerialNo));
1603         if ((lenSerialNo <= 0) || (lenSerialNo > _MAX_SERIAL_NUMBER_SIZE))
1604         {
1605                 if (pSerial != null)
1606                 {
1607                         memset(pSerial, 0, _MAX_SERIAL_NUMBER_SIZE);
1608                         lenSerialNo = 1;
1609                 }
1610         }
1611         else
1612         {
1613                 memcpy(serialName, pSerial, lenSerialNo);
1614         }
1615
1616         //Get Device ID
1617         r = pCert->GetKeyIdN(&pKeyId);
1618         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_DECODING_FAILED, "Failed to get key Id.");
1619
1620         std::unique_ptr< byte[] > pKeyIdBuffer(pKeyId);
1621
1622         keyIdB64Length = _Base64::GetEncodedSize(_MAX_CERT_SHA1_DIGEST_SIZE);
1623         SysTryReturnResult(NID_SEC_CERT, keyIdB64Length >= 0, E_ENCODING_FAILED, "Failed to encode data in base 64 encoding.");
1624
1625         std::unique_ptr< char[] > pId64(new (std::nothrow) char[keyIdB64Length]);
1626         SysTryReturnResult(NID_SEC_CERT, pId64 != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
1627
1628         memset(pId64.get(), 0, keyIdB64Length);
1629         r = _Base64::Encode(reinterpret_cast< byte* >(pKeyIdBuffer.get()), _MAX_CERT_SHA1_DIGEST_SIZE, pId64.get(), keyIdB64Length);
1630         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_DECODING_FAILED, "Decoding failed.");
1631
1632         r = __userCertDbStore.CheckDuplicateCertificate(reinterpret_cast< byte* >(subjectNameBuffer), lenSubjectName);
1633         SysTryReturnResult(NID_SEC_CERT, IsFailed(r), E_FILE_ALREADY_EXIST, "File already exists.");
1634         SysTryReturnResult(NID_SEC_CERT, r == E_DATA_NOT_FOUND, r, "Failed to check duplicate");
1635
1636         //Get the last installed certificate id from db table
1637         __userCertDbStore.GetCurrentCertId(certId);
1638
1639         //Calculate the new certificate id for installation
1640         certId = certId + 1;
1641
1642         if (pPrivateKey != null)
1643         {
1644                 //Get file name for private key and store private key into file.
1645                 fileStore.GetFileNameFromHandle(certId, _CERT_PATH_PRIVATE_KEY, privateKeyFile);
1646         }
1647         else
1648         {
1649                 privateKeyLen = 0;
1650         }
1651
1652         //Get file name for certificate and write device certificate to file
1653         fileStore.GetFileNameFromHandle(certId, _CERT_PATH_USER_CERT, tempFileName);
1654
1655         //Insert Record into Database
1656         //It is generated automatically by sequence
1657         memset(&certRecord, 0, sizeof(certRecord));
1658
1659         memcpy(certRecord.certPubKeyHash, pId64.get(), keyIdB64Length); //Base64 encoded device id
1660         certRecord.certFormat = static_cast< int >(certFormat);
1661
1662         std::unique_ptr< char[] > pFileName(Tizen::Base::_StringConverter::CopyToCharArrayN(tempFileName));
1663         SysTryReturnResult(NID_SEC_CERT, pFileName != null, E_SYSTEM, "Failed to get attributes.");
1664
1665         int len = strlen(pFileName.get());
1666         strncpy(certRecord.fileName, pFileName.get(), len);
1667         certRecord.subjectNameLen = lenSubjectName;
1668
1669         memcpy(certRecord.subjectName, subjectNameBuffer, lenSubjectName);
1670         certRecord.issuerNameLen = lenIssuerName;
1671         memcpy(certRecord.issuerName, szIssuerName, lenIssuerName);
1672
1673         std::unique_ptr< char[] > pPriKeyFileName(Tizen::Base::_StringConverter::CopyToCharArrayN(privateKeyFile));
1674         SysTryReturnResult(NID_SEC_CERT, pPriKeyFileName != null, E_SYSTEM, "Failed to get attributes.");
1675
1676         len = strlen(pPriKeyFileName.get());
1677         strncpy(certRecord.prvKeyPath, pPriKeyFileName.get(), len);
1678         certRecord.prvKeyLen = privateKeyLen;
1679         certRecord.parentCa = certId;
1680         strcpy(certRecord.installed, installedRecord);
1681
1682         memcpy(certRecord.serialNo, serialName, lenSerialNo);
1683
1684         certRecord.serialNoLen = lenSerialNo;
1685
1686         r = __userCertDbStore.InsertUserCertificate(&certRecord);
1687         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_DATABASE, "Failed to insert user certificate.");
1688
1689         fileStore.SetFilePath(tempFileName);
1690
1691         r = fileStore.WriteToFile(pCertBuffer, certLength);
1692         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_INACCESSIBLE_PATH, "Failed to write in file.");
1693
1694         if (pPrivateKey != null)
1695         {
1696                 fileStore.SetFilePath(privateKeyFile);
1697
1698                 r = fileStore.WriteToFile(pPrivateKey, privateKeyLen);
1699                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_INACCESSIBLE_PATH, "Failed to write in file.");
1700         }
1701
1702         return r;
1703 }
1704
1705 result
1706 _CertDbManager::GetUserCertificateChain(char* pIssuerName, int issuerNameLen, char* pSubjectName, int subjectNameLen, _CertEncodingType encodingType, _CertificateListInfo** ppCertListInfoTypes)
1707 {
1708         result r = E_SUCCESS;
1709         CaCertRecord certRecord = {0, };
1710         UserCertRecord userCertRecord = {0, };
1711         _CertificateListInfo* pHoldList = null;
1712         BIO* pBio = null;
1713         X509* pCert = null;
1714         EVP_PKEY* pKey = null;
1715         int certCount = 0;
1716         int recordCount = 0;
1717         int subjectNameBase64Len = 0;
1718         int count = 0;
1719         int readLength = 0;
1720         int priKeyLen = 0;
1721         int subNameLen = 0;
1722         int curCertId = 0;
1723         int certificateBase64Len = 0;
1724         char installedRecord[_MAX_TYPE_RECORD_SIZE] = "T\0";
1725         char condition[_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_SUBJECT_OFFSET_SIZE] = {0};
1726         byte issuerNameBase64[_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_ISSUER_OFFSET_SIZE] = {0, };
1727         byte subjectNameBase64[_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_ISSUER_OFFSET_SIZE] = {0, };
1728         byte subName[_MAX_ISSUER_SUBJECT_NAME_SIZE] = {0, };
1729         bool isIssuerNameInList = false;
1730
1731         subjectNameBase64Len = _Base64::GetEncodedSize(issuerNameLen);
1732         memset(issuerNameBase64, 0, sizeof(issuerNameBase64));
1733         r = _Base64::Encode(reinterpret_cast< byte* >(pIssuerName), issuerNameLen, reinterpret_cast< char* >(issuerNameBase64), subjectNameBase64Len);
1734         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_ENCODING_FAILED, "Failed to encode data in base 64 encoding.");
1735
1736         if ((pSubjectName != null) && (subjectNameLen > 0))
1737         {
1738                 subjectNameBase64Len = _Base64::GetEncodedSize(subjectNameLen);
1739                 memset(subjectNameBase64, 0, sizeof(subjectNameBase64));
1740                 r = _Base64::Encode(reinterpret_cast< byte* >(pSubjectName), subjectNameLen, reinterpret_cast< char* >(subjectNameBase64), subjectNameBase64Len);
1741                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_ENCODING_FAILED, "Failed to encode data in base 64 encoding.");
1742                 snprintf(condition, (_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_SUBJECT_OFFSET_SIZE), "subjectName = '%s' and installed = '%s'", subjectNameBase64, installedRecord);
1743         }
1744         else
1745         {
1746                 r = __userCertDbStore.GetNumberOfCertificates(recordCount);
1747                 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to get certificates.", GetErrorMessage(r));
1748                 SysTryReturnResult(NID_SEC_CERT, recordCount > 0, E_OBJ_NOT_FOUND, "Failed to get certificate records.");
1749                 snprintf(condition, (_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_SUBJECT_OFFSET_SIZE), "installed = '%s'", installedRecord);
1750         }
1751
1752         memset(&userCertRecord, 0, sizeof(userCertRecord));
1753         r = __userCertDbStore.GetFirstRecordByConditions(reinterpret_cast< byte* >(condition), &userCertRecord);
1754         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to get certificates record.", GetErrorMessage(r));
1755
1756         std::unique_ptr< _CertPrivateKeyInfo > pPriKey(new (std::nothrow) _CertPrivateKeyInfo());
1757         SysTryReturnResult(NID_SEC_CERT, pPriKey != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
1758         do
1759         {
1760                 std::unique_ptr< _CertFileStore > pFileStore(new (std::nothrow) _CertFileStore());
1761                 SysTryReturnResult(NID_SEC_CERT, pFileStore != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
1762
1763                 std::unique_ptr< _CertificateListInfo > pCertList(new (std::nothrow) _CertificateListInfo);
1764                 SysTryReturnResult(NID_SEC_CERT, pCertList != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
1765
1766                 memset(pCertList.get(), 0, sizeof(*pCertList.get()));
1767
1768                 pCertList->pNext = null;
1769
1770                 r = pFileStore->SetFileHandle(userCertRecord.certId, _CERT_PATH_USER_CERT);
1771                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to set file handle.");
1772
1773                 r = pFileStore->ReadFromFile(reinterpret_cast< byte* >(pCertList->certificate), pCertList->length);
1774                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to read from file.");
1775                 certificateBase64Len = _Base64::GetEncodedSize(pCertList->length);
1776
1777                 if (encodingType == _CERT_ENC_TYPE_PEM)
1778                 {
1779                         const byte* pCertBuffer = pCertList->certificate;
1780
1781                         pBio = BIO_new(BIO_s_mem());
1782                         SysTryReturnResult(NID_SEC_CERT, pBio != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
1783
1784                         pCert = d2i_X509(null, &pCertBuffer, pCertList->length);
1785                         SysTryCatch(NID_SEC_CERT, pCert != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Certificate convertion failed.");
1786
1787                         readLength = PEM_write_bio_X509(pBio, pCert);
1788                         SysTryCatch(NID_SEC_CERT, readLength > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Certificate conversion failed");
1789
1790                         pCertList->length = certificateBase64Len + (2 * _MAX_PEM_HEADER);
1791
1792                         readLength = BIO_read(pBio, pCertList->certificate, pCertList->length);
1793                         SysTryCatch(NID_SEC_CERT, readLength > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Certificate conversion failed");
1794
1795                         pCertList->length = readLength;
1796
1797                         BIO_free(pBio);
1798                         pBio = null;
1799
1800                         X509_free(pCert);
1801                         pCert = null;
1802
1803                 }
1804                 else if (encodingType == _CERT_ENC_TYPE_BASE64)
1805                 {
1806                         int certLen = _Base64::GetEncodedSize(pCertList->length);
1807                         SysTryReturnResult(NID_SEC_CERT, certLen > 0, E_SYSTEM, "Certificate length is invalid.");
1808                         memset(pCertList->certificate + pCertList->length, 0, sizeof(pCertList->certificate) - pCertList->length);
1809                         r = _Base64::Encode(reinterpret_cast< byte* >(pCertList->certificate), pCertList->length, reinterpret_cast< char* >(pCertList->certificate), certLen);
1810                         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_ENCODING_FAILED, "Failed to encode data in base 64 encoding.");
1811
1812                         pCertList->length = certLen;
1813                 }
1814
1815                 std::unique_ptr< byte[] > pPrivateKey(new (std::nothrow) byte[_MAX_CERT_PRIVATE_KEY_SIZE]);
1816                 SysTryReturnResult(NID_SEC_CERT, pPrivateKey != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
1817
1818                 memset(pPrivateKey.get(), 0, _MAX_CERT_PRIVATE_KEY_SIZE);
1819                 pCertList->format = static_cast< _CertFormat >(userCertRecord.certFormat);
1820                 pCertList->certFileId = userCertRecord.certId;
1821
1822                 r = pFileStore->SetFileHandle(userCertRecord.certId, _CERT_PATH_PRIVATE_KEY);
1823                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to set file handle.");
1824
1825                 priKeyLen = 0;
1826
1827                 r = pFileStore->ReadFromFile(reinterpret_cast< byte* >(pPrivateKey.get()), priKeyLen);
1828                 if (!IsFailed(r) && priKeyLen != 0)
1829                 {
1830                         byte* pPrivateTempKey = null;
1831                         pPriKey->SetPrivateKey(priKeyLen, pPrivateKey.get());
1832                         pCertList->priKeyLen = _Base64::GetEncodedSize(priKeyLen) + _MAX_PEM_HEADER;
1833
1834                         pPrivateKey.reset(null);
1835                         priKeyLen = 0;
1836
1837                         pPriKey->GetPkcs8EncDecKeyN(priKeyLen, &pPrivateTempKey, 0);
1838                         SysTryReturnResult(NID_SEC_CERT, pPrivateTempKey != null, E_SYSTEM, "Failed to get private key buffer.");
1839
1840                         pPrivateKey = std::unique_ptr< byte[] >(pPrivateTempKey);
1841
1842                         if (encodingType == _CERT_ENC_TYPE_PEM)
1843                         {
1844                                 const byte* pKeyBuffer = pPrivateKey.get();
1845                                 pBio = BIO_new(BIO_s_mem());
1846                                 SysTryReturnResult(NID_SEC_CERT, pBio != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
1847
1848                                 pKey = d2i_PrivateKey(EVP_PKEY_RSA, null, &pKeyBuffer, priKeyLen);
1849                                 SysTryCatch(NID_SEC_CERT, pKey != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Private key conversion failed");
1850
1851                                 PEM_write_bio_PrivateKey(pBio, pKey, null, null, 0, 0, null);
1852                                 SysTryCatch(NID_SEC_CERT, pBio != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Private key to bio conversion failed");
1853
1854                                 readLength = BIO_read(pBio, pCertList->privatekey, pCertList->priKeyLen);
1855
1856                                 SysTryCatch(NID_SEC_CERT, readLength > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Private Key conversion failed");
1857
1858                                 pCertList->priKeyLen = readLength;
1859
1860                                 BIO_free(pBio);
1861                                 pBio = null;
1862
1863                                 X509_free(pCert);
1864                                 pCert = null;
1865                         }
1866                         else if (encodingType == _CERT_ENC_TYPE_BASE64)
1867                         {
1868                                 pCertList->priKeyLen = _Base64::GetEncodedSize(priKeyLen);
1869                                 memset(pCertList->privatekey, 0, sizeof(pCertList->privatekey));
1870
1871                                 r = _Base64::Encode(reinterpret_cast< byte* >(pPrivateKey.get()), priKeyLen, reinterpret_cast< char* >(pCertList->privatekey), pCertList->priKeyLen);
1872                                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_ENCODING_FAILED, "Failed to encode data in base 64 encoding.");
1873                         }
1874                         else
1875                         {
1876                                 memcpy(pCertList->privatekey, pPrivateKey.get(), priKeyLen);
1877                                 pCertList->priKeyLen = priKeyLen;
1878                         }
1879                 }
1880
1881                 pPrivateKey.reset(null);
1882
1883                 pHoldList = pCertList.release();
1884                 *ppCertListInfoTypes = pHoldList;
1885
1886                 certCount++;
1887
1888                 memset(subName, 0, _MAX_ISSUER_SUBJECT_NAME_SIZE);
1889                 memcpy(subName, userCertRecord.issuerName, userCertRecord.issuerNameLen);
1890                 subNameLen = userCertRecord.issuerNameLen;
1891
1892                 do
1893                 {
1894                         subjectNameBase64Len = _Base64::GetEncodedSize(subNameLen);
1895                         memset(subjectNameBase64, 0, sizeof(subjectNameBase64));
1896                         r = _Base64::Encode(reinterpret_cast< byte* >(subName), subNameLen, reinterpret_cast< char* >(subjectNameBase64), subjectNameBase64Len);
1897                         SysTryCatch(NID_SEC_CERT, !IsFailed(r), , r, "[%s] Failed to encode data in base 64 encoding.", GetErrorMessage(r));
1898                         snprintf(condition, (_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_SUBJECT_OFFSET_SIZE), "subjectName = '%s' and installed = '%s'", subjectNameBase64, installedRecord);
1899
1900                         if (strcmp(reinterpret_cast< char* >(issuerNameBase64), reinterpret_cast< char* >(subjectNameBase64)) == 0)
1901                         {
1902                                 isIssuerNameInList = true;
1903                         }
1904
1905                         memset(&certRecord, 0, sizeof(certRecord));
1906                         r = __caCertDbStore.GetFirstRecordByConditions(reinterpret_cast< byte* >(condition), &certRecord);
1907                         SysTryCatch(NID_SEC_CERT, !IsFailed(r), , r, "[%s] Failed to get certificates record.", GetErrorMessage(r));
1908
1909                         if (strcmp(certRecord.issuerName, certRecord.subjectName) != 0)
1910                         {
1911                                 std::unique_ptr< _CertificateListInfo > pCertList(new (std::nothrow) _CertificateListInfo());
1912                                 SysTryReturnResult(NID_SEC_CERT, pCertList != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
1913
1914                                 memset(pCertList.get(), 0, sizeof(*pCertList.get()));
1915                                 pCertList->pNext = null;
1916
1917                                 r = pFileStore->SetFileHandle(certRecord.certId, _CERT_PATH_CA_CERT);
1918                                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to set file handle.");
1919
1920                                 r = pFileStore->ReadFromFile(reinterpret_cast< byte* >(pCertList->certificate), pCertList->length);
1921                                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to read from file.");
1922                                 certificateBase64Len = _Base64::GetEncodedSize(pCertList->length);
1923
1924                                 if (encodingType == _CERT_ENC_TYPE_PEM)
1925                                 {
1926                                         const byte* pCertBuffer = pCertList->certificate;
1927
1928                                         pBio = BIO_new(BIO_s_mem());
1929                                         SysTryReturnResult(NID_SEC_CERT, pBio != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
1930
1931                                         pCert = d2i_X509(null, &pCertBuffer, pCertList->length);
1932                                         SysTryCatch(NID_SEC_CERT, pCert != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Certificate convertion failed.");
1933
1934                                         readLength = PEM_write_bio_X509(pBio, pCert);
1935                                         SysTryCatch(NID_SEC_CERT, readLength > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Certificate conversion failed");
1936
1937                                         pCertList->length = certificateBase64Len + (2 * _MAX_PEM_HEADER);
1938
1939                                         readLength = BIO_read(pBio, pCertList->certificate, pCertList->length);
1940                                         SysTryCatch(NID_SEC_CERT, readLength > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Certificate conversion failed");
1941
1942                                         pCertList->length = readLength;
1943
1944                                         BIO_free(pBio);
1945                                         pBio = null;
1946
1947                                         X509_free(pCert);
1948                                         pCert = null;
1949                                 }
1950                                 else if (encodingType == _CERT_ENC_TYPE_BASE64)
1951                                 {
1952                                         int certLen = _Base64::GetEncodedSize(pCertList->length);
1953                                         memset(pCertList->certificate + pCertList->length, 0, sizeof(pCertList->certificate) - pCertList->length);
1954                                         r = _Base64::Encode(reinterpret_cast< byte* >(pCertList->certificate), pCertList->length, reinterpret_cast< char* >(pCertList->certificate), certLen);
1955                                         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_ENCODING_FAILED, "Failed to encode data in base 64 encoding.");
1956                                         pCertList->length = certLen;
1957                                 }
1958                                 pCertList->format = (_CertFormat) certRecord.certFormat;
1959                                 pCertList->certType = (_CaCertType) certRecord.certType;
1960                                 pCertList->certFileId = certRecord.certId;
1961
1962                                 pHoldList->pNext = pCertList.release();
1963                                 pHoldList = pHoldList->pNext;
1964
1965                                 certCount++;
1966
1967                                 memset(subName, 0, _MAX_ISSUER_SUBJECT_NAME_SIZE);
1968                                 memcpy(subName, certRecord.issuerName, certRecord.issuerNameLen);
1969                                 subNameLen = certRecord.issuerNameLen;
1970                         }
1971
1972                 }
1973                 while (strcmp(certRecord.issuerName, certRecord.subjectName));
1974
1975                 if (!isIssuerNameInList)
1976                 {
1977                         if (*ppCertListInfoTypes != null)
1978                         {
1979                                 _CertService::FreeCertList(*ppCertListInfoTypes);
1980                                 *ppCertListInfoTypes = null;
1981                         }
1982
1983                         memset(condition, 0, sizeof(condition));
1984                         snprintf(condition, (_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_SUBJECT_OFFSET_SIZE), "installed = '%s'", installedRecord);
1985
1986                         count++;
1987
1988                         memset(&userCertRecord, 0, sizeof(userCertRecord));
1989                         r = __userCertDbStore.GetFirstRecordByConditions(reinterpret_cast< byte* >(condition), &userCertRecord);
1990                         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to get certificates record.", GetErrorMessage(r));
1991
1992                         curCertId = userCertRecord.certId;
1993
1994                         for (readLength = 0; readLength < count; readLength++)
1995                         {
1996
1997                                 memset(&userCertRecord, 0, sizeof(userCertRecord));
1998                                 r = __userCertDbStore.GetNextRecordByCondition(reinterpret_cast< byte* >(condition), &userCertRecord, curCertId);
1999                                 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to get certificate records.", GetErrorMessage(r));
2000                                 curCertId = userCertRecord.certId;
2001                         }
2002                 }
2003
2004         }
2005         while (isIssuerNameInList != true);
2006
2007 CATCH:
2008         if (pBio != null)
2009         {
2010                 BIO_free(pBio);
2011         }
2012         if (pCert != null)
2013         {
2014                 X509_free(pCert);
2015         }
2016         if (pKey != null)
2017         {
2018                 EVP_PKEY_free(pKey);
2019         }
2020
2021         return r;
2022 }
2023
2024 result
2025 _CertDbManager::GetUserCertificateChain(_CertFormat certFormat, _CertChain* pCertChain, _CertPrivateKeyInfo* pPrivateKeyInfo, char* pSubjectName)
2026 {
2027         result r = E_SUCCESS;
2028         UserCertRecord userCertRecord = {0, };
2029         CaCertRecord caCertRecord = {0, };
2030         int subjNameB64len = 0;
2031         int parentCa = 0;
2032         char subjectNameBase64[_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_ISSUER_OFFSET_SIZE] = {0, };
2033         char conditonRecord[_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_SUBJECT_OFFSET_SIZE] = {0, };
2034         char installedRecord[_MAX_TYPE_RECORD_SIZE] = "T\0";
2035
2036         subjNameB64len = _Base64::GetEncodedSize(strlen(pSubjectName));
2037         memset(subjectNameBase64, 0, sizeof(subjectNameBase64));
2038         r = _Base64::Encode(reinterpret_cast< byte* >(pSubjectName), strlen(pSubjectName), subjectNameBase64, subjNameB64len);
2039         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_ENCODING_FAILED, "Failed to encode data in base 64 encoding.");
2040         snprintf(conditonRecord, (_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_SUBJECT_OFFSET_SIZE), "subjectName = '%s' and installed = '%s'", subjectNameBase64, installedRecord);
2041
2042         r = __userCertDbStore.GetFirstRecordByConditions(reinterpret_cast< byte* >(conditonRecord), &userCertRecord);
2043         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to get certificates record.", GetErrorMessage(r));
2044
2045         if (pPrivateKeyInfo != null)
2046         {
2047                 pPrivateKeyInfo->SetPrivateKey(userCertRecord.prvKeyPath);
2048         }
2049
2050         r = pCertChain->AddCertificate(certFormat, userCertRecord.fileName);
2051         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] AddCertificate failed.", GetErrorMessage(r));
2052
2053         parentCa = userCertRecord.parentCa;
2054
2055         do
2056         {
2057                 memset(&caCertRecord, 0, sizeof(caCertRecord));
2058                 memset(conditonRecord, 0, _MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_SUBJECT_OFFSET_SIZE);
2059                 snprintf(conditonRecord, (_MAX_ISSUER_SUBJECT_NAME_SIZE + _MAX_SUBJECT_OFFSET_SIZE), "certId = %d and installed = '%s'", parentCa, installedRecord);
2060
2061                 r = __caCertDbStore.GetFirstRecordByConditions(reinterpret_cast< byte* >(conditonRecord), &caCertRecord);
2062                 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to get certificates record.", GetErrorMessage(r));
2063
2064                 parentCa = caCertRecord.parentCa;
2065                 if (caCertRecord.certId != caCertRecord.parentCa) //Exclude root certificate from the chain
2066                 {
2067                         r = pCertChain->AddCertificate(certFormat, caCertRecord.fileName);
2068                         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to add certificate in chain.", GetErrorMessage(r));
2069                 }
2070
2071         }
2072         while (caCertRecord.certId != caCertRecord.parentCa);
2073
2074         return E_SUCCESS;
2075 }
2076
2077 result
2078 _CertDbManager::GetUserCertificateInfoByCertId(int certId, int* pSubjectLength, byte* pSubjectName, int* pIssuerLength, byte* pIssuerName)
2079 {
2080         result r = E_SUCCESS;
2081         UserCertRecord userCertRecord = {0, };
2082         char installedRecord[_MAX_TYPE_RECORD_SIZE] = "T\0";
2083         char condition[_MAX_TYPE_CONST_SIZE] = {0, };
2084
2085         snprintf(condition, _MAX_TYPE_CONST_SIZE, "certId = %d and installed = '%s'", certId, installedRecord);
2086
2087         r = __userCertDbStore.GetFirstRecordByConditions(reinterpret_cast< byte* >(condition), &userCertRecord);
2088         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to get certificates record.", GetErrorMessage(r));
2089
2090         *pSubjectLength = userCertRecord.subjectNameLen;
2091         memcpy(pSubjectName, userCertRecord.subjectName, userCertRecord.subjectNameLen);
2092         *pIssuerLength = userCertRecord.issuerNameLen;
2093         memcpy(pIssuerName, userCertRecord.issuerName, userCertRecord.issuerNameLen);
2094
2095         return E_SUCCESS;
2096
2097 }
2098
2099 result
2100 _CertDbManager::GetUserCertificateInfoByCertId(int certId, _CertEncodingType encodingType, _CertInfo** ppUserCertInfo)
2101 {
2102         result r = E_SUCCESS;
2103         char condition[_MAX_TYPE_CONST_SIZE] = {0, };
2104         char installedRecord[_MAX_TYPE_RECORD_SIZE] = "T\0";
2105         int priKeyLen = 0;
2106         int readCount = 0;
2107         int certBufferLen = 0;
2108         int keyBufferLen = 0;
2109         int certificateBase64Len = 0;
2110         const byte* pCertBuffer = null;
2111         const byte* pKeyBuffer = null;
2112         byte* pPrivateTempKey = null;
2113         UserCertRecord certRecord = {0, };
2114         _CertFileStore fileStore;
2115         std::unique_ptr< _CertPrivateKeyInfo > pPriKey;
2116         BIO* pBio = null;
2117         X509* pCert = null;
2118         EVP_PKEY* pKey = null;
2119
2120         *ppUserCertInfo = null;
2121
2122         SysTryReturnResult(NID_SEC_CERT, certId > 0, E_INVALID_ARG, "Invalid input parameter.");
2123         snprintf(condition, _MAX_TYPE_CONST_SIZE, "certId = %d and installed = '%s'", certId, installedRecord);
2124
2125         r = __userCertDbStore.GetFirstRecordByConditions(reinterpret_cast< byte* >(condition), &certRecord);
2126         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to get certificates record.", GetErrorMessage(r));
2127
2128         std::unique_ptr< _CertInfo > pCertInfo(new (std::nothrow) _CertInfo);
2129         SysTryCatch(NID_SEC_CERT, pCertInfo != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
2130
2131         memset(pCertInfo.get(), 0, sizeof(*pCertInfo.get()));
2132
2133         r = fileStore.SetFileHandle(certRecord.certId, _CERT_PATH_USER_CERT);
2134         SysTryCatch(NID_SEC_CERT, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[%s] Failed to set file handle.", GetErrorMessage(r));
2135
2136         r = fileStore.ReadFromFile(reinterpret_cast< byte* >(pCertInfo->certificate), pCertInfo->certLength);
2137         SysTryCatch(NID_SEC_CERT, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[%s] Failed to read from file.", GetErrorMessage(r));
2138         certificateBase64Len = _Base64::GetEncodedSize(pCertInfo->certLength);
2139
2140         if (encodingType == _CERT_ENC_TYPE_PEM)
2141         {
2142                 pBio = BIO_new(BIO_s_mem());
2143                 SysTryCatch(NID_SEC_CERT, pBio != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
2144
2145                 pCertBuffer = new (std::nothrow) byte[pCertInfo->certLength];
2146                 SysTryCatch(NID_SEC_CERT, pCertBuffer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
2147
2148                 memcpy((void*) pCertBuffer, pCertInfo->certificate, pCertInfo->certLength);
2149                 certBufferLen = pCertInfo->certLength;
2150
2151                 pCert = d2i_X509(null, &pCertBuffer, certBufferLen);
2152                 SysTryCatch(NID_SEC_CERT, pCert != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Certificate convertion failed.");
2153
2154                 readCount = PEM_write_bio_X509(pBio, pCert);
2155                 SysTryCatch(NID_SEC_CERT, readCount > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Certificate conversion failed");
2156
2157                 pCertInfo->certLength = certificateBase64Len + (2 * _MAX_PEM_HEADER);
2158                 readCount = BIO_read(pBio, pCertInfo->certificate, pCertInfo->certLength);
2159                 SysTryCatch(NID_SEC_CERT, readCount > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Certificate conversion failed");
2160
2161                 pCertInfo->certLength = readCount;
2162         }
2163         else if (encodingType == _CERT_ENC_TYPE_BASE64)
2164         {
2165                 int certLen = _Base64::GetEncodedSize(pCertInfo->certLength);
2166                 memset(pCertInfo->certificate + pCertInfo->certLength, 0, sizeof(pCertInfo->certificate) - pCertInfo->certLength);
2167                 r = _Base64::Encode(reinterpret_cast< byte* >(pCertInfo->certificate), pCertInfo->certLength, reinterpret_cast< char* >(pCertInfo->certificate), certLen);
2168                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_ENCODING_FAILED, "Failed to encode data in base 64 encoding.");
2169                 pCertInfo->certLength = certLen;
2170         }
2171         pCertInfo->certId = certRecord.certId;
2172         pCertInfo->certFormat = (_CertFormat) certRecord.certFormat;
2173         pCertInfo->certType = _CERT_TYPE_USER_CERT;
2174
2175         if (certRecord.prvKeyLen > 0)
2176         {
2177                 pPriKey = std::unique_ptr< _CertPrivateKeyInfo >(new (std::nothrow) _CertPrivateKeyInfo());
2178                 SysTryReturnResult(NID_SEC_CERT, pPriKey != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
2179
2180                 std::unique_ptr< byte[] > pPrivateKey(new (std::nothrow) byte[_MAX_CERT_PRIVATE_KEY_SIZE]);
2181                 SysTryReturnResult(NID_SEC_CERT, pPrivateKey != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
2182
2183                 memset(pPrivateKey.get(), 0, _MAX_CERT_PRIVATE_KEY_SIZE);
2184                 r = fileStore.SetFileHandle(certRecord.certId, _CERT_PATH_PRIVATE_KEY);
2185                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to set file handle.");
2186
2187                 r = fileStore.ReadFromFile(reinterpret_cast< byte* >(pPrivateKey.get()), priKeyLen);
2188                 if (!IsFailed(r) && priKeyLen != 0)
2189                 {
2190                         pPriKey->SetPrivateKey(priKeyLen, pPrivateKey.get());
2191
2192                         pCertInfo->privateKeyLen = _Base64::GetEncodedSize(priKeyLen) + _MAX_PEM_HEADER;
2193
2194                         priKeyLen = 0;
2195
2196                         pPrivateKey.reset(null);
2197
2198                         pPriKey->GetPkcs8EncDecKeyN(priKeyLen, &pPrivateTempKey, 0);
2199                         SysTryReturnResult(NID_SEC_CERT, pPrivateTempKey != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
2200
2201                         pPrivateKey = std::unique_ptr< byte[] >(pPrivateTempKey);
2202
2203                         if (encodingType == _CERT_ENC_TYPE_PEM)
2204                         {
2205                                 BIO_free(pBio);
2206
2207                                 pBio = BIO_new(BIO_s_mem());
2208                                 SysTryReturnResult(NID_SEC_CERT, pBio != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
2209
2210                                 pKeyBuffer = new (std::nothrow) byte[priKeyLen];
2211                                 SysTryCatch(NID_SEC_CERT, pKeyBuffer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
2212
2213                                 memcpy((void*) pKeyBuffer, pPrivateKey.get(), priKeyLen);
2214                                 keyBufferLen = priKeyLen;
2215
2216                                 pKey = d2i_PrivateKey(EVP_PKEY_RSA, null, &pKeyBuffer, keyBufferLen);
2217                                 SysTryCatch(NID_SEC_CERT, pKey != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Private key conversion failed");
2218
2219                                 PEM_write_bio_PrivateKey(pBio, pKey, null, null, 0, 0, null);
2220
2221                                 readCount = BIO_read(pBio, pCertInfo->privatekey, pCertInfo->privateKeyLen);
2222                                 SysTryCatch(NID_SEC_CERT, readCount > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Private Key conversion failed");
2223
2224                                 pCertInfo->privateKeyLen = readCount;
2225                         }
2226                         else if (encodingType == _CERT_ENC_TYPE_BASE64)
2227                         {
2228                                 pCertInfo->privateKeyLen = _Base64::GetEncodedSize(priKeyLen);
2229                                 memset(pCertInfo->privatekey, 0, sizeof(pCertInfo->privatekey));
2230                                 r = _Base64::Encode(reinterpret_cast< byte* >(pPrivateKey.get()), priKeyLen, reinterpret_cast< char* >(pCertInfo->privatekey), pCertInfo->privateKeyLen);
2231                                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_ENCODING_FAILED, "Failed to encode data in base 64 encoding.");
2232
2233                         }
2234                         else
2235                         {
2236                                 memcpy(pCertInfo->privatekey, pPrivateKey.get(), priKeyLen);
2237                                 pCertInfo->privateKeyLen = priKeyLen;
2238                         }
2239                 }
2240         }
2241
2242         *ppUserCertInfo = pCertInfo.release();
2243
2244 CATCH:
2245
2246         if (encodingType == _CERT_ENC_TYPE_PEM)
2247         {
2248                 BIO_free(pBio);
2249                 X509_free(pCert);
2250                 EVP_PKEY_free(pKey);
2251         }
2252
2253         return r;
2254 }
2255
2256
2257 } } } //Tizen::Security::Cert