2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
9 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 * @file FSecCert_CertManager.cpp
20 * @brief This file contains implementation of X509 Certificate and private key interface APIs.
23 #include <unique_ptr.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>
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"
50 using namespace Tizen::Base;
51 using namespace Tizen::System;
52 using namespace Tizen::Io;
58 void operator ()(byte* c)
65 namespace Tizen { namespace Security { namespace Cert
68 static const char* _CERT_BASE64_HEADER = "-----BEGIN CERTIFICATE-----";
69 static const char* _CERT_BASE64_TRAILER = "-----END CERTIFICATE-----";
72 _CertManager::CreateCrtFile(void)
80 byte certBufData[_MAX_CERTIFICATE_SIZE] = {0, };
82 int certBufferLen = 0;
84 int certificateBase64Len = 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);
90 r = fileCrt.Construct(tmpCrtFileName, L"a+");
91 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Construct failed.", GetErrorMessage(r));
93 r = dir.Construct(dirName);
94 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to construct directory.", GetErrorMessage(r));
96 std::unique_ptr< DirEnumerator > pDirEnum(dir.ReadN());
97 SysTryReturn(NID_SEC_CERT, pDirEnum != null, GetLastResult(), GetLastResult(), "[%s] Failed to read directory.", GetErrorMessage(GetLastResult()));
99 while (pDirEnum->MoveNext() == E_SUCCESS)
103 DirEntry entry = pDirEnum->GetCurrentDirEntry();
105 fileName.Append(dirName);
106 fileName.Append(entry.GetName());
107 if ((entry.GetName() == "..") || (entry.GetName() == "."))
112 r = file.Construct(fileName, L"r");
113 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to construct file.", GetErrorMessage(r));
115 r = File::GetAttributes(fileName, attr);
116 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to get file attributes.", GetErrorMessage(r));
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));
122 readCnt = file.Read(certBufData, fileSize);
123 certificateBase64Len = _Base64::GetEncodedSize(readCnt);
125 if (!IsFailed(r) && readCnt == fileSize)
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.");
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.");
136 memcpy(static_cast<void*>(pCertBuffer.get()), certBufData, readCnt);
137 certBufferLen = readCnt;
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.");
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");
146 readCnt = certificateBase64Len + (2 * _MAX_PEM_HEADER);
148 readLength = BIO_read(pBio, certBufData, readCnt);
149 SysTryCatch(NID_SEC_CERT, readLength > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Certificate conversion failed");
151 readCnt = readLength;
153 r = fileCrt.Write(certBufData, readLength);
154 SysTryCatch(NID_SEC_CERT, !IsFailed(r), , r, "[%] Failed to write certificate to file.", GetErrorMessage(r));
159 memset(certBufData, 0, _MAX_CERTIFICATE_SIZE);
163 Tizen::Io::File::Remove(crtFileName);
164 Tizen::Io::File::Move(tmpCrtFileName, crtFileName);
172 _CertManager::OpenContext(_CertContextType type, CertChainCtx* pHCertCtx)
174 SysTryReturnResult(NID_SEC_CERT, type > 0, E_INVALID_ARG, "Invalid input parameter.");
176 _CertChain* pCertChain = new (std::nothrow) _CertChain();
177 SysTryReturnResult(NID_SEC_CERT, pCertChain != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
179 pCertChain->SetContextType(type);
180 *pHCertCtx = (CertChainCtx) pCertChain;
186 _CertManager::AddCertificate(CertChainCtx certCtx, byte* pCert, int certLen)
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);
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.");
198 certFormat = _CertManager::GetEncodedCertBuffer(pCert, certLen, &pDerCert, &derCertBufferLength, &encodingType);
199 std::unique_ptr< byte[] > pDerCertBuffer(pDerCert);
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.");
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.");
213 _CertManager::VerifyChain(CertChainCtx certCtx, _CertDomainType* pDomain)
215 result r = E_SUCCESS;
216 _CertChain* pCertChain = reinterpret_cast< _CertChain* >(certCtx);
218 SysTryReturnResult(NID_SEC_CERT, pCertChain != null, E_INVALID_ARG, "Initial parameters are invalid.");
220 r = pCertChain->VerifyCertChainWithDb();
221 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to verify certificate chain.", GetErrorMessage(r));
225 *pDomain = pCertChain->GetCertTypeByDomain();
232 _CertManager::VerifyCertificate(CertificateHandle certHandle, byte* pPublickey, int keyLen)
234 result r = E_SUCCESS;
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.");
240 _Certificate* pTempCert = reinterpret_cast< _Certificate* >(certHandle);
241 SysTryReturnResult(NID_SEC_CERT, pTempCert != null, E_INVALID_ARG, "Initial parameters are invalid.");
243 _CertFormat format = pTempCert->GetCertFormat();
245 if (format == _CERT_X509)
247 _X509Certificate* pCert = reinterpret_cast< _X509Certificate* >(certHandle);
249 pCert->VerifySignature(pPublickey, keyLen);
250 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to get signature.", GetErrorMessage(r));
255 SysLogException(NID_SEC_CERT, E_INVALID_CONTENT, "[E_INVALID_CONTENT]GetCertificateType: Unknown certificate format.");
263 _CertManager::GetChainDepth(CertChainCtx certCtx, int* pDepth)
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();
272 _CertManager::GetNthCertificate(CertChainCtx certCtx, int nth, CertificateHandle* pCertHandle)
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.");
279 r = pCertChain->MoveHead();
280 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to move ahead in certificate chain.");
282 for (int index = 0; index < nth; index++)
284 r = pCertChain->MoveNext();
285 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to move next in certificate chain.");
287 format = pCertChain->GetCertFormat();
288 if (format == _CERT_X509)
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.");
294 pCert->SetContextCertificate(true);
295 *pCertHandle = (CertificateHandle) pCert;
302 _CertManager::GetCertBuffer(CertificateHandle certHandle, char** ppCertbuffer, int* pCertLen)
304 result r = E_SUCCESS;
307 _Certificate* pTempCert = null;
310 SysTryReturnResult(NID_SEC_CERT, certHandle != null, E_INVALID_ARG, "Initial params not set.");
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.");
316 _X509Certificate* pCert = reinterpret_cast< _X509Certificate* >(certHandle);
318 r = pCert->GetCertBuffer(pBuf, bufSize);
319 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to move next in certificate chain.");
321 *ppCertbuffer = new (std::nothrow) char[bufSize];
322 SysTryReturnResult(NID_SEC_CERT, *ppCertbuffer != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
324 memcpy(*ppCertbuffer, pBuf, bufSize);
331 _CertManager::CloseContext(CertChainCtx certCtx)
333 _CertChain* pCertChain = static_cast< _CertChain* >(certCtx);
334 SysTryReturnResult(NID_SEC_CERT, pCertChain != null, E_INVALID_ARG, "Initial parameter not set.");
341 _CertManager::GetCertInfo(CertificateHandle certHandle, _CertFieldType field, _CertFieldInfos* pCertInfo)
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;
351 char* pSigAlg = null;
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.");
356 pTbsCert = pCert->GetTbsCertInstance();
357 SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
359 if (field & _CERT_FIELD_SERIAL)
361 pTbsCert->GetSerialNumber(pSerial, serialLen);
364 byte* pSerialNumber = null;
368 pSerialNumber = static_cast< byte* >(pSerial);
369 memset(pCertInfo->serialNo, 0, _MAX_SERIAL_NUMBER_SIZE + 1);
370 for (index = 0; index < iterVal; index++)
372 sprintf(&pCertInfo->serialNo[index * 2], "%02X", pSerialNumber[index]);
376 if (field & _CERT_FIELD_SIGALGORITHM)
378 pSigAlg = pTbsCert->GetSignatureAlgoId();
381 int len = strlen(pSigAlg);
382 if (len <= _MAX_CERT_ALGORITHM_SIZE)
384 strcpy(pCertInfo->sigAlgorithm, pSigAlg);
388 memcpy(pCertInfo->sigAlgorithm, pSigAlg, _MAX_CERT_ALGORITHM_SIZE);
389 pCertInfo->sigAlgorithm[_MAX_CERT_ALGORITHM_SIZE] = '\0';
395 strcpy(pCertInfo->sigAlgorithm, "Unknown");
398 if (field & _CERT_FIELD_VALIDITY)
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);
407 _CertTime::FormatDateTime(notBefore, pCertInfo->validityFrom);
408 _CertTime::FormatDateTime(notAfter, pCertInfo->validityTo);
411 if (field & _CERT_FIELD_SUBJECT)
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)
418 strcpy(pCertInfo->subjectName, reinterpret_cast< const char* >(pSubjectName));
420 ParseCertTitle(reinterpret_cast< char* >(pSubjectName), pCertInfo->certTitle);
423 if (field & _CERT_FIELD_ISSUER)
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)
430 strcpy(pCertInfo->issuerName, reinterpret_cast< const char* >(pIssuerName));
432 ParseCertTitle(reinterpret_cast< char* >(pIssuerName), pCertInfo->certSubTitle);
435 if (field & _CERT_FIELD_FINGERPRINT)
437 byte* pX509Buff = null;
438 int x509BuffSize = 0;
440 memset(pCertInfo->fingerPrint, 0, _MAX_CERT_FINGERPRINT_SIZE + 1);
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.");
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. ");
449 memset(pFingerPrint.get(), 0, SHA_DIGEST_LENGTH + 1);
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.");
455 int maxValue = SHA_DIGEST_LENGTH;
456 for (index = 0; index < maxValue; index++)
458 sprintf(&pCertInfo->fingerPrint[index * 2], "%02X", pFingerPrint[index]);
460 pCertInfo->fingerPrintLen = fingerPrintLen;
463 if (field & _CERT_FIELD_PUBLICKEY)
465 byte* pPublicKeyBuffer = null;
466 pTbsCert->GetPublicKeyInfoN(publicKeyLen, &pPublicKeyBuffer);
467 if (pPublicKeyBuffer != null)
469 std::unique_ptr< byte[] > pPublicKeyAuto(pPublicKeyBuffer);
470 int iterVal = publicKeyLen;
473 memset(pCertInfo->publicKey, 0, _MAX_CERT_PUBLIC_KEY_SIZE + 1);
474 for (index = 0; index < iterVal; index++)
476 sprintf(&pCertInfo->publicKey[index * 2], "%02X", pPublicKeyBuffer[index]);
482 if (field & _CERT_FIELD_VERSION)
484 pCertInfo->certVersion = pTbsCert->GetVersion();
485 SysTryReturnResult(NID_SEC_CERT, pCertInfo->certVersion > 0, E_SYSTEM, "Failed to get version.");
488 if (field & _CERT_FIELD_TYPE)
490 char type[6] = "X.509";
491 memset(pCertInfo->certTypeFormat, 0, sizeof(pCertInfo->certTypeFormat));
492 strcpy(pCertInfo->certTypeFormat, type);
494 if (strcmp(pCertInfo->certTitle, pCertInfo->certSubTitle) == 0)
496 char selfSigned[12] = "Self-signed";
497 memset(pCertInfo->certSubTitle, 0, sizeof(pCertInfo->certSubTitle));
498 strcpy(pCertInfo->certSubTitle, selfSigned);
506 _CertManager::GetEncodedCertBuffer(byte* pCertBuffer, int certBufferLen, byte** pDerCertBuffer, int* pDerCertBufferLength, _CertEncodingType* encodingType)
508 result r = E_SUCCESS;
509 _CertFormat certFormat = _CERT_UNKNOWN;
511 X509* pOpensslX509Cert = null;
512 char* pBase64Header = null;
513 char* pBase64Trailer = null;
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.");
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.");
527 pBase64Header = strstr(reinterpret_cast< char* >(pCertBuffer), _CERT_BASE64_HEADER);
528 pBase64Trailer = strstr(reinterpret_cast< char* >(pCertBuffer), _CERT_BASE64_TRAILER);
530 if ((pBase64Header != null) && (pBase64Trailer != null) && (pBase64Trailer > pBase64Header))
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.");
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");
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);
542 decodedLen = i2d_X509(pOpensslX509Cert, pDerCertBuffer);
543 SysTryCatch(NID_SEC_CERT, decodedLen > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Invalid certificate length.");
545 *pDerCertBufferLength = decodedLen;
547 certFormat = _CERT_X509;
548 *encodingType = _CERT_ENC_TYPE_PEM;
550 else if (pX509Cert->Parse(pCertBuffer, certBufferLen) == E_SUCCESS)
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.");
555 memcpy(pCertBuf.get(), pCertBuffer, certBufferLen);
556 certBufLen = certBufferLen;
558 *pDerCertBuffer = pCertBuf.release();
559 *pDerCertBufferLength = certBufLen;
561 certFormat = _CERT_X509;
562 *encodingType = _CERT_ENC_TYPE_BINARY;
566 certBufLen = _Base64::GetDecodedSize(certBufferLen);
567 SysTryReturn(NID_SEC_CERT, certBufLen > 0, _CERT_UNKNOWN, E_SYSTEM, "[E_SYSTEM] Invalid certificate length.");
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.");
572 memset(pCertBuf.get(), 0, certBufLen);
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.");
578 *pDerCertBuffer = pCertBuf.release();
579 *pDerCertBufferLength = decodedLen;
581 certFormat = _CERT_X509;
582 *encodingType = _CERT_ENC_TYPE_BASE64;
585 SetLastResult(E_SUCCESS); //To clear the result of parsing certificate.
594 if (pOpensslX509Cert != null)
596 X509_free(pOpensslX509Cert);
603 _CertManager::GetPublicKey(CertificateHandle certificate, char* pBuffer, int* pBufLen)
605 _Certificate* pTempCert = reinterpret_cast< _Certificate* >(certificate);
606 _X509Certificate* pCert = null;
607 _X509TbsCert* pTbsCert = null;
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.");
614 _CertFormat format = pTempCert->GetCertFormat();
615 SysTryReturnResult(NID_SEC_CERT, format == _CERT_X509, E_SYSTEM, "Failed to get certificate format.");
617 pCert = reinterpret_cast< _X509Certificate* >(certificate);
618 SysTryReturnResult(NID_SEC_CERT, pCert != null, E_INVALID_ARG, "Invalid input parameter.");
620 pTbsCert = pCert->GetTbsCertInstance();
621 SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
623 pTbsCert->GetPublicKeyInfoN(pubKeyLen, &pPuKey);
624 SysTryReturnResult(NID_SEC_CERT, pPuKey != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
626 std::unique_ptr< byte[] > pPubKeyAuto(pPuKey);
628 memcpy(pBuffer, pPubKeyAuto.get(), pubKeyLen);
632 *pBufLen = pubKeyLen;
639 _CertManager::GetSignature(CertificateHandle certificate, char* pBuffer, int* pBufLen)
641 _Certificate* pTempCert = reinterpret_cast< _Certificate* >(certificate);
642 _X509Certificate* pCert = null;
643 byte* pSignature = null;
645 _CertSignature* pSig = null;
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.");
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);
655 pSig = pCert->GetSignInstance();
656 SysTryReturnResult(NID_SEC_CERT, pSig != null, E_SYSTEM, "Failed to get certificate signature.");
658 pSignature = pSig->GetSignatureInfo(signLength);
659 memcpy(pBuffer, pSignature, signLength);
663 *pBufLen = signLength;
669 _CertManager::GetVersion(CertificateHandle certificate)
671 _Certificate* pTempCert = null;
672 _X509Certificate* pCert = null;
673 _X509TbsCert* pTbsCert = null;
675 pTempCert = reinterpret_cast< _Certificate* >(certificate);
676 SysTryReturn(NID_SEC_CERT, pTempCert != null, -1, E_INVALID_ARG, "[E_INVALID_ARG] Initial parameter not set.");
678 _CertFormat format = pTempCert->GetCertFormat();
680 SysTryReturn(NID_SEC_CERT, format == _CERT_X509, -1, E_SYSTEM, "[E_SYSTEM] Unknown certificate format.");
681 pCert = reinterpret_cast< _X509Certificate* >(certificate);
683 pTbsCert = pCert->GetTbsCertInstance();
684 SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
686 return pTbsCert->GetVersion();
690 _CertManager::GetValidity(CertificateHandle certificate, _CertValidityType* pValidity)
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;
699 SysTryReturnResult(NID_SEC_CERT, pTempCert != null, E_INVALID_ARG, "Initial parameter not set.");
701 _CertFormat format = pTempCert->GetCertFormat();
702 SysTryReturnResult(NID_SEC_CERT, format == _CERT_X509, E_SYSTEM, "Unknown certificate format.");
704 pCert = reinterpret_cast< _X509Certificate* >(certificate);
706 Tizen::System::SystemTime::GetCurrentTime(UTC_TIME, curTime);
708 pTbsCert = pCert->GetTbsCertInstance();
709 SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
711 pTbsCert->GetBeforeTimes(notBefore);
712 pTbsCert->GetAfterTimes(notAfter);
713 if (curTime <= notAfter && curTime >= notBefore)
715 *pValidity = _CERT_VALIDITY_VALID;
717 else if (curTime < notBefore)
719 *pValidity = _CERT_VALIDITY_NOT_YET_VALID;
721 else if (curTime > notAfter)
723 *pValidity = _CERT_VALIDITY_EXPIRED;
730 _CertManager::GetCertificateType(CertificateHandle certHandle, _CaCertType* pCertType)
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;
742 SysTryReturnResult(NID_SEC_CERT, pParentCert != null, E_INVALID_ARG, "Initial parameter not set.");
745 _CertFormat format = pParentCert->GetCertFormat();
746 SysTryReturnResult(NID_SEC_CERT, format == _CERT_X509, E_SYSTEM, "Failed to get certificate format.");
748 pCert = reinterpret_cast< _X509Certificate* >(certHandle);
749 SysTryReturnResult(NID_SEC_CERT, pCert != null, E_INVALID_ARG, "Initial parameter not set.");
751 pTbsCert = pCert->GetTbsCertInstance();
752 SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
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.");
759 strcpy(subjectName, reinterpret_cast< const char* >(pTbsCert->GetSubjectName()));
760 strcpy(issuerName, reinterpret_cast< const char* >(pTbsCert->GetIssuerName()));
762 pCertDb = _CertDbManager::GetInstance();
763 SysTryReturnResult(NID_SEC_CERT, pCertDb != null, E_SYSTEM, "Failed to get instance of certificate database manager.");
765 r = pCertDb->FindCertType(format, issuerName, subjectName, pCertType);
769 *pCertType = _CERT_TYPE_MAX;
777 _CertManager::ParseCertTitle(char subject[_MAX_ISSUER_SUBJECT_NAME_SIZE + 1], char title[_MAX_ISSUER_SUBJECT_NAME_SIZE + 1])
781 SysTryReturn(NID_SEC_CERT, subject[0] != '\0', E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Invalid input parameter.");
783 SysAssertf(strlen(subject) <= (size_t) _MAX_ISSUER_SUBJECT_NAME_SIZE, "The buffer size of source is too big.");
786 char* pPivotPtr = null;
787 char* pSavePtr = null;
788 char* pSubStr = null;
789 char tempSubject[_MAX_ISSUER_SUBJECT_NAME_SIZE + 1] = {0, };
791 strncpy(tempSubject, subject, strlen(subject));
792 pPivotPtr = tempSubject;
793 for (;; pSubStr = null)
795 pSubStr = strtok_r(pPivotPtr, "/", &pSavePtr);
797 if (strncmp(pSubStr, _CERT_COMMON_NAME, strlen(_CERT_COMMON_NAME)) == 0)
799 pSubStr = pSubStr + strlen(_CERT_COMMON_NAME);
803 else if (strncmp(pSubStr, _CERT_ORG_NAME, strlen(_CERT_ORG_NAME)) == 0)
805 pSubStr = pSubStr + strlen(_CERT_ORG_NAME);
809 else if (strncmp(pSubStr, _CERT_ORG_UNIT_NAME, strlen(_CERT_ORG_UNIT_NAME)) == 0)
811 pSubStr = pSubStr + strlen(_CERT_ORG_UNIT_NAME);
815 else if (strncmp(pSubStr, _CERT_EMAIL_ADDRESS, strlen(_CERT_EMAIL_ADDRESS)) == 0)
817 pSubStr = pSubStr + strlen(_CERT_EMAIL_ADDRESS);
822 pPivotPtr = pSavePtr;
826 SysTryReturn(NID_SEC_CERT, done, E_PARSING_FAILED, E_SYSTEM, "[%s] Failed to parse Certificate title.", GetErrorMessage(E_PARSING_FAILED));
829 for (int index = 0; index < _MAX_ISSUER_SUBJECT_NAME_SIZE + 1; index++)
834 // copy title into out param
835 strncpy(title, pSubStr, strlen(pSubStr));
840 //User Certificate APIs
842 _CertManager::MakeParseAndVerifyCertChainBufferN(byte* pCertChainBuffer, int certChainLength, byte* pUserPrivateKeyBuffer, int userPrivateKeyLength, _CertChain** ppX509CertChain, _CertPrivateKeyInfo** ppX509PrivateKeyInfo)
844 result r = E_SUCCESS;
846 int currCertBufLen = 0;
847 int totCertCount = 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);
857 pCertBuf = pCertChainBuffer;
858 bufSize = certChainLength;
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.");
863 // Process Private Key
864 if (pUserPrivateKeyBuffer != null && userPrivateKeyLength > 0)
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.");
871 while (dataOffset < bufSize)
873 pCurrCertBuf = pCertBuf + dataOffset;
874 currCertBufLen = _CertManager::GetBlockSize(pCurrCertBuf);
876 dataOffset += currCertBufLen;
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.");
884 if (pPKeyInfo != null)
886 // Find Device/User Certificate
887 while (dataOffset < bufSize)
889 pCurrCertBuf = pCertBuf + dataOffset;
890 currCertBufLen = _CertManager::GetBlockSize(pCurrCertBuf);
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.");
895 r = pTmpCert->Parse(pCurrCertBuf, currCertBufLen);
896 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_DECODING_FAILED, "Failed to parse and verify certificate chain.");
898 r = _CertManager::CheckRsaPublicPrivateKeyPair(pTmpCert.get(), pPKeyInfo.get());
901 r = pCertChain->AddCertificate(pTmpCert.get());
902 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_INVALID_CONDITION, "Failed to parse and verify certificate chain.");
905 addedNumberCertificate++;
906 pUserCert = pTmpCert.release();
910 dataOffset += currCertBufLen;
913 SysTryReturnResult(NID_SEC_CERT, pubPriPair, E_INVALID_KEY, "Failed to parse and verify certificate chain.");
918 //As there is no private key present in chain, it is assumed that first certificate is user certificate
919 if (pUserCert == null)
921 pCurrCertBuf = pCertBuf + dataOffset;
922 currCertBufLen = _CertManager::GetBlockSize(pCurrCertBuf);
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.");
927 r = pUserCertAuto->Parse(pCurrCertBuf, currCertBufLen);
928 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_DECODING_FAILED, "Failed to parse first certificate in chain.");
930 r = pCertChain->AddCertificate(pUserCertAuto.get());
931 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_INVALID_CONDITION, "Failed to add first certificate in chain. ");
933 addedNumberCertificate++;
934 pUserCert = pUserCertAuto.release();
938 while (totCertCount > addedNumberCertificate)
941 countTotalCertificateChecked++;
943 if (countTotalCertificateChecked > totCertCount)
948 SysTryReturnResult(NID_SEC_CERT, pUserCert != null, E_INVALID_ARG, "Invalid certificate in chain. ");
950 while (dataOffset < bufSize)
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. ");
955 pCurrCertBuf = pCertBuf + dataOffset;
956 currCertBufLen = _CertManager::GetBlockSize(pCurrCertBuf);
958 r = pCurrentCert->Parse(pCurrCertBuf, currCertBufLen);
959 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_DECODING_FAILED, "Failed to parse certificate in chain. ");
961 if (pUserCert->IsIssuer(pCurrentCert.get()))
963 r = pCertChain->AddCertificate(pCurrentCert.get());
964 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_INVALID_CONDITION, "Failed to add certificate in chain. ");
966 pUserCert = pCurrentCert.release();
967 addedNumberCertificate++;
971 dataOffset += currCertBufLen;
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));
979 *ppX509CertChain = pCertChain.release();
980 *ppX509PrivateKeyInfo = pPKeyInfo.release();
986 _CertManager::CheckRsaPublicPrivateKeyPair(_X509Certificate* pX509Certificate, _CertPrivateKeyInfo* pX509CertificatePrivateKey)
988 result r = E_SUCCESS;
990 EVP_PKEY* pPrivateKey = null;
991 int privateKeyLength = 0;
992 X509* pX509Cert = null;
993 const char* pSigalg = null;
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.");
998 pX509Cert = static_cast< X509* >(pX509Certificate->GetX509CertObject());
999 SysTryReturnResult(NID_SEC_CERT, pX509Cert != null, E_SYSTEM, "Failed to parse certificate. ");
1002 pSigalg = OBJ_nid2ln(OBJ_obj2nid(pX509Cert->sig_alg->algorithm));
1003 SysTryReturnResult(NID_SEC_CERT, pSigalg != null, E_SYSTEM, "Unable to get certificate algorithm.");
1005 if (strstr(pSigalg, "WithRSA"))
1007 byte* pPriKey = null;
1009 pX509CertificatePrivateKey->GetPrivateKeyN(privateKeyLength, &pPriKey);
1010 SysTryReturnResult(NID_SEC_CERT, pPriKey != null, E_SYSTEM, "Unable to get certificate private key.");
1012 std::unique_ptr< byte[] > pPriKeyBuf(pPriKey);
1014 pPrivateKey = d2i_PrivateKey(EVP_PKEY_RSA, null, const_cast< const unsigned char** >(static_cast< unsigned char** >(&pPriKey)), privateKeyLength);
1015 if (pPrivateKey != null)
1017 retValue = X509_check_private_key(pX509Cert, pPrivateKey);
1019 EVP_PKEY_free(pPrivateKey);
1021 SysTryReturnResult(NID_SEC_CERT, retValue == 1, E_SYSTEM, "Private public key mismatch, this key does not belong to this certificate.");
1028 SysLog(NID_SEC_CERT, "Private key conversion failed.");
1036 SysLog(NID_SEC_CERT, "Unsupported Algorithm = %s", pSigalg);
1044 _CertManager::GetCertificateSubjectNameN(CertificateHandle certificateHandle, byte** ppSubjectName, int* pSubjectNameLength)
1048 _Certificate* pTempCert = static_cast< _Certificate* >(certificateHandle);
1049 _CertFormat format = pTempCert->GetCertFormat();
1051 SysTryReturnResult(NID_SEC_CERT, format == _CERT_X509, E_INVALID_ARG, "Invalid certificate format.");
1053 _X509Certificate* pCert = static_cast< _X509Certificate* >(certificateHandle);
1054 pCert->GetIssuerBuffer(pBuf, len);
1056 *ppSubjectName = new (std::nothrow) byte[len];
1057 SysTryReturnResult(NID_SEC_CERT, *ppSubjectName != null, E_OUT_OF_MEMORY, "Failed to allocate memory. ");
1059 memset(*ppSubjectName, 0, len);
1060 memcpy(*ppSubjectName, pBuf, len);
1061 *pSubjectNameLength = len;
1067 _CertManager::GetCertificateIssuerNameN(CertificateHandle certificateHandle, byte** ppIssuerName, int* pIssuerNameLength)
1069 _Certificate* pTempCert = static_cast< _Certificate* >(certificateHandle);
1070 _CertFormat format = pTempCert->GetCertFormat();
1074 SysTryReturnResult(NID_SEC_CERT, format == _CERT_X509, E_INVALID_ARG, "Invalid certificate format.");
1076 _X509Certificate* pCert = static_cast< _X509Certificate* >(certificateHandle);
1077 pCert->GetSubjectNameBuffer(pBuf, len);
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;
1089 _CertManager::OpenUserCertificateStore(int& totalCount)
1091 result r = E_SUCCESS;
1092 UserCertRecord certRecord = {0};
1093 _CertRootList* pHoldList = null;
1094 _CertFileStore fileStore;
1095 CertificateStoreCtx certificateStoreCtx = null;
1097 char condition[_MAX_TYPE_CONST_SIZE] = {0};
1098 char installedRecord[_MAX_TYPE_RECORD_SIZE] = "T\0";
1104 sprintf(condition, "installed = '%s'", installedRecord);
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.");
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));
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.");
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.");
1118 memset(pRootCa.get(), 0, sizeof(*pRootCa.get()));
1119 pCertListFirstNode->pNext = null;
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.");
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.");
1127 pCertListFirstNode->length = certLength;
1128 pCertListFirstNode->format = (_CertFormat) certRecord.certFormat;
1130 pRootCa->pRootList = pHoldList = pCertListFirstNode.release();
1132 certificateStoreCtx = (CertificateStoreCtx) pRootCa.release();
1136 while ((pUserCertDbStore->GetNextRecordByCondition(reinterpret_cast< byte* >(condition), &certRecord, certRecord.certId)) == E_SUCCESS)
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.");
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.");
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.");
1147 pCertList->pNext = null;
1148 pCertList->length = certLength;
1149 pCertList->format = (_CertFormat) certRecord.certFormat;
1151 pHoldList->pNext = pCertList.release();
1152 pHoldList = pHoldList->pNext;
1157 SetLastResult(E_SUCCESS); //To clear the result of GetNextRecordByCondition function
1159 return certificateStoreCtx;
1164 _CertManager::OpenRootCaStore(_CaCertType type, int& totalCount) // _CERT_TYPE_TRUSTED_CA or _CERT_TYPE_ROOT_CA, ?
1166 result r = E_SUCCESS;
1167 CaCertRecord certRecord = {0};
1168 _CertRootList* pHoldList = null;
1169 _CertFileStore fileStore;
1170 CertificateStoreCtx certificateStoreCtx = null;
1172 char condition[_MAX_TYPE_CONST_SIZE] = {0};
1173 char installedRecord[_MAX_TYPE_RECORD_SIZE] = "T\0";
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.");
1182 sprintf(condition, "certType = %d and installed = '%s'", static_cast< int >(type), installedRecord);
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.");
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));
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.");
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.");
1196 memset(pRootCa.get(), 0, sizeof(*pRootCa.get()));
1197 pCertListFirstNode->pNext = null;
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.");
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.");
1205 pCertListFirstNode->length = certLength;
1206 pCertListFirstNode->format = (_CertFormat) certRecord.certFormat;
1208 pRootCa->pRootList = pHoldList = pCertListFirstNode.release();
1210 certificateStoreCtx = (CertificateStoreCtx) pRootCa.release();
1214 while ((pCaCertDbStore->GetNextRecordByCondition(reinterpret_cast< byte* >(condition), &certRecord, certRecord.certId)) == E_SUCCESS)
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.");
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.");
1224 pCertList->pNext = null;
1225 pCertList->length = certLength;
1226 pCertList->format = (_CertFormat) certRecord.certFormat;
1228 pHoldList->pNext = pCertList.release();
1229 pHoldList = pHoldList->pNext;
1234 SetLastResult(E_SUCCESS); //To clear the result of GetNextRecordByCondition function
1236 return certificateStoreCtx;
1240 enum _Asn1EncodingStyle
1242 _ASN1_ENCODING_TYPE_PRIMITIVE = 0x00,
1243 _ASN1_ENCODING_TYPE_CONSTRUCTED = 0x20,
1244 _ASN1_ENCODING_TYPE_UNKNOWN = 0xFF
1245 }; //_Asn1EncodingStyle
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;
1253 _CertManager::GetBlockSize(byte* pBuf)
1257 int contentLength = 0;
1258 _Asn1EncodingStyle encodingType = _ASN1_ENCODING_TYPE_PRIMITIVE;
1262 SysTryReturn(NID_SEC_CERT, pBuf != null, retVal, E_INVALID_ARG, "[E_INVALID_ARG] Invalid input argument.");
1264 encodingType = (_Asn1EncodingStyle) (pBuf[0] & _CERT_ASN1_ENCODING_TYPE_OFFSET_);
1266 if (pBuf[1] > _CERT_ASN1_TAG_CHECK_BIT_)
1268 // Length is in indefinite form
1269 if (pBuf[1] == _CERT_ASN1_LENGTH_CHECK_BIT_)
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.
1276 contentLength = 2; //4
1278 // Length is in Long form
1283 //STRICT: Size cannot be seven "1" bits
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.");
1287 count = (pBuf[1]) & _CERT_ASN1_TAG_CHECK_BIT_;
1289 for (lenpos = 2; lenpos < 2 + count; ++lenpos)
1291 length = (length << 8) | pBuf[lenpos];
1293 contentLength = lenpos;
1296 // Length is in short form
1303 length += contentLength;
1307 } } } //Tizen::Security::Cert