Fix memory leak in the Tizen::Security::Cert namespace
[platform/framework/native/appfw.git] / src / security / cert / FSecCert_CertManager.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file                FSecCert_CertManager.cpp
20  * @brief               This file contains implementation of X509 Certificate and private key interface APIs.
21 */
22
23 #include <unique_ptr.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <error.h>
28 #include <new>
29 #include <sys/stat.h>
30 #include <assert.h>
31 #include <dirent.h>
32 #include <openssl/sha.h>
33 #include <openssl/evp.h>
34 #include <openssl/pem.h>
35 #include <FBaseByteBuffer.h>
36 #include <FBaseResult.h>
37 #include <FSysSystemTime.h>
38 #include <FBaseSysLog.h>
39 #include <FIoDirectory.h>
40 #include <FIoDirEnumerator.h>
41 #include <FIoFileAttributes.h>
42 #include <FIoFile.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[] > 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         pTbsCert = pCert->GetTbsCertInstance();
357         SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
358
359         if (field & _CERT_FIELD_SERIAL)
360         {
361                 pTbsCert->GetSerialNumber(pSerial, serialLen);
362                 if (pSerial != null)
363                 {
364                         byte* pSerialNumber = null;
365                         int iterVal = 0;
366                         int index = 0;
367                         iterVal = serialLen;
368                         pSerialNumber = static_cast< byte* >(pSerial);
369                         memset(pCertInfo->serialNo, 0, _MAX_SERIAL_NUMBER_SIZE + 1);
370                         for (index = 0; index < iterVal; index++)
371                         {
372                                 sprintf(&pCertInfo->serialNo[index * 2], "%02X", pSerialNumber[index]);
373                         }
374                 }
375         }
376         if (field & _CERT_FIELD_SIGALGORITHM)
377         {
378                 pSigAlg = pTbsCert->GetSignatureAlgoId();
379                 if (pSigAlg != null)
380                 {
381                         int len = strlen(pSigAlg);
382                         if (len <= _MAX_CERT_ALGORITHM_SIZE)
383                         {
384                                 strcpy(pCertInfo->sigAlgorithm, pSigAlg);
385                         }
386                         else
387                         {
388                                 memcpy(pCertInfo->sigAlgorithm, pSigAlg, _MAX_CERT_ALGORITHM_SIZE);
389                                 pCertInfo->sigAlgorithm[_MAX_CERT_ALGORITHM_SIZE] = '\0';
390                         }
391
392                 }
393                 else
394                 {
395                         strcpy(pCertInfo->sigAlgorithm, "Unknown");
396                 }
397         }
398         if (field & _CERT_FIELD_VALIDITY)
399         {
400                 Tizen::Base::DateTime notBefore;
401                 Tizen::Base::DateTime notAfter;
402                 pTbsCert->GetAfterTimes(notAfter);
403                 pTbsCert->GetBeforeTimes(notBefore);
404                 memset(pCertInfo->validityFrom, 0, _MAX_CERT_VALIDITY_SIZE + 1);
405                 memset(pCertInfo->validityTo, 0, _MAX_CERT_VALIDITY_SIZE + 1);
406
407                 _CertTime::FormatDateTime(notBefore, pCertInfo->validityFrom);
408                 _CertTime::FormatDateTime(notAfter, pCertInfo->validityTo);
409         }
410
411         if (field & _CERT_FIELD_SUBJECT)
412         {
413                 byte* pSubjectName = pTbsCert->GetSubjectName();
414                 int subLen = strlen(reinterpret_cast< const char* >(pSubjectName));
415                 memset(pCertInfo->subjectName, 0, _MAX_ISSUER_SUBJECT_NAME_SIZE + 1);
416                 if (subLen <= _MAX_ISSUER_SUBJECT_NAME_SIZE + 1)
417                 {
418                         strcpy(pCertInfo->subjectName, reinterpret_cast< const char* >(pSubjectName));
419                 }
420                 ParseCertTitle(reinterpret_cast< char* >(pSubjectName), pCertInfo->certTitle);
421                 ClearLastResult();
422         }
423         if (field & _CERT_FIELD_ISSUER)
424         {
425                 byte* pIssuerName = pTbsCert->GetIssuerName();
426                 int issuerLen = strlen(reinterpret_cast< const char* >(pIssuerName));
427                 memset(pCertInfo->issuerName, 0, _MAX_ISSUER_SUBJECT_NAME_SIZE + 1);
428                 if (issuerLen <= _MAX_ISSUER_SUBJECT_NAME_SIZE + 1)
429                 {
430                         strcpy(pCertInfo->issuerName, reinterpret_cast< const char* >(pIssuerName));
431                 }
432                 ParseCertTitle(reinterpret_cast< char* >(pIssuerName), pCertInfo->certSubTitle);
433                 ClearLastResult();
434         }
435         if (field & _CERT_FIELD_FINGERPRINT)
436         {
437                 byte* pX509Buff = null;
438                 int x509BuffSize = 0;
439
440                 memset(pCertInfo->fingerPrint, 0, _MAX_CERT_FINGERPRINT_SIZE + 1);
441
442                 //As per OpenSSL APIs, it takes input as unsigned data types
443                 pCert->GetCertBuffer(pX509Buff, x509BuffSize);
444                 SysTryReturnResult(NID_SEC_CERT, pX509Buff != null, E_SYSTEM, "Failed to get certificate buffer.");
445
446                 std::unique_ptr< byte[] > pFingerPrint(new (std::nothrow) byte[SHA_DIGEST_LENGTH + 1]);
447                 SysTryReturnResult(NID_SEC_CERT, pFingerPrint != null, E_OUT_OF_MEMORY, "Failed to allocate memory. ");
448
449                 memset(pFingerPrint.get(), 0, SHA_DIGEST_LENGTH + 1);
450
451                 resValue = EVP_Digest(pX509Buff, x509BuffSize, pFingerPrint.get(), reinterpret_cast< unsigned int* >(&fingerPrintLen), EVP_sha1(), 0);
452                 SysTryReturnResult(NID_SEC_CERT, resValue == 1, E_SYSTEM, "Failed to create digest hash.");
453
454                 int index = 0;
455                 int maxValue = SHA_DIGEST_LENGTH;
456                 for (index = 0; index < maxValue; index++)
457                 {
458                         sprintf(&pCertInfo->fingerPrint[index * 2], "%02X", pFingerPrint[index]);
459                 }
460                 pCertInfo->fingerPrintLen = fingerPrintLen;
461
462         }
463         if (field & _CERT_FIELD_PUBLICKEY)
464         {
465                 byte* pPublicKeyBuffer = null;
466                 pTbsCert->GetPublicKeyInfoN(publicKeyLen, &pPublicKeyBuffer);
467                 if (pPublicKeyBuffer != null)
468                 {
469                         std::unique_ptr< byte[] > pPublicKeyAuto(pPublicKeyBuffer);
470                         int iterVal = publicKeyLen;
471                         int index = 0;
472
473                         memset(pCertInfo->publicKey, 0, _MAX_CERT_PUBLIC_KEY_SIZE + 1);
474                         for (index = 0; index < iterVal; index++)
475                         {
476                                 sprintf(&pCertInfo->publicKey[index * 2], "%02X", pPublicKeyBuffer[index]);
477                         }
478
479                 }
480         }
481
482         if (field & _CERT_FIELD_VERSION)
483         {
484                 pCertInfo->certVersion = pTbsCert->GetVersion();
485                 SysTryReturnResult(NID_SEC_CERT, pCertInfo->certVersion > 0, E_SYSTEM, "Failed to get version.");
486         }
487
488         if (field & _CERT_FIELD_TYPE)
489         {
490                 char type[6] = "X.509";
491                 memset(pCertInfo->certTypeFormat, 0, sizeof(pCertInfo->certTypeFormat));
492                 strcpy(pCertInfo->certTypeFormat, type);
493         }
494         if (strcmp(pCertInfo->certTitle, pCertInfo->certSubTitle) == 0)
495         {
496                 char selfSigned[12] = "Self-signed";
497                 memset(pCertInfo->certSubTitle, 0, sizeof(pCertInfo->certSubTitle));
498                 strcpy(pCertInfo->certSubTitle, selfSigned);
499         }
500
501         return r;
502 }
503
504
505 _CertFormat
506 _CertManager::GetEncodedCertBuffer(byte* pCertBuffer, int certBufferLen, byte** pDerCertBuffer, int* pDerCertBufferLength, _CertEncodingType* encodingType)
507 {
508         result r = E_SUCCESS;
509         _CertFormat certFormat = _CERT_UNKNOWN;
510         BIO* pBio = null;
511         X509* pOpensslX509Cert = null;
512         char* pBase64Header = null;
513         char* pBase64Trailer = null;
514         int readCount = 0;
515         int certBufLen = 0;
516         int decodedLen = 0;
517         int pemCertSize = 0;
518
519         ClearLastResult();
520
521         SysTryReturn(NID_SEC_CERT, pCertBuffer != null, _CERT_UNKNOWN, E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument passed.");
522         SysTryReturn(NID_SEC_CERT, certBufferLen > 0, _CERT_UNKNOWN, E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument passed.");
523
524         std::unique_ptr< _X509Certificate > pX509Cert(new (std::nothrow) _X509Certificate());
525         SysTryReturn(NID_SEC_CERT, pX509Cert != null, _CERT_UNKNOWN, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
526
527         pBase64Header = strstr(reinterpret_cast< char* >(pCertBuffer), _CERT_BASE64_HEADER);
528         pBase64Trailer = strstr(reinterpret_cast< char* >(pCertBuffer), _CERT_BASE64_TRAILER);
529
530         if ((pBase64Header != null) && (pBase64Trailer != null) && (pBase64Trailer > pBase64Header))
531         {
532                 pBio = BIO_new(BIO_s_mem());
533                 SysTryReturn(NID_SEC_CERT, pBio != null, _CERT_UNKNOWN, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
534
535                 pemCertSize = (int(pBase64Trailer - pBase64Header) + strlen(_CERT_BASE64_TRAILER));
536                 readCount = BIO_write(pBio, (const void*) pBase64Header, pemCertSize);
537                 SysTryCatch(NID_SEC_CERT, readCount > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Certificate conversion failed");
538
539                 pOpensslX509Cert = PEM_read_bio_X509(pBio, NULL, 0, NULL);
540                 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);
541
542                 decodedLen = i2d_X509(pOpensslX509Cert, pDerCertBuffer);
543                 SysTryCatch(NID_SEC_CERT, decodedLen > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Invalid certificate length.");
544
545                 *pDerCertBufferLength = decodedLen;
546
547                 certFormat = _CERT_X509;
548                 *encodingType = _CERT_ENC_TYPE_PEM;
549         }
550         else if (pX509Cert->Parse(pCertBuffer, certBufferLen) == E_SUCCESS)
551         {
552                 std::unique_ptr< byte, ByteDeleter > pCertBuf(static_cast<byte*>(malloc(sizeof(byte) * certBufferLen)));
553                 SysTryReturn(NID_SEC_CERT, pCertBuf != null, _CERT_UNKNOWN, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
554
555                 memcpy(pCertBuf.get(), pCertBuffer, certBufferLen);
556                 certBufLen = certBufferLen;
557
558                 *pDerCertBuffer = pCertBuf.release();
559                 *pDerCertBufferLength = certBufLen;
560
561                 certFormat = _CERT_X509;
562                 *encodingType = _CERT_ENC_TYPE_BINARY;
563         }
564         else
565         {
566                 certBufLen = _Base64::GetDecodedSize(certBufferLen);
567                 SysTryReturn(NID_SEC_CERT, certBufLen > 0, _CERT_UNKNOWN, E_SYSTEM, "[E_SYSTEM] Invalid certificate length.");
568
569                 std::unique_ptr< byte, ByteDeleter > pCertBuf(static_cast<byte*>(malloc(sizeof(byte) * certBufLen)));
570                 SysTryReturn(NID_SEC_CERT, pCertBuf != null, _CERT_UNKNOWN, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
571
572                 memset(pCertBuf.get(), 0, certBufLen);
573
574                 decodedLen = certBufLen;
575                 readCount = _Base64::Decode(reinterpret_cast< char* >(pCertBuffer), certBufferLen, pCertBuf.get(), decodedLen);
576                 SysTryReturn(NID_SEC_CERT, readCount > 0, _CERT_UNKNOWN, E_SYSTEM, "[E_SYSTEM] Certificate decoding failed.");
577
578                 *pDerCertBuffer = pCertBuf.release();
579                 *pDerCertBufferLength = decodedLen;
580
581                 certFormat = _CERT_X509;
582                 *encodingType = _CERT_ENC_TYPE_BASE64;
583         }
584
585         SetLastResult(E_SUCCESS); //To clear the result of parsing certificate.
586
587 CATCH:
588
589         if (pBio != null)
590         {
591                 BIO_free(pBio);
592         }
593
594         if (pOpensslX509Cert != null)
595         {
596                 X509_free(pOpensslX509Cert);
597         }
598
599         return certFormat;
600 }
601
602 result
603 _CertManager::GetPublicKey(CertificateHandle certificate, char* pBuffer, int* pBufLen)
604 {
605         _Certificate* pTempCert = reinterpret_cast< _Certificate* >(certificate);
606         _X509Certificate* pCert = null;
607         _X509TbsCert* pTbsCert = null;
608         byte* pPuKey = null;
609         int pubKeyLen = 0;
610
611         SysTryReturnResult(NID_SEC_CERT, pBuffer != null, E_INVALID_ARG, "Invalid input parameter.");
612         SysTryReturnResult(NID_SEC_CERT, pTempCert != null, E_INVALID_ARG, "Invalid input parameter.");
613
614         _CertFormat format = pTempCert->GetCertFormat();
615         SysTryReturnResult(NID_SEC_CERT, format == _CERT_X509, E_SYSTEM, "Failed to get certificate format.");
616
617         pCert = reinterpret_cast< _X509Certificate* >(certificate);
618         SysTryReturnResult(NID_SEC_CERT, pCert != null, E_INVALID_ARG, "Invalid input parameter.");
619
620         pTbsCert = pCert->GetTbsCertInstance();
621         SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
622
623         pTbsCert->GetPublicKeyInfoN(pubKeyLen, &pPuKey);
624         SysTryReturnResult(NID_SEC_CERT, pPuKey != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
625
626         std::unique_ptr< byte[] > pPubKeyAuto(pPuKey);
627
628         memcpy(pBuffer, pPubKeyAuto.get(), pubKeyLen);
629
630         if (pBufLen)
631         {
632                 *pBufLen = pubKeyLen;
633         }
634
635         return E_SUCCESS;
636 }
637
638 result
639 _CertManager::GetSignature(CertificateHandle certificate, char* pBuffer, int* pBufLen)
640 {
641         _Certificate* pTempCert = reinterpret_cast< _Certificate* >(certificate);
642         _X509Certificate* pCert = null;
643         byte* pSignature = null;
644         _CertFormat format;
645         _CertSignature* pSig = null;
646         int signLength = 0;
647
648         SysTryReturnResult(NID_SEC_CERT, pBuffer != null, E_INVALID_ARG, "Invalid input parameter.");
649         SysTryReturnResult(NID_SEC_CERT, pTempCert != null, E_INVALID_ARG, "Initial parameter not set.");
650
651         format = pTempCert->GetCertFormat();
652         SysTryReturnResult(NID_SEC_CERT, format == _CERT_X509, E_SYSTEM, "Failed to get certificate format.");
653         pCert = reinterpret_cast< _X509Certificate* >(certificate);
654
655         pSig = pCert->GetSignInstance();
656         SysTryReturnResult(NID_SEC_CERT, pSig != null, E_SYSTEM, "Failed to get certificate signature.");
657
658         pSignature = pSig->GetSignatureInfo(signLength);
659         memcpy(pBuffer, pSignature, signLength);
660
661         if (pBufLen != null)
662         {
663                 *pBufLen = signLength;
664         }
665         return E_SUCCESS;
666 }
667
668 int
669 _CertManager::GetVersion(CertificateHandle certificate)
670 {
671         _Certificate* pTempCert = null;
672         _X509Certificate* pCert = null;
673         _X509TbsCert* pTbsCert = null;
674
675         pTempCert = reinterpret_cast< _Certificate* >(certificate);
676         SysTryReturn(NID_SEC_CERT, pTempCert != null, -1, E_INVALID_ARG, "[E_INVALID_ARG] Initial parameter not set.");
677
678         _CertFormat format = pTempCert->GetCertFormat();
679
680         SysTryReturn(NID_SEC_CERT, format == _CERT_X509, -1, E_SYSTEM, "[E_SYSTEM] Unknown certificate format.");
681         pCert = reinterpret_cast< _X509Certificate* >(certificate);
682
683         pTbsCert = pCert->GetTbsCertInstance();
684         SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
685
686         return pTbsCert->GetVersion();
687 }
688
689 result
690 _CertManager::GetValidity(CertificateHandle certificate, _CertValidityType* pValidity)
691 {
692         _Certificate* pTempCert = reinterpret_cast< _Certificate* >(certificate);
693         _X509Certificate* pCert = null;
694         _X509TbsCert* pTbsCert = null;
695         Tizen::Base::DateTime notBefore;
696         Tizen::Base::DateTime notAfter;
697         Tizen::Base::DateTime curTime;
698
699         SysTryReturnResult(NID_SEC_CERT, pTempCert != null, E_INVALID_ARG, "Initial parameter not set.");
700
701         _CertFormat format = pTempCert->GetCertFormat();
702         SysTryReturnResult(NID_SEC_CERT, format == _CERT_X509, E_SYSTEM, "Unknown certificate format.");
703
704         pCert = reinterpret_cast< _X509Certificate* >(certificate);
705
706         Tizen::System::SystemTime::GetCurrentTime(UTC_TIME, curTime);
707
708         pTbsCert = pCert->GetTbsCertInstance();
709         SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
710
711         pTbsCert->GetBeforeTimes(notBefore);
712         pTbsCert->GetAfterTimes(notAfter);
713         if (curTime <= notAfter && curTime >= notBefore)
714         {
715                 *pValidity = _CERT_VALIDITY_VALID;
716         }
717         else if (curTime < notBefore)
718         {
719                 *pValidity = _CERT_VALIDITY_NOT_YET_VALID;
720         }
721         else if (curTime > notAfter)
722         {
723                 *pValidity = _CERT_VALIDITY_EXPIRED;
724         }
725         return E_SUCCESS;
726
727 }
728
729 result
730 _CertManager::GetCertificateType(CertificateHandle certHandle, _CaCertType* pCertType)
731 {
732         result r = E_SUCCESS;
733         char subjectName[_MAX_ISSUER_SUBJECT_NAME_SIZE] = {0, };
734         char issuerName[_MAX_ISSUER_SUBJECT_NAME_SIZE] = {0, };
735         int lenSubjectName = 0;
736         int lenIssuerName = 0;
737         _Certificate* pParentCert = reinterpret_cast< _Certificate* >(certHandle);
738         _X509Certificate* pCert = null;
739         _X509TbsCert* pTbsCert = null;
740         _CertDbManager* pCertDb = null;
741
742         SysTryReturnResult(NID_SEC_CERT, pParentCert != null, E_INVALID_ARG, "Initial parameter not set.");
743
744
745         _CertFormat format = pParentCert->GetCertFormat();
746         SysTryReturnResult(NID_SEC_CERT, format == _CERT_X509, E_SYSTEM, "Failed to get certificate format.");
747
748         pCert = reinterpret_cast< _X509Certificate* >(certHandle);
749         SysTryReturnResult(NID_SEC_CERT, pCert != null, E_INVALID_ARG, "Initial parameter not set.");
750
751         pTbsCert = pCert->GetTbsCertInstance();
752         SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
753
754         lenSubjectName = strlen(reinterpret_cast< const char* >(pTbsCert->GetSubjectName()));
755         lenIssuerName = strlen(reinterpret_cast< const char* >(pTbsCert->GetIssuerName()));
756         SysTryReturnResult(NID_SEC_CERT, lenSubjectName > 0, E_SYSTEM, "Subject length is not valid.");
757         SysTryReturnResult(NID_SEC_CERT, lenIssuerName > 0, E_SYSTEM, "Issuer length is not valid.");
758
759         strcpy(subjectName, reinterpret_cast< const char* >(pTbsCert->GetSubjectName()));
760         strcpy(issuerName, reinterpret_cast< const char* >(pTbsCert->GetIssuerName()));
761
762         pCertDb = _CertDbManager::GetInstance();
763         SysTryReturnResult(NID_SEC_CERT, pCertDb != null, E_SYSTEM, "Failed to get instance of certificate database manager.");
764
765         r = pCertDb->FindCertType(format, issuerName, subjectName, pCertType);
766
767         if (IsFailed(r))
768         {
769                 *pCertType = _CERT_TYPE_MAX;
770                 return E_SYSTEM;
771         }
772
773         return E_SUCCESS;
774 }
775
776 result
777 _CertManager::ParseCertTitle(char subject[_MAX_ISSUER_SUBJECT_NAME_SIZE + 1], char title[_MAX_ISSUER_SUBJECT_NAME_SIZE + 1])
778 {
779         ClearLastResult();
780
781         SysTryReturn(NID_SEC_CERT, subject[0] != '\0', E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Invalid input parameter.");
782
783         SysAssertf(strlen(subject) <= (size_t) _MAX_ISSUER_SUBJECT_NAME_SIZE, "The buffer size of source is too big.");
784
785         bool done = false;
786         char* pPivotPtr = null;
787         char* pSavePtr = null;
788         char* pSubStr = null;
789         char tempSubject[_MAX_ISSUER_SUBJECT_NAME_SIZE + 1] = {0, };
790
791         strncpy(tempSubject, subject, strlen(subject));
792         pPivotPtr = tempSubject;
793         for (;; pSubStr = null)
794         {
795                 pSubStr = strtok_r(pPivotPtr, "/", &pSavePtr);
796
797                 if (strncmp(pSubStr, _CERT_COMMON_NAME, strlen(_CERT_COMMON_NAME)) == 0)
798                 {
799                         pSubStr = pSubStr + strlen(_CERT_COMMON_NAME);
800                         done = true;
801                         break;
802                 }
803                 else if (strncmp(pSubStr, _CERT_ORG_NAME, strlen(_CERT_ORG_NAME)) == 0)
804                 {
805                         pSubStr = pSubStr + strlen(_CERT_ORG_NAME);
806                         done = true;
807                         break;
808                 }
809                 else if (strncmp(pSubStr, _CERT_ORG_UNIT_NAME, strlen(_CERT_ORG_UNIT_NAME)) == 0)
810                 {
811                         pSubStr = pSubStr + strlen(_CERT_ORG_UNIT_NAME);
812                         done = true;
813                         break;
814                 }
815                 else if (strncmp(pSubStr, _CERT_EMAIL_ADDRESS, strlen(_CERT_EMAIL_ADDRESS)) == 0)
816                 {
817                         pSubStr = pSubStr + strlen(_CERT_EMAIL_ADDRESS);
818                         done = true;
819                         break;
820                 }
821
822                 pPivotPtr = pSavePtr;
823                 pSubStr = null;
824         }
825
826         SysTryReturn(NID_SEC_CERT, done, E_PARSING_FAILED, E_SYSTEM, "[%s] Failed to parse Certificate title.", GetErrorMessage(E_PARSING_FAILED));
827
828         // initialize buffer
829         for (int index = 0; index < _MAX_ISSUER_SUBJECT_NAME_SIZE + 1; index++)
830         {
831                 title[index] = '\0';
832         }
833
834         // copy title into out param
835         strncpy(title, pSubStr, strlen(pSubStr));
836
837         return E_SUCCESS;
838 }
839
840 //User Certificate APIs
841 result
842 _CertManager::MakeParseAndVerifyCertChainBufferN(byte* pCertChainBuffer, int certChainLength, byte* pUserPrivateKeyBuffer, int userPrivateKeyLength, _CertChain** ppX509CertChain, _CertPrivateKeyInfo** ppX509PrivateKeyInfo)
843 {
844         result r = E_SUCCESS;
845         int dataOffset = 0;
846         int currCertBufLen = 0;
847         int totCertCount = 0;
848         int bufSize = 0;
849         int countTotalCertificateChecked = 0;
850         int addedNumberCertificate = 0;
851         bool pubPriPair = false;
852         byte* pCertBuf = null;
853         byte* pCurrCertBuf = null;
854         _X509Certificate* pUserCert = null;
855         std::unique_ptr< _CertPrivateKeyInfo > pPKeyInfo(null);
856
857         pCertBuf = pCertChainBuffer;
858         bufSize = certChainLength;
859
860         SysTryReturnResult(NID_SEC_CERT, pCertBuf != null, E_INVALID_ARG, "Invalid certificate chain buffer.");
861         SysTryReturnResult(NID_SEC_CERT, bufSize > 0, E_INVALID_ARG, "Invalid length of certificate chain buffer.");
862
863         // Process Private Key
864         if (pUserPrivateKeyBuffer != null && userPrivateKeyLength > 0)
865         {
866                 pPKeyInfo = std::unique_ptr< _CertPrivateKeyInfo >(new (std::nothrow) _CertPrivateKeyInfo(pUserPrivateKeyBuffer, userPrivateKeyLength));
867                 SysTryReturnResult(NID_SEC_CERT, pPKeyInfo != null, E_OUT_OF_MEMORY, "Failed allocate memory.");
868         }
869
870         // Get Cert Count
871         while (dataOffset < bufSize)
872         {
873                 pCurrCertBuf = pCertBuf + dataOffset;
874                 currCertBufLen = _CertManager::GetBlockSize(pCurrCertBuf);
875                 totCertCount++;
876                 dataOffset += currCertBufLen;
877         }
878
879         dataOffset = 0;
880
881         std::unique_ptr< _CertChain > pCertChain(new (std::nothrow) _CertChain());
882         SysTryReturnResult(NID_SEC_CERT, pCertChain != null, E_OUT_OF_MEMORY, "Failed to parse and verify certificate chain.");
883
884         if (pPKeyInfo != null)
885         {
886                 // Find Device/User Certificate
887                 while (dataOffset < bufSize)
888                 {
889                         pCurrCertBuf = pCertBuf + dataOffset;
890                         currCertBufLen = _CertManager::GetBlockSize(pCurrCertBuf);
891
892                         std::unique_ptr< _X509Certificate > pTmpCert(new (std::nothrow) _X509Certificate());
893                         SysTryReturnResult(NID_SEC_CERT, pTmpCert != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
894
895                         r = pTmpCert->Parse(pCurrCertBuf, currCertBufLen);
896                         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_DECODING_FAILED, "Failed to parse and verify certificate chain.");
897
898                         r = _CertManager::CheckRsaPublicPrivateKeyPair(pTmpCert.get(), pPKeyInfo.get());
899                         if (!IsFailed(r))
900                         {
901                                 r = pCertChain->AddCertificate(pTmpCert.get());
902                                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_INVALID_CONDITION, "Failed to parse and verify certificate chain.");
903
904                                 pubPriPair = true;
905                                 addedNumberCertificate++;
906                                 pUserCert = pTmpCert.release();
907                                 break;
908                         }
909
910                         dataOffset += currCertBufLen;
911                 }
912                 //Check key pair
913                 SysTryReturnResult(NID_SEC_CERT, pubPriPair, E_INVALID_KEY, "Failed to parse and verify certificate chain.");
914         }
915
916         dataOffset = 0;
917
918         //As there is no private key present in chain, it is assumed that first certificate is user certificate
919         if (pUserCert == null)
920         {
921                 pCurrCertBuf = pCertBuf + dataOffset;
922                 currCertBufLen = _CertManager::GetBlockSize(pCurrCertBuf);
923
924                 std::unique_ptr< _X509Certificate > pUserCertAuto(new (std::nothrow) _X509Certificate());
925                 SysTryReturnResult(NID_SEC_CERT, pUserCertAuto != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
926
927                 r = pUserCertAuto->Parse(pCurrCertBuf, currCertBufLen);
928                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_DECODING_FAILED, "Failed to parse first certificate in chain.");
929
930                 r = pCertChain->AddCertificate(pUserCertAuto.get());
931                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_INVALID_CONDITION, "Failed to add first certificate in chain. ");
932
933                 addedNumberCertificate++;
934                 pUserCert = pUserCertAuto.release();
935         }
936
937
938         while (totCertCount > addedNumberCertificate)
939         {
940                 dataOffset = 0;
941                 countTotalCertificateChecked++;
942
943                 if (countTotalCertificateChecked > totCertCount)
944                 {
945                         break;
946                 }
947
948                 SysTryReturnResult(NID_SEC_CERT, pUserCert != null, E_INVALID_ARG, "Invalid certificate in chain. ");
949
950                 while (dataOffset < bufSize)
951                 {
952                         std::unique_ptr< _X509Certificate > pCurrentCert(new (std::nothrow) _X509Certificate());
953                         SysTryReturnResult(NID_SEC_CERT, pCurrentCert != null, E_OUT_OF_MEMORY, "Failed to allocate memory. ");
954
955                         pCurrCertBuf = pCertBuf + dataOffset;
956                         currCertBufLen = _CertManager::GetBlockSize(pCurrCertBuf);
957
958                         r = pCurrentCert->Parse(pCurrCertBuf, currCertBufLen);
959                         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_DECODING_FAILED, "Failed to parse certificate in chain. ");
960
961                         if (pUserCert->IsIssuer(pCurrentCert.get()))
962                         {
963                                 r = pCertChain->AddCertificate(pCurrentCert.get());
964                                 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_INVALID_CONDITION, "Failed to add certificate in chain. ");
965
966                                 pUserCert = pCurrentCert.release();
967                                 addedNumberCertificate++;
968                                 break;
969                         }
970
971                         dataOffset += currCertBufLen;
972                 }
973         }
974
975         //Here is the place where we verifying certificate chain before installation
976         r = pCertChain->VerifyCertChainWithDb();
977         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to verify certificate chain.", GetErrorMessage(r));
978
979         *ppX509CertChain = pCertChain.release();
980         *ppX509PrivateKeyInfo = pPKeyInfo.release();
981
982         return r;
983 }
984
985 result
986 _CertManager::CheckRsaPublicPrivateKeyPair(_X509Certificate* pX509Certificate, _CertPrivateKeyInfo* pX509CertificatePrivateKey)
987 {
988         result r = E_SUCCESS;
989         int retValue = 0;
990         EVP_PKEY* pPrivateKey = null;
991         int privateKeyLength = 0;
992         X509* pX509Cert = null;
993         const char* pSigalg = null;
994
995         SysTryReturnResult(NID_SEC_CERT, pX509Certificate != null, E_INVALID_ARG, "Invalid input parameter. ");
996         SysTryReturnResult(NID_SEC_CERT, pX509CertificatePrivateKey != null, E_INVALID_ARG, "Invalid input parameter.");
997
998         pX509Cert = static_cast< X509* >(pX509Certificate->GetX509CertObject());
999         SysTryReturnResult(NID_SEC_CERT, pX509Cert != null, E_SYSTEM, "Failed to parse certificate. ");
1000
1001         //const char *
1002         pSigalg = OBJ_nid2ln(OBJ_obj2nid(pX509Cert->sig_alg->algorithm));
1003         SysTryReturnResult(NID_SEC_CERT, pSigalg != null, E_SYSTEM, "Unable to get certificate algorithm.");
1004
1005         if (strstr(pSigalg, "WithRSA"))
1006         {
1007                 byte* pPriKey = null;
1008
1009                 pX509CertificatePrivateKey->GetPrivateKeyN(privateKeyLength, &pPriKey);
1010                 SysTryReturnResult(NID_SEC_CERT, pPriKey != null, E_SYSTEM, "Unable to get certificate private key.");
1011
1012                 std::unique_ptr< byte[] > pPriKeyBuf(pPriKey);
1013
1014                 pPrivateKey = d2i_PrivateKey(EVP_PKEY_RSA, null, const_cast< const unsigned char** >(static_cast< unsigned char** >(&pPriKey)), privateKeyLength);
1015                 if (pPrivateKey != null)
1016                 {
1017                         retValue = X509_check_private_key(pX509Cert, pPrivateKey);
1018
1019                         EVP_PKEY_free(pPrivateKey);
1020
1021                         SysTryReturnResult(NID_SEC_CERT, retValue == 1, E_SYSTEM, "Private public key mismatch, this key does not belong to this certificate.");
1022
1023
1024                 }
1025                 else
1026                 {
1027                         r = E_SYSTEM;
1028                         SysLog(NID_SEC_CERT, "Private key conversion failed.");
1029                 }
1030
1031
1032         }
1033         else
1034         {
1035                 r = E_SYSTEM;
1036                 SysLog(NID_SEC_CERT, "Unsupported Algorithm = %s", pSigalg);
1037         }
1038
1039
1040         return r;
1041 }
1042
1043 result
1044 _CertManager::GetCertificateSubjectNameN(CertificateHandle certificateHandle, byte** ppSubjectName, int* pSubjectNameLength)
1045 {
1046         int len = 0;
1047         byte* pBuf = null;
1048         _Certificate* pTempCert = static_cast< _Certificate* >(certificateHandle);
1049         _CertFormat format = pTempCert->GetCertFormat();
1050
1051         SysTryReturnResult(NID_SEC_CERT, format == _CERT_X509, E_INVALID_ARG, "Invalid certificate format.");
1052
1053         _X509Certificate* pCert = static_cast< _X509Certificate* >(certificateHandle);
1054         pCert->GetIssuerBuffer(pBuf, len);
1055
1056         *ppSubjectName = new (std::nothrow) byte[len];
1057         SysTryReturnResult(NID_SEC_CERT, *ppSubjectName != null, E_OUT_OF_MEMORY, "Failed to allocate memory. ");
1058
1059         memset(*ppSubjectName, 0, len);
1060         memcpy(*ppSubjectName, pBuf, len);
1061         *pSubjectNameLength = len;
1062
1063         return E_SUCCESS;
1064 }
1065
1066 result
1067 _CertManager::GetCertificateIssuerNameN(CertificateHandle certificateHandle, byte** ppIssuerName, int* pIssuerNameLength)
1068 {
1069         _Certificate* pTempCert = static_cast< _Certificate* >(certificateHandle);
1070         _CertFormat format = pTempCert->GetCertFormat();
1071         byte* pBuf = null;
1072         int len = 0;
1073
1074         SysTryReturnResult(NID_SEC_CERT, format == _CERT_X509, E_INVALID_ARG, "Invalid certificate format.");
1075
1076         _X509Certificate* pCert = static_cast< _X509Certificate* >(certificateHandle);
1077         pCert->GetSubjectNameBuffer(pBuf, len);
1078
1079         *ppIssuerName = new (std::nothrow) byte[len];
1080         SysTryReturnResult(NID_SEC_CERT, *ppIssuerName != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
1081         memset(*ppIssuerName, 0, len);
1082         memcpy(*ppIssuerName, pBuf, len);
1083         *pIssuerNameLength = len;
1084
1085         return E_SUCCESS;
1086 }
1087
1088 CertificateStoreCtx
1089 _CertManager::OpenUserCertificateStore(int& totalCount)
1090 {
1091         result r = E_SUCCESS;
1092         UserCertRecord certRecord = {0};
1093         _CertRootList* pHoldList = null;
1094         _CertFileStore fileStore;
1095         CertificateStoreCtx certificateStoreCtx = null;
1096         int certLength = 0;
1097         char condition[_MAX_TYPE_CONST_SIZE] = {0};
1098         char installedRecord[_MAX_TYPE_RECORD_SIZE] = "T\0";
1099
1100         ClearLastResult();
1101
1102         totalCount = 0;
1103
1104         sprintf(condition, "installed = '%s'", installedRecord);
1105
1106         std::unique_ptr< _UserCertDbStore > pUserCertDbStore(new (std::nothrow) _UserCertDbStore());
1107         SysTryReturn(NID_SEC_CERT, pUserCertDbStore != null, certificateStoreCtx, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
1108
1109         r = pUserCertDbStore->GetFirstRecordByConditions(reinterpret_cast< byte* >(condition), &certRecord);
1110         SysTryReturn(NID_SEC_CERT, !IsFailed(r), certificateStoreCtx, r, "[%s] Failed to get first certificate record.", GetErrorMessage(r));
1111
1112         std::unique_ptr< _CertRootList > pCertListFirstNode(new (std::nothrow) _CertRootList());
1113         SysTryReturn(NID_SEC_CERT, pCertListFirstNode != null, certificateStoreCtx, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
1114
1115         std::unique_ptr< _CertRootCaInfo > pRootCa(new (std::nothrow) _CertRootCaInfo());
1116         SysTryReturn(NID_SEC_CERT, pRootCa != null, certificateStoreCtx, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
1117
1118         memset(pRootCa.get(), 0, sizeof(*pRootCa.get()));
1119         pCertListFirstNode->pNext = null;
1120
1121         r = fileStore.SetFileHandle(certRecord.certId, _CERT_PATH_USER_CERT);
1122         SysTryReturn(NID_SEC_CERT, !IsFailed(r), certificateStoreCtx, E_SYSTEM, "E_SYSTEM Failed to set file handle.");
1123
1124         r = fileStore.ReadFromFile(reinterpret_cast< byte* >(pCertListFirstNode->certificate), certLength);
1125         SysTryReturn(NID_SEC_CERT, !IsFailed(r), certificateStoreCtx, E_SYSTEM, "E_SYSTEM Failed to read from file.");
1126
1127         pCertListFirstNode->length = certLength;
1128         pCertListFirstNode->format = (_CertFormat) certRecord.certFormat;
1129
1130         pRootCa->pRootList = pHoldList = pCertListFirstNode.release();
1131
1132         certificateStoreCtx = (CertificateStoreCtx) pRootCa.release();
1133
1134         totalCount++;
1135
1136         while ((pUserCertDbStore->GetNextRecordByCondition(reinterpret_cast< byte* >(condition), &certRecord, certRecord.certId)) == E_SUCCESS)
1137         {
1138                 std::unique_ptr< _CertRootList > pCertList(new (std::nothrow) _CertRootList());
1139                 SysTryReturn(NID_SEC_CERT, pCertList != null, certificateStoreCtx, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
1140
1141                 r = fileStore.SetFileHandle(certRecord.certId, _CERT_PATH_USER_CERT);
1142                 SysTryReturn(NID_SEC_CERT, !IsFailed(r), certificateStoreCtx, E_SYSTEM, "[E_SYSTEM] Failed to set file handle.");
1143
1144                 r = fileStore.ReadFromFile(reinterpret_cast< byte* >(pCertList->certificate), certLength);
1145                 SysTryReturn(NID_SEC_CERT, !IsFailed(r), certificateStoreCtx, E_SYSTEM, "[E_SYSTEM] Failed to read from file.");
1146
1147                 pCertList->pNext = null;
1148                 pCertList->length = certLength;
1149                 pCertList->format = (_CertFormat) certRecord.certFormat;
1150
1151                 pHoldList->pNext = pCertList.release();
1152                 pHoldList = pHoldList->pNext;
1153
1154                 totalCount++;
1155         }
1156
1157         SetLastResult(E_SUCCESS); //To clear the result of GetNextRecordByCondition function
1158
1159         return certificateStoreCtx;
1160 }
1161
1162
1163 CertificateStoreCtx
1164 _CertManager::OpenRootCaStore(_CaCertType type, int& totalCount) // _CERT_TYPE_TRUSTED_CA or _CERT_TYPE_ROOT_CA, ?
1165 {
1166         result r = E_SUCCESS;
1167         CaCertRecord certRecord = {0};
1168         _CertRootList* pHoldList = null;
1169         _CertFileStore fileStore;
1170         CertificateStoreCtx certificateStoreCtx = null;
1171         int certLength = 0;
1172         char condition[_MAX_TYPE_CONST_SIZE] = {0};
1173         char installedRecord[_MAX_TYPE_RECORD_SIZE] = "T\0";
1174
1175         ClearLastResult();
1176
1177         totalCount = 0;
1178
1179         SysTryReturn(NID_SEC_CERT, type > _CERT_TYPE_NOT_BOUNDED, certificateStoreCtx, E_INVALID_ARG, "[E_INVALID_ARG] Invalid certificate type.");
1180         SysTryReturn(NID_SEC_CERT, type < _CERT_TYPE_MAX, certificateStoreCtx, E_INVALID_ARG, "[E_INVALID_ARG] Invalid certificate type.");
1181
1182         sprintf(condition, "certType = %d and installed = '%s'", static_cast< int >(type), installedRecord);
1183
1184         std::unique_ptr< _CaCertDbStore > pCaCertDbStore(new (std::nothrow) _CaCertDbStore());
1185         SysTryReturn(NID_SEC_CERT, pCaCertDbStore != null, certificateStoreCtx, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
1186
1187         r = pCaCertDbStore->GetFirstRecordByConditions(reinterpret_cast< byte* >(condition), &certRecord);
1188         SysTryReturn(NID_SEC_CERT, !IsFailed(r), certificateStoreCtx, r, "[%s] Failed to get first certificate record.", GetErrorMessage(r));
1189
1190         std::unique_ptr< _CertRootList > pCertListFirstNode(new (std::nothrow) _CertRootList());
1191         SysTryReturn(NID_SEC_CERT, pCertListFirstNode != null, certificateStoreCtx, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
1192
1193         std::unique_ptr< _CertRootCaInfo > pRootCa(new (std::nothrow) _CertRootCaInfo());
1194         SysTryReturn(NID_SEC_CERT, pRootCa != null, certificateStoreCtx, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
1195
1196         memset(pRootCa.get(), 0, sizeof(*pRootCa.get()));
1197         pCertListFirstNode->pNext = null;
1198
1199         r = fileStore.SetFileHandle(certRecord.certId, _CERT_PATH_CA_CERT);
1200         SysTryReturn(NID_SEC_CERT, !IsFailed(r), certificateStoreCtx, E_SYSTEM, "[E_SYSTEM] Failed to set file handle.");
1201
1202         r = fileStore.ReadFromFile(reinterpret_cast< byte* >(pCertListFirstNode->certificate), certLength);
1203         SysTryReturn(NID_SEC_CERT, !IsFailed(r), certificateStoreCtx, E_SYSTEM, "[E_SYSTEM] Failed to read from file.");
1204
1205         pCertListFirstNode->length = certLength;
1206         pCertListFirstNode->format = (_CertFormat) certRecord.certFormat;
1207
1208         pRootCa->pRootList = pHoldList = pCertListFirstNode.release();
1209
1210         certificateStoreCtx = (CertificateStoreCtx) pRootCa.release();
1211
1212         totalCount++;
1213
1214         while ((pCaCertDbStore->GetNextRecordByCondition(reinterpret_cast< byte* >(condition), &certRecord, certRecord.certId)) == E_SUCCESS)
1215         {
1216                 std::unique_ptr< _CertRootList > pCertList(new (std::nothrow) _CertRootList());
1217                 SysTryReturn(NID_SEC_CERT, pCertList != null, certificateStoreCtx, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
1218
1219                 r = fileStore.SetFileHandle(certRecord.certId, _CERT_PATH_CA_CERT);
1220                 SysTryReturn(NID_SEC_CERT, !IsFailed(r), certificateStoreCtx, E_SYSTEM, "[E_SYSTEM] Failed to set file handle.");
1221                 r = fileStore.ReadFromFile(reinterpret_cast< byte* >(pCertList->certificate), certLength);
1222                 SysTryReturn(NID_SEC_CERT, !IsFailed(r), certificateStoreCtx, E_SYSTEM, "[E_SYSTEM] Failed to read from file.");
1223
1224                 pCertList->pNext = null;
1225                 pCertList->length = certLength;
1226                 pCertList->format = (_CertFormat) certRecord.certFormat;
1227
1228                 pHoldList->pNext = pCertList.release();
1229                 pHoldList = pHoldList->pNext;
1230
1231                 totalCount++;
1232         }
1233
1234         SetLastResult(E_SUCCESS); //To clear the result of GetNextRecordByCondition function
1235
1236         return certificateStoreCtx;
1237 }
1238
1239
1240 enum _Asn1EncodingStyle
1241 {
1242         _ASN1_ENCODING_TYPE_PRIMITIVE = 0x00,
1243         _ASN1_ENCODING_TYPE_CONSTRUCTED = 0x20,
1244         _ASN1_ENCODING_TYPE_UNKNOWN = 0xFF
1245 }; //_Asn1EncodingStyle
1246
1247
1248 static const int _CERT_ASN1_TAG_CHECK_BIT_ = 0x7F;
1249 static const int _CERT_ASN1_LENGTH_CHECK_BIT_ = 0x80;
1250 static const int _CERT_ASN1_ENCODING_TYPE_OFFSET_ = 0x20;
1251
1252 int
1253 _CertManager::GetBlockSize(byte* pBuf)
1254 {
1255         int length = 0;
1256         int retVal = -1;
1257         int contentLength = 0;
1258         _Asn1EncodingStyle encodingType = _ASN1_ENCODING_TYPE_PRIMITIVE;
1259
1260
1261         ClearLastResult();
1262         SysTryReturn(NID_SEC_CERT, pBuf != null, retVal, E_INVALID_ARG, "[E_INVALID_ARG] Invalid input argument.");
1263
1264         encodingType = (_Asn1EncodingStyle) (pBuf[0] & _CERT_ASN1_ENCODING_TYPE_OFFSET_);
1265
1266         if (pBuf[1] > _CERT_ASN1_TAG_CHECK_BIT_)
1267         {
1268                 // Length is in indefinite form
1269                 if (pBuf[1] == _CERT_ASN1_LENGTH_CHECK_BIT_)
1270                 {
1271                         // STRICT: indefinite form cannot be used with Primitive encoding
1272                         SysTryReturn(NID_SEC_CERT, encodingType != _ASN1_ENCODING_TYPE_PRIMITIVE, retVal, E_INVALID_CONTENT, "[E_INVALID_CONTENT] Encoding type is not valid.");
1273                         //For the indefinite form, the length octets indicate that the contents octets are terminated by end-of-contents
1274                         //octets (see 8.1.5), and shall consist of a single octet.
1275                         // 0x80 0x00 0x00
1276                         contentLength = 2; //4
1277                 }
1278                 // Length is in Long form
1279                 else
1280                 {
1281                         int count = 0;
1282                         int lenpos = 0;
1283                         //STRICT: Size cannot be seven "1" bits
1284
1285                         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.");
1286
1287                         count = (pBuf[1]) & _CERT_ASN1_TAG_CHECK_BIT_;
1288                         length = 0;
1289                         for (lenpos = 2; lenpos < 2 + count; ++lenpos)
1290                         {
1291                                 length = (length << 8) | pBuf[lenpos];
1292                         }
1293                         contentLength = lenpos;
1294                 }
1295         }
1296         // Length is in short form
1297         else
1298         {
1299                 length = pBuf[1];
1300                 contentLength = 2;
1301         }
1302
1303         length += contentLength;
1304         return length;
1305 }
1306
1307 } } } //Tizen::Security::Cert