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_CertList.cpp
20 // @brief This file contains implementation of X509 Certificate list.
31 #include <openssl/x509.h>
32 #include <FBaseByteBuffer.h>
33 #include <FBaseResult.h>
34 #include <FBaseSysLog.h>
35 #include "FSecCert_CertList.h"
36 #include "FSecCert_CertOidDef.h"
38 using namespace Tizen::Base;
40 namespace Tizen { namespace Security { namespace Cert
43 // _X509RevokedCert class
45 _X509RevokedCert::_X509RevokedCert(void)
46 : __serialNumberLen(0)
48 , __pNextRevokedCert(null)
50 memset(__serialNumber, 0, _MAX_SERIAL_NUMBER_SIZE);
53 _X509RevokedCert::~_X509RevokedCert(void)
58 _X509RevokedCert::SetSerialNumber(byte* pSerial, int len)
60 memcpy(__serialNumber, pSerial, len);
61 __serialNumberLen = len;
65 _X509RevokedCert::GetSerialNumber(void)
67 return __serialNumber;
71 _X509RevokedCert::SetTime(byte* pRevocationDate)
73 _CertTime::_CertTimeType revokedTimeType = _CertTime::CERT_TIME_UTC;
74 if ((strlen(reinterpret_cast< const char* >(pRevocationDate))) == static_cast< int >(_MAX_CERT_TIME_LEN))
76 revokedTimeType = _CertTime::CERT_TIME_GENERAL;
78 __revokedTime.SetTime(revokedTimeType, pRevocationDate);
82 _X509RevokedCert::GetTime(void)
84 return __revokedTime.GetTime();
88 _X509RevokedCert::AddExt(byte* pOid, bool critical, byte* pValue, int len)
90 if (__pExtension == null)
92 __pExtension = std::unique_ptr< _CertExtension > (new (std::nothrow) _CertExtension());
93 SysTryReturn(NID_SEC_CERT, __pExtension != null, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
95 __pExtension->AddExt(pOid, critical, pValue, len);
99 _X509RevokedCert::GetExt(byte* pOid)
101 if (__pExtension != null)
103 return __pExtension->GetExt(pOid);
109 _X509RevokedCert::GetExt(_CertExt type)
111 if (__pExtension != null)
113 return __pExtension->GetExt(type);
119 _X509RevokedCert::GetExtNum(void)
121 if (__pExtension != null)
123 return __pExtension->GetExtNum();
129 _X509RevokedCert::GetExtEntry(short getId)
131 if (__pExtension != null)
133 return __pExtension->GetExtEntry(getId);
139 // _X509TBSCertList class
142 _X509TbsCertList::_X509TbsCertList(void)
144 , __pSignatureAlgoId(null)
150 _X509TbsCertList::~_X509TbsCertList(void)
152 __revokedCerts.RemoveAll(true);
156 // version Version OPTIONAL,
157 // -- if present, MUST be v2
160 _X509TbsCertList::SetVersion(byte* pVersion, int len)
162 __version = pVersion[0] + 1; // MUST be 2
170 _X509TbsCertList::GetVersion(void)
176 _X509TbsCertList::SetSignature(const char* pAlgo)
178 __pSignatureAlgoId.reset(null);
182 int size = strlen(pAlgo);
184 __pSignatureAlgoId = std::unique_ptr<char[]> (new (std::nothrow) char[size + 1]);
185 if (__pSignatureAlgoId != null)
187 memcpy(__pSignatureAlgoId.get(), pAlgo, size);
188 __pSignatureAlgoId[size] = 0x00;
195 _X509TbsCertList::GetSigature(void)
197 return __pSignatureAlgoId.get();
201 _X509TbsCertList::SetIssuerName(byte* pName)
203 __pIssuer.reset(null);
207 int len = strlen(reinterpret_cast< const char* >(pName));
208 __pIssuer = std::unique_ptr<byte[]> (new (std::nothrow) byte[len + 1]);
209 SysTryReturnResult(NID_SEC_CERT, __pIssuer != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
211 memset(__pIssuer.get(), 0, len + 1);
212 strcpy(reinterpret_cast< char* >(__pIssuer.get()), reinterpret_cast< const char* >(pName));
219 _X509TbsCertList::GetIssuerName(void)
221 return __pIssuer.get();
225 _X509TbsCertList::SetTimes(byte* pThisUpdate, byte* pNextUpdate)
227 _CertTime::_CertTimeType thisTimeType = _CertTime::CERT_TIME_UTC;
228 _CertTime::_CertTimeType nextTimeType = _CertTime::CERT_TIME_UTC;
230 if (strlen(reinterpret_cast< const char* >(pThisUpdate)) == static_cast< int >(_MAX_CERT_TIME_LEN))
232 thisTimeType = _CertTime::CERT_TIME_GENERAL;
234 __thisUpdate.SetTime(thisTimeType, pThisUpdate);
235 if (pNextUpdate != null)
237 if (strlen(reinterpret_cast< const char* >(pNextUpdate)) == static_cast< int >(_MAX_CERT_TIME_LEN))
239 nextTimeType = _CertTime::CERT_TIME_GENERAL;
241 __nextUpdate.SetTime(nextTimeType, pNextUpdate);
251 _X509TbsCertList::AddCrlEntry(_X509RevokedCert* pCrlEntry)
253 __revokedCerts.Add(pCrlEntry);
258 _X509TbsCertList::GetEntryNumber(void)
260 return __revokedCerts.GetCount();
264 _X509TbsCertList::GetEntry(int getId)
266 return reinterpret_cast<_X509RevokedCert*> (__revokedCerts.GetAt(getId));
270 _X509TbsCertList::AddExtension(byte* pOid, bool critical, byte* pValue, int len)
272 __extension.AddExt(pOid, critical, pValue, len);
278 _CertList::_CertList(void)
283 _CertList::~_CertList()
285 if (__pX509Crl != null)
287 X509_CRL_free(static_cast< X509_CRL* >(__pX509Crl));
295 _CertList::ParseAlgorithmIdentifier()
297 const char* pAlgorithmIdentifier = null;
298 X509_CRL* pX509Crl = static_cast< X509_CRL* >(__pX509Crl);
299 SysTryReturnResult(NID_SEC_CERT, pX509Crl != null, E_SYSTEM, "Initial parameters are not set");
301 pAlgorithmIdentifier = OBJ_nid2ln(OBJ_obj2nid(pX509Crl->crl->sig_alg->algorithm));
302 SysTryReturnResult(NID_SEC_CERT, pAlgorithmIdentifier != null, E_PARSING_FAILED, "Parsing of algorithm identifier of chain failed.");
304 __tbsCertList.SetSignature(pAlgorithmIdentifier);
310 _CertList::ParseIssuerName()
313 X509_CRL* pX509Crl = static_cast< X509_CRL* >(__pX509Crl);
314 SysTryReturnResult(NID_SEC_CERT, pX509Crl != null, E_SYSTEM, "Initial parameters are not set");
316 pName = reinterpret_cast< byte* >(X509_NAME_oneline(pX509Crl->crl->issuer, null, 0));
317 SysTryReturnResult(NID_SEC_CERT, pName != null, E_PARSING_FAILED, "Parsing of issuer name of chain failed.");
319 __tbsCertList.SetIssuerName(pName);
325 _CertList::ParseUpdateTimes()
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");
332 ASN1_TIME_to_generalizedtime(pX509Crl->crl->lastUpdate, &pTimeLastUpdate);
333 ASN1_TIME_to_generalizedtime(pX509Crl->crl->nextUpdate, &pTimeNextUpdate);
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.");
338 memcpy(pThisUpdate.get(), pTimeLastUpdate->data, pTimeLastUpdate->length);
339 pThisUpdate[pTimeLastUpdate->length] = 0x00;
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.");
344 memcpy(pNextUpdate.get(), pTimeNextUpdate->data, pTimeNextUpdate->length);
345 pNextUpdate[pTimeNextUpdate->length] = 0x00;
347 __tbsCertList.SetTimes(pThisUpdate.get(), pNextUpdate.get());
353 _CertList::ParseRevokedCerts()
357 bool critical = false;
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");
368 certCount = sk_X509_REVOKED_num(pX509Crl->crl->revoked);
370 for (certIndex = 0; certIndex < certCount; certIndex++)
372 pRevokedCert = sk_X509_REVOKED_value(pX509Crl->crl->revoked, certIndex);
374 if (pRevokedCert == null)
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.");
382 pNewCRLEntry->SetSerialNumber(pRevokedCert->serialNumber->data, pRevokedCert->serialNumber->length);
384 ASN1_TIME_to_generalizedtime(pRevokedCert->revocationDate, &pRevocationDate);
386 pNewCRLEntry->SetTime(pRevocationDate->data);
388 // pCrlEntryExtensions
389 SysTryReturnResult(NID_SEC_CERT, pX509Crl->crl->extensions != null, E_SUCCESS, "No extensions are present in certificates");
391 fieldCount = sk_X509_EXTENSION_num(pRevokedCert->extensions);
393 for (int i = 0; i < fieldCount; i++)
395 pExt = sk_X509_EXTENSION_value(pRevokedCert->extensions, i);
399 pOid = reinterpret_cast< byte* >(const_cast< char* >(OBJ_nid2ln(OBJ_obj2nid(pExt->object))));
401 critical = pExt->critical;
402 pValue = pExt->value->data;
403 extLen = pExt->value->length;
407 pNewCRLEntry->AddExt(pOid, critical, pValue, extLen);
411 __tbsCertList.AddCrlEntry(pNewCRLEntry.release());
418 _CertList::ParseExtensions()
422 bool critical = false;
425 X509_EXTENSION* pExt = NULL;
426 X509_CRL* pX509Crl = static_cast< X509_CRL* >(__pX509Crl);
428 SysTryReturnResult(NID_SEC_CERT, pX509Crl != null, E_SYSTEM, "Initial parameters are not set");
430 SysTryReturnResult(NID_SEC_CERT, pX509Crl->crl->extensions != null, E_SUCCESS, "No extesions are present in certificates");
432 fieldCount = sk_X509_EXTENSION_num(pX509Crl->crl->extensions);
434 for (int i = 0; i < fieldCount; i++)
436 pExt = sk_X509_EXTENSION_value(pX509Crl->crl->extensions, i);
440 pOid = reinterpret_cast< byte* >(const_cast< char* >(OBJ_nid2ln(OBJ_obj2nid(pExt->object))));
442 critical = pExt->critical;
443 pValue = pExt->value->data;
444 extLen = pExt->value->length;
449 __tbsCertList.AddExtension(pOid, critical, pValue, extLen);
453 } // End of while loop
460 _CertList::ParseSignature()
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");
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.");
472 __signatureInfo.SetSignature(pAlgorithmIdentifier, pX509Crl->signature->length, pX509Crl->signature->data);
478 _CertList::ParseObject(void)
481 X509_CRL* pX509Crl = static_cast< X509_CRL* >(__pX509Crl);
482 const unsigned char* pX509Buff = const_cast< const unsigned char* >(_pX509Buff.get());
484 SysAssertf(pX509Buff != null, "Not yet constructed. Reconstructor the object.");
486 if (pX509Crl != null)
488 X509_CRL_free(pX509Crl);
492 pBio = BIO_new(BIO_s_mem());
493 SysTryReturnResult(NID_SEC_CERT, pBio != null, E_OUT_OF_MEMORY, "Failed to allocate memory.");
495 BIO_write(pBio, pX509Buff, _x509BuffSize);
497 pX509Crl = d2i_X509_CRL_bio(pBio, null);
498 SysTryReturnResult(NID_SEC_CERT, pX509Crl != null, E_PARSING_FAILED, "Failed to decode certificate chain.");
500 __pX509Crl = pX509Crl;
504 if (ParseAlgorithmIdentifier() != E_SUCCESS)
506 return E_PARSING_FAILED;
508 if (ParseIssuerName() != E_SUCCESS)
510 return E_PARSING_FAILED;
512 if (ParseUpdateTimes() != E_SUCCESS)
514 return E_PARSING_FAILED;
516 if (ParseRevokedCerts() != E_SUCCESS)
518 return E_PARSING_FAILED;
521 if (ParseSignature() != E_SUCCESS)
523 return E_PARSING_FAILED;
529 _CertList::GetCrlBuffer(byte*& pBuf, int& bufSize)
531 SysTryReturnResult(NID_SEC_CERT, _pX509Buff != null, E_INVALID_ARG, "Initial parameters not set");
532 pBuf = _pX509Buff.get();
533 bufSize = _x509BuffSize;
538 _CertList::GetTbsCertListInstance(void)
540 return &__tbsCertList;
544 _CertList::GetSignInstance(void)
546 return &__signatureInfo;
549 } } } //Tizen::Security::Cert