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;
54 namespace Tizen { namespace Security { namespace Cert
57 static const char* _CERT_BASE64_HEADER = "-----BEGIN CERTIFICATE-----";
58 static const char* _CERT_BASE64_TRAILER = "-----END CERTIFICATE-----";
61 _CertManager::CreateCrtFile(void)
69 byte certBufData[_MAX_CERTIFICATE_SIZE] = {0, };
70 const unsigned char* pCertBuffer = null;
72 int certBufferLen = 0;
74 int certificateBase64Len = 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);
80 r = fileCrt.Construct(tmpCrtFileName, L"a+");
81 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Construct failed.", GetErrorMessage(r));
83 r = dir.Construct(dirName);
84 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to construct directory.", GetErrorMessage(r));
86 std::unique_ptr< DirEnumerator > pDirEnum(dir.ReadN());
87 SysTryReturn(NID_SEC_CERT, pDirEnum != null, GetLastResult(), GetLastResult(), "[%s] Failed to read directory.", GetErrorMessage(GetLastResult()));
89 while (pDirEnum->MoveNext() == E_SUCCESS)
93 DirEntry entry = pDirEnum->GetCurrentDirEntry();
95 fileName.Append(dirName);
96 fileName.Append(entry.GetName());
97 if ((entry.GetName() == "..") || (entry.GetName() == "."))
102 r = file.Construct(fileName, L"r");
103 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to construct file.", GetErrorMessage(r));
105 r = File::GetAttributes(fileName, attr);
106 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to get file attributes.", GetErrorMessage(r));
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));
112 readCnt = file.Read(certBufData, fileSize);
113 certificateBase64Len = _Base64::GetEncodedSize(readCnt);
115 if (!IsFailed(r) && readCnt == fileSize)
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.");
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.");
126 memcpy((void*) pCertBuffer, certBufData, readCnt);
127 certBufferLen = readCnt;
129 pCert = d2i_X509(null, &pCertBuffer, certBufferLen);
130 SysTryCatch(NID_SEC_CERT, pCert != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Certificate conversion failed.");
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");
135 readCnt = certificateBase64Len + (2 * _MAX_PEM_HEADER);
137 readLength = BIO_read(pBio, certBufData, readCnt);
138 SysTryCatch(NID_SEC_CERT, readLength > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Certificate conversion failed");
140 readCnt = readLength;
142 r = fileCrt.Write(certBufData, readLength);
143 SysTryCatch(NID_SEC_CERT, !IsFailed(r), , r, "[%] Failed to write certificate to file.", GetErrorMessage(r));
148 memset(certBufData, 0, _MAX_CERTIFICATE_SIZE);
152 Tizen::Io::File::Remove(crtFileName);
153 Tizen::Io::File::Move(tmpCrtFileName, crtFileName);
161 _CertManager::OpenContext(_CertContextType type, CertChainCtx* pHCertCtx)
163 SysTryReturnResult(NID_SEC_CERT, type > 0, E_INVALID_ARG, "Invalid input parameter.");
165 _CertChain* pCertChain = new (std::nothrow) _CertChain();
166 SysTryReturnResult(NID_SEC_CERT, pCertChain != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
168 pCertChain->SetContextType(type);
169 *pHCertCtx = (CertChainCtx) pCertChain;
175 _CertManager::AddCertificate(CertChainCtx certCtx, byte* pCert, int certLen)
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);
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.");
187 certFormat = _CertManager::GetEncodedCertBuffer(pCert, certLen, &pDerCert, &derCertBufferLength, &encodingType);
188 std::unique_ptr< byte[] > pDerCertBuffer(pDerCert);
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.");
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.");
202 _CertManager::VerifyChain(CertChainCtx certCtx, _CertDomainType* pDomain)
204 result r = E_SUCCESS;
205 _CertChain* pCertChain = reinterpret_cast< _CertChain* >(certCtx);
207 SysTryReturnResult(NID_SEC_CERT, pCertChain != null, E_INVALID_ARG, "Initial parameters are invalid.");
209 r = pCertChain->VerifyCertChainWithDb();
210 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to verify certificate chain.", GetErrorMessage(r));
214 *pDomain = pCertChain->GetCertTypeByDomain();
221 _CertManager::VerifyCertificate(CertificateHandle certHandle, byte* pPublickey, int keyLen)
223 result r = E_SUCCESS;
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.");
229 _Certificate* pTempCert = reinterpret_cast< _Certificate* >(certHandle);
230 SysTryReturnResult(NID_SEC_CERT, pTempCert != null, E_INVALID_ARG, "Initial parameters are invalid.");
232 _CertFormat format = pTempCert->GetCertFormat();
234 if (format == _CERT_X509)
236 _X509Certificate* pCert = reinterpret_cast< _X509Certificate* >(certHandle);
238 pCert->VerifySignature(pPublickey, keyLen);
239 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to get signature.", GetErrorMessage(r));
244 SysLogException(NID_SEC_CERT, E_INVALID_CONTENT, "[E_INVALID_CONTENT]GetCertificateType: Unknown certificate format.");
252 _CertManager::GetChainDepth(CertChainCtx certCtx, int* pDepth)
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();
261 _CertManager::GetNthCertificate(CertChainCtx certCtx, int nth, CertificateHandle* pCertHandle)
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.");
268 r = pCertChain->MoveHead();
269 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to move ahead in certificate chain.");
271 for (int index = 0; index < nth; index++)
273 r = pCertChain->MoveNext();
274 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to move next in certificate chain.");
276 format = pCertChain->GetCertFormat();
277 if (format == _CERT_X509)
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.");
283 pCert->SetContextCertificate(true);
284 *pCertHandle = (CertificateHandle) pCert;
291 _CertManager::GetCertBuffer(CertificateHandle certHandle, char** ppCertbuffer, int* pCertLen)
293 result r = E_SUCCESS;
296 _Certificate* pTempCert = null;
299 SysTryReturnResult(NID_SEC_CERT, certHandle != null, E_INVALID_ARG, "Initial params not set.");
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.");
305 _X509Certificate* pCert = reinterpret_cast< _X509Certificate* >(certHandle);
307 r = pCert->GetCertBuffer(pBuf, bufSize);
308 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to move next in certificate chain.");
310 *ppCertbuffer = new (std::nothrow) char[bufSize];
311 SysTryReturnResult(NID_SEC_CERT, *ppCertbuffer != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
313 memcpy(*ppCertbuffer, pBuf, bufSize);
320 _CertManager::CloseContext(CertChainCtx certCtx)
322 _CertChain* pCertChain = static_cast< _CertChain* >(certCtx);
323 SysTryReturnResult(NID_SEC_CERT, pCertChain != null, E_INVALID_ARG, "Initial parameter not set.");
330 _CertManager::GetCertInfo(CertificateHandle certHandle, _CertFieldType field, _CertFieldInfos* pCertInfo)
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;
340 char* pSigAlg = null;
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.");
345 pTbsCert = pCert->GetTbsCertInstance();
346 SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
348 if (field & _CERT_FIELD_SERIAL)
350 pTbsCert->GetSerialNumber(pSerial, serialLen);
353 byte* pSerialNumber = null;
357 pSerialNumber = static_cast< byte* >(pSerial);
358 memset(pCertInfo->serialNo, 0, _MAX_SERIAL_NUMBER_SIZE + 1);
359 for (index = 0; index < iterVal; index++)
361 sprintf(&pCertInfo->serialNo[index * 2], "%02X", pSerialNumber[index]);
365 if (field & _CERT_FIELD_SIGALGORITHM)
367 pSigAlg = pTbsCert->GetSignatureAlgoId();
370 int len = strlen(pSigAlg);
371 if (len <= _MAX_CERT_ALGORITHM_SIZE)
373 strcpy(pCertInfo->sigAlgorithm, pSigAlg);
377 memcpy(pCertInfo->sigAlgorithm, pSigAlg, _MAX_CERT_ALGORITHM_SIZE);
378 pCertInfo->sigAlgorithm[_MAX_CERT_ALGORITHM_SIZE] = '\0';
384 strcpy(pCertInfo->sigAlgorithm, "Unknown");
387 if (field & _CERT_FIELD_VALIDITY)
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);
396 _CertTime::FormatDateTime(notBefore, pCertInfo->validityFrom);
397 _CertTime::FormatDateTime(notAfter, pCertInfo->validityTo);
400 if (field & _CERT_FIELD_SUBJECT)
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)
407 strcpy(pCertInfo->subjectName, reinterpret_cast< const char* >(pSubjectName));
409 ParseCertTitle(reinterpret_cast< char* >(pSubjectName), pCertInfo->certTitle);
412 if (field & _CERT_FIELD_ISSUER)
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)
419 strcpy(pCertInfo->issuerName, reinterpret_cast< const char* >(pIssuerName));
421 ParseCertTitle(reinterpret_cast< char* >(pIssuerName), pCertInfo->certSubTitle);
424 if (field & _CERT_FIELD_FINGERPRINT)
426 byte* pX509Buff = null;
427 int x509BuffSize = 0;
429 memset(pCertInfo->fingerPrint, 0, _MAX_CERT_FINGERPRINT_SIZE + 1);
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.");
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. ");
438 memset(pFingerPrint.get(), 0, SHA_DIGEST_LENGTH + 1);
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.");
444 int maxValue = SHA_DIGEST_LENGTH;
445 for (index = 0; index < maxValue; index++)
447 sprintf(&pCertInfo->fingerPrint[index * 2], "%02X", pFingerPrint[index]);
449 pCertInfo->fingerPrintLen = fingerPrintLen;
452 if (field & _CERT_FIELD_PUBLICKEY)
454 byte* pPublicKeyBuffer = null;
455 pTbsCert->GetPublicKeyInfoN(publicKeyLen, &pPublicKeyBuffer);
456 if (pPublicKeyBuffer != null)
458 std::unique_ptr< byte[] > pPublicKeyAuto(pPublicKeyBuffer);
459 int iterVal = publicKeyLen;
462 memset(pCertInfo->publicKey, 0, _MAX_CERT_PUBLIC_KEY_SIZE + 1);
463 for (index = 0; index < iterVal; index++)
465 sprintf(&pCertInfo->publicKey[index * 2], "%02X", pPublicKeyBuffer[index]);
471 if (field & _CERT_FIELD_VERSION)
473 pCertInfo->certVersion = pTbsCert->GetVersion();
474 SysTryReturnResult(NID_SEC_CERT, pCertInfo->certVersion > 0, E_SYSTEM, "Failed to get version.");
477 if (field & _CERT_FIELD_TYPE)
479 char type[6] = "X.509";
480 memset(pCertInfo->certTypeFormat, 0, sizeof(pCertInfo->certTypeFormat));
481 strcpy(pCertInfo->certTypeFormat, type);
483 if (strcmp(pCertInfo->certTitle, pCertInfo->certSubTitle) == 0)
485 char selfSigned[12] = "Self-signed";
486 memset(pCertInfo->certSubTitle, 0, sizeof(pCertInfo->certSubTitle));
487 strcpy(pCertInfo->certSubTitle, selfSigned);
495 _CertManager::GetEncodedCertBuffer(byte* pCertBuffer, int certBufferLen, byte** pDerCertBuffer, int* pDerCertBufferLength, _CertEncodingType* encodingType)
497 result r = E_SUCCESS;
498 _CertFormat certFormat = _CERT_UNKNOWN;
500 X509* pOpensslX509Cert = null;
501 char* pBase64Header = null;
502 char* pBase64Trailer = null;
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.");
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.");
516 pBase64Header = strstr(reinterpret_cast< char* >(pCertBuffer), _CERT_BASE64_HEADER);
517 pBase64Trailer = strstr(reinterpret_cast< char* >(pCertBuffer), _CERT_BASE64_TRAILER);
519 if ((pBase64Header != null) && (pBase64Trailer != null) && (pBase64Trailer > pBase64Header))
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.");
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");
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);
531 decodedLen = i2d_X509(pOpensslX509Cert, pDerCertBuffer);
532 SysTryCatch(NID_SEC_CERT, decodedLen > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Invalid certificate length.");
534 *pDerCertBufferLength = decodedLen;
536 certFormat = _CERT_X509;
537 *encodingType = _CERT_ENC_TYPE_PEM;
539 else if (pX509Cert->Parse(pCertBuffer, certBufferLen) == E_SUCCESS)
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.");
544 memcpy(pCertBuf.get(), pCertBuffer, certBufferLen);
545 certBufLen = certBufferLen;
547 *pDerCertBuffer = pCertBuf.release();
548 *pDerCertBufferLength = certBufLen;
550 certFormat = _CERT_X509;
551 *encodingType = _CERT_ENC_TYPE_BINARY;
555 certBufLen = _Base64::GetDecodedSize(certBufferLen);
556 SysTryReturn(NID_SEC_CERT, certBufLen > 0, _CERT_UNKNOWN, E_SYSTEM, "[E_SYSTEM] Invalid certificate length.");
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.");
561 memset(pCertBuf.get(), 0, certBufLen);
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.");
567 *pDerCertBuffer = pCertBuf.release();
568 *pDerCertBufferLength = decodedLen;
570 certFormat = _CERT_X509;
571 *encodingType = _CERT_ENC_TYPE_BASE64;
574 SetLastResult(E_SUCCESS); //To clear the result of parsing certificate.
583 if (pOpensslX509Cert != null)
585 X509_free(pOpensslX509Cert);
592 _CertManager::GetPublicKey(CertificateHandle certificate, char* pBuffer, int* pBufLen)
594 _Certificate* pTempCert = reinterpret_cast< _Certificate* >(certificate);
595 _X509Certificate* pCert = null;
596 _X509TbsCert* pTbsCert = null;
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.");
603 _CertFormat format = pTempCert->GetCertFormat();
604 SysTryReturnResult(NID_SEC_CERT, format == _CERT_X509, E_SYSTEM, "Failed to get certificate format.");
606 pCert = reinterpret_cast< _X509Certificate* >(certificate);
607 SysTryReturnResult(NID_SEC_CERT, pCert != null, E_INVALID_ARG, "Invalid input parameter.");
609 pTbsCert = pCert->GetTbsCertInstance();
610 SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
612 pTbsCert->GetPublicKeyInfoN(pubKeyLen, &pPuKey);
613 SysTryReturnResult(NID_SEC_CERT, pPuKey != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
615 std::unique_ptr< byte[] > pPubKeyAuto(pPuKey);
617 memcpy(pBuffer, pPubKeyAuto.get(), pubKeyLen);
621 *pBufLen = pubKeyLen;
628 _CertManager::GetSignature(CertificateHandle certificate, char* pBuffer, int* pBufLen)
630 _Certificate* pTempCert = reinterpret_cast< _Certificate* >(certificate);
631 _X509Certificate* pCert = null;
632 byte* pSignature = null;
634 _CertSignature* pSig = null;
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.");
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);
644 pSig = pCert->GetSignInstance();
645 SysTryReturnResult(NID_SEC_CERT, pSig != null, E_SYSTEM, "Failed to get certificate signature.");
647 pSignature = pSig->GetSignatureInfo(signLength);
648 memcpy(pBuffer, pSignature, signLength);
652 *pBufLen = signLength;
658 _CertManager::GetVersion(CertificateHandle certificate)
660 _Certificate* pTempCert = null;
661 _X509Certificate* pCert = null;
662 _X509TbsCert* pTbsCert = null;
664 pTempCert = reinterpret_cast< _Certificate* >(certificate);
665 SysTryReturn(NID_SEC_CERT, pTempCert != null, -1, E_INVALID_ARG, "[E_INVALID_ARG] Initial parameter not set.");
667 _CertFormat format = pTempCert->GetCertFormat();
669 SysTryReturn(NID_SEC_CERT, format == _CERT_X509, -1, E_SYSTEM, "[E_SYSTEM] Unknown certificate format.");
670 pCert = reinterpret_cast< _X509Certificate* >(certificate);
672 pTbsCert = pCert->GetTbsCertInstance();
673 SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
675 return pTbsCert->GetVersion();
679 _CertManager::GetValidity(CertificateHandle certificate, _CertValidityType* pValidity)
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;
688 SysTryReturnResult(NID_SEC_CERT, pTempCert != null, E_INVALID_ARG, "Initial parameter not set.");
690 _CertFormat format = pTempCert->GetCertFormat();
691 SysTryReturnResult(NID_SEC_CERT, format == _CERT_X509, E_SYSTEM, "Unknown certificate format.");
693 pCert = reinterpret_cast< _X509Certificate* >(certificate);
695 Tizen::System::SystemTime::GetCurrentTime(UTC_TIME, curTime);
697 pTbsCert = pCert->GetTbsCertInstance();
698 SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
700 pTbsCert->GetBeforeTimes(notBefore);
701 pTbsCert->GetAfterTimes(notAfter);
702 if (curTime <= notAfter && curTime >= notBefore)
704 *pValidity = _CERT_VALIDITY_VALID;
706 else if (curTime < notBefore)
708 *pValidity = _CERT_VALIDITY_NOT_YET_VALID;
710 else if (curTime > notAfter)
712 *pValidity = _CERT_VALIDITY_EXPIRED;
719 _CertManager::GetCertificateType(CertificateHandle certHandle, _CaCertType* pCertType)
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;
731 SysTryReturnResult(NID_SEC_CERT, pParentCert != null, E_INVALID_ARG, "Initial parameter not set.");
734 _CertFormat format = pParentCert->GetCertFormat();
735 SysTryReturnResult(NID_SEC_CERT, format == _CERT_X509, E_SYSTEM, "Failed to get certificate format.");
737 pCert = reinterpret_cast< _X509Certificate* >(certHandle);
738 SysTryReturnResult(NID_SEC_CERT, pCert != null, E_INVALID_ARG, "Initial parameter not set.");
740 pTbsCert = pCert->GetTbsCertInstance();
741 SysTryReturnResult(NID_SEC_CERT, pTbsCert != null, E_SYSTEM, "Failed to get certificate to be signed instance.");
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.");
748 strcpy(subjectName, reinterpret_cast< const char* >(pTbsCert->GetSubjectName()));
749 strcpy(issuerName, reinterpret_cast< const char* >(pTbsCert->GetIssuerName()));
751 pCertDb = _CertDbManager::GetInstance();
752 SysTryReturnResult(NID_SEC_CERT, pCertDb != null, E_SYSTEM, "Failed to get instance of certificate database manager.");
754 r = pCertDb->FindCertType(format, issuerName, subjectName, pCertType);
758 *pCertType = _CERT_TYPE_MAX;
766 _CertManager::ParseCertTitle(char subject[_MAX_ISSUER_SUBJECT_NAME_SIZE + 1], char title[_MAX_ISSUER_SUBJECT_NAME_SIZE + 1])
770 SysTryReturn(NID_SEC_CERT, subject[0] != '\0', E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Invalid input parameter.");
772 SysAssertf(strlen(subject) <= (size_t) _MAX_ISSUER_SUBJECT_NAME_SIZE, "The buffer size of source is too big.");
775 char* pPivotPtr = null;
776 char* pSavePtr = null;
777 char* pSubStr = null;
778 char tempSubject[_MAX_ISSUER_SUBJECT_NAME_SIZE + 1] = {0, };
780 strncpy(tempSubject, subject, strlen(subject));
781 pPivotPtr = tempSubject;
782 for (;; pSubStr = null)
784 pSubStr = strtok_r(pPivotPtr, "/", &pSavePtr);
786 if (strncmp(pSubStr, _CERT_COMMON_NAME, strlen(_CERT_COMMON_NAME)) == 0)
788 pSubStr = pSubStr + strlen(_CERT_COMMON_NAME);
792 else if (strncmp(pSubStr, _CERT_ORG_NAME, strlen(_CERT_ORG_NAME)) == 0)
794 pSubStr = pSubStr + strlen(_CERT_ORG_NAME);
798 else if (strncmp(pSubStr, _CERT_ORG_UNIT_NAME, strlen(_CERT_ORG_UNIT_NAME)) == 0)
800 pSubStr = pSubStr + strlen(_CERT_ORG_UNIT_NAME);
804 else if (strncmp(pSubStr, _CERT_EMAIL_ADDRESS, strlen(_CERT_EMAIL_ADDRESS)) == 0)
806 pSubStr = pSubStr + strlen(_CERT_EMAIL_ADDRESS);
811 pPivotPtr = pSavePtr;
815 SysTryReturn(NID_SEC_CERT, done, E_PARSING_FAILED, E_SYSTEM, "[%s] Failed to parse Certificate title.", GetErrorMessage(E_PARSING_FAILED));
818 for (int index = 0; index < _MAX_ISSUER_SUBJECT_NAME_SIZE + 1; index++)
823 // copy title into out param
824 strncpy(title, pSubStr, strlen(pSubStr));
829 //User Certificate APIs
831 _CertManager::MakeParseAndVerifyCertChainBufferN(byte* pCertChainBuffer, int certChainLength, byte* pUserPrivateKeyBuffer, int userPrivateKeyLength, _CertChain** ppX509CertChain, _CertPrivateKeyInfo** ppX509PrivateKeyInfo)
833 result r = E_SUCCESS;
835 int currCertBufLen = 0;
836 int totCertCount = 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);
846 pCertBuf = pCertChainBuffer;
847 bufSize = certChainLength;
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.");
852 // Process Private Key
853 if (pUserPrivateKeyBuffer != null && userPrivateKeyLength > 0)
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.");
860 while (dataOffset < bufSize)
862 pCurrCertBuf = pCertBuf + dataOffset;
863 currCertBufLen = _CertManager::GetBlockSize(pCurrCertBuf);
865 dataOffset += currCertBufLen;
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.");
873 if (pPKeyInfo != null)
875 // Find Device/User Certificate
876 while (dataOffset < bufSize)
878 pCurrCertBuf = pCertBuf + dataOffset;
879 currCertBufLen = _CertManager::GetBlockSize(pCurrCertBuf);
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.");
884 r = pTmpCert->Parse(pCurrCertBuf, currCertBufLen);
885 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_DECODING_FAILED, "Failed to parse and verify certificate chain.");
887 r = _CertManager::CheckRsaPublicPrivateKeyPair(pTmpCert.get(), pPKeyInfo.get());
890 r = pCertChain->AddCertificate(pTmpCert.get());
891 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_INVALID_CONDITION, "Failed to parse and verify certificate chain.");
894 addedNumberCertificate++;
895 pUserCert = pTmpCert.release();
899 dataOffset += currCertBufLen;
902 SysTryReturnResult(NID_SEC_CERT, pubPriPair, E_INVALID_KEY, "Failed to parse and verify certificate chain.");
907 //As there is no private key present in chain, it is assumed that first certificate is user certificate
908 if (pUserCert == null)
910 pCurrCertBuf = pCertBuf + dataOffset;
911 currCertBufLen = _CertManager::GetBlockSize(pCurrCertBuf);
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.");
916 r = pUserCertAuto->Parse(pCurrCertBuf, currCertBufLen);
917 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_DECODING_FAILED, "Failed to parse first certificate in chain.");
919 r = pCertChain->AddCertificate(pUserCertAuto.get());
920 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_INVALID_CONDITION, "Failed to add first certificate in chain. ");
922 addedNumberCertificate++;
923 pUserCert = pUserCertAuto.release();
927 while (totCertCount > addedNumberCertificate)
930 countTotalCertificateChecked++;
932 if (countTotalCertificateChecked > totCertCount)
937 SysTryReturnResult(NID_SEC_CERT, pUserCert != null, E_INVALID_ARG, "Invalid certificate in chain. ");
939 while (dataOffset < bufSize)
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. ");
944 pCurrCertBuf = pCertBuf + dataOffset;
945 currCertBufLen = _CertManager::GetBlockSize(pCurrCertBuf);
947 r = pCurrentCert->Parse(pCurrCertBuf, currCertBufLen);
948 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_DECODING_FAILED, "Failed to parse certificate in chain. ");
950 if (pUserCert->IsIssuer(pCurrentCert.get()))
952 r = pCertChain->AddCertificate(pCurrentCert.get());
953 SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_INVALID_CONDITION, "Failed to add certificate in chain. ");
955 pUserCert = pCurrentCert.release();
956 addedNumberCertificate++;
960 dataOffset += currCertBufLen;
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));
968 *ppX509CertChain = pCertChain.release();
969 *ppX509PrivateKeyInfo = pPKeyInfo.release();
975 _CertManager::CheckRsaPublicPrivateKeyPair(_X509Certificate* pX509Certificate, _CertPrivateKeyInfo* pX509CertificatePrivateKey)
977 result r = E_SUCCESS;
979 EVP_PKEY* pPrivateKey = null;
980 int privateKeyLength = 0;
981 X509* pX509Cert = null;
982 const char* pSigalg = null;
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.");
987 pX509Cert = static_cast< X509* >(pX509Certificate->GetX509CertObject());
988 SysTryReturnResult(NID_SEC_CERT, pX509Cert != null, E_SYSTEM, "Failed to parse certificate. ");
991 pSigalg = OBJ_nid2ln(OBJ_obj2nid(pX509Cert->sig_alg->algorithm));
992 SysTryReturnResult(NID_SEC_CERT, pSigalg != null, E_SYSTEM, "Unable to get certificate algorithm.");
994 if (strstr(pSigalg, "WithRSA"))
996 byte* pPriKey = null;
998 pX509CertificatePrivateKey->GetPrivateKeyN(privateKeyLength, &pPriKey);
999 SysTryReturnResult(NID_SEC_CERT, pPriKey != null, E_SYSTEM, "Unable to get certificate private key.");
1001 std::unique_ptr< byte[] > pPriKeyBuf(pPriKey);
1003 pPrivateKey = d2i_PrivateKey(EVP_PKEY_RSA, null, const_cast< const unsigned char** >(static_cast< unsigned char** >(&pPriKey)), privateKeyLength);
1004 if (pPrivateKey != null)
1006 retValue = X509_check_private_key(pX509Cert, pPrivateKey);
1008 EVP_PKEY_free(pPrivateKey);
1010 SysTryReturnResult(NID_SEC_CERT, retValue == 1, E_SYSTEM, "Private public key mismatch, this key does not belong to this certificate.");
1017 SysLog(NID_SEC_CERT, "Private key conversion failed.");
1025 SysLog(NID_SEC_CERT, "Unsupported Algorithm = %s", pSigalg);
1033 _CertManager::GetCertificateSubjectNameN(CertificateHandle certificateHandle, byte** ppSubjectName, int* pSubjectNameLength)
1037 _Certificate* pTempCert = static_cast< _Certificate* >(certificateHandle);
1038 _CertFormat format = pTempCert->GetCertFormat();
1040 SysTryReturnResult(NID_SEC_CERT, format == _CERT_X509, E_INVALID_ARG, "Invalid certificate format.");
1042 _X509Certificate* pCert = static_cast< _X509Certificate* >(certificateHandle);
1043 pCert->GetIssuerBuffer(pBuf, len);
1045 *ppSubjectName = new (std::nothrow) byte[len];
1046 SysTryReturnResult(NID_SEC_CERT, *ppSubjectName != null, E_OUT_OF_MEMORY, "Failed to allocate memory. ");
1048 memset(*ppSubjectName, 0, len);
1049 memcpy(*ppSubjectName, pBuf, len);
1050 *pSubjectNameLength = len;
1056 _CertManager::GetCertificateIssuerNameN(CertificateHandle certificateHandle, byte** ppIssuerName, int* pIssuerNameLength)
1058 _Certificate* pTempCert = static_cast< _Certificate* >(certificateHandle);
1059 _CertFormat format = pTempCert->GetCertFormat();
1063 SysTryReturnResult(NID_SEC_CERT, format == _CERT_X509, E_INVALID_ARG, "Invalid certificate format.");
1065 _X509Certificate* pCert = static_cast< _X509Certificate* >(certificateHandle);
1066 pCert->GetSubjectNameBuffer(pBuf, len);
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;
1078 _CertManager::OpenUserCertificateStore(int& totalCount)
1080 result r = E_SUCCESS;
1081 UserCertRecord certRecord = {0};
1082 _CertRootList* pHoldList = null;
1083 _CertFileStore fileStore;
1084 CertificateStoreCtx certificateStoreCtx = null;
1086 char condition[_MAX_TYPE_CONST_SIZE] = {0};
1087 char installedRecord[_MAX_TYPE_RECORD_SIZE] = "T\0";
1093 sprintf(condition, "installed = '%s'", installedRecord);
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.");
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));
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.");
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.");
1107 memset(pRootCa.get(), 0, sizeof(*pRootCa.get()));
1108 pCertListFirstNode->pNext = null;
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.");
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.");
1116 pCertListFirstNode->length = certLength;
1117 pCertListFirstNode->format = (_CertFormat) certRecord.certFormat;
1119 pRootCa->pRootList = pHoldList = pCertListFirstNode.release();
1121 certificateStoreCtx = (CertificateStoreCtx) pRootCa.release();
1125 while ((pUserCertDbStore->GetNextRecordByCondition(reinterpret_cast< byte* >(condition), &certRecord, certRecord.certId)) == E_SUCCESS)
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.");
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.");
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.");
1136 pCertList->pNext = null;
1137 pCertList->length = certLength;
1138 pCertList->format = (_CertFormat) certRecord.certFormat;
1140 pHoldList->pNext = pCertList.release();
1141 pHoldList = pHoldList->pNext;
1146 SetLastResult(E_SUCCESS); //To clear the result of GetNextRecordByCondition function
1148 return certificateStoreCtx;
1153 _CertManager::OpenRootCaStore(_CaCertType type, int& totalCount) // _CERT_TYPE_TRUSTED_CA or _CERT_TYPE_ROOT_CA, ?
1155 result r = E_SUCCESS;
1156 CaCertRecord certRecord = {0};
1157 _CertRootList* pHoldList = null;
1158 _CertFileStore fileStore;
1159 CertificateStoreCtx certificateStoreCtx = null;
1161 char condition[_MAX_TYPE_CONST_SIZE] = {0};
1162 char installedRecord[_MAX_TYPE_RECORD_SIZE] = "T\0";
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.");
1171 sprintf(condition, "certType = %d and installed = '%s'", static_cast< int >(type), installedRecord);
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.");
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));
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.");
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.");
1185 memset(pRootCa.get(), 0, sizeof(*pRootCa.get()));
1186 pCertListFirstNode->pNext = null;
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.");
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.");
1194 pCertListFirstNode->length = certLength;
1195 pCertListFirstNode->format = (_CertFormat) certRecord.certFormat;
1197 pRootCa->pRootList = pHoldList = pCertListFirstNode.release();
1199 certificateStoreCtx = (CertificateStoreCtx) pRootCa.release();
1203 while ((pCaCertDbStore->GetNextRecordByCondition(reinterpret_cast< byte* >(condition), &certRecord, certRecord.certId)) == E_SUCCESS)
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.");
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.");
1213 pCertList->pNext = null;
1214 pCertList->length = certLength;
1215 pCertList->format = (_CertFormat) certRecord.certFormat;
1217 pHoldList->pNext = pCertList.release();
1218 pHoldList = pHoldList->pNext;
1223 SetLastResult(E_SUCCESS); //To clear the result of GetNextRecordByCondition function
1225 return certificateStoreCtx;
1229 enum _Asn1EncodingStyle
1231 _ASN1_ENCODING_TYPE_PRIMITIVE = 0x00,
1232 _ASN1_ENCODING_TYPE_CONSTRUCTED = 0x20,
1233 _ASN1_ENCODING_TYPE_UNKNOWN = 0xFF
1234 }; //_Asn1EncodingStyle
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;
1242 _CertManager::GetBlockSize(byte* pBuf)
1246 int contentLength = 0;
1247 _Asn1EncodingStyle encodingType = _ASN1_ENCODING_TYPE_PRIMITIVE;
1251 SysTryReturn(NID_SEC_CERT, pBuf != null, retVal, E_INVALID_ARG, "[E_INVALID_ARG] Invalid input argument.");
1253 encodingType = (_Asn1EncodingStyle) (pBuf[0] & _CERT_ASN1_ENCODING_TYPE_OFFSET_);
1255 if (pBuf[1] > _CERT_ASN1_TAG_CHECK_BIT_)
1257 // Length is in indefinite form
1258 if (pBuf[1] == _CERT_ASN1_LENGTH_CHECK_BIT_)
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.
1265 contentLength = 2; //4
1267 // Length is in Long form
1272 //STRICT: Size cannot be seven "1" bits
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.");
1276 count = (pBuf[1]) & _CERT_ASN1_TAG_CHECK_BIT_;
1278 for (lenpos = 2; lenpos < 2 + count; ++lenpos)
1280 length = (length << 8) | pBuf[lenpos];
1282 contentLength = lenpos;
1285 // Length is in short form
1292 length += contentLength;
1296 } } } //Tizen::Security::Cert