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