Fixed Klocworks issues
[platform/framework/native/appfw.git] / src / security / cert / FSecCertX509Certificate.cpp
1 //
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Apache License, Version 2.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 /**
18  * @file                FSecCertCertificate.cpp
19  * @brief               This is the implementation file for X509Certificate class.
20  *
21  * This header file contains the implementation of X509Certificate class.
22  *
23  */
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <new>
27 #include <unique_ptr.h>
28 #include <FBaseResult.h>
29 #include <FSecCertTypes.h>
30 #include <FSecCertX509Certificate.h>
31 #include <FSecPublicKey.h>
32 #include <FBaseSysLog.h>
33 #include <FSecCert_CertService.h>
34
35
36 using namespace Tizen::Base;
37
38 namespace Tizen { namespace Security { namespace Cert
39 {
40
41 static const int _MAX_PUBLIC_KEY_BUFFER_SIZE = 4096;
42 static const int _MAX_SIGNATURE_BUFFER_SIZE = 1024;
43
44 X509Certificate::X509Certificate(void)
45         : __certHandle(0)
46         , __pX509CertificateImpl(null)
47 {
48         __certFormat = L"";
49 }
50
51 X509Certificate::~X509Certificate(void)
52 {
53
54         if (__certHandle != 0)
55         {
56                 _CertService::CloseCertificate(&__certHandle);
57         }
58
59
60 }
61
62 result
63 X509Certificate::Construct(const Tizen::Base::ByteBuffer& input)
64 {
65         result r = E_SUCCESS;
66         int length = 0;
67         byte* pBuffer = null;
68
69         SysAssertf(__certHandle == 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class");
70
71         pBuffer = const_cast< byte* >(input.GetPointer());
72         SysTryReturnResult(NID_SEC_CERT, pBuffer != null, E_INVALID_ARG, "Invalid input argument passed.");
73
74         length = input.GetRemaining();
75         SysTryReturnResult(NID_SEC_CERT, length > 0, E_INVALID_ARG, "Input  buffer length is not positive.");
76
77         r = _CertService::OpenCertificate(reinterpret_cast< char* >(pBuffer), length, &__certHandle);
78         SysTryReturnResult(NID_SEC_CERT, !IsFailed(r), E_SYSTEM, "Failed to open certificates.");
79
80         __certFormat = L"X509";
81
82         return r;
83 }
84
85 Tizen::Base::String
86 X509Certificate::GetFormat(void) const
87 {
88         ClearLastResult();
89
90         return L"X509";
91 }
92
93 CertificateType
94 X509Certificate::GetType(void) const
95 {
96         result r = E_SUCCESS;
97         CertificateType certType = UNKNOWN_TYPE;
98         _CaCertType type = _CERT_TYPE_NOT_BOUNDED;
99
100         ClearLastResult();
101
102         SysAssertf(__certHandle != 0, "Not yet constructed. Construct() should be called before use.");
103
104         r = _CertService::CheckCertType(__certHandle, &type);
105         SysTryCatch(NID_SEC_CERT, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to get certificate type.");
106
107         switch (type)
108         {
109         case _CERT_TYPE_ROOT_CA:
110         // fall through
111         case _CERT_TYPE_DEV_ROOT_CA:
112         // fall through
113         case _CERT_TYPE_ROOT_CA_BY_USER:
114                 certType = ROOT_CA;
115                 break;
116
117         case _CERT_TYPE_ROOT_DOMAIN1:
118         // fall through
119         case _CERT_TYPE_SIM_ROOT_DOMAIN1:
120         // fall through
121         case _CERT_TYPE_DEV_ROOT_DOMAIN1:
122                 certType = OPERATOR_DOMAIN;
123                 break;
124
125         case _CERT_TYPE_ROOT_DOMAIN3:
126         // fall through
127         case _CERT_TYPE_SIM_ROOT_DOMAIN3:
128         // fall through
129         case _CERT_TYPE_DEV_ROOT_DOMAIN3:
130                 certType = TRUSTED_THIRD_PARTY_DOMAIN;
131                 break;
132
133         default:
134                 certType = UNKNOWN_TYPE;
135                 break;
136         }
137 CATCH:
138         return certType;
139
140 }
141
142 ByteBuffer*
143 X509Certificate::GetEncodedDataN(void) const
144 {
145         result r = E_SUCCESS;
146         int length = 0;
147         char* pBufferValue = null;
148
149         ClearLastResult();
150
151         SysAssertf(__certHandle != 0, "Not yet constructed. Construct() should be called before use.");
152
153         r = _CertService::GetCertBufferN(__certHandle, pBufferValue, &length);
154
155         std::unique_ptr< char[] > pBuffer(pBufferValue);
156
157         SysTryReturn(NID_SEC_CERT, pBuffer != null, null, E_SYSTEM, "[E_SYSTEM] Failed to get encoded data of certificate.");
158         SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] Failed to get encoded data of certificate.");
159         SysTryReturn(NID_SEC_CERT, length > 0, null, E_SYSTEM, "[E_SYSTEM] Failed to get encoded data of certificate.");
160
161         std::unique_ptr< ByteBuffer > pEncCert(new (std::nothrow) ByteBuffer());
162         SysTryReturn(NID_SEC_CERT, pEncCert != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY]  Failed to allocate memory");
163
164         r = pEncCert->Construct(length);
165         SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, r, "[%s] Propagated.", GetErrorMessage(r));
166
167         r = pEncCert->SetArray(reinterpret_cast< byte* >(pBuffer.get()), 0, length);
168         SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
169
170         pEncCert->Flip();
171
172         return pEncCert.release();
173 }
174
175 bool
176 X509Certificate::Verify(const Tizen::Security::IPublicKey& publicKey)
177 {
178         result r = E_SUCCESS;
179         int keyLen = 0;
180         byte* pPublickey = null;
181
182         SysAssertf(__certHandle != 0, "Not yet constructed. Construct() should be called before use.");
183
184         std::unique_ptr< ByteBuffer > pPubKeyBuffer(publicKey.GetEncodedN());
185         SysTryReturn(NID_SEC_CERT, pPubKeyBuffer != null, false, GetLastResult(), "[%s] Propagated.", GetErrorMessage(GetLastResult()));
186
187         pPublickey = const_cast< byte* >(pPubKeyBuffer->GetPointer());
188         SysTryReturn(NID_SEC_CERT, pPublickey != null, false, E_INVALID_ARG, "[E_INVALID_ARG] Invalid input argument passed.");
189
190         keyLen = pPubKeyBuffer->GetRemaining();
191         SysTryReturn(NID_SEC_CERT, keyLen > 0, false, E_INVALID_ARG, "[E_INVALID_ARG] Public key buffer length is not positive.");
192
193         r = _CertService::VerifyCert(__certHandle, pPublickey, keyLen);
194         SysTryReturn(NID_SEC_CERT, !IsFailed(r), false, E_SYSTEM, "[E_SYSTEM] Certificate verification failed.");
195
196         return true;
197 }
198
199 int
200 X509Certificate::GetSpecVersion(void) const
201 {
202         ClearLastResult();
203
204         SysAssertf(__certHandle != 0, "Not yet constructed. Construct() should be called before use.");
205
206         return _CertService::GetCertVersion(__certHandle);
207
208 }
209
210 ValidityPeriod
211 X509Certificate::CheckValidityPeriod(void)
212 {
213         result r = E_SUCCESS;
214         _CertValidityType type = _CERT_VALIDITY_UNKNOWN;
215         ValidityPeriod validity = VALIDITY_PERIOD_EXPIRED;
216
217         ClearLastResult();
218
219         SysAssertf(__certHandle != 0, "Not yet constructed. Construct() should be called before use.");
220
221         r = _CertService::CheckCertValidity(__certHandle, &type);
222         SysTryCatch(NID_SEC_CERT, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to get certificate validity information.");
223
224         switch (type)
225         {
226         case _CERT_VALIDITY_VALID:
227                 validity = VALIDITY_PERIOD_VALID;
228                 break;
229
230         case _CERT_VALIDITY_EXPIRED:
231                 validity = VALIDITY_PERIOD_EXPIRED;
232                 break;
233
234         case _CERT_VALIDITY_NOT_YET_VALID:
235                 validity = VALIDITY_PERIOD_NOT_YET_VALID;
236                 break;
237
238         default:
239                 break;
240         }
241
242 CATCH:
243
244         return validity;
245 }
246
247 String
248 X509Certificate::GetSerialNumber(void) const
249 {
250         result r = E_SUCCESS;
251         _CertFieldInfos certInfo;
252         Tizen::Base::String dataString;
253
254         ClearLastResult();
255
256         SysAssertf(__certHandle != 0, "Not yet constructed. Construct() should be called before use.");
257
258         r = _CertService::GetCertInfo(__certHandle, _CERT_FIELD_SERIAL, &certInfo);
259         SysTryCatch(NID_SEC_CERT, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to get certificate serial number information.");
260
261         dataString = certInfo.serialNo;
262
263 CATCH:
264         return dataString;
265 }
266
267 String
268 X509Certificate::GetSignatureAlgorithm(void) const
269 {
270         result r = E_SUCCESS;
271         _CertFieldInfos certInfo;
272         Tizen::Base::String dataString;
273
274         ClearLastResult();
275
276         SysAssertf(__certHandle != 0, "Not yet constructed. Construct() should be called before use.");
277
278         r = _CertService::GetCertInfo(__certHandle, _CERT_FIELD_SIGALGORITHM, &certInfo);
279         SysTryCatch(NID_SEC_CERT, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to get certificate signature algorithm information.");
280
281         dataString = certInfo.sigAlgorithm;
282
283 CATCH:
284         return dataString;
285 }
286
287 String
288 X509Certificate::GetNotBefore(void) const
289 {
290         result r = E_SUCCESS;
291         _CertFieldInfos certInfo;
292         Tizen::Base::String dataString;
293
294         ClearLastResult();
295
296         SysAssertf(__certHandle != 0, "Not yet constructed. Construct() should be called before use.");
297
298         r = _CertService::GetCertInfo(__certHandle, _CERT_FIELD_VALIDITY, &certInfo);
299         SysTryCatch(NID_SEC_CERT, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to get certificate validity information.");
300
301         dataString = certInfo.validityFrom;
302
303 CATCH:
304         return dataString;
305 }
306
307 String
308 X509Certificate::GetNotAfter(void) const
309 {
310         result r = E_SUCCESS;
311         _CertFieldInfos certInfo;
312         Tizen::Base::String dataString;
313
314         ClearLastResult();
315
316         SysAssertf(__certHandle != 0, "Not yet constructed. Construct() should be called before use.");
317
318         r = _CertService::GetCertInfo(__certHandle, _CERT_FIELD_VALIDITY, &certInfo);
319         SysTryCatch(NID_SEC_CERT, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to get certificate validity information.");
320
321         dataString = certInfo.validityTo;
322
323 CATCH:
324         return dataString;
325
326 }
327
328 String
329 X509Certificate::GetSubject(void) const
330 {
331         result r = E_SUCCESS;
332         _CertFieldInfos certInfo;
333         Tizen::Base::String dataString;
334
335         ClearLastResult();
336
337         SysAssertf(__certHandle != 0, "Not yet constructed. Construct() should be called before use.");
338
339         r = _CertService::GetCertInfo(__certHandle, _CERT_FIELD_SUBJECT, &certInfo);
340         SysTryCatch(NID_SEC_CERT, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to get certificate issuer information.");
341
342         dataString = certInfo.subjectName;
343
344 CATCH:
345         return dataString;
346 }
347
348 String
349 X509Certificate::GetIssuer(void) const
350 {
351         result r = E_SUCCESS;
352         _CertFieldInfos certInfo;
353         Tizen::Base::String dataString;
354
355         ClearLastResult();
356
357         SysAssertf(__certHandle != 0, "Not yet constructed. Construct() should be called before use.");
358
359         r = _CertService::GetCertInfo(__certHandle, _CERT_FIELD_ISSUER, &certInfo);
360         SysTryCatch(NID_SEC_CERT, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to get certificate issuer information.");
361
362         dataString = certInfo.issuerName;
363
364 CATCH:
365         return dataString;
366
367 }
368
369 ByteBuffer*
370 X509Certificate::GetSignatureN(void) const
371 {
372         result r = E_SUCCESS;
373         byte buffer[_MAX_SIGNATURE_BUFFER_SIZE] = {0, };
374         int bufLen = sizeof(buffer);
375
376         ClearLastResult();
377
378         SysAssertf(__certHandle != 0, "Not yet constructed. Construct() should be called before use.");
379
380         r = _CertService::GetCertSignature(__certHandle, reinterpret_cast< char* >(buffer), &bufLen);
381         SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] Failed to get certificate signature.");
382
383         std::unique_ptr< ByteBuffer > pSignatureBuffer(new (std::nothrow) ByteBuffer());
384         SysTryReturn(NID_SEC_CERT, pSignatureBuffer != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
385
386         r = pSignatureBuffer->Construct(bufLen);
387         SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, r, "[%s] Propagated.", GetErrorMessage(r));
388
389         r = pSignatureBuffer->SetArray(static_cast< const byte* >(buffer), 0, bufLen);
390         SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
391
392         pSignatureBuffer->Flip();
393
394         return pSignatureBuffer.release();
395 }
396
397 ByteBuffer*
398 X509Certificate::GetFingerprintN(void) const
399 {
400         result r = E_SUCCESS;
401         _CertFieldInfos certInfo;
402
403         ClearLastResult();
404
405         SysAssertf(__certHandle != 0, "Not yet constructed. Construct() should be called before use.");
406
407         r = _CertService::GetCertInfo(__certHandle, _CERT_FIELD_FINGERPRINT, &certInfo);
408         SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] Failed To get certificate fingerprint information.");
409
410         std::unique_ptr< ByteBuffer > pFingerprint(new (std::nothrow) ByteBuffer());
411         SysTryReturn(NID_SEC_CERT, pFingerprint != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
412
413         r = pFingerprint->Construct(certInfo.fingerPrintLen);
414         SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, r, "[%s] Propagated.", GetErrorMessage(r));
415
416         r = pFingerprint->SetArray(reinterpret_cast< const byte* >(certInfo.fingerPrint), 0, certInfo.fingerPrintLen);
417         SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
418
419         pFingerprint->Flip();
420
421         return pFingerprint.release();
422 }
423
424 Tizen::Security::IPublicKey*
425 X509Certificate::GetPublicKeyN(void) const
426 {
427         result r = E_SUCCESS;
428         ByteBuffer keyBuffer;
429         byte buffer[_MAX_PUBLIC_KEY_BUFFER_SIZE] = {0, };
430         int bufLen = sizeof(buffer);
431
432         ClearLastResult();
433
434         SysAssertf(__certHandle != 0, "Not yet constructed. Construct() should be called before use.");
435
436         r = _CertService::GetCertPublicKey(__certHandle, reinterpret_cast< char* >(buffer), static_cast< int* >(&bufLen));
437         SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_KEY_NOT_FOUND, "[E_KEY_NOT_FOUND] Failed to get certificate public key information.");
438
439         r = keyBuffer.Construct(bufLen);
440         SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, r, "[%s] Propagated.", GetErrorMessage(r));
441
442         r = keyBuffer.SetArray(static_cast< const byte* >(buffer), 0, bufLen);
443         SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
444
445         keyBuffer.Flip();
446
447         std::unique_ptr< IPublicKey > pPubKey(dynamic_cast< IPublicKey* >(new (std::nothrow) PublicKey()));
448         SysTryReturn(NID_SEC_CERT, pPubKey != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
449
450         r = pPubKey->SetKey(keyBuffer);
451         SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
452
453         return pPubKey.release();
454 }
455
456 } } } //Tizen::Security::Cert