Merge "Beautified source code of appfw/src/base/utility" into tizen_2.2
[platform/framework/native/appfw.git] / src / security / cert / FSecCert_CertList.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                FSecCert_CertList.cpp
19 // @brief               This file contains implementation of X509 Certificate list.
20 //
21 #include <stdio.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include <error.h>
25 #include <memory.h>
26 #include <new>
27 #include <sys/stat.h>
28 #include <assert.h>
29 #include <dirent.h>
30 #include <openssl/x509.h>
31 #include <FBaseByteBuffer.h>
32 #include <FBaseResult.h>
33 #include <FBaseSysLog.h>
34 #include "FSecCert_CertList.h"
35 #include "FSecCert_CertOidDef.h"
36
37 using namespace Tizen::Base;
38
39 namespace Tizen { namespace Security { namespace Cert
40 {
41 //
42 // _X509RevokedCert class
43 //
44 _X509RevokedCert::_X509RevokedCert(void)
45         : __serialNumberLen(0)
46         , __pExtension(null)
47         , __pNextRevokedCert(null)
48 {
49         memset(__serialNumber, 0, _MAX_SERIAL_NUMBER_SIZE);
50 }
51
52 _X509RevokedCert::~_X509RevokedCert(void)
53 {
54 }
55
56 void
57 _X509RevokedCert::SetSerialNumber(byte* pSerial, int len)
58 {
59         memcpy(__serialNumber, pSerial, len);
60         __serialNumberLen = len;
61 }
62
63 byte*
64 _X509RevokedCert::GetSerialNumber(void)
65 {
66         return __serialNumber;
67 }
68
69 void
70 _X509RevokedCert::SetTime(byte* pRevocationDate)
71 {
72         _CertTime::_CertTimeType revokedTimeType = _CertTime::CERT_TIME_UTC;
73         if ((strlen(reinterpret_cast< const char* >(pRevocationDate))) == static_cast< int >(_MAX_CERT_TIME_LEN))
74         {
75                 revokedTimeType = _CertTime::CERT_TIME_GENERAL;
76         }
77         __revokedTime.SetTime(revokedTimeType, pRevocationDate);
78 }
79
80 byte*
81 _X509RevokedCert::GetTime(void)
82 {
83         return __revokedTime.GetTime();
84 }
85
86 void
87 _X509RevokedCert::AddExt(byte* pOid, bool critical, byte* pValue, int len)
88 {
89         if (__pExtension == null)
90         {
91                 __pExtension = std::unique_ptr< _CertExtension >(new (std::nothrow) _CertExtension());
92                 SysTryReturn(NID_SEC_CERT, __pExtension != null, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
93         }
94         __pExtension->AddExt(pOid, critical, pValue, len);
95 }
96
97 _CertExtensionInfo*
98 _X509RevokedCert::GetExt(byte* pOid)
99 {
100         if (__pExtension != null)
101         {
102                 return __pExtension->GetExt(pOid);
103         }
104         return null;
105 }
106
107 _CertExtensionInfo*
108 _X509RevokedCert::GetExt(_CertExt type)
109 {
110         if (__pExtension != null)
111         {
112                 return __pExtension->GetExt(type);
113         }
114         return null;
115 }
116
117 short
118 _X509RevokedCert::GetExtNum(void)
119 {
120         if (__pExtension != null)
121         {
122                 return __pExtension->GetExtNum();
123         }
124         return 0;
125 }
126
127 _CertExtensionInfo*
128 _X509RevokedCert::GetExtEntry(short getId)
129 {
130         if (__pExtension != null)
131         {
132                 return __pExtension->GetExtEntry(getId);
133         }
134         return null;
135 }
136
137 //
138 // _X509TBSCertList class
139 //
140
141 _X509TbsCertList::_X509TbsCertList(void)
142         : __version(1)
143         , __pSignatureAlgoId(null)
144         , __pIssuer(null)
145 {
146
147 }
148
149 _X509TbsCertList::~_X509TbsCertList(void)
150 {
151         __revokedCerts.RemoveAll(true);
152 }
153
154 //
155 //  version                 Version OPTIONAL,
156 //                               -- if present, MUST be v2
157 //
158 void
159 _X509TbsCertList::SetVersion(byte* pVersion, int len)
160 {
161         __version = pVersion[0] + 1;   // MUST be 2
162         if (__version != 2)
163         {
164                 __version = 2;
165         }
166 }
167
168 int
169 _X509TbsCertList::GetVersion(void)
170 {
171         return __version;
172 }
173
174 void
175 _X509TbsCertList::SetSignature(const char* pAlgo)
176 {
177         __pSignatureAlgoId.reset(null);
178
179         if (pAlgo != null)
180         {
181                 int size = strlen(pAlgo);
182
183                 __pSignatureAlgoId = std::unique_ptr< char[] >(new (std::nothrow) char[size + 1]);
184                 if (__pSignatureAlgoId != null)
185                 {
186                         memcpy(__pSignatureAlgoId.get(), pAlgo, size);
187                         __pSignatureAlgoId[size] = 0x00;
188                 }
189
190         }
191 }
192
193 char*
194 _X509TbsCertList::GetSigature(void)
195 {
196         return __pSignatureAlgoId.get();
197 }
198
199 result
200 _X509TbsCertList::SetIssuerName(byte* pName)
201 {
202         __pIssuer.reset(null);
203
204         if (pName != null)
205         {
206                 int len = strlen(reinterpret_cast< const char* >(pName));
207                 __pIssuer = std::unique_ptr< byte[] >(new (std::nothrow) byte[len + 1]);
208                 SysTryReturnResult(NID_SEC_CERT, __pIssuer != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
209
210                 memset(__pIssuer.get(), 0, len + 1);
211                 strcpy(reinterpret_cast< char* >(__pIssuer.get()), reinterpret_cast< const char* >(pName));
212         }
213
214         return E_SUCCESS;
215 }
216
217 byte*
218 _X509TbsCertList::GetIssuerName(void)
219 {
220         return __pIssuer.get();
221 }
222
223 result
224 _X509TbsCertList::SetTimes(byte* pThisUpdate, byte* pNextUpdate)
225 {
226         _CertTime::_CertTimeType thisTimeType = _CertTime::CERT_TIME_UTC;
227         _CertTime::_CertTimeType nextTimeType = _CertTime::CERT_TIME_UTC;
228
229         if (strlen(reinterpret_cast< const char* >(pThisUpdate)) == static_cast< int >(_MAX_CERT_TIME_LEN))
230         {
231                 thisTimeType = _CertTime::CERT_TIME_GENERAL;
232         }
233         __thisUpdate.SetTime(thisTimeType, pThisUpdate);
234         if (pNextUpdate != null)
235         {
236                 if (strlen(reinterpret_cast< const char* >(pNextUpdate)) == static_cast< int >(_MAX_CERT_TIME_LEN))
237                 {
238                         nextTimeType = _CertTime::CERT_TIME_GENERAL;
239                 }
240                 __nextUpdate.SetTime(nextTimeType, pNextUpdate);
241         }
242         else
243         {
244                 pNextUpdate = null;
245         }
246         return E_SUCCESS;
247 }
248
249 void
250 _X509TbsCertList::AddCrlEntry(_X509RevokedCert* pCrlEntry)
251 {
252         __revokedCerts.Add(pCrlEntry);
253 }
254
255
256 int
257 _X509TbsCertList::GetEntryNumber(void)
258 {
259         return __revokedCerts.GetCount();
260 }
261
262 _X509RevokedCert*
263 _X509TbsCertList::GetEntry(int getId)
264 {
265         return reinterpret_cast< _X509RevokedCert* >(__revokedCerts.GetAt(getId));
266 }
267
268 void
269 _X509TbsCertList::AddExtension(byte* pOid, bool critical, byte* pValue, int len)
270 {
271         __extension.AddExt(pOid, critical, pValue, len);
272 }
273
274 //
275 // _CertList class
276 //
277 _CertList::_CertList(void)
278         : __pX509Crl(null)
279 {
280 }
281
282 _CertList::~_CertList()
283 {
284         if (__pX509Crl != null)
285         {
286                 X509_CRL_free(static_cast< X509_CRL* >(__pX509Crl));
287         }
288
289 }
290
291
292
293 result
294 _CertList::ParseAlgorithmIdentifier()
295 {
296         const char* pAlgorithmIdentifier = null;
297         X509_CRL* pX509Crl = static_cast< X509_CRL* >(__pX509Crl);
298         SysTryReturnResult(NID_SEC_CERT, pX509Crl != null, E_SYSTEM, "Initial parameters are not set");
299
300         pAlgorithmIdentifier = OBJ_nid2ln(OBJ_obj2nid(pX509Crl->crl->sig_alg->algorithm));
301         SysTryReturnResult(NID_SEC_CERT, pAlgorithmIdentifier != null, E_PARSING_FAILED, "Parsing of algorithm identifier of chain failed.");
302
303         __tbsCertList.SetSignature(pAlgorithmIdentifier);
304
305         return E_SUCCESS;
306 }
307
308 result
309 _CertList::ParseIssuerName()
310 {
311         byte* pName = null;
312         X509_CRL* pX509Crl = static_cast< X509_CRL* >(__pX509Crl);
313         SysTryReturnResult(NID_SEC_CERT, pX509Crl != null, E_SYSTEM, "Initial parameters are not set");
314
315         pName = reinterpret_cast< byte* >(X509_NAME_oneline(pX509Crl->crl->issuer, null, 0));
316         SysTryReturnResult(NID_SEC_CERT, pName != null, E_PARSING_FAILED, "Parsing of issuer name of chain failed.");
317
318         __tbsCertList.SetIssuerName(pName);
319
320         free(pName);
321         return E_SUCCESS;
322 }
323
324 result
325 _CertList::ParseUpdateTimes()
326 {
327         ASN1_GENERALIZEDTIME* pTimeLastUpdate = NULL;
328         ASN1_GENERALIZEDTIME* pTimeNextUpdate = NULL;
329         X509_CRL* pX509Crl = static_cast< X509_CRL* >(__pX509Crl);
330         SysTryReturnResult(NID_SEC_CERT, pX509Crl != null, E_SYSTEM, "Initial parameters are not set");
331
332         ASN1_TIME_to_generalizedtime(pX509Crl->crl->lastUpdate, &pTimeLastUpdate);
333         ASN1_TIME_to_generalizedtime(pX509Crl->crl->nextUpdate, &pTimeNextUpdate);
334
335         std::unique_ptr< byte[] > pThisUpdate(new (std::nothrow) byte[pTimeLastUpdate->length + 1]);
336         SysTryReturnResult(NID_SEC_CERT, pThisUpdate != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
337
338         memcpy(pThisUpdate.get(), pTimeLastUpdate->data, pTimeLastUpdate->length);
339         pThisUpdate[pTimeLastUpdate->length] = 0x00;
340
341         std::unique_ptr< byte[] > pNextUpdate(new (std::nothrow) byte[pTimeNextUpdate->length + 1]);
342         SysTryReturnResult(NID_SEC_CERT, pNextUpdate != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
343
344         memcpy(pNextUpdate.get(), pTimeNextUpdate->data, pTimeNextUpdate->length);
345         pNextUpdate[pTimeNextUpdate->length] = 0x00;
346
347         __tbsCertList.SetTimes(pThisUpdate.get(), pNextUpdate.get());
348
349         return E_SUCCESS;
350 }
351
352 result
353 _CertList::ParseRevokedCerts()
354 {
355         byte* pValue = null;
356         byte* pOid = null;
357         bool critical = false;
358         int fieldCount = 0;
359         int extLen = 0;
360         int certCount = 0;
361         int certIndex = 0;
362         X509_REVOKED* pRevokedCert = null;
363         ASN1_GENERALIZEDTIME* pRevocationDate = null;
364         X509_EXTENSION* pExt = NULL;
365         X509_CRL* pX509Crl = static_cast< X509_CRL* >(__pX509Crl);
366         SysTryReturnResult(NID_SEC_CERT, pX509Crl != null, E_SYSTEM, "Initial parameters are not set");
367
368         certCount = sk_X509_REVOKED_num(pX509Crl->crl->revoked);
369
370         for (certIndex = 0; certIndex < certCount; certIndex++)
371         {
372                 pRevokedCert = sk_X509_REVOKED_value(pX509Crl->crl->revoked, certIndex);
373
374                 if (pRevokedCert == null)
375                 {
376                         continue;
377                 }
378
379                 std::unique_ptr< _X509RevokedCert > pNewCRLEntry(new (std::nothrow) _X509RevokedCert());
380                 SysTryReturnResult(NID_SEC_CERT, pNewCRLEntry != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
381
382                 pNewCRLEntry->SetSerialNumber(pRevokedCert->serialNumber->data, pRevokedCert->serialNumber->length);
383
384                 ASN1_TIME_to_generalizedtime(pRevokedCert->revocationDate, &pRevocationDate);
385
386                 pNewCRLEntry->SetTime(pRevocationDate->data);
387
388                 // pCrlEntryExtensions
389                 SysTryReturnResult(NID_SEC_CERT, pX509Crl->crl->extensions != null, E_SUCCESS, "No extensions are present in certificates");
390
391                 fieldCount = sk_X509_EXTENSION_num(pRevokedCert->extensions);
392
393                 for (int i = 0; i < fieldCount; i++)
394                 {
395                         pExt = sk_X509_EXTENSION_value(pRevokedCert->extensions, i);
396
397                         if (pExt != null)
398                         {
399                                 pOid = reinterpret_cast< byte* >(const_cast< char* >(OBJ_nid2ln(OBJ_obj2nid(pExt->object))));
400
401                                 critical = pExt->critical;
402                                 pValue = pExt->value->data;
403                                 extLen = pExt->value->length;
404
405                                 if (pOid != null)
406                                 {
407                                         pNewCRLEntry->AddExt(pOid, critical, pValue, extLen);
408                                 }
409                         }
410                 }
411                 __tbsCertList.AddCrlEntry(pNewCRLEntry.release());
412         }
413
414         return E_SUCCESS;
415 }
416
417 result
418 _CertList::ParseExtensions()
419 {
420         byte* pValue = null;
421         byte* pOid = null;
422         bool critical = false;
423         int fieldCount = 0;
424         int extLen = 0;
425         X509_EXTENSION* pExt = NULL;
426         X509_CRL* pX509Crl = static_cast< X509_CRL* >(__pX509Crl);
427
428         SysTryReturnResult(NID_SEC_CERT, pX509Crl != null, E_SYSTEM, "Initial parameters are not set");
429
430         SysTryReturnResult(NID_SEC_CERT, pX509Crl->crl->extensions != null, E_SUCCESS, "No extesions are present in certificates");
431
432         fieldCount = sk_X509_EXTENSION_num(pX509Crl->crl->extensions);
433
434         for (int i = 0; i < fieldCount; i++)
435         {
436                 pExt = sk_X509_EXTENSION_value(pX509Crl->crl->extensions, i);
437
438                 if (pExt != null)
439                 {
440                         pOid = reinterpret_cast< byte* >(const_cast< char* >(OBJ_nid2ln(OBJ_obj2nid(pExt->object))));
441
442                         critical = pExt->critical;
443                         pValue = pExt->value->data;
444                         extLen = pExt->value->length;
445
446
447                         if (pOid != null)
448                         {
449                                 __tbsCertList.AddExtension(pOid, critical, pValue, extLen);
450                         }
451                 }
452
453         } // End of while loop
454
455         return E_SUCCESS;
456
457 }
458
459 result
460 _CertList::ParseSignature()
461 {
462         result r = E_PARSING_FAILED;
463         const char* pAlgorithmIdentifier = null;
464         X509_CRL* pX509Crl = static_cast< X509_CRL* >(__pX509Crl);
465         SysTryReturnResult(NID_SEC_CERT, pX509Crl != null, E_SYSTEM, "Initial parameters are not set");
466
467         // get SEQUENCE
468         pAlgorithmIdentifier = OBJ_nid2ln(OBJ_obj2nid(pX509Crl->sig_alg->algorithm));
469         SysTryReturnResult(NID_SEC_CERT, pAlgorithmIdentifier != null, E_SYSTEM, "Signature algorithm not present in certificate list.");
470         SysTryReturnResult(NID_SEC_CERT, pX509Crl->signature->data != null, E_SYSTEM, "Signature data not present in certificate list.");
471
472         __signatureInfo.SetSignature(pAlgorithmIdentifier, pX509Crl->signature->length, pX509Crl->signature->data);
473
474         return r;
475 }
476
477 result
478 _CertList::ParseObject(void)
479 {
480         BIO* pBio = null;
481         X509_CRL* pX509Crl = static_cast< X509_CRL* >(__pX509Crl);
482         const unsigned char* pX509Buff = const_cast< const unsigned char* >(_pX509Buff.get());
483
484         SysAssertf(pX509Buff != null, "Not yet constructed. Reconstructor the object.");
485
486         if (pX509Crl != null)
487         {
488                 X509_CRL_free(pX509Crl);
489                 __pX509Crl = null;
490         }
491
492         pBio = BIO_new(BIO_s_mem());
493         SysTryReturnResult(NID_SEC_CERT, pBio != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
494
495         BIO_write(pBio, pX509Buff, _x509BuffSize);
496
497         pX509Crl = d2i_X509_CRL_bio(pBio, null);
498         SysTryReturnResult(NID_SEC_CERT, pX509Crl != null, E_PARSING_FAILED, "Failed to decode certificate chain.");
499
500         __pX509Crl = pX509Crl;
501
502         BIO_free(pBio);
503
504         if (ParseAlgorithmIdentifier() != E_SUCCESS)
505         {
506                 return E_PARSING_FAILED;
507         }
508         if (ParseIssuerName() != E_SUCCESS)
509         {
510                 return E_PARSING_FAILED;
511         }
512         if (ParseUpdateTimes() != E_SUCCESS)
513         {
514                 return E_PARSING_FAILED;
515         }
516         if (ParseRevokedCerts() != E_SUCCESS)
517         {
518                 return E_PARSING_FAILED;
519         }
520
521         if (ParseSignature() != E_SUCCESS)
522         {
523                 return E_PARSING_FAILED;
524         }
525         return E_SUCCESS;
526 }
527
528 result
529 _CertList::GetCrlBuffer(byte*& pBuf, int& bufSize)
530 {
531         SysTryReturnResult(NID_SEC_CERT, _pX509Buff != null, E_INVALID_ARG, "Initial parameters not set");
532         pBuf = _pX509Buff.get();
533         bufSize = _x509BuffSize;
534         return E_SUCCESS;
535 }
536
537 _X509TbsCertList*
538 _CertList::GetTbsCertListInstance(void)
539 {
540         return &__tbsCertList;
541 }
542
543 _CertSignature*
544 _CertList::GetSignInstance(void)
545 {
546         return &__signatureInfo;
547 }
548
549 } } } //Tizen::Security::Cert