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