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 FSecCertX509CertificatePath.cpp
20 * @brief This is the implementation file for X509CertificatePath class.
22 * This header file contains the implementation of X509CertificatePath class.
28 #include <unique_ptr.h>
29 #include <FBaseResult.h>
30 #include <FSecCertTypes.h>
31 #include <FSecCertX509CertificatePath.h>
32 #include <FSecCertX509Certificate.h>
33 #include <FBaseSysLog.h>
34 #include <FBase_StringConverter.h>
35 #include <FSecCert_CertService.h>
38 using namespace Tizen::Base;
40 namespace Tizen { namespace Security { namespace Cert
44 X509CertificatePath::X509CertificatePath(void)
47 , __trustAnchorIndex(-1)
48 , __pX509CertificatePathImpl(null)
53 X509CertificatePath::~X509CertificatePath(void)
57 _CertService::CloseContext(__certCtx);
62 X509CertificatePath::GetFormat(void) const
69 X509CertificatePath::AddCertificate(const Tizen::Security::Cert::ICertificate& certificate)
75 SysTryReturnResult(NID_SEC_CERT, ((certificate.GetFormat()).CompareTo(L"X509")) == 0, E_INVALID_ARG, "Certificate format is not valid.");
79 r = _CertService::OpenContext(_CERT_CONTEXT_CERT, &__certCtx);
80 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to create certificate chain context.", GetErrorMessage(r));
83 std::unique_ptr<ByteBuffer> pBuffer(certificate.GetEncodedDataN());
84 SysTryReturnResult(NID_SEC_CERT, pBuffer != null, E_INVALID_ARG, "Failed to get encoded certificate buffer.");
86 pCert = const_cast< byte* >(pBuffer->GetPointer());
87 SysTryReturnResult(NID_SEC_CERT, pCert != null, E_INVALID_ARG, "Invalid input certificate passed.");
89 certLen = pBuffer->GetRemaining();
90 SysTryReturnResult(NID_SEC_CERT, certLen > 0, E_INVALID_ARG, "Input certificate length is not positive.");
92 r = _CertService::AddCertificate(__certCtx, pCert, certLen);
93 SysTryReturn(NID_SEC_CERT, !IsFailed(r), r, r, "[%s] Failed to add certificate chain context.", GetErrorMessage(r));
101 X509CertificatePath::GetLength(void) const
104 SysTryReturn(NID_SEC_CERT, __certCtx != 0, -1, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
109 Tizen::Security::Cert::ICertificate*
110 X509CertificatePath::GetCertificateN(int nth) const
112 result r = E_SUCCESS;
113 CertificateHandle certHandle = 0;
114 char* pCertBufferValue = null;
115 ByteBuffer certInput;
120 SysTryReturn(NID_SEC_CERT, nth >= 0 && nth < __depth, null, E_INVALID_ARG, "[E_INVALID_ARG] Invalid input argument.");
121 SysTryReturn(NID_SEC_CERT, __certCtx != 0, null, E_SYSTEM, "[E_SYSTEM] Certificate list is empty, call AddCertificate() function.");
123 r = _CertService::GetNthCert(__certCtx, nth, &certHandle);
124 SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] Failed to get nth certificate.");
125 SysTryReturn(NID_SEC_CERT, certHandle != null, null, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] Certificate not found.");
127 r = _CertService::GetCertBufferN(certHandle, pCertBufferValue, &certLen);
128 std::unique_ptr< char[] > pCertBuffer(pCertBufferValue);
130 SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] Failed to get certificate buffer.");
131 SysTryReturn(NID_SEC_CERT, pCertBuffer != null, null, E_SYSTEM, "[E_SYSTEM] Failed to get certificate buffer.");
133 r = certInput.Construct(certLen);
134 SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, r, "[%s] Propagated.", GetErrorMessage(r));
136 r = certInput.SetArray(reinterpret_cast< byte* >(pCertBuffer.get()), 0, certLen);
137 SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
140 std::unique_ptr< X509Certificate > pCert(new (std::nothrow) X509Certificate());
141 SysTryReturn(NID_SEC_CERT, pCert != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
143 r = pCert->Construct(certInput);
144 SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, r, "[%s] Propagated.", GetErrorMessage(r));
146 return pCert.release();
149 Tizen::Security::Cert::ValidationResult
150 X509CertificatePath::Validate(void)
152 result r = E_SUCCESS;
154 _CertDomainType domain = _CERT_INVALID_DOMAIN;
155 Tizen::Security::Cert::ValidationResult validationResult = VALIDATION_ERROR_INVALID_PATH;
158 SysTryReturn(NID_SEC_CERT, __certCtx != 0, validationResult, E_SYSTEM, "[E_SYSTEM] Certificate list is empty, call AddCertificate() function.");
160 r = _CertService::VerifyChain(__certCtx, &domain);
164 validationResult = VALIDATION_SUCCESS;
165 SysLog(NID_SEC_CERT, "validation result = success");
168 case E_DATA_NOT_FOUND:
169 validationResult = VALIDATION_ERROR_NO_ROOT;
170 SysLog(NID_SEC_CERT, "validation result = no root cert ");
173 case E_INVALID_CERTIFICATE:
174 validationResult = VALIDATION_ERROR_CERT_EXPIRED;
175 SysLog(NID_SEC_CERT, "validation result = cert expired");
178 case E_CERTIFICATE_VERIFICATION_FAILED:
179 validationResult = VALIDATION_ERROR_INVALID_SIGNATURE;
180 SysLog(NID_SEC_CERT, "validation result = invalid signature");
184 validationResult = VALIDATION_ERROR_INVALID_PATH;
185 SysLog(NID_SEC_CERT, "validation result = invalid path");
189 SysTryReturn(NID_SEC_CERT, !IsFailed(r), validationResult, E_SYSTEM, "[E_SYSTEM] Verification of certificate chain failed.");
191 r = _CertService::GetChainDepth(__certCtx, &depth);
192 SysTryReturn(NID_SEC_CERT, !IsFailed(r), VALIDATION_ERROR_INVALID_PATH, E_SYSTEM, "[E_SYSTEM] Failed to get certificate chain depth.");
194 __trustAnchorIndex = depth - 1;
195 SysTryReturn(NID_SEC_CERT, __trustAnchorIndex > 0, VALIDATION_ERROR_INVALID_PATH, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred, trusted anchor not found.");
197 return validationResult;
201 Tizen::Security::Cert::ValidationResult
202 X509CertificatePath::Validate(const ICertificate& trustAnchor)
204 result r = E_SUCCESS;
208 r = AddCertificate(trustAnchor);
209 SysTryReturn(NID_SEC_CERT, !IsFailed(r), VALIDATION_ERROR_INVALID_PATH, r, "[%s] Failed to add certificate.", GetErrorMessage(r));
214 Tizen::Security::Cert::ICertificate*
215 X509CertificatePath::GetTrustAnchorN(void) const
217 result r = E_SUCCESS;
218 CertificateHandle certHandle = 0;
219 char* pTempCertValue = null;
221 ByteBuffer certBuffer;
225 SysTryReturn(NID_SEC_CERT, __certCtx != 0, null, E_SYSTEM, "[E_SYSTEM] Certificate list is empty, call AddCertificate() function.");
226 SysTryReturn(NID_SEC_CERT, __trustAnchorIndex != -1, null, E_SYSTEM, "[E_SYSTEM] Certificate list is empty, call Validate() function.");
228 r = _CertService::GetNthCert(__certCtx, __trustAnchorIndex, &certHandle);
229 SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] Failed to get nth certificate.");
230 SysTryReturn(NID_SEC_CERT, certHandle != null, null, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] Certificate not found.");
232 r = _CertService::GetCertBufferN(certHandle, pTempCertValue, &certLen);
234 std::unique_ptr< char[] > pTempCert(pTempCertValue);
236 SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] Failed to get certificate buffer.");
237 SysTryReturn(NID_SEC_CERT, pTempCert != null, null, E_SYSTEM, "[E_SYSTEM] Failed to get certificate buffer.");
239 r = certBuffer.Construct(certLen);
240 SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
242 r = certBuffer.SetArray(reinterpret_cast< const byte* >(pTempCert.get()), 0, certLen);
243 SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
247 std::unique_ptr< X509Certificate > pCert(new (std::nothrow) X509Certificate());
248 SysTryReturn(NID_SEC_CERT, pCert != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
250 r = pCert->Construct(certBuffer);
251 SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, r, "[%s] Propagated.", GetErrorMessage(r));
253 return pCert.release();
256 } } } // Tizen::Security::Cert