Removed un-necessary error message
[platform/framework/native/appfw.git] / src / security / cert / FSecCert_X509CertificateStoreImpl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file                FSecCert_X509CertificateStoreImpl.cpp
20  * @brief               This is the implementation file for _X509CertificateStoreImpl class.
21  */
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <new>
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>
33
34 using namespace Tizen::Base;
35
36 namespace Tizen { namespace Security { namespace Cert
37 {
38
39 static const int _MAX_CERT_BUFFER_SIZE = 2048;
40
41 _X509CertificateStoreImpl::_X509CertificateStoreImpl(void)
42         : __certType(static_cast< int >(_CERT_TYPE_NOT_BOUNDED))
43         , __curPos(0)
44 {
45         ClearLastResult();
46
47         __pCertServiceProxy = _CertServiceProxy::GetInstance();
48         SysTryReturnVoidResult(NID_SEC_CERT, __pCertServiceProxy != null, E_SYSTEM, "[E_SYSTEM] Failed to get certificate proxy instance.");
49 }
50
51 _X509CertificateStoreImpl::~_X509CertificateStoreImpl(void)
52 {
53         if ((__certType > _CERT_TYPE_NOT_BOUNDED) && (__certType < _CERT_TYPE_MAX))
54         {
55                 __pCertServiceProxy->CloseCertificateStore(__certType);
56         }
57 }
58
59 result
60 _X509CertificateStoreImpl::GetName(String& name) const
61 {
62         result r = __pCertServiceProxy->GetName();
63         if (!IsFailed(r))
64         {
65                 name = L"CertServiceStore";
66         }
67
68         return r;
69 }
70
71 result
72 _X509CertificateStoreImpl::SetCertificateSelector(const Tizen::Security::Cert::ICertificateSelector& selector)
73 {
74         int count = 0;
75
76         CertificateType certType = (const_cast< ICertificateSelector& >(selector)).GetType();
77
78         if ((__certType > _CERT_TYPE_NOT_BOUNDED) && (__certType < _CERT_TYPE_MAX))
79         {
80                 __pCertServiceProxy->CloseCertificateStore(__certType);
81         }
82         __curPos = 0;
83
84         switch (certType)
85         {
86         case ROOT_CA:
87                 __certType = _CERT_TYPE_ROOT_CA;
88                 break;
89
90         case OPERATOR_DOMAIN:
91                 __certType = _CERT_TYPE_ROOT_DOMAIN1;
92                 break;
93
94         case TRUSTED_THIRD_PARTY_DOMAIN:
95                 __certType = _CERT_TYPE_ROOT_DOMAIN3;
96                 break;
97
98         case USER_CERT:
99                 __certType = _CERT_TYPE_USER_CERT;
100                 break;
101
102         default:
103                 SysTryReturnResult(NID_SEC_CERT, false, E_INVALID_ARG, "Invalid certificate type.");
104                 break;
105         }
106
107         return __pCertServiceProxy->OpenCertificateStoreByType(static_cast< _CaCertType >(__certType), count);
108 }
109
110 result
111 _X509CertificateStoreImpl::GetCertificateCount(int& count)
112 {
113         return __pCertServiceProxy->GetCertificateCount(__certType, count);
114 }
115
116
117 Tizen::Security::Cert::ICertificate*
118 _X509CertificateStoreImpl::GetNextCertificateN(void)
119 {
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;
125
126         ClearLastResult();
127
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));
130         __curPos = curPos;
131
132         r = certBuffer.Construct(certLen);
133         SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, r, "[%s] Failed to allocate memory.", GetErrorMessage(r));
134
135         r = certBuffer.SetArray(certBytes, 0, certLen);
136         SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM]An unexpected system error occurred.");
137
138         certBuffer.Flip();
139
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.");
142
143         r = pCert->Construct(certBuffer);
144         SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] X509Certificate instance is not constructed.");
145
146         return pCert.release();
147 }
148
149
150 result
151 _X509CertificateStoreImpl::Insert(CertificateType certificateType, const Tizen::Security::Cert::ICertificate& certificate)
152 {
153         result r = E_SUCCESS;
154         byte* pBuffer = null;
155         int bufferLen = 0;
156         _CaCertType certType = _CERT_TYPE_NOT_BOUNDED;
157
158         switch (certificateType)
159         {
160         case ROOT_CA:
161                 certType = _CERT_TYPE_ROOT_CA;
162                 break;
163
164         case OPERATOR_DOMAIN:
165                 certType = _CERT_TYPE_ROOT_DOMAIN1;
166                 break;
167
168         case TRUSTED_THIRD_PARTY_DOMAIN:
169                 certType = _CERT_TYPE_ROOT_DOMAIN3;
170                 break;
171
172         case USER_CERT:
173                 certType = _CERT_TYPE_USER_CERT;
174                 break;
175
176         default:
177                 SysTryReturnResult(NID_SEC_CERT, false, E_INVALID_ARG, "Invalid certificate type.");
178                 break;
179         }
180
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.");
183
184         pBuffer = const_cast< byte* >(pEncodedData->GetPointer());
185         SysTryReturnResult(NID_SEC_CERT, pBuffer != null, E_INVALID_ARG, "Invalid input argument passed.");
186
187         bufferLen = pEncodedData->GetRemaining();
188         SysTryReturnResult(NID_SEC_CERT, bufferLen > 0, E_INVALID_ARG, "Length value is not positive.");
189
190         if (certType == _CERT_TYPE_USER_CERT)
191         {
192                 r = __pCertServiceProxy->InsertUserCertChainPrivateKey(reinterpret_cast< char* >(pBuffer), bufferLen, null, 0);
193         }
194         else
195         {
196                 r = __pCertServiceProxy->InsertCaCertificate(static_cast< int >(certType), _CERT_X509, pBuffer, bufferLen);
197         }
198
199         if (r == E_FILE_ALREADY_EXIST)
200         {
201                 r = E_SUCCESS;
202         }
203         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to insert root certificate.", GetErrorMessage(r));
204
205         return r;
206 }
207
208 result
209 _X509CertificateStoreImpl::InsertPkcs12(const String& filePath, const String& password, bool checkPrivilege)
210 {
211         result r = E_SUCCESS;
212         std::unique_ptr< char[] > pFilePath(_StringConverter::CopyToCharArrayN(filePath));
213         std::unique_ptr< char[] > pPassword(_StringConverter::CopyToCharArrayN(password));
214
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.");
217
218         //password can be null
219         r = __pCertServiceProxy->InsertPkcs12Content(pFilePath.get(), pPassword.get(), checkPrivilege);
220         if (r == E_FILE_ALREADY_EXIST)
221         {
222                 r = E_SUCCESS;
223         }
224         SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to insert pkcs 12 user certificate.", GetErrorMessage(r));
225
226         return r;
227 }
228
229
230 result
231 _X509CertificateStoreImpl::Update(CertificateType certificateType, const Tizen::Security::Cert::ICertificate& oldCert, const Tizen::Security::Cert::ICertificate& newCert)
232 {
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;
239
240         switch (certificateType)
241         {
242         case ROOT_CA:
243                 certType = _CERT_TYPE_ROOT_CA;
244                 break;
245
246         case OPERATOR_DOMAIN:
247                 certType = _CERT_TYPE_ROOT_DOMAIN1;
248                 break;
249
250         case TRUSTED_THIRD_PARTY_DOMAIN:
251                 certType = _CERT_TYPE_ROOT_DOMAIN3;
252                 break;
253
254         case USER_CERT:
255                 certType = _CERT_TYPE_USER_CERT;
256                 break;
257
258         default:
259                 SysTryReturnResult(NID_SEC_CERT, false, E_INVALID_ARG, "Invalid certificate type.");
260                 break;
261         }
262
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.");
265
266         pOldBuffer = const_cast< byte* >(pOldEncodedData->GetPointer());
267         SysTryReturnResult(NID_SEC_CERT, pOldBuffer != null, E_INVALID_ARG, "Invalid input argument passed.");
268
269         oldBufferLen = pOldEncodedData->GetRemaining();
270         SysTryReturnResult(NID_SEC_CERT, oldBufferLen > 0, E_INVALID_ARG, "Input old certificate length is not positive.");
271
272         pOldEncodedData.reset(null);
273
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.");
276
277         pNewBuffer = const_cast< byte* >(pNewEncodedData->GetPointer());
278         SysTryReturnResult(NID_SEC_CERT, pNewBuffer != null, E_INVALID_ARG, "Invalid input argument passed.");
279
280         newBufferLen = pNewEncodedData->GetRemaining();
281         SysTryReturnResult(NID_SEC_CERT, newBufferLen > 0, E_INVALID_ARG, "Input new certificate length is not positive.");
282
283         if (certType == _CERT_TYPE_USER_CERT)
284         {
285                 CertificateHandle certHandle = 0;
286                 int certId = 0;
287
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));
290
291                 r = _CertService::GetUserCertificateId(certHandle, certId);
292
293                 _CertService::CloseCertificate(&certHandle);
294                 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to find user certificates in store.", GetErrorMessage(r));
295
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));
298
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));
301         }
302         else
303         {
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));
306         }
307
308         return r;
309 }
310
311
312 result
313 _X509CertificateStoreImpl::Remove(CertificateType certificateType, const Tizen::Security::Cert::ICertificate& certificate)
314 {
315         result r = E_SUCCESS;
316         byte* pBuffer = null;
317         int bufferLen = 0;
318         _CaCertType certType = _CERT_TYPE_NOT_BOUNDED;
319
320         switch (certificateType)
321         {
322         case ROOT_CA:
323                 certType = _CERT_TYPE_ROOT_CA;
324                 break;
325
326         case OPERATOR_DOMAIN:
327                 certType = _CERT_TYPE_ROOT_DOMAIN1;
328                 break;
329
330         case TRUSTED_THIRD_PARTY_DOMAIN:
331                 certType = _CERT_TYPE_ROOT_DOMAIN3;
332                 break;
333
334         case USER_CERT:
335                 certType = _CERT_TYPE_USER_CERT;
336                 break;
337
338         default:
339                 SysTryReturnResult(NID_SEC_CERT, false, E_INVALID_ARG, "Invalid certificate type.");
340                 break;
341         }
342
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.");
345
346         pBuffer = const_cast< byte* >(pEncodedData->GetPointer());
347         SysTryReturnResult(NID_SEC_CERT, pBuffer != null, E_INVALID_ARG, "Invalid input argument passed.");
348
349         bufferLen = pEncodedData->GetRemaining();
350         SysTryReturnResult(NID_SEC_CERT, bufferLen > 0, E_INVALID_ARG, "Input certificate length is not positive.");
351
352         if (certType == _CERT_TYPE_USER_CERT)
353         {
354                 CertificateHandle certHandle = 0;
355                 int certId = 0;
356
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));
359
360                 r = _CertService::GetUserCertificateId(certHandle, certId);
361
362                 _CertService::CloseCertificate(&certHandle);
363                 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to find user certificates in store.", GetErrorMessage(r));
364
365                 r = __pCertServiceProxy->RemoveUserCertChainByCertId(certId);
366                 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s]Failed to remove user certificates.", GetErrorMessage(r));
367         }
368         else
369         {
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));
372         }
373
374         return r;
375 }
376
377 _X509CertificateStoreImpl*
378 _X509CertificateStoreImpl::GetInstance(X509CertificateStore& x509CertificateStore)
379 {
380         return x509CertificateStore.__pX509CertificateStoreImpl;
381 }
382
383 const _X509CertificateStoreImpl*
384 _X509CertificateStoreImpl::GetInstance(const X509CertificateStore& x509CertificateStore)
385 {
386         return x509CertificateStore.__pX509CertificateStoreImpl;
387 }
388
389 int
390 InsertPkcs12Content(const char* pPath, const char* pPassword)
391 {
392         result r = E_SUCCESS;
393         _X509CertificateStoreImpl store;
394         String filePath;
395         String password;
396
397         filePath.SetCapacity(strlen(pPath) + 1);
398         password.SetCapacity(strlen(pPassword) + 1);
399
400         filePath.Format(strlen(pPath) + 1, L"%s", pPath);
401         password.Format(strlen(pPassword) + 1, L"%s", pPassword);
402
403         r = store.InsertPkcs12(filePath, password, false);
404         SysTryReturn(NID_SEC_CERT, !IsFailed(r), -1, r, "[%s] Failed to remove certificate.", GetErrorMessage(r));
405
406         return 0;
407 }
408
409
410 } } }       // Tizen::Security::Cert