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_X509CertificateStoreImpl.cpp
20 * @brief This is the implementation file for _X509CertificateStoreImpl class.
25 #include <unique_ptr.h>
26 #include <FBaseResult.h>
27 #include <FSecCertX509Certificate.h>
28 #include <FBaseSysLog.h>
29 #include <FBase_StringConverter.h>
30 #include <FSecCert_CertService.h>
31 #include <FSecCert_CertServiceProxy.h>
32 #include <FSecCert_X509CertificateStoreImpl.h>
34 using namespace Tizen::Base;
36 namespace Tizen { namespace Security { namespace Cert
39 static const int _MAX_CERT_BUFFER_SIZE = 2048;
41 _X509CertificateStoreImpl::_X509CertificateStoreImpl(void)
42 : __certType(static_cast< int >(_CERT_TYPE_NOT_BOUNDED))
47 __pCertServiceProxy = _CertServiceProxy::GetInstance();
48 SysTryReturnVoidResult(NID_SEC_CERT, __pCertServiceProxy != null, E_SYSTEM, "[E_SYSTEM] Failed to get certificate proxy instance.");
51 _X509CertificateStoreImpl::~_X509CertificateStoreImpl(void)
53 if ((__certType > _CERT_TYPE_NOT_BOUNDED) && (__certType < _CERT_TYPE_MAX))
55 __pCertServiceProxy->CloseCertificateStore(__certType);
60 _X509CertificateStoreImpl::GetName(String& name) const
62 result r = __pCertServiceProxy->GetName();
65 name = L"CertServiceStore";
72 _X509CertificateStoreImpl::SetCertificateSelector(const Tizen::Security::Cert::ICertificateSelector& selector)
76 CertificateType certType = (const_cast< ICertificateSelector& >(selector)).GetType();
78 if ((__certType > _CERT_TYPE_NOT_BOUNDED) && (__certType < _CERT_TYPE_MAX))
80 __pCertServiceProxy->CloseCertificateStore(__certType);
87 __certType = _CERT_TYPE_ROOT_CA;
91 __certType = _CERT_TYPE_ROOT_DOMAIN1;
94 case TRUSTED_THIRD_PARTY_DOMAIN:
95 __certType = _CERT_TYPE_ROOT_DOMAIN3;
99 __certType = _CERT_TYPE_USER_CERT;
103 SysTryReturnResult(NID_SEC_CERT, false, E_INVALID_ARG, "Invalid certificate type.");
107 return __pCertServiceProxy->OpenCertificateStoreByType(static_cast< _CaCertType >(__certType), count);
111 _X509CertificateStoreImpl::GetCertificateCount(int& count)
113 return __pCertServiceProxy->GetCertificateCount(__certType, count);
117 Tizen::Security::Cert::ICertificate*
118 _X509CertificateStoreImpl::GetNextCertificateN(void)
120 result r = E_SUCCESS;
121 ByteBuffer certBuffer;
122 byte certBytes[_MAX_CERT_BUFFER_SIZE] = {0, };
123 int certLen = sizeof(certBytes);
124 int curPos = __curPos;
128 r = __pCertServiceProxy->GetNextCertificate(__certType, curPos, certBytes, certLen);
129 SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, r, "[%s] Failed to get next root certificate.", GetErrorMessage(r));
132 r = certBuffer.Construct(certLen);
133 SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, r, "[%s] Failed to allocate memory.", GetErrorMessage(r));
135 r = certBuffer.SetArray(certBytes, 0, certLen);
136 SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM]An unexpected system error occurred.");
140 std::unique_ptr< X509Certificate > pCert(new (std::nothrow) X509Certificate());
141 SysTryReturn(NID_SEC_CERT, pCert != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
143 r = pCert->Construct(certBuffer);
144 SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] X509Certificate instance is not constructed.");
146 return pCert.release();
151 _X509CertificateStoreImpl::Insert(CertificateType certificateType, const Tizen::Security::Cert::ICertificate& certificate)
153 result r = E_SUCCESS;
154 byte* pBuffer = null;
156 _CaCertType certType = _CERT_TYPE_NOT_BOUNDED;
158 switch (certificateType)
161 certType = _CERT_TYPE_ROOT_CA;
164 case OPERATOR_DOMAIN:
165 certType = _CERT_TYPE_ROOT_DOMAIN1;
168 case TRUSTED_THIRD_PARTY_DOMAIN:
169 certType = _CERT_TYPE_ROOT_DOMAIN3;
173 certType = _CERT_TYPE_USER_CERT;
177 SysTryReturnResult(NID_SEC_CERT, false, E_INVALID_ARG, "Invalid certificate type.");
181 std::unique_ptr< ByteBuffer > pEncodedData(certificate.GetEncodedDataN());
182 SysTryReturnResult(NID_SEC_CERT, pEncodedData != null, E_INVALID_ARG, "Failed to get encoded data on input certificate.");
184 pBuffer = const_cast< byte* >(pEncodedData->GetPointer());
185 SysTryReturnResult(NID_SEC_CERT, pBuffer != null, E_INVALID_ARG, "Invalid input argument passed.");
187 bufferLen = pEncodedData->GetRemaining();
188 SysTryReturnResult(NID_SEC_CERT, bufferLen > 0, E_INVALID_ARG, "Length value is not positive.");
190 if (certType == _CERT_TYPE_USER_CERT)
192 r = __pCertServiceProxy->InsertUserCertChainPrivateKey(reinterpret_cast< char* >(pBuffer), bufferLen, null, 0);
196 r = __pCertServiceProxy->InsertCaCertificate(static_cast< int >(certType), _CERT_X509, pBuffer, bufferLen);
199 if (r == E_FILE_ALREADY_EXIST)
203 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to insert root certificate.", GetErrorMessage(r));
209 _X509CertificateStoreImpl::InsertPkcs12(const String& filePath, const String& password, bool checkPrivilege)
211 result r = E_SUCCESS;
212 std::unique_ptr< char[] > pFilePath(_StringConverter::CopyToCharArrayN(filePath));
213 std::unique_ptr< char[] > pPassword(_StringConverter::CopyToCharArrayN(password));
215 SysTryReturnResult(NID_SEC_CERT, filePath.GetLength() > 0, E_INVALID_ARG, "Length of file path is not positive.");
216 SysTryReturnResult(NID_SEC_CERT, pFilePath != null, E_INVALID_ARG, "File path is invalid.");
218 //password can be null
219 r = __pCertServiceProxy->InsertPkcs12Content(pFilePath.get(), pPassword.get(), checkPrivilege);
220 if (r == E_FILE_ALREADY_EXIST)
224 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to insert pkcs 12 user certificate.", GetErrorMessage(r));
231 _X509CertificateStoreImpl::Update(CertificateType certificateType, const Tizen::Security::Cert::ICertificate& oldCert, const Tizen::Security::Cert::ICertificate& newCert)
233 result r = E_SUCCESS;
234 byte* pOldBuffer = null;
235 byte* pNewBuffer = null;
236 int oldBufferLen = 0;
237 int newBufferLen = 0;
238 _CaCertType certType = _CERT_TYPE_NOT_BOUNDED;
240 switch (certificateType)
243 certType = _CERT_TYPE_ROOT_CA;
246 case OPERATOR_DOMAIN:
247 certType = _CERT_TYPE_ROOT_DOMAIN1;
250 case TRUSTED_THIRD_PARTY_DOMAIN:
251 certType = _CERT_TYPE_ROOT_DOMAIN3;
255 certType = _CERT_TYPE_USER_CERT;
259 SysTryReturnResult(NID_SEC_CERT, false, E_INVALID_ARG, "Invalid certificate type.");
263 std::unique_ptr< ByteBuffer > pOldEncodedData(oldCert.GetEncodedDataN());
264 SysTryReturnResult(NID_SEC_CERT, pOldEncodedData != null, E_INVALID_ARG, "Failed to get encoded data on old input certificate.");
266 pOldBuffer = const_cast< byte* >(pOldEncodedData->GetPointer());
267 SysTryReturnResult(NID_SEC_CERT, pOldBuffer != null, E_INVALID_ARG, "Invalid input argument passed.");
269 oldBufferLen = pOldEncodedData->GetRemaining();
270 SysTryReturnResult(NID_SEC_CERT, oldBufferLen > 0, E_INVALID_ARG, "Input old certificate length is not positive.");
272 pOldEncodedData.reset(null);
274 std::unique_ptr< ByteBuffer > pNewEncodedData(newCert.GetEncodedDataN());
275 SysTryReturnResult(NID_SEC_CERT, pNewEncodedData != null, E_INVALID_ARG, "Failed to get encoded data on new input certificate.");
277 pNewBuffer = const_cast< byte* >(pNewEncodedData->GetPointer());
278 SysTryReturnResult(NID_SEC_CERT, pNewBuffer != null, E_INVALID_ARG, "Invalid input argument passed.");
280 newBufferLen = pNewEncodedData->GetRemaining();
281 SysTryReturnResult(NID_SEC_CERT, newBufferLen > 0, E_INVALID_ARG, "Input new certificate length is not positive.");
283 if (certType == _CERT_TYPE_USER_CERT)
285 CertificateHandle certHandle = 0;
288 r = _CertService::OpenCertificate(reinterpret_cast< char* >(pOldBuffer), oldBufferLen, &certHandle);
289 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to open certificates.", GetErrorMessage(r));
291 r = _CertService::GetUserCertificateId(certHandle, certId);
293 _CertService::CloseCertificate(&certHandle);
294 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to find user certificates in store.", GetErrorMessage(r));
296 r = __pCertServiceProxy->RemoveUserCertChainByCertId(certId);
297 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to remove/update user certificates from store.", GetErrorMessage(r));
299 r = __pCertServiceProxy->InsertUserCertChainPrivateKey(reinterpret_cast< char* >(pNewBuffer), newBufferLen, null, 0);
300 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to install/update user certificates.", GetErrorMessage(r));
304 r = __pCertServiceProxy->UpdateCaCertificate(static_cast< int >(certType), pOldBuffer, oldBufferLen, pNewBuffer, newBufferLen);
305 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to update certificate.", GetErrorMessage(r));
313 _X509CertificateStoreImpl::Remove(CertificateType certificateType, const Tizen::Security::Cert::ICertificate& certificate)
315 result r = E_SUCCESS;
316 byte* pBuffer = null;
318 _CaCertType certType = _CERT_TYPE_NOT_BOUNDED;
320 switch (certificateType)
323 certType = _CERT_TYPE_ROOT_CA;
326 case OPERATOR_DOMAIN:
327 certType = _CERT_TYPE_ROOT_DOMAIN1;
330 case TRUSTED_THIRD_PARTY_DOMAIN:
331 certType = _CERT_TYPE_ROOT_DOMAIN3;
335 certType = _CERT_TYPE_USER_CERT;
339 SysTryReturnResult(NID_SEC_CERT, false, E_INVALID_ARG, "Invalid certificate type.");
343 std::unique_ptr< ByteBuffer > pEncodedData(certificate.GetEncodedDataN());
344 SysTryReturnResult(NID_SEC_CERT, pEncodedData != null, E_INVALID_ARG, "Failed to get encoded data on input certificate.");
346 pBuffer = const_cast< byte* >(pEncodedData->GetPointer());
347 SysTryReturnResult(NID_SEC_CERT, pBuffer != null, E_INVALID_ARG, "Invalid input argument passed.");
349 bufferLen = pEncodedData->GetRemaining();
350 SysTryReturnResult(NID_SEC_CERT, bufferLen > 0, E_INVALID_ARG, "Input certificate length is not positive.");
352 if (certType == _CERT_TYPE_USER_CERT)
354 CertificateHandle certHandle = 0;
357 r = _CertService::OpenCertificate(reinterpret_cast< char* >(pBuffer), bufferLen, &certHandle);
358 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to open certificates.", GetErrorMessage(r));
360 r = _CertService::GetUserCertificateId(certHandle, certId);
362 _CertService::CloseCertificate(&certHandle);
363 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to find user certificates in store.", GetErrorMessage(r));
365 r = __pCertServiceProxy->RemoveUserCertChainByCertId(certId);
366 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to remove user certificates.", GetErrorMessage(r));
370 r = __pCertServiceProxy->RemoveCaCertificate(static_cast< int >(certType), pBuffer, bufferLen);
371 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to remove certificate.", GetErrorMessage(r));
377 _X509CertificateStoreImpl*
378 _X509CertificateStoreImpl::GetInstance(X509CertificateStore& x509CertificateStore)
380 return x509CertificateStore.__pX509CertificateStoreImpl;
383 const _X509CertificateStoreImpl*
384 _X509CertificateStoreImpl::GetInstance(const X509CertificateStore& x509CertificateStore)
386 return x509CertificateStore.__pX509CertificateStoreImpl;
390 InsertPkcs12Content(const char* pPath, const char* pPassword)
392 result r = E_SUCCESS;
393 _X509CertificateStoreImpl store;
397 filePath.SetCapacity(strlen(pPath) + 1);
398 password.SetCapacity(strlen(pPassword) + 1);
400 filePath.Format(strlen(pPath) + 1, L"%s", pPath);
401 password.Format(strlen(pPassword) + 1, L"%s", pPassword);
403 r = store.InsertPkcs12(filePath, password, false);
404 SysTryReturn(NID_SEC_CERT, !IsFailed(r), -1, r, "[%s] Failed to remove certificate.", GetErrorMessage(r));
410 } } } // Tizen::Security::Cert