Fix the boiler plate codes
[platform/framework/native/appfw.git] / src / security / cert / FSecCertX509CertificatePath.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                FSecCertX509CertificatePath.cpp
19  * @brief               This is the implementation file for X509CertificatePath class.
20  *
21  * This header file contains the implementation of X509CertificatePath class.
22  *
23  */
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <new>
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>
35
36
37 using namespace Tizen::Base;
38
39 namespace Tizen { namespace Security { namespace Cert
40 {
41
42
43 X509CertificatePath::X509CertificatePath(void)
44         : __certCtx(0)
45         , __depth(0)
46         , __trustAnchorIndex(-1)
47         , __pX509CertificatePathImpl(null)
48 {
49
50 }
51
52 X509CertificatePath::~X509CertificatePath(void)
53 {
54         if (__certCtx != 0)
55         {
56                 _CertService::CloseContext(__certCtx);
57         }
58 }
59
60 Tizen::Base::String
61 X509CertificatePath::GetFormat(void) const
62 {
63         ClearLastResult();
64         return L"X509";
65 }
66
67 result
68 X509CertificatePath::AddCertificate(const Tizen::Security::Cert::ICertificate& certificate)
69 {
70         result r = E_SUCCESS;
71         byte* pCert = null;
72         int certLen = 0;
73
74         SysTryReturnResult(NID_SEC_CERT, ((certificate.GetFormat()).CompareTo(L"X509")) == 0, E_INVALID_ARG, "Certificate format is not valid.");
75
76         if (__certCtx == 0)
77         {
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));
80         }
81
82         std::unique_ptr< ByteBuffer > pBuffer(certificate.GetEncodedDataN());
83         SysTryReturnResult(NID_SEC_CERT, pBuffer != null, E_INVALID_ARG, "Failed to get encoded certificate buffer.");
84
85         pCert = const_cast< byte* >(pBuffer->GetPointer());
86         SysTryReturnResult(NID_SEC_CERT, pCert != null, E_INVALID_ARG, "Invalid input certificate passed.");
87
88         certLen = pBuffer->GetRemaining();
89         SysTryReturnResult(NID_SEC_CERT, certLen > 0, E_INVALID_ARG, "Input certificate length is not positive.");
90
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));
93
94         __depth++;
95
96         return r;
97 }
98
99 int
100 X509CertificatePath::GetLength(void) const
101 {
102         ClearLastResult();
103         SysTryReturn(NID_SEC_CERT, __certCtx != 0, -1, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
104         return __depth;
105
106 }
107
108 Tizen::Security::Cert::ICertificate*
109 X509CertificatePath::GetCertificateN(int nth) const
110 {
111         result r = E_SUCCESS;
112         CertificateHandle certHandle = 0;
113         char* pCertBufferValue = null;
114         ByteBuffer certInput;
115         int certLen = 0;
116
117         ClearLastResult();
118
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.");
121
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.");
125
126         r = _CertService::GetCertBufferN(certHandle, pCertBufferValue, &certLen);
127         std::unique_ptr< char[] > pCertBuffer(pCertBufferValue);
128
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.");
131
132         r = certInput.Construct(certLen);
133         SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, r, "[%s] Propagated.", GetErrorMessage(r));
134
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.");
137         certInput.Flip();
138
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.");
141
142         r = pCert->Construct(certInput);
143         SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, r, "[%s] Propagated.", GetErrorMessage(r));
144
145         return pCert.release();
146 }
147
148 Tizen::Security::Cert::ValidationResult
149 X509CertificatePath::Validate(void)
150 {
151         result r = E_SUCCESS;
152         int depth = 0;
153         _CertDomainType domain = _CERT_INVALID_DOMAIN;
154         Tizen::Security::Cert::ValidationResult validationResult = VALIDATION_ERROR_INVALID_PATH;
155         ClearLastResult();
156
157         SysTryReturn(NID_SEC_CERT, __certCtx != 0, validationResult, E_SYSTEM, "[E_SYSTEM] Certificate list is empty, call AddCertificate() function.");
158
159         r = _CertService::VerifyChain(__certCtx, &domain);
160         switch (r)
161         {
162         case E_SUCCESS:
163                 validationResult = VALIDATION_SUCCESS;
164                 SysLog(NID_SEC_CERT, "validation result = success");
165                 break;
166
167         case E_DATA_NOT_FOUND:
168                 validationResult = VALIDATION_ERROR_NO_ROOT;
169                 SysLog(NID_SEC_CERT, "validation result = no root cert ");
170                 break;
171
172         case E_INVALID_CERTIFICATE:
173                 validationResult = VALIDATION_ERROR_CERT_EXPIRED;
174                 SysLog(NID_SEC_CERT, "validation result = cert expired");
175                 break;
176
177         case E_CERTIFICATE_VERIFICATION_FAILED:
178                 validationResult = VALIDATION_ERROR_INVALID_SIGNATURE;
179                 SysLog(NID_SEC_CERT, "validation result = invalid signature");
180                 break;
181
182         default:
183                 validationResult = VALIDATION_ERROR_INVALID_PATH;
184                 SysLog(NID_SEC_CERT, "validation result = invalid path");
185                 break;
186
187         }
188         SysTryReturn(NID_SEC_CERT, !IsFailed(r), validationResult, E_SYSTEM, "[E_SYSTEM] Verification of certificate chain failed.");
189
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.");
192
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.");
195
196         return validationResult;
197
198 }
199
200 Tizen::Security::Cert::ValidationResult
201 X509CertificatePath::Validate(const ICertificate& trustAnchor)
202 {
203         result r = E_SUCCESS;
204
205         ClearLastResult();
206
207         r = AddCertificate(trustAnchor);
208         SysTryReturn(NID_SEC_CERT, !IsFailed(r), VALIDATION_ERROR_INVALID_PATH, r, "[%s] Failed to add certificate.", GetErrorMessage(r));
209
210         return Validate();
211 }
212
213 Tizen::Security::Cert::ICertificate*
214 X509CertificatePath::GetTrustAnchorN(void) const
215 {
216         result r = E_SUCCESS;
217         CertificateHandle certHandle = 0;
218         char* pTempCertValue = null;
219         int certLen = 0;
220         ByteBuffer certBuffer;
221
222         ClearLastResult();
223
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.");
226
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.");
230
231         r = _CertService::GetCertBufferN(certHandle, pTempCertValue, &certLen);
232
233         std::unique_ptr< char[] > pTempCert(pTempCertValue);
234
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.");
237
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.");
240
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.");
243
244         certBuffer.Flip();
245
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.");
248
249         r = pCert->Construct(certBuffer);
250         SysTryReturn(NID_SEC_CERT, !IsFailed(r), null, r, "[%s] Propagated.", GetErrorMessage(r));
251
252         return pCert.release();
253 }
254
255 } } } // Tizen::Security::Cert