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 FSecCertX509CertificatePath.cpp
19 * @brief This is the implementation file for X509CertificatePath class.
21 * This header file contains the implementation of X509CertificatePath class.
27 #include <unique_ptr.h>
28 #include <FBaseResult.h>
29 #include <FSecCertTypes.h>
30 #include <FSecCertX509CertificatePath.h>
31 #include <FSecCertX509Certificate.h>
32 #include <FBaseSysLog.h>
33 #include <FBase_StringConverter.h>
34 #include <FSecCert_CertService.h>
37 using namespace Tizen::Base;
39 namespace Tizen { namespace Security { namespace Cert
43 X509CertificatePath::X509CertificatePath(void)
46 , __trustAnchorIndex(-1)
47 , __pX509CertificatePathImpl(null)
52 X509CertificatePath::~X509CertificatePath(void)
56 _CertService::CloseContext(__certCtx);
61 X509CertificatePath::GetFormat(void) const
68 X509CertificatePath::AddCertificate(const Tizen::Security::Cert::ICertificate& certificate)
74 SysTryReturnResult(NID_SEC_CERT, ((certificate.GetFormat()).CompareTo(L"X509")) == 0, E_INVALID_ARG, "Certificate format is not valid.");
78 r = _CertService::OpenContext(_CERT_CONTEXT_CERT, &__certCtx);
79 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to create certificate chain context.", GetErrorMessage(r));
82 std::unique_ptr< ByteBuffer > pBuffer(certificate.GetEncodedDataN());
83 SysTryReturnResult(NID_SEC_CERT, pBuffer != null, E_INVALID_ARG, "Failed to get encoded certificate buffer.");
85 pCert = const_cast< byte* >(pBuffer->GetPointer());
86 SysTryReturnResult(NID_SEC_CERT, pCert != null, E_INVALID_ARG, "Invalid input certificate passed.");
88 certLen = pBuffer->GetRemaining();
89 SysTryReturnResult(NID_SEC_CERT, certLen > 0, E_INVALID_ARG, "Input certificate length is not positive.");
91 r = _CertService::AddCertificate(__certCtx, pCert, certLen);
92 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to add certificate chain context.", GetErrorMessage(r));
100 X509CertificatePath::GetLength(void) const
103 SysTryReturn(NID_SEC_CERT, __certCtx != 0, -1, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
108 Tizen::Security::Cert::ICertificate*
109 X509CertificatePath::GetCertificateN(int nth) const
111 result r = E_SUCCESS;
112 CertificateHandle certHandle = 0;
113 char* pCertBufferValue = null;
114 ByteBuffer certInput;
119 SysTryReturn(NID_SEC_CERT, nth >= 0 && nth < __depth, null, E_INVALID_ARG, "[E_INVALID_ARG] Invalid input argument.");
120 SysTryReturn(NID_SEC_CERT, __certCtx != 0, null, E_SYSTEM, "[E_SYSTEM] Certificate list is empty, call AddCertificate() function.");
122 r = _CertService::GetNthCert(__certCtx, nth, &certHandle);
123 SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] Failed to get nth certificate.");
124 SysTryReturn(NID_SEC_CERT, certHandle != null, null, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] Certificate not found.");
126 r = _CertService::GetCertBufferN(certHandle, pCertBufferValue, &certLen);
127 std::unique_ptr< char[] > pCertBuffer(pCertBufferValue);
129 SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] Failed to get certificate buffer.");
130 SysTryReturn(NID_SEC_CERT, pCertBuffer != null, null, E_SYSTEM, "[E_SYSTEM] Failed to get certificate buffer.");
132 r = certInput.Construct(certLen);
133 SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, r, "[%s] Propagated.", GetErrorMessage(r));
135 r = certInput.SetArray(reinterpret_cast< byte* >(pCertBuffer.get()), 0, certLen);
136 SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
139 std::unique_ptr< X509Certificate > pCert(new (std::nothrow) X509Certificate());
140 SysTryReturn(NID_SEC_CERT, pCert != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
142 r = pCert->Construct(certInput);
143 SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, r, "[%s] Propagated.", GetErrorMessage(r));
145 return pCert.release();
148 Tizen::Security::Cert::ValidationResult
149 X509CertificatePath::Validate(void)
151 result r = E_SUCCESS;
153 _CertDomainType domain = _CERT_INVALID_DOMAIN;
154 Tizen::Security::Cert::ValidationResult validationResult = VALIDATION_ERROR_INVALID_PATH;
157 SysTryReturn(NID_SEC_CERT, __certCtx != 0, validationResult, E_SYSTEM, "[E_SYSTEM] Certificate list is empty, call AddCertificate() function.");
159 r = _CertService::VerifyChain(__certCtx, &domain);
163 validationResult = VALIDATION_SUCCESS;
164 SysLog(NID_SEC_CERT, "validation result = success");
167 case E_DATA_NOT_FOUND:
168 validationResult = VALIDATION_ERROR_NO_ROOT;
169 SysLog(NID_SEC_CERT, "validation result = no root cert ");
172 case E_INVALID_CERTIFICATE:
173 validationResult = VALIDATION_ERROR_CERT_EXPIRED;
174 SysLog(NID_SEC_CERT, "validation result = cert expired");
177 case E_CERTIFICATE_VERIFICATION_FAILED:
178 validationResult = VALIDATION_ERROR_INVALID_SIGNATURE;
179 SysLog(NID_SEC_CERT, "validation result = invalid signature");
183 validationResult = VALIDATION_ERROR_INVALID_PATH;
184 SysLog(NID_SEC_CERT, "validation result = invalid path");
188 SysTryReturn(NID_SEC_CERT, !IsFailed(r), validationResult, E_SYSTEM, "[E_SYSTEM] Verification of certificate chain failed.");
190 r = _CertService::GetChainDepth(__certCtx, &depth);
191 SysTryReturn(NID_SEC_CERT, !IsFailed(r), VALIDATION_ERROR_INVALID_PATH, E_SYSTEM, "[E_SYSTEM] Failed to get certificate chain depth.");
193 __trustAnchorIndex = depth - 1;
194 SysTryReturn(NID_SEC_CERT, __trustAnchorIndex > 0, VALIDATION_ERROR_INVALID_PATH, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred, trusted anchor not found.");
196 return validationResult;
200 Tizen::Security::Cert::ValidationResult
201 X509CertificatePath::Validate(const ICertificate& trustAnchor)
203 result r = E_SUCCESS;
207 r = AddCertificate(trustAnchor);
208 SysTryReturn(NID_SEC_CERT, !IsFailed(r), VALIDATION_ERROR_INVALID_PATH, r, "[%s] Failed to add certificate.", GetErrorMessage(r));
213 Tizen::Security::Cert::ICertificate*
214 X509CertificatePath::GetTrustAnchorN(void) const
216 result r = E_SUCCESS;
217 CertificateHandle certHandle = 0;
218 char* pTempCertValue = null;
220 ByteBuffer certBuffer;
224 SysTryReturn(NID_SEC_CERT, __certCtx != 0, null, E_SYSTEM, "[E_SYSTEM] Certificate list is empty, call AddCertificate() function.");
225 SysTryReturn(NID_SEC_CERT, __trustAnchorIndex != -1, null, E_SYSTEM, "[E_SYSTEM] Certificate list is empty, call Validate() function.");
227 r = _CertService::GetNthCert(__certCtx, __trustAnchorIndex, &certHandle);
228 SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] Failed to get nth certificate.");
229 SysTryReturn(NID_SEC_CERT, certHandle != null, null, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] Certificate not found.");
231 r = _CertService::GetCertBufferN(certHandle, pTempCertValue, &certLen);
233 std::unique_ptr< char[] > pTempCert(pTempCertValue);
235 SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] Failed to get certificate buffer.");
236 SysTryReturn(NID_SEC_CERT, pTempCert != null, null, E_SYSTEM, "[E_SYSTEM] Failed to get certificate buffer.");
238 r = certBuffer.Construct(certLen);
239 SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
241 r = certBuffer.SetArray(reinterpret_cast< const byte* >(pTempCert.get()), 0, certLen);
242 SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
246 std::unique_ptr< X509Certificate > pCert(new (std::nothrow) X509Certificate());
247 SysTryReturn(NID_SEC_CERT, pCert != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
249 r = pCert->Construct(certBuffer);
250 SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, r, "[%s] Propagated.", GetErrorMessage(r));
252 return pCert.release();
255 } } } // Tizen::Security::Cert