2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
8 // http://www.apache.org/licenses/LICENSE-2.0
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.
18 // @file FSecCert_CertList.cpp
19 // @brief This file contains implementation of X509 Certificate list.
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"
37 using namespace Tizen::Base;
39 namespace Tizen { namespace Security { namespace Cert
42 // _X509RevokedCert class
44 _X509RevokedCert::_X509RevokedCert(void)
45 : __serialNumberLen(0)
47 , __pNextRevokedCert(null)
49 memset(__serialNumber, 0, _MAX_SERIAL_NUMBER_SIZE);
52 _X509RevokedCert::~_X509RevokedCert(void)
57 _X509RevokedCert::SetSerialNumber(byte* pSerial, int len)
59 memcpy(__serialNumber, pSerial, len);
60 __serialNumberLen = len;
64 _X509RevokedCert::GetSerialNumber(void)
66 return __serialNumber;
70 _X509RevokedCert::SetTime(byte* pRevocationDate)
72 _CertTime::_CertTimeType revokedTimeType = _CertTime::CERT_TIME_UTC;
73 if ((strlen(reinterpret_cast< const char* >(pRevocationDate))) == static_cast< int >(_MAX_CERT_TIME_LEN))
75 revokedTimeType = _CertTime::CERT_TIME_GENERAL;
77 __revokedTime.SetTime(revokedTimeType, pRevocationDate);
81 _X509RevokedCert::GetTime(void)
83 return __revokedTime.GetTime();
87 _X509RevokedCert::AddExt(byte* pOid, bool critical, byte* pValue, int len)
89 if (__pExtension == null)
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.");
94 __pExtension->AddExt(pOid, critical, pValue, len);
98 _X509RevokedCert::GetExt(byte* pOid)
100 if (__pExtension != null)
102 return __pExtension->GetExt(pOid);
108 _X509RevokedCert::GetExt(_CertExt type)
110 if (__pExtension != null)
112 return __pExtension->GetExt(type);
118 _X509RevokedCert::GetExtNum(void)
120 if (__pExtension != null)
122 return __pExtension->GetExtNum();
128 _X509RevokedCert::GetExtEntry(short getId)
130 if (__pExtension != null)
132 return __pExtension->GetExtEntry(getId);
138 // _X509TBSCertList class
141 _X509TbsCertList::_X509TbsCertList(void)
143 , __pSignatureAlgoId(null)
149 _X509TbsCertList::~_X509TbsCertList(void)
151 __revokedCerts.RemoveAll(true);
155 // version Version OPTIONAL,
156 // -- if present, MUST be v2
159 _X509TbsCertList::SetVersion(byte* pVersion, int len)
161 __version = pVersion[0] + 1; // MUST be 2
169 _X509TbsCertList::GetVersion(void)
175 _X509TbsCertList::SetSignature(const char* pAlgo)
177 __pSignatureAlgoId.reset(null);
181 int size = strlen(pAlgo);
183 __pSignatureAlgoId = std::unique_ptr< char[] >(new (std::nothrow) char[size + 1]);
184 if (__pSignatureAlgoId != null)
186 memcpy(__pSignatureAlgoId.get(), pAlgo, size);
187 __pSignatureAlgoId[size] = 0x00;
194 _X509TbsCertList::GetSigature(void)
196 return __pSignatureAlgoId.get();
200 _X509TbsCertList::SetIssuerName(byte* pName)
202 __pIssuer.reset(null);
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.");
210 memset(__pIssuer.get(), 0, len + 1);
211 strcpy(reinterpret_cast< char* >(__pIssuer.get()), reinterpret_cast< const char* >(pName));
218 _X509TbsCertList::GetIssuerName(void)
220 return __pIssuer.get();
224 _X509TbsCertList::SetTimes(byte* pThisUpdate, byte* pNextUpdate)
226 _CertTime::_CertTimeType thisTimeType = _CertTime::CERT_TIME_UTC;
227 _CertTime::_CertTimeType nextTimeType = _CertTime::CERT_TIME_UTC;
229 if (strlen(reinterpret_cast< const char* >(pThisUpdate)) == static_cast< int >(_MAX_CERT_TIME_LEN))
231 thisTimeType = _CertTime::CERT_TIME_GENERAL;
233 __thisUpdate.SetTime(thisTimeType, pThisUpdate);
234 if (pNextUpdate != null)
236 if (strlen(reinterpret_cast< const char* >(pNextUpdate)) == static_cast< int >(_MAX_CERT_TIME_LEN))
238 nextTimeType = _CertTime::CERT_TIME_GENERAL;
240 __nextUpdate.SetTime(nextTimeType, pNextUpdate);
250 _X509TbsCertList::AddCrlEntry(_X509RevokedCert* pCrlEntry)
252 __revokedCerts.Add(pCrlEntry);
257 _X509TbsCertList::GetEntryNumber(void)
259 return __revokedCerts.GetCount();
263 _X509TbsCertList::GetEntry(int getId)
265 return reinterpret_cast< _X509RevokedCert* >(__revokedCerts.GetAt(getId));
269 _X509TbsCertList::AddExtension(byte* pOid, bool critical, byte* pValue, int len)
271 __extension.AddExt(pOid, critical, pValue, len);
277 _CertList::_CertList(void)
282 _CertList::~_CertList()
284 if (__pX509Crl != null)
286 X509_CRL_free(static_cast< X509_CRL* >(__pX509Crl));
294 _CertList::ParseAlgorithmIdentifier()
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");
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.");
303 __tbsCertList.SetSignature(pAlgorithmIdentifier);
309 _CertList::ParseIssuerName()
312 X509_CRL* pX509Crl = static_cast< X509_CRL* >(__pX509Crl);
313 SysTryReturnResult(NID_SEC_CERT, pX509Crl != null, E_SYSTEM, "Initial parameters are not set");
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.");
318 __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