Removed const from Format
[platform/framework/native/appfw.git] / src / security / cert / FSecCert_CertManager.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_CertManager.cpp
19  * @brief               This file contains implementation of X509 Certificate and private key interface APIs.
20 */
21
22 #include <unique_ptr.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include <error.h>
27 #include <new>
28 #include <sys/stat.h>
29 #include <assert.h>
30 #include <dirent.h>
31 #include <openssl/sha.h>
32 #include <openssl/evp.h>
33 #include <openssl/pem.h>
34 #include <FBaseByteBuffer.h>
35 #include <FBaseResult.h>
36 #include <FSysSystemTime.h>
37 #include <FBaseSysLog.h>
38 #include <FIoDirectory.h>
39 #include <FIoDirEnumerator.h>
40 #include <FIoFileAttributes.h>
41 #include <FIoFile.h>
42 #include "FSecCertX509Certificate.h"
43 #include "FSecCert_CertManager.h"
44 #include "FSecCert_CertPrivateKeyInfo.h"
45 #include "FSecCert_CertDbManager.h"
46 #include "FSecCert_Base64.h"
47 #include "FSecCert_CertOidDef.h"
48 #include "FSecCert_CertFileStore.h"
49
50 using namespace Tizen::Base;
51 using namespace Tizen::System;
52 using namespace Tizen::Io;
53
54 namespace
55 {
56 struct ByteDeleter
57 {
58         void operator ()(byte* c)
59         {
60                 free(c);
61         }
62 };
63 }
64
65 namespace Tizen { namespace Security { namespace Cert
66 {
67
68 static const char* _CERT_BASE64_HEADER = "-----BEGIN CERTIFICATE-----";
69 static const char* _CERT_BASE64_TRAILER = "-----END CERTIFICATE-----";
70
71 result
72 _CertManager::CreateCrtFile(void)
73 {
74         result r = E_SUCCESS;
75         BIO* pBio = null;
76         X509* pCert = null;
77         Directory dir;
78         File fileCrt;
79         FileAttributes attr;
80         byte certBufData[_MAX_CERTIFICATE_SIZE] = {0, };
81         long fileSize = 0;
82         int certBufferLen = 0;
83         int readLength = 0;
84         int certificateBase64Len = 0;
85         int readCnt = 0;
86         String dirName(_CERT_ROOT_CA_CERT_FILE_DIRECTORY);
87         String crtFileName(_CERT_MGR_CRT_FILE_PATH);
88         String tmpCrtFileName(_TEMP_CERT_MGR_CRT_FILE_PATH);
89
90         r = fileCrt.Construct(tmpCrtFileName, L"a+");
91         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Construct failed.", GetErrorMessage(r));
92
93         r = dir.Construct(dirName);
94         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to construct directory.", GetErrorMessage(r));
95
96         std::unique_ptr< DirEnumerator > pDirEnum(dir.ReadN());
97         SysTryReturn(NID_SEC_CERT, pDirEnum != null, GetLastResult(), GetLastResult(), "[%s] Failed to read directory.", GetErrorMessage(GetLastResult()));
98
99         while (pDirEnum->MoveNext() == E_SUCCESS)
100         {
101                 String fileName;
102                 File file;
103                 DirEntry entry = pDirEnum->GetCurrentDirEntry();
104
105                 fileName.Append(dirName);
106                 fileName.Append(entry.GetName());
107                 if ((entry.GetName() == "..") || (entry.GetName() == "."))
108                 {
109                         continue;
110                 }
111
112                 r = file.Construct(fileName, L"r");
113                 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to construct file.", GetErrorMessage(r));
114
115                 r = File::GetAttributes(fileName, attr);
116                 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to get file attributes.", GetErrorMessage(r));
117
118                 fileSize = attr.GetFileSize();
119                 SysTryCatch(NID_SEC_CERT, fileSize > 0, r = GetLastResult(), GetLastResult(), "[%s] Failed to get file size.", GetErrorMessage(r));
120                 SysTryCatch(NID_SEC_CERT, fileSize < _MAX_CERTIFICATE_SIZE, r = GetLastResult(), GetLastResult(), "[%s] File size exceeds maximum specified length.", GetErrorMessage(r));
121
122                 readCnt = file.Read(certBufData, fileSize);
123                 certificateBase64Len = _Base64::GetEncodedSize(readCnt);
124                 r = GetLastResult();
125                 if (!IsFailed(r) && readCnt == fileSize)
126                 {
127                         BIO_free(pBio);
128                         X509_free(pCert);
129
130                         pBio = BIO_new(BIO_s_mem());
131                         SysTryCatch(NID_SEC_CERT, pBio != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
132
133                         std::unique_ptr< unsigned char[] > pCertBuffer(new (std::nothrow) unsigned char[readCnt]);
134                         SysTryCatch(NID_SEC_CERT, pCertBuffer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
135
136                         memcpy(static_cast< void* >(pCertBuffer.get()), certBufData, readCnt);
137                         certBufferLen = readCnt;
138
139                         const unsigned char* pTemp = pCertBuffer.get();
140                         pCert = d2i_X509(null, &pTemp, certBufferLen);
141                         SysTryCatch(NID_SEC_CERT, pCert != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Certificate conversion failed.");
142
143                         readLength = PEM_write_bio_X509(pBio, pCert);
144                         SysTryCatch(NID_SEC_CERT, readLength > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Certificate conversion failed");
145
146                         readCnt = certificateBase64Len + (2 * _MAX_PEM_HEADER);
147
148                         readLength = BIO_read(pBio, certBufData, readCnt);
149                         SysTryCatch(NID_SEC_CERT, readLength > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Certificate conversion failed");
150
151                         readCnt = readLength;
152
153                         r = fileCrt.Write(certBufData, readLength);
154                         SysTryCatch(NID_SEC_CERT, !IsFailed(r), , r, "[%] Failed to write certificate to file.", GetErrorMessage(r));
155
156                         fileSize = 0;
157                         readCnt = 0;
158                         readLength = 0;
159                         memset(certBufData, 0, _MAX_CERTIFICATE_SIZE);
160                 }
161         }
162         fileCrt.Flush();
163         Tizen::Io::File::Remove(crtFileName);
164         Tizen::Io::File::Move(tmpCrtFileName, crtFileName);
165 CATCH:
166         BIO_free(pBio);
167         X509_free(pCert);
168         return r;
169 }
170
171 result
172 _CertManager::OpenContext(_CertContextType type, CertChainCtx* pHCertCtx)
173 {
174         SysTryReturnResult(NID_SEC_CERT, type > 0, E_INVALID_ARG, "Invalid input parameter.");
175
176         _CertChain* pCertChain = new (std::nothrow) _CertChain();
177         SysTryReturnResult(NID_SEC_CERT, pCertChain != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
178
179         pCertChain->SetContextType(type);
180         *pHCertCtx = (CertChainCtx) pCertChain;
181
182         return E_SUCCESS;
183 }
184
185 result
186 _CertManager::AddCertificate(CertChainCtx certCtx, byte* pCert, int certLen)
187 {
188         result r = E_SUCCESS;
189         byte* pDerCert = null;
190         int derCertBufferLength = 0;
191         _CertFormat certFormat = _CERT_UNKNOWN;
192         _CertEncodingType encodingType = _CERT_ENC_TYPE_UNKNOWN;
193         _CertChain* pCertChain = reinterpret_cast< _CertChain* >(certCtx);
194
195         SysTryReturnResult(NID_SEC_CERT, pCertChain != null, E_INVALID_ARG, "Initial parameters are invalid.");
196         SysTryReturnResult(NID_SEC_CERT, pCert != null, E_INVALID_ARG, "Initial parameters are invalid.");
197
198         certFormat = _CertManager::GetEncodedCertBuffer(pCert, certLen, &pDerCert, &derCertBufferLength, &encodingType);
199         std::unique_ptr< byte, ByteDeleter > pDerCertBuffer(pDerCert);
200         pDerCert = null;
201
202         SysTryReturnResult(NID_SEC_CERT, certFormat == _CERT_X509, E_INVALID_ARG, "Unsupported certificate format.");
203         SysTryReturnResult(NID_SEC_CERT, derCertBufferLength > 0, E_INVALID_ARG, "Invalid certificate length.");
204         SysTryReturnResult(NID_SEC_CERT, pDerCertBuffer != null, E_INVALID_ARG, "Input certificate buffer.");
205
206         r = pCertChain->AddCertificate(certFormat, static_cast< byte* >(pDerCertBuffer.get()), derCertBufferLength);
207         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "Failed to add certificate in chain context.");
208
209         return r;
210 }
211
212 result
213 _CertManager::VerifyChain(CertChainCtx certCtx, _CertDomainType* pDomain)
214 {
215         result r = E_SUCCESS;
216         _CertChain* pCertChain = reinterpret_cast< _CertChain* >(certCtx);
217
218         SysTryReturnResult(NID_SEC_CERT, pCertChain != null, E_INVALID_ARG, "Initial parameters are invalid.");
219
220         r = pCertChain->VerifyCertChainWithDb();
221         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to verify certificate chain.", GetErrorMessage(r));
222
223         if (pDomain != null)
224         {
225                 *pDomain = pCertChain->GetCertTypeByDomain();
226         }
227
228         return r;
229 }
230
231 result
232 _CertManager::VerifyCertificate(CertificateHandle certHandle, byte* pPublickey, int keyLen)
233 {
234         result r = E_SUCCESS;
235
236         SysTryReturnResult(NID_SEC_CERT, pPublickey != null, E_INVALID_ARG, "Initial parameters are invalid.");
237         SysTryReturnResult(NID_SEC_CERT, keyLen > 0, E_INVALID_ARG, "Initial parameters are invalid.");
238         SysTryReturnResult(NID_SEC_CERT, certHandle != 0, E_INVALID_ARG, "Initial parameters are invalid.");
239
240         _Certificate* pTempCert = reinterpret_cast< _Certificate* >(certHandle);
241         SysTryReturnResult(NID_SEC_CERT, pTempCert != null, E_INVALID_ARG, "Initial parameters are invalid.");
242
243         _CertFormat format = pTempCert->GetCertFormat();
244
245         if (format == _CERT_X509)
246         {
247                 _X509Certificate* pCert = reinterpret_cast< _X509Certificate* >(certHandle);
248
249                 pCert->VerifySignature(pPublickey, keyLen);
250                 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to get signature.", GetErrorMessage(r));
251
252         }
253         else
254         {
255                 SysLogException(NID_SEC_CERT, E_INVALID_CONTENT, "[E_INVALID_CONTENT]GetCertificateType: Unknown certificate format.");
256                 r = E_SYSTEM;
257         }
258
259         return r;
260 }
261
262 result
263 _CertManager::GetChainDepth(CertChainCtx certCtx, int* pDepth)
264 {
265         _CertChain* pCertChain = reinterpret_cast< _CertChain* >(certCtx);
266         SysTryReturnResult(NID_SEC_CERT, pCertChain != null, E_INVALID_ARG, "Initial parameters are invalid.");
267         *pDepth = pCertChain->GetCount();
268         return E_SUCCESS;
269 }
270
271 result
272 _CertManager::GetNthCertificate(CertChainCtx certCtx, int nth, CertificateHandle* pCertHandle)
273 {
274         result r = E_SUCCESS;
275         _CertFormat format = _CERT_UNKNOWN;
276         _CertChain* pCertChain = reinterpret_cast< _CertChain* >(certCtx);
277         SysTryReturnResult(NID_SEC_CERT, pCertChain != null, E_INVALID_ARG, "Initial parameters are invalid.");
278
279         r = pCertChain->MoveHead();
280         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to move ahead in certificate chain.");
281
282         for (int index = 0; index < nth; index++)
283         {
284                 r = pCertChain->MoveNext();
285                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to move next in certificate chain.");
286         }
287         format = pCertChain->GetCertFormat();
288         if (format == _CERT_X509)
289         {
290                 _X509Certificate* pCert = null;
291                 pCert = pCertChain->GetCurrentCertificate();
292                 SysTryReturnResult(NID_SEC_CERT, pCert != null, E_SYSTEM, "Failed to get certificate from chain, broken certificate chain.");
293
294                 pCert->SetContextCertificate(true);
295                 *pCertHandle = (CertificateHandle) pCert;
296         }
297
298         return r;
299 }
300
301 result
302 _CertManager::GetCertBuffer(CertificateHandle certHandle, char** ppCertbuffer, int* pCertLen)
303 {
304         result r = E_SUCCESS;
305         byte* pBuf = null;
306         int bufSize = 0;
307         _Certificate* pTempCert = null;
308         _CertFormat format;
309
310         SysTryReturnResult(NID_SEC_CERT, certHandle != null, E_INVALID_ARG, "Initial params not set.");
311
312         pTempCert = reinterpret_cast< _Certificate* >(certHandle);
313         format = pTempCert->GetCertFormat();
314         SysTryReturnResult(NID_SEC_CERT, format == _CERT_X509, E_INVALID_ARG, "Initial params not set.");
315
316         _X509Certificate* pCert = reinterpret_cast< _X509Certificate* >(certHandle);
317
318         r = pCert->GetCertBuffer(pBuf, bufSize);
319         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to move next in certificate chain.");
320
321         *ppCertbuffer = new (std::nothrow) char[bufSize];
322         SysTryReturnResult(NID_SEC_CERT, *ppCertbuffer != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
323
324         memcpy(*ppCertbuffer, pBuf, bufSize);
325         *pCertLen = bufSize;
326
327         return r;
328 }
329
330 result
331 _CertManager::CloseContext(CertChainCtx certCtx)
332 {
333         _CertChain* pCertChain = static_cast< _CertChain* >(certCtx);
334         SysTryReturnResult(NID_SEC_CERT, pCertChain != null, E_INVALID_ARG, "Initial parameter not set.");
335
336         delete pCertChain;
337         return E_SUCCESS;
338 }
339
340 result
341 _CertManager::GetCertInfo(CertificateHandle certHandle, _CertFieldType field, _CertFieldInfos* pCertInfo)
342 {
343         result r = E_SUCCESS;
344         _X509Certificate* pCert = static_cast< _X509Certificate* >(certHandle);
345         _X509TbsCert* pTbsCert = null;
346         byte* pSerial = null;
347         int publicKeyLen = 0;
348         int fingerPrintLen = 0;
349         int serialLen = 0;
350         int resValue = 0;
351         char* pSigAlg = null;
352
353         SysTryReturnResult(NID_SEC_CERT, pCert != null, E_INVALID_ARG, "Initial params not set.");
354         SysTryReturnResult(NID_SEC_CERT, pCertInfo != null, E_INVALID_ARG, "Initial params not set.");
355
356         memset(pCertInfo, 0, sizeof(_CertFieldInfos));
357
358         pTbsCert = pCert->GetTbsCertInstance();
359         SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
360
361         if (field & _CERT_FIELD_SERIAL)
362         {
363                 pTbsCert->GetSerialNumber(pSerial, serialLen);
364                 if (pSerial != null)
365                 {
366                         byte* pSerialNumber = null;
367                         int iterVal = 0;
368                         int index = 0;
369                         iterVal = serialLen;
370                         pSerialNumber = static_cast< byte* >(pSerial);
371                         memset(pCertInfo->serialNo, 0, _MAX_SERIAL_NUMBER_SIZE + 1);
372                         for (index = 0; index < iterVal; index++)
373                         {
374                                 snprintf(&pCertInfo->serialNo[index * 2], (_MAX_SERIAL_NUMBER_SIZE + 1), "%02X", pSerialNumber[index]);
375                         }
376                 }
377         }
378         if (field & _CERT_FIELD_SIGALGORITHM)
379         {
380                 pSigAlg = pTbsCert->GetSignatureAlgoId();
381                 if (pSigAlg != null)
382                 {
383                         int len = strlen(pSigAlg);
384                         if (len <= _MAX_CERT_ALGORITHM_SIZE)
385                         {
386                                 strncpy(pCertInfo->sigAlgorithm, pSigAlg, len);
387                         }
388                         else
389                         {
390                                 memcpy(pCertInfo->sigAlgorithm, pSigAlg, _MAX_CERT_ALGORITHM_SIZE);
391                                 pCertInfo->sigAlgorithm[_MAX_CERT_ALGORITHM_SIZE] = '\0';
392                         }
393
394                 }
395                 else
396                 {
397                         strcpy(pCertInfo->sigAlgorithm, "Unknown");
398                 }
399         }
400         if (field & _CERT_FIELD_VALIDITY)
401         {
402                 Tizen::Base::DateTime notBefore;
403                 Tizen::Base::DateTime notAfter;
404
405                 pTbsCert->GetAfterTimes(notAfter);
406                 pTbsCert->GetBeforeTimes(notBefore);
407
408                 memset(pCertInfo->validityFrom, 0, _MAX_CERT_VALIDITY_SIZE + 1);
409                 memset(pCertInfo->validityTo, 0, _MAX_CERT_VALIDITY_SIZE + 1);
410
411                 _CertTime::FormatDateTime(notBefore, pCertInfo->validityFrom);
412
413                 _CertTime::FormatDateTime(notAfter, pCertInfo->validityTo);
414
415         }
416
417         if (field & _CERT_FIELD_SUBJECT)
418         {
419                 byte* pSubjectName = pTbsCert->GetSubjectName();
420                 int subLen = strlen(reinterpret_cast< const char* >(pSubjectName));
421                 memset(pCertInfo->subjectName, 0, _MAX_ISSUER_SUBJECT_NAME_SIZE + 1);
422                 if (subLen <= _MAX_ISSUER_SUBJECT_NAME_SIZE + 1)
423                 {
424                         strncpy(pCertInfo->subjectName, reinterpret_cast< const char* >(pSubjectName), subLen);
425                 }
426                 ParseCertTitle(reinterpret_cast< char* >(pSubjectName), pCertInfo->certTitle);
427                 ClearLastResult();
428         }
429         if (field & _CERT_FIELD_ISSUER)
430         {
431                 byte* pIssuerName = pTbsCert->GetIssuerName();
432                 int issuerLen = strlen(reinterpret_cast< const char* >(pIssuerName));
433                 memset(pCertInfo->issuerName, 0, _MAX_ISSUER_SUBJECT_NAME_SIZE + 1);
434                 if (issuerLen <= _MAX_ISSUER_SUBJECT_NAME_SIZE + 1)
435                 {
436                         strncpy(pCertInfo->issuerName, reinterpret_cast< const char* >(pIssuerName), issuerLen);
437                 }
438                 ParseCertTitle(reinterpret_cast< char* >(pIssuerName), pCertInfo->certSubTitle);
439                 ClearLastResult();
440         }
441         if (field & _CERT_FIELD_FINGERPRINT)
442         {
443                 byte* pX509Buff = null;
444                 int x509BuffSize = 0;
445
446                 memset(pCertInfo->fingerPrint, 0, _MAX_CERT_FINGERPRINT_SIZE + 1);
447
448                 //As per OpenSSL APIs, it takes input as unsigned data types
449                 pCert->GetCertBuffer(pX509Buff, x509BuffSize);
450                 SysTryReturnResult(NID_SEC_CERT, pX509Buff != null, E_SYSTEM, "Failed to get certificate buffer.");
451
452                 std::unique_ptr< byte[] > pFingerPrint(new (std::nothrow) byte[SHA_DIGEST_LENGTH + 1]);
453                 SysTryReturnResult(NID_SEC_CERT, pFingerPrint != null, E_OUT_OF_MEMORY, "Failed to allocate memory. ");
454
455                 memset(pFingerPrint.get(), 0, SHA_DIGEST_LENGTH + 1);
456
457                 resValue = EVP_Digest(pX509Buff, x509BuffSize, pFingerPrint.get(), reinterpret_cast< unsigned int* >(&fingerPrintLen), EVP_sha1(), 0);
458                 SysTryReturnResult(NID_SEC_CERT, resValue == 1, E_SYSTEM, "Failed to create digest hash.");
459
460                 int index = 0;
461                 int maxValue = SHA_DIGEST_LENGTH;
462                 for (index = 0; index < maxValue; index++)
463                 {
464                         snprintf(&pCertInfo->fingerPrint[index * 2], (_MAX_CERT_FINGERPRINT_SIZE + 1), "%02X", pFingerPrint[index]);
465                 }
466                 pCertInfo->fingerPrintLen = fingerPrintLen;
467
468         }
469         if (field & _CERT_FIELD_PUBLICKEY)
470         {
471                 byte* pPublicKeyBuffer = null;
472                 pTbsCert->GetPublicKeyInfoN(publicKeyLen, &pPublicKeyBuffer);
473                 if (pPublicKeyBuffer != null)
474                 {
475                         std::unique_ptr< byte[] > pPublicKeyAuto(pPublicKeyBuffer);
476                         int iterVal = publicKeyLen;
477                         int index = 0;
478
479                         memset(pCertInfo->publicKey, 0, _MAX_CERT_PUBLIC_KEY_SIZE + 1);
480                         for (index = 0; index < iterVal; index++)
481                         {
482                                 snprintf(&pCertInfo->publicKey[index * 2], (_MAX_CERT_PUBLIC_KEY_SIZE + 1), "%02X", pPublicKeyBuffer[index]);
483                         }
484
485                 }
486         }
487
488         if (field & _CERT_FIELD_VERSION)
489         {
490                 pCertInfo->certVersion = pTbsCert->GetVersion();
491                 SysTryReturnResult(NID_SEC_CERT, pCertInfo->certVersion > 0, E_SYSTEM, "Failed to get version.");
492         }
493
494         if (field & _CERT_FIELD_TYPE)
495         {
496                 char type[6] = "X.509";
497                 memset(pCertInfo->certTypeFormat, 0, sizeof(pCertInfo->certTypeFormat));
498                 strcpy(pCertInfo->certTypeFormat, type);
499         }
500         if (strcmp(pCertInfo->certTitle, pCertInfo->certSubTitle) == 0)
501         {
502                 char selfSigned[12] = "Self-signed";
503                 memset(pCertInfo->certSubTitle, 0, sizeof(pCertInfo->certSubTitle));
504                 strcpy(pCertInfo->certSubTitle, selfSigned);
505         }
506
507         return r;
508 }
509
510
511 _CertFormat
512 _CertManager::GetEncodedCertBuffer(byte* pCertBuffer, int certBufferLen, byte** pDerCertBuffer, int* pDerCertBufferLength, _CertEncodingType* encodingType)
513 {
514         result r = E_SUCCESS;
515         _CertFormat certFormat = _CERT_UNKNOWN;
516         BIO* pBio = null;
517         X509* pOpensslX509Cert = null;
518         char* pBase64Header = null;
519         char* pBase64Trailer = null;
520         int readCount = 0;
521         int certBufLen = 0;
522         int decodedLen = 0;
523         int pemCertSize = 0;
524
525         ClearLastResult();
526
527         SysTryReturn(NID_SEC_CERT, pCertBuffer != null, _CERT_UNKNOWN, E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument passed.");
528         SysTryReturn(NID_SEC_CERT, certBufferLen > 0, _CERT_UNKNOWN, E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument passed.");
529
530         std::unique_ptr< _X509Certificate > pX509Cert(new (std::nothrow) _X509Certificate());
531         SysTryReturn(NID_SEC_CERT, pX509Cert != null, _CERT_UNKNOWN, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
532
533         pBase64Header = strstr(reinterpret_cast< char* >(pCertBuffer), _CERT_BASE64_HEADER);
534         pBase64Trailer = strstr(reinterpret_cast< char* >(pCertBuffer), _CERT_BASE64_TRAILER);
535
536         if ((pBase64Header != null) && (pBase64Trailer != null) && (pBase64Trailer > pBase64Header))
537         {
538                 pBio = BIO_new(BIO_s_mem());
539                 SysTryReturn(NID_SEC_CERT, pBio != null, _CERT_UNKNOWN, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
540
541                 pemCertSize = (int(pBase64Trailer - pBase64Header) + strlen(_CERT_BASE64_TRAILER));
542                 readCount = BIO_write(pBio, (const void*) pBase64Header, pemCertSize);
543                 SysTryCatch(NID_SEC_CERT, readCount > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Certificate conversion failed");
544
545                 pOpensslX509Cert = PEM_read_bio_X509(pBio, NULL, 0, NULL);
546                 SysTryCatch(NID_SEC_CERT, pOpensslX509Cert != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Certificate convention failed. readCount = %d Calculated length = %d pBase64Trailer = %s, pBase64Header = %s", readCount, pemCertSize, pBase64Trailer, pBase64Header);
547
548                 decodedLen = i2d_X509(pOpensslX509Cert, pDerCertBuffer);
549                 SysTryCatch(NID_SEC_CERT, decodedLen > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Invalid certificate length.");
550
551                 *pDerCertBufferLength = decodedLen;
552
553                 certFormat = _CERT_X509;
554                 *encodingType = _CERT_ENC_TYPE_PEM;
555         }
556         else if (pX509Cert->Parse(pCertBuffer, certBufferLen) == E_SUCCESS)
557         {
558                 std::unique_ptr< byte, ByteDeleter > pCertBuf(static_cast< byte* >(malloc(sizeof(byte) * certBufferLen)));
559                 SysTryReturn(NID_SEC_CERT, pCertBuf != null, _CERT_UNKNOWN, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
560
561                 memcpy(pCertBuf.get(), pCertBuffer, certBufferLen);
562                 certBufLen = certBufferLen;
563
564                 *pDerCertBuffer = pCertBuf.release();
565                 *pDerCertBufferLength = certBufLen;
566
567                 certFormat = _CERT_X509;
568                 *encodingType = _CERT_ENC_TYPE_BINARY;
569         }
570         else
571         {
572                 certBufLen = _Base64::GetDecodedSize(certBufferLen);
573                 SysTryReturn(NID_SEC_CERT, certBufLen > 0, _CERT_UNKNOWN, E_SYSTEM, "[E_SYSTEM] Invalid certificate length.");
574
575                 std::unique_ptr< byte, ByteDeleter > pCertBuf(static_cast< byte* >(malloc(sizeof(byte) * certBufLen)));
576                 SysTryReturn(NID_SEC_CERT, pCertBuf != null, _CERT_UNKNOWN, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
577
578                 memset(pCertBuf.get(), 0, certBufLen);
579
580                 decodedLen = certBufLen;
581                 readCount = _Base64::Decode(reinterpret_cast< char* >(pCertBuffer), certBufferLen, pCertBuf.get(), decodedLen);
582                 SysTryReturn(NID_SEC_CERT, readCount > 0, _CERT_UNKNOWN, E_SYSTEM, "[E_SYSTEM] Certificate decoding failed.");
583
584                 *pDerCertBuffer = pCertBuf.release();
585                 *pDerCertBufferLength = decodedLen;
586
587                 certFormat = _CERT_X509;
588                 *encodingType = _CERT_ENC_TYPE_BASE64;
589         }
590
591         SetLastResult(E_SUCCESS); //To clear the result of parsing certificate.
592
593 CATCH:
594
595         if (pBio != null)
596         {
597                 BIO_free(pBio);
598         }
599
600         if (pOpensslX509Cert != null)
601         {
602                 X509_free(pOpensslX509Cert);
603         }
604
605         return certFormat;
606 }
607
608 result
609 _CertManager::GetPublicKey(CertificateHandle certificate, char* pBuffer, int* pBufLen)
610 {
611         _Certificate* pTempCert = reinterpret_cast< _Certificate* >(certificate);
612         _X509Certificate* pCert = null;
613         _X509TbsCert* pTbsCert = null;
614         byte* pPuKey = null;
615         int pubKeyLen = 0;
616
617         SysTryReturnResult(NID_SEC_CERT, pBuffer != null, E_INVALID_ARG, "Invalid input parameter.");
618         SysTryReturnResult(NID_SEC_CERT, pTempCert != null, E_INVALID_ARG, "Invalid input parameter.");
619
620         _CertFormat format = pTempCert->GetCertFormat();
621         SysTryReturnResult(NID_SEC_CERT, format == _CERT_X509, E_SYSTEM, "Failed to get certificate format.");
622
623         pCert = reinterpret_cast< _X509Certificate* >(certificate);
624         SysTryReturnResult(NID_SEC_CERT, pCert != null, E_INVALID_ARG, "Invalid input parameter.");
625
626         pTbsCert = pCert->GetTbsCertInstance();
627         SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
628
629         pTbsCert->GetPublicKeyInfoN(pubKeyLen, &pPuKey);
630         SysTryReturnResult(NID_SEC_CERT, pPuKey != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
631
632         std::unique_ptr< byte[] > pPubKeyAuto(pPuKey);
633
634         memcpy(pBuffer, pPubKeyAuto.get(), pubKeyLen);
635
636         if (pBufLen)
637         {
638                 *pBufLen = pubKeyLen;
639         }
640
641         return E_SUCCESS;
642 }
643
644 result
645 _CertManager::GetSignature(CertificateHandle certificate, char* pBuffer, int* pBufLen)
646 {
647         _Certificate* pTempCert = reinterpret_cast< _Certificate* >(certificate);
648         _X509Certificate* pCert = null;
649         byte* pSignature = null;
650         _CertFormat format;
651         _CertSignature* pSig = null;
652         int signLength = 0;
653
654         SysTryReturnResult(NID_SEC_CERT, pBuffer != null, E_INVALID_ARG, "Invalid input parameter.");
655         SysTryReturnResult(NID_SEC_CERT, pTempCert != null, E_INVALID_ARG, "Initial parameter not set.");
656
657         format = pTempCert->GetCertFormat();
658         SysTryReturnResult(NID_SEC_CERT, format == _CERT_X509, E_SYSTEM, "Failed to get certificate format.");
659         pCert = reinterpret_cast< _X509Certificate* >(certificate);
660
661         pSig = pCert->GetSignInstance();
662         SysTryReturnResult(NID_SEC_CERT, pSig != null, E_SYSTEM, "Failed to get certificate signature.");
663
664         pSignature = pSig->GetSignatureInfo(signLength);
665         memcpy(pBuffer, pSignature, signLength);
666
667         if (pBufLen != null)
668         {
669                 *pBufLen = signLength;
670         }
671         return E_SUCCESS;
672 }
673
674 int
675 _CertManager::GetVersion(CertificateHandle certificate)
676 {
677         _Certificate* pTempCert = null;
678         _X509Certificate* pCert = null;
679         _X509TbsCert* pTbsCert = null;
680
681         pTempCert = reinterpret_cast< _Certificate* >(certificate);
682         SysTryReturn(NID_SEC_CERT, pTempCert != null, -1, E_INVALID_ARG, "[E_INVALID_ARG] Initial parameter not set.");
683
684         _CertFormat format = pTempCert->GetCertFormat();
685
686         SysTryReturn(NID_SEC_CERT, format == _CERT_X509, -1, E_SYSTEM, "[E_SYSTEM] Unknown certificate format.");
687         pCert = reinterpret_cast< _X509Certificate* >(certificate);
688
689         pTbsCert = pCert->GetTbsCertInstance();
690         SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
691
692         return pTbsCert->GetVersion();
693 }
694
695 result
696 _CertManager::GetValidity(CertificateHandle certificate, _CertValidityType* pValidity)
697 {
698         _Certificate* pTempCert = reinterpret_cast< _Certificate* >(certificate);
699         _X509Certificate* pCert = null;
700         _X509TbsCert* pTbsCert = null;
701         Tizen::Base::DateTime notBefore;
702         Tizen::Base::DateTime notAfter;
703         Tizen::Base::DateTime curTime;
704
705         SysTryReturnResult(NID_SEC_CERT, pTempCert != null, E_INVALID_ARG, "Initial parameter not set.");
706
707         _CertFormat format = pTempCert->GetCertFormat();
708         SysTryReturnResult(NID_SEC_CERT, format == _CERT_X509, E_SYSTEM, "Unknown certificate format.");
709
710         pCert = reinterpret_cast< _X509Certificate* >(certificate);
711
712         Tizen::System::SystemTime::GetCurrentTime(UTC_TIME, curTime);
713
714         pTbsCert = pCert->GetTbsCertInstance();
715         SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
716
717         pTbsCert->GetBeforeTimes(notBefore);
718         pTbsCert->GetAfterTimes(notAfter);
719         if (curTime <= notAfter && curTime >= notBefore)
720         {
721                 *pValidity = _CERT_VALIDITY_VALID;
722         }
723         else if (curTime < notBefore)
724         {
725                 *pValidity = _CERT_VALIDITY_NOT_YET_VALID;
726         }
727         else if (curTime > notAfter)
728         {
729                 *pValidity = _CERT_VALIDITY_EXPIRED;
730         }
731         return E_SUCCESS;
732
733 }
734
735 result
736 _CertManager::GetCertificateType(CertificateHandle certHandle, _CaCertType* pCertType)
737 {
738         result r = E_SUCCESS;
739         char subjectName[_MAX_ISSUER_SUBJECT_NAME_SIZE] = {0, };
740         char issuerName[_MAX_ISSUER_SUBJECT_NAME_SIZE] = {0, };
741         int lenSubjectName = 0;
742         int lenIssuerName = 0;
743         _Certificate* pParentCert = reinterpret_cast< _Certificate* >(certHandle);
744         _X509Certificate* pCert = null;
745         _X509TbsCert* pTbsCert = null;
746         _CertDbManager* pCertDb = null;
747
748         SysTryReturnResult(NID_SEC_CERT, pParentCert != null, E_INVALID_ARG, "Initial parameter not set.");
749
750
751         _CertFormat format = pParentCert->GetCertFormat();
752         SysTryReturnResult(NID_SEC_CERT, format == _CERT_X509, E_SYSTEM, "Failed to get certificate format.");
753
754         pCert = reinterpret_cast< _X509Certificate* >(certHandle);
755         SysTryReturnResult(NID_SEC_CERT, pCert != null, E_INVALID_ARG, "Initial parameter not set.");
756
757         pTbsCert = pCert->GetTbsCertInstance();
758         SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
759
760         lenSubjectName = strlen(reinterpret_cast< const char* >(pTbsCert->GetSubjectName()));
761         lenIssuerName = strlen(reinterpret_cast< const char* >(pTbsCert->GetIssuerName()));
762         SysTryReturnResult(NID_SEC_CERT, lenSubjectName > 0, E_SYSTEM, "Subject length is not valid.");
763         SysTryReturnResult(NID_SEC_CERT, lenIssuerName > 0, E_SYSTEM, "Issuer length is not valid.");
764
765         strncpy(subjectName, reinterpret_cast< const char* >(pTbsCert->GetSubjectName()), lenSubjectName);
766         strncpy(issuerName, reinterpret_cast< const char* >(pTbsCert->GetIssuerName()), lenIssuerName);
767
768         pCertDb = _CertDbManager::GetInstance();
769         SysTryReturnResult(NID_SEC_CERT, pCertDb != null, E_SYSTEM, "Failed to get instance of certificate database manager.");
770
771         r = pCertDb->FindCertType(format, issuerName, subjectName, pCertType);
772
773         if (IsFailed(r))
774         {
775                 *pCertType = _CERT_TYPE_MAX;
776                 return E_SYSTEM;
777         }
778
779         return E_SUCCESS;
780 }
781
782 result
783 _CertManager::ParseCertTitle(char subject[_MAX_ISSUER_SUBJECT_NAME_SIZE + 1], char title[_MAX_ISSUER_SUBJECT_NAME_SIZE + 1])
784 {
785         ClearLastResult();
786
787         SysTryReturn(NID_SEC_CERT, subject[0] != '\0', E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Invalid input parameter.");
788
789         SysAssertf(strlen(subject) <= (size_t) _MAX_ISSUER_SUBJECT_NAME_SIZE, "The buffer size of source is too big.");
790
791         bool done = false;
792         char* pPivotPtr = null;
793         char* pSavePtr = null;
794         char* pSubStr = null;
795         char tempSubject[_MAX_ISSUER_SUBJECT_NAME_SIZE + 1] = {0, };
796
797         strncpy(tempSubject, subject, strlen(subject + 1));
798         pPivotPtr = tempSubject;
799         for (;; pSubStr = null)
800         {
801                 pSubStr = strtok_r(pPivotPtr, "/", &pSavePtr);
802
803                 if (strncmp(pSubStr, _CERT_COMMON_NAME, strlen(_CERT_COMMON_NAME)) == 0)
804                 {
805                         pSubStr = pSubStr + strlen(_CERT_COMMON_NAME);
806                         done = true;
807                         break;
808                 }
809                 else if (strncmp(pSubStr, _CERT_ORG_NAME, strlen(_CERT_ORG_NAME)) == 0)
810                 {
811                         pSubStr = pSubStr + strlen(_CERT_ORG_NAME);
812                         done = true;
813                         break;
814                 }
815                 else if (strncmp(pSubStr, _CERT_ORG_UNIT_NAME, strlen(_CERT_ORG_UNIT_NAME)) == 0)
816                 {
817                         pSubStr = pSubStr + strlen(_CERT_ORG_UNIT_NAME);
818                         done = true;
819                         break;
820                 }
821                 else if (strncmp(pSubStr, _CERT_EMAIL_ADDRESS, strlen(_CERT_EMAIL_ADDRESS)) == 0)
822                 {
823                         pSubStr = pSubStr + strlen(_CERT_EMAIL_ADDRESS);
824                         done = true;
825                         break;
826                 }
827
828                 pPivotPtr = pSavePtr;
829                 pSubStr = null;
830         }
831
832         SysTryReturn(NID_SEC_CERT, done, E_PARSING_FAILED, E_SYSTEM, "[%s] Failed to parse Certificate title.", GetErrorMessage(E_PARSING_FAILED));
833
834         // initialize buffer
835         for (int index = 0; index < _MAX_ISSUER_SUBJECT_NAME_SIZE + 1; index++)
836         {
837                 title[index] = '\0';
838         }
839
840         // copy title into out param
841         strncpy(title, pSubStr, strlen(pSubStr));
842
843         return E_SUCCESS;
844 }
845
846 //User Certificate APIs
847 result
848 _CertManager::MakeParseAndVerifyCertChainBufferN(byte* pCertChainBuffer, int certChainLength, byte* pUserPrivateKeyBuffer, int userPrivateKeyLength, _CertChain** ppX509CertChain, _CertPrivateKeyInfo** ppX509PrivateKeyInfo)
849 {
850         result r = E_SUCCESS;
851         int dataOffset = 0;
852         int currCertBufLen = 0;
853         int totCertCount = 0;
854         int bufSize = 0;
855         int countTotalCertificateChecked = 0;
856         int addedNumberCertificate = 0;
857         bool pubPriPair = false;
858         byte* pCertBuf = null;
859         byte* pCurrCertBuf = null;
860         _X509Certificate* pUserCert = null;
861         std::unique_ptr< _CertPrivateKeyInfo > pPKeyInfo(null);
862
863         pCertBuf = pCertChainBuffer;
864         bufSize = certChainLength;
865
866         SysTryReturnResult(NID_SEC_CERT, pCertBuf != null, E_INVALID_ARG, "Invalid certificate chain buffer.");
867         SysTryReturnResult(NID_SEC_CERT, bufSize > 0, E_INVALID_ARG, "Invalid length of certificate chain buffer.");
868
869         // Process Private Key
870         if (pUserPrivateKeyBuffer != null && userPrivateKeyLength > 0)
871         {
872                 pPKeyInfo = std::unique_ptr< _CertPrivateKeyInfo >(new (std::nothrow) _CertPrivateKeyInfo(pUserPrivateKeyBuffer, userPrivateKeyLength));
873                 SysTryReturnResult(NID_SEC_CERT, pPKeyInfo != null, E_OUT_OF_MEMORY, "Failed allocate memory.");
874         }
875
876         // Get Cert Count
877         while (dataOffset < bufSize)
878         {
879                 pCurrCertBuf = pCertBuf + dataOffset;
880                 currCertBufLen = _CertManager::GetBlockSize(pCurrCertBuf);
881                 totCertCount++;
882                 dataOffset += currCertBufLen;
883         }
884
885         dataOffset = 0;
886
887         std::unique_ptr< _CertChain > pCertChain(new (std::nothrow) _CertChain());
888         SysTryReturnResult(NID_SEC_CERT, pCertChain != null, E_OUT_OF_MEMORY, "Failed to parse and verify certificate chain.");
889
890         if (pPKeyInfo != null)
891         {
892                 // Find Device/User Certificate
893                 while (dataOffset < bufSize)
894                 {
895                         pCurrCertBuf = pCertBuf + dataOffset;
896                         currCertBufLen = _CertManager::GetBlockSize(pCurrCertBuf);
897
898                         std::unique_ptr< _X509Certificate > pTmpCert(new (std::nothrow) _X509Certificate());
899                         SysTryReturnResult(NID_SEC_CERT, pTmpCert != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
900
901                         r = pTmpCert->Parse(pCurrCertBuf, currCertBufLen);
902                         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_DECODING_FAILED, "Failed to parse and verify certificate chain.");
903
904                         r = _CertManager::CheckRsaPublicPrivateKeyPair(pTmpCert.get(), pPKeyInfo.get());
905                         if (!IsFailed(r))
906                         {
907                                 r = pCertChain->AddCertificate(pTmpCert.get());
908                                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_INVALID_CONDITION, "Failed to parse and verify certificate chain.");
909
910                                 pubPriPair = true;
911                                 addedNumberCertificate++;
912                                 pUserCert = pTmpCert.release();
913                                 break;
914                         }
915
916                         dataOffset += currCertBufLen;
917                 }
918                 //Check key pair
919                 SysTryReturnResult(NID_SEC_CERT, pubPriPair, E_INVALID_KEY, "Failed to parse and verify certificate chain.");
920         }
921
922         dataOffset = 0;
923
924         //As there is no private key present in chain, it is assumed that first certificate is user certificate
925         if (pUserCert == null)
926         {
927                 pCurrCertBuf = pCertBuf + dataOffset;
928                 currCertBufLen = _CertManager::GetBlockSize(pCurrCertBuf);
929
930                 std::unique_ptr< _X509Certificate > pUserCertAuto(new (std::nothrow) _X509Certificate());
931                 SysTryReturnResult(NID_SEC_CERT, pUserCertAuto != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
932
933                 r = pUserCertAuto->Parse(pCurrCertBuf, currCertBufLen);
934                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_DECODING_FAILED, "Failed to parse first certificate in chain.");
935
936                 r = pCertChain->AddCertificate(pUserCertAuto.get());
937                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_INVALID_CONDITION, "Failed to add first certificate in chain. ");
938
939                 addedNumberCertificate++;
940                 pUserCert = pUserCertAuto.release();
941         }
942
943
944         while (totCertCount > addedNumberCertificate)
945         {
946                 dataOffset = 0;
947                 countTotalCertificateChecked++;
948
949                 if (countTotalCertificateChecked > totCertCount)
950                 {
951                         break;
952                 }
953
954                 SysTryReturnResult(NID_SEC_CERT, pUserCert != null, E_INVALID_ARG, "Invalid certificate in chain. ");
955
956                 while (dataOffset < bufSize)
957                 {
958                         std::unique_ptr< _X509Certificate > pCurrentCert(new (std::nothrow) _X509Certificate());
959                         SysTryReturnResult(NID_SEC_CERT, pCurrentCert != null, E_OUT_OF_MEMORY, "Failed to allocate memory. ");
960
961                         pCurrCertBuf = pCertBuf + dataOffset;
962                         currCertBufLen = _CertManager::GetBlockSize(pCurrCertBuf);
963
964                         r = pCurrentCert->Parse(pCurrCertBuf, currCertBufLen);
965                         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_DECODING_FAILED, "Failed to parse certificate in chain. ");
966
967                         if (pUserCert->IsIssuer(pCurrentCert.get()))
968                         {
969                                 r = pCertChain->AddCertificate(pCurrentCert.get());
970                                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_INVALID_CONDITION, "Failed to add certificate in chain. ");
971
972                                 pUserCert = pCurrentCert.release();
973                                 addedNumberCertificate++;
974                                 break;
975                         }
976
977                         dataOffset += currCertBufLen;
978                 }
979         }
980
981         //Here is the place where we verifying certificate chain before installation
982         r = pCertChain->VerifyCertChainWithDb();
983         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to verify certificate chain.", GetErrorMessage(r));
984
985         *ppX509CertChain = pCertChain.release();
986         *ppX509PrivateKeyInfo = pPKeyInfo.release();
987
988         return r;
989 }
990
991 result
992 _CertManager::CheckRsaPublicPrivateKeyPair(_X509Certificate* pX509Certificate, _CertPrivateKeyInfo* pX509CertificatePrivateKey)
993 {
994         result r = E_SUCCESS;
995         int retValue = 0;
996         EVP_PKEY* pPrivateKey = null;
997         int privateKeyLength = 0;
998         X509* pX509Cert = null;
999         const char* pSigalg = null;
1000
1001         SysTryReturnResult(NID_SEC_CERT, pX509Certificate != null, E_INVALID_ARG, "Invalid input parameter. ");
1002         SysTryReturnResult(NID_SEC_CERT, pX509CertificatePrivateKey != null, E_INVALID_ARG, "Invalid input parameter.");
1003
1004         pX509Cert = static_cast< X509* >(pX509Certificate->GetX509CertObject());
1005         SysTryReturnResult(NID_SEC_CERT, pX509Cert != null, E_SYSTEM, "Failed to parse certificate. ");
1006
1007         //const char *
1008         pSigalg = OBJ_nid2ln(OBJ_obj2nid(pX509Cert->sig_alg->algorithm));
1009         SysTryReturnResult(NID_SEC_CERT, pSigalg != null, E_SYSTEM, "Unable to get certificate algorithm.");
1010
1011         if (strstr(pSigalg, "WithRSA"))
1012         {
1013                 byte* pPriKey = null;
1014
1015                 pX509CertificatePrivateKey->GetPrivateKeyN(privateKeyLength, &pPriKey);
1016                 SysTryReturnResult(NID_SEC_CERT, pPriKey != null, E_SYSTEM, "Unable to get certificate private key.");
1017
1018                 std::unique_ptr< byte[] > pPriKeyBuf(pPriKey);
1019
1020                 pPrivateKey = d2i_PrivateKey(EVP_PKEY_RSA, null, const_cast< const unsigned char** >(static_cast< unsigned char** >(&pPriKey)), privateKeyLength);
1021                 if (pPrivateKey != null)
1022                 {
1023                         retValue = X509_check_private_key(pX509Cert, pPrivateKey);
1024
1025                         EVP_PKEY_free(pPrivateKey);
1026
1027                         SysTryReturnResult(NID_SEC_CERT, retValue == 1, E_SYSTEM, "Private public key mismatch, this key does not belong to this certificate.");
1028
1029
1030                 }
1031                 else
1032                 {
1033                         r = E_SYSTEM;
1034                         SysLog(NID_SEC_CERT, "Private key conversion failed.");
1035                 }
1036
1037
1038         }
1039         else
1040         {
1041                 r = E_SYSTEM;
1042                 SysLog(NID_SEC_CERT, "Unsupported Algorithm = %s", pSigalg);
1043         }
1044
1045
1046         return r;
1047 }
1048
1049 result
1050 _CertManager::GetCertificateSubjectNameN(CertificateHandle certificateHandle, byte** ppSubjectName, int* pSubjectNameLength)
1051 {
1052         int len = 0;
1053         byte* pBuf = null;
1054         _Certificate* pTempCert = static_cast< _Certificate* >(certificateHandle);
1055         _CertFormat format = pTempCert->GetCertFormat();
1056
1057         SysTryReturnResult(NID_SEC_CERT, format == _CERT_X509, E_INVALID_ARG, "Invalid certificate format.");
1058
1059         _X509Certificate* pCert = static_cast< _X509Certificate* >(certificateHandle);
1060         pCert->GetIssuerBuffer(pBuf, len);
1061
1062         *ppSubjectName = new (std::nothrow) byte[len];
1063         SysTryReturnResult(NID_SEC_CERT, *ppSubjectName != null, E_OUT_OF_MEMORY, "Failed to allocate memory. ");
1064
1065         memset(*ppSubjectName, 0, len);
1066         memcpy(*ppSubjectName, pBuf, len);
1067         *pSubjectNameLength = len;
1068
1069         return E_SUCCESS;
1070 }
1071
1072 result
1073 _CertManager::GetCertificateIssuerNameN(CertificateHandle certificateHandle, byte** ppIssuerName, int* pIssuerNameLength)
1074 {
1075         _Certificate* pTempCert = static_cast< _Certificate* >(certificateHandle);
1076         _CertFormat format = pTempCert->GetCertFormat();
1077         byte* pBuf = null;
1078         int len = 0;
1079
1080         SysTryReturnResult(NID_SEC_CERT, format == _CERT_X509, E_INVALID_ARG, "Invalid certificate format.");
1081
1082         _X509Certificate* pCert = static_cast< _X509Certificate* >(certificateHandle);
1083         pCert->GetSubjectNameBuffer(pBuf, len);
1084
1085         *ppIssuerName = new (std::nothrow) byte[len];
1086         SysTryReturnResult(NID_SEC_CERT, *ppIssuerName != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
1087         memset(*ppIssuerName, 0, len);
1088         memcpy(*ppIssuerName, pBuf, len);
1089         *pIssuerNameLength = len;
1090
1091         return E_SUCCESS;
1092 }
1093
1094 CertificateStoreCtx
1095 _CertManager::OpenUserCertificateStore(int& totalCount)
1096 {
1097         result r = E_SUCCESS;
1098         UserCertRecord certRecord = {0};
1099         _CertRootList* pHoldList = null;
1100         _CertFileStore fileStore;
1101         CertificateStoreCtx certificateStoreCtx = null;
1102         int certLength = 0;
1103         char condition[_MAX_TYPE_CONST_SIZE] = {0};
1104         char installedRecord[_MAX_TYPE_RECORD_SIZE] = "T\0";
1105
1106         ClearLastResult();
1107
1108         totalCount = 0;
1109
1110         snprintf(condition, _MAX_TYPE_CONST_SIZE, "installed = '%s'", installedRecord);
1111
1112         std::unique_ptr< _UserCertDbStore > pUserCertDbStore(new (std::nothrow) _UserCertDbStore());
1113         SysTryReturn(NID_SEC_CERT, pUserCertDbStore != null, certificateStoreCtx, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
1114
1115         r = pUserCertDbStore->GetFirstRecordByConditions(reinterpret_cast< byte* >(condition), &certRecord);
1116         SysTryReturn(NID_SEC_CERT, !IsFailed(r), certificateStoreCtx, r, "[%s] Failed to get first certificate record.", GetErrorMessage(r));
1117
1118         std::unique_ptr< _CertRootList > pCertListFirstNode(new (std::nothrow) _CertRootList());
1119         SysTryReturn(NID_SEC_CERT, pCertListFirstNode != null, certificateStoreCtx, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
1120
1121         std::unique_ptr< _CertRootCaInfo > pRootCa(new (std::nothrow) _CertRootCaInfo());
1122         SysTryReturn(NID_SEC_CERT, pRootCa != null, certificateStoreCtx, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
1123
1124         memset(pRootCa.get(), 0, sizeof(*pRootCa.get()));
1125         pCertListFirstNode->pNext = null;
1126
1127         r = fileStore.SetFileHandle(certRecord.certId, _CERT_PATH_USER_CERT);
1128         SysTryReturn(NID_SEC_CERT, !IsFailed(r), certificateStoreCtx, E_SYSTEM, "E_SYSTEM Failed to set file handle.");
1129
1130         r = fileStore.ReadFromFile(reinterpret_cast< byte* >(pCertListFirstNode->certificate), certLength);
1131         SysTryReturn(NID_SEC_CERT, !IsFailed(r), certificateStoreCtx, E_SYSTEM, "E_SYSTEM Failed to read from file.");
1132
1133         pCertListFirstNode->length = certLength;
1134         pCertListFirstNode->format = (_CertFormat) certRecord.certFormat;
1135
1136         pRootCa->pRootList = pHoldList = pCertListFirstNode.release();
1137
1138         certificateStoreCtx = (CertificateStoreCtx) pRootCa.release();
1139
1140         totalCount++;
1141
1142         while ((pUserCertDbStore->GetNextRecordByCondition(reinterpret_cast< byte* >(condition), &certRecord, certRecord.certId)) == E_SUCCESS)
1143         {
1144                 std::unique_ptr< _CertRootList > pCertList(new (std::nothrow) _CertRootList());
1145                 SysTryReturn(NID_SEC_CERT, pCertList != null, certificateStoreCtx, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
1146
1147                 r = fileStore.SetFileHandle(certRecord.certId, _CERT_PATH_USER_CERT);
1148                 SysTryReturn(NID_SEC_CERT, !IsFailed(r), certificateStoreCtx, E_SYSTEM, "[E_SYSTEM] Failed to set file handle.");
1149
1150                 r = fileStore.ReadFromFile(reinterpret_cast< byte* >(pCertList->certificate), certLength);
1151                 SysTryReturn(NID_SEC_CERT, !IsFailed(r), certificateStoreCtx, E_SYSTEM, "[E_SYSTEM] Failed to read from file.");
1152
1153                 pCertList->pNext = null;
1154                 pCertList->length = certLength;
1155                 pCertList->format = (_CertFormat) certRecord.certFormat;
1156
1157                 pHoldList->pNext = pCertList.release();
1158                 pHoldList = pHoldList->pNext;
1159
1160                 totalCount++;
1161         }
1162
1163         SetLastResult(E_SUCCESS); //To clear the result of GetNextRecordByCondition function
1164
1165         return certificateStoreCtx;
1166 }
1167
1168
1169 CertificateStoreCtx
1170 _CertManager::OpenRootCaStore(_CaCertType type, int& totalCount) // _CERT_TYPE_TRUSTED_CA or _CERT_TYPE_ROOT_CA, ?
1171 {
1172         result r = E_SUCCESS;
1173         CaCertRecord certRecord = {0};
1174         _CertRootList* pHoldList = null;
1175         _CertFileStore fileStore;
1176         CertificateStoreCtx certificateStoreCtx = null;
1177         int certLength = 0;
1178         char condition[_MAX_TYPE_CONST_SIZE] = {0};
1179         char installedRecord[_MAX_TYPE_RECORD_SIZE] = "T\0";
1180
1181         ClearLastResult();
1182
1183         totalCount = 0;
1184
1185         SysTryReturn(NID_SEC_CERT, type > _CERT_TYPE_NOT_BOUNDED, certificateStoreCtx, E_INVALID_ARG, "[E_INVALID_ARG] Invalid certificate type.");
1186         SysTryReturn(NID_SEC_CERT, type < _CERT_TYPE_MAX, certificateStoreCtx, E_INVALID_ARG, "[E_INVALID_ARG] Invalid certificate type.");
1187
1188         snprintf(condition, _MAX_TYPE_CONST_SIZE, "certType = %d and installed = '%s'", static_cast< int >(type), installedRecord);
1189
1190         std::unique_ptr< _CaCertDbStore > pCaCertDbStore(new (std::nothrow) _CaCertDbStore());
1191         SysTryReturn(NID_SEC_CERT, pCaCertDbStore != null, certificateStoreCtx, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
1192
1193         r = pCaCertDbStore->GetFirstRecordByConditions(reinterpret_cast< byte* >(condition), &certRecord);
1194         SysTryReturn(NID_SEC_CERT, !IsFailed(r), certificateStoreCtx, r, "[%s] Failed to get first certificate record.", GetErrorMessage(r));
1195
1196         std::unique_ptr< _CertRootList > pCertListFirstNode(new (std::nothrow) _CertRootList());
1197         SysTryReturn(NID_SEC_CERT, pCertListFirstNode != null, certificateStoreCtx, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
1198
1199         std::unique_ptr< _CertRootCaInfo > pRootCa(new (std::nothrow) _CertRootCaInfo());
1200         SysTryReturn(NID_SEC_CERT, pRootCa != null, certificateStoreCtx, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
1201
1202         memset(pRootCa.get(), 0, sizeof(*pRootCa.get()));
1203         pCertListFirstNode->pNext = null;
1204
1205         r = fileStore.SetFileHandle(certRecord.certId, _CERT_PATH_CA_CERT);
1206         SysTryReturn(NID_SEC_CERT, !IsFailed(r), certificateStoreCtx, E_SYSTEM, "[E_SYSTEM] Failed to set file handle.");
1207
1208         r = fileStore.ReadFromFile(reinterpret_cast< byte* >(pCertListFirstNode->certificate), certLength);
1209         SysTryReturn(NID_SEC_CERT, !IsFailed(r), certificateStoreCtx, E_SYSTEM, "[E_SYSTEM] Failed to read from file.");
1210
1211         pCertListFirstNode->length = certLength;
1212         pCertListFirstNode->format = (_CertFormat) certRecord.certFormat;
1213
1214         pRootCa->pRootList = pHoldList = pCertListFirstNode.release();
1215
1216         certificateStoreCtx = (CertificateStoreCtx) pRootCa.release();
1217
1218         totalCount++;
1219
1220         while ((pCaCertDbStore->GetNextRecordByCondition(reinterpret_cast< byte* >(condition), &certRecord, certRecord.certId)) == E_SUCCESS)
1221         {
1222                 std::unique_ptr< _CertRootList > pCertList(new (std::nothrow) _CertRootList());
1223                 SysTryReturn(NID_SEC_CERT, pCertList != null, certificateStoreCtx, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
1224
1225                 r = fileStore.SetFileHandle(certRecord.certId, _CERT_PATH_CA_CERT);
1226                 SysTryReturn(NID_SEC_CERT, !IsFailed(r), certificateStoreCtx, E_SYSTEM, "[E_SYSTEM] Failed to set file handle.");
1227                 r = fileStore.ReadFromFile(reinterpret_cast< byte* >(pCertList->certificate), certLength);
1228                 SysTryReturn(NID_SEC_CERT, !IsFailed(r), certificateStoreCtx, E_SYSTEM, "[E_SYSTEM] Failed to read from file.");
1229
1230                 pCertList->pNext = null;
1231                 pCertList->length = certLength;
1232                 pCertList->format = (_CertFormat) certRecord.certFormat;
1233
1234                 pHoldList->pNext = pCertList.release();
1235                 pHoldList = pHoldList->pNext;
1236
1237                 totalCount++;
1238         }
1239
1240         SetLastResult(E_SUCCESS); //To clear the result of GetNextRecordByCondition function
1241
1242         return certificateStoreCtx;
1243 }
1244
1245 result
1246 _CertManager::CheckRootCaIntegrity(void)
1247 {
1248         result r = E_SUCCESS;
1249         CaCertRecord certRecord = {0};
1250         _CertFileStore fileStore;
1251         char condition[_MAX_TYPE_CONST_SIZE] = {0};
1252         char installedRecord[_MAX_TYPE_RECORD_SIZE] = "T\0";
1253         static const int _BUF_SIZE = 4096;
1254         static const int _FILE_NAME_LENGTH = 9; // 001.cert
1255         static const wchar_t _ROOT_CA_CERT_FILE_DIRECTORY[] = L"/opt/usr/share/certs/rootcert/";
1256
1257         ClearLastResult();
1258
1259         snprintf(condition, _MAX_TYPE_CONST_SIZE, "certType = %d and installed = '%s'", _CERT_TYPE_ROOT_CA, installedRecord);
1260
1261         std::unique_ptr< _CaCertDbStore > pCaCertDbStore(new (std::nothrow) _CaCertDbStore());
1262         SysTryReturnResult(NID_SEC_CERT, pCaCertDbStore != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
1263
1264         r = pCaCertDbStore->GetFirstRecordByConditions(reinterpret_cast< byte* >(condition), &certRecord);
1265         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to get first certificate record.", GetErrorMessage(r));
1266
1267         do
1268         {
1269                 std::unique_ptr< File > pFile(null);
1270                 std::unique_ptr< ByteBuffer > pBuffer(null);
1271                 std::unique_ptr< X509Certificate > pCert(null);
1272                 String tempPath(certRecord.fileName);
1273                 String certPath(_ROOT_CA_CERT_FILE_DIRECTORY);
1274                 ByteBuffer* pTempBuffer = null;
1275                 wchar_t certFile[_FILE_NAME_LENGTH] = {0, };
1276                 swprintf(certFile, _FILE_NAME_LENGTH, L"%03d.cert", certRecord.certId);
1277                 certPath.Append(certFile);
1278
1279                 SysTryCatch(NID_SEC_CERT, certPath == tempPath, , E_SYSTEM, "[%s] The root CA certificate DB was damaged.", GetErrorMessage(E_SYSTEM));
1280
1281                 pFile.reset(new (std::nothrow) File());
1282                 SysTryReturnResult(NID_SEC_CERT, pFile != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
1283
1284                 r = pFile->Construct(certPath, "r");
1285                 SysTryCatch(NID_SEC_CERT, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1286
1287                 pBuffer.reset(new (std::nothrow) ByteBuffer());
1288                 SysTryReturnResult(NID_SEC_CERT, pBuffer != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
1289
1290                 r = pBuffer->Construct(_BUF_SIZE);
1291                 SysTryCatch(NID_SEC_CERT, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1292
1293                 pTempBuffer = pBuffer.get();
1294                 r = pFile->Read(*pTempBuffer);
1295                 SysTryCatch(NID_SEC_CERT, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1296
1297                 pTempBuffer->Flip();
1298
1299                 pCert.reset(new (std::nothrow) X509Certificate());
1300                 SysTryReturnResult(NID_SEC_CERT, pBuffer != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
1301
1302                 r = pCert->Construct(*pTempBuffer);
1303                 SysTryCatch(NID_SEC_CERT, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1304
1305                 continue;
1306
1307 CATCH:
1308                 SysSecureLog(NID_SEC_CERT, "Remove broken certificate %d", certRecord.certId);
1309
1310                 r = pCaCertDbStore->RemoveCertificateById(certRecord.certId);
1311                 SysTryLog(NID_SEC_CERT, !IsFailed(r), "[%s] Propagating.", GetErrorMessage(r));
1312
1313                 r = File::Remove(certPath);
1314                 SysTryLog(NID_SEC_CERT, !IsFailed(r), "[%s] Propagating.", GetErrorMessage(r));
1315         }
1316         while ((pCaCertDbStore->GetNextRecordByCondition(reinterpret_cast< byte* >(condition), &certRecord, certRecord.certId)) == E_SUCCESS);
1317
1318         return E_SUCCESS;
1319 }
1320
1321
1322 enum _Asn1EncodingStyle
1323 {
1324         _ASN1_ENCODING_TYPE_PRIMITIVE = 0x00,
1325         _ASN1_ENCODING_TYPE_CONSTRUCTED = 0x20,
1326         _ASN1_ENCODING_TYPE_UNKNOWN = 0xFF
1327 }; //_Asn1EncodingStyle
1328
1329
1330 static const int _CERT_ASN1_TAG_CHECK_BIT_ = 0x7F;
1331 static const int _CERT_ASN1_LENGTH_CHECK_BIT_ = 0x80;
1332 static const int _CERT_ASN1_ENCODING_TYPE_OFFSET_ = 0x20;
1333
1334 int
1335 _CertManager::GetBlockSize(byte* pBuf)
1336 {
1337         int length = 0;
1338         int retVal = -1;
1339         int contentLength = 0;
1340         _Asn1EncodingStyle encodingType = _ASN1_ENCODING_TYPE_PRIMITIVE;
1341
1342
1343         ClearLastResult();
1344         SysTryReturn(NID_SEC_CERT, pBuf != null, retVal, E_INVALID_ARG, "[E_INVALID_ARG] Invalid input argument.");
1345
1346         encodingType = (_Asn1EncodingStyle) (pBuf[0] & _CERT_ASN1_ENCODING_TYPE_OFFSET_);
1347
1348         if (pBuf[1] > _CERT_ASN1_TAG_CHECK_BIT_)
1349         {
1350                 // Length is in indefinite form
1351                 if (pBuf[1] == _CERT_ASN1_LENGTH_CHECK_BIT_)
1352                 {
1353                         // STRICT: indefinite form cannot be used with Primitive encoding
1354                         SysTryReturn(NID_SEC_CERT, encodingType != _ASN1_ENCODING_TYPE_PRIMITIVE, retVal, E_INVALID_CONTENT, "[E_INVALID_CONTENT] Encoding type is not valid.");
1355                         //For the indefinite form, the length octets indicate that the contents octets are terminated by end-of-contents
1356                         //octets (see 8.1.5), and shall consist of a single octet.
1357                         // 0x80 0x00 0x00
1358                         contentLength = 2; //4
1359                 }
1360                 // Length is in Long form
1361                 else
1362                 {
1363                         int count = 0;
1364                         int lenpos = 0;
1365                         //STRICT: Size cannot be seven "1" bits
1366
1367                         SysTryReturn(NID_SEC_CERT, !(((pBuf[1]) & _CERT_ASN1_TAG_CHECK_BIT_) == _CERT_ASN1_TAG_CHECK_BIT_), retVal, E_INVALID_ARG, "[E_INVALID_ARG] Invalid input argument.");
1368
1369                         count = (pBuf[1]) & _CERT_ASN1_TAG_CHECK_BIT_;
1370                         length = 0;
1371                         for (lenpos = 2; lenpos < 2 + count; ++lenpos)
1372                         {
1373                                 length = (length << 8) | pBuf[lenpos];
1374                         }
1375                         contentLength = lenpos;
1376                 }
1377         }
1378         // Length is in short form
1379         else
1380         {
1381                 length = pBuf[1];
1382                 contentLength = 2;
1383         }
1384
1385         length += contentLength;
1386         return length;
1387 }
1388
1389 } } } //Tizen::Security::Cert