Revert "Fix prevent defect for locales"
[platform/framework/native/appfw.git] / src / security / pkcs / FSecPkcs_Pkcs08EncryptedPrivateKeyInfoImpl.cpp
1 //
2 // Copyright (c) 2013 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                FSecPkcs_Pkcs08EncryptedPrivateKeyInfoImpl.cpp
19  * @brief               This is the implementation file for _Pkcs08EncryptedPrivateKeyInfoImpl class.
20  *
21  * This header file contains the implementation of _Pkcs08EncryptedPrivateKeyInfoImpl class.
22  *
23  */
24
25
26 #include <new>
27 #include <openssl/evp.h>
28 #include <openssl/bn.h>
29 #include <openssl/x509.h>
30 #include <openssl/crypto.h>
31 #include <openssl/asn1t.h>
32 #include <openssl/asn1.h>
33 #include <openssl/objects.h>
34 #include <unique_ptr.h>
35 #include <FBaseSysLog.h>
36 #include <FBaseByteBuffer.h>
37 #include <FBaseResult.h>
38 #include <FSecPkcsPkcs08PrivateKeyInfo.h>
39 #include <FSecPkcsPkcs08EncryptedPrivateKeyInfo.h>
40 #include <FSecPkcsIAlgorithmParameters.h>
41 #include <FSecPkcsAlgorithmIdentifier.h>
42 #include <FSecPkcsTypes.h>
43
44 #include "FSecPkcs_PkcsUtility.h"
45 #include "FSecPkcs_Pkcs08EncryptedPrivateKeyInfoImpl.h"
46
47 using namespace Tizen::Base;
48
49 namespace Tizen { namespace Security { namespace Pkcs
50 {
51
52 //EncryptedPrivateKeyInfo Class Life cycle
53
54 //Default Constructor
55 _Pkcs08EncryptedPrivateKeyInfoImpl::_Pkcs08EncryptedPrivateKeyInfoImpl(void)
56 {
57 }
58
59 //Default Destructor
60 _Pkcs08EncryptedPrivateKeyInfoImpl::~_Pkcs08EncryptedPrivateKeyInfoImpl(void)
61 {
62         //do nothing
63 }
64
65 result
66 _Pkcs08EncryptedPrivateKeyInfoImpl::Construct(const Tizen::Base::ByteBuffer& encodedData)
67 {
68         result r = E_SUCCESS;
69
70         X509_SIG* pPkcs8Key = null;
71         Tizen::Base::String prfOid = null;
72         std::unique_ptr< IAlgorithmParameters > pEncParam;
73         Tizen::Base::ByteBuffer encryptedKeyBuffer;
74         const byte* pBuffer = null;
75         byte* pDigestValue = null;
76         int bufferLen = 0;
77         int digestLength = 0;
78         int prf_nid = 0;
79
80         SysAssertf(__encryptedData.GetRemaining() <= 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
81
82         pBuffer = encodedData.GetPointer();
83         SysTryReturnResult(NID_SEC_CRYPTO, pBuffer != null, E_INVALID_ARG, "The specified input parameter is invalid.");
84
85         bufferLen = encodedData.GetRemaining();
86         SysTryReturnResult(NID_SEC_CRYPTO, bufferLen > 0, E_INVALID_ARG, "The specified input parameter is invalid.");
87
88         pPkcs8Key = d2i_X509_SIG(null, reinterpret_cast< const unsigned char** >(&pBuffer), bufferLen);
89         SysTryReturnResult(NID_SEC_CRYPTO, pPkcs8Key != null, E_INVALID_ARG, "The specified input parameter is invalid.");
90
91         SysTryCatch(NID_SEC_CRYPTO, pPkcs8Key->digest->type == V_ASN1_OCTET_STRING, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
92
93         if (pPkcs8Key->algor)
94         {
95                 prf_nid = OBJ_obj2nid(pPkcs8Key->algor->algorithm);
96                 prfOid = _PkcsUtility::ConvertToOid(prf_nid);
97
98                 r = GetLastResult();
99                 SysTryCatch(NID_SEC_CRYPTO, r != E_UNSUPPORTED_ALGORITHM, r = E_UNSUPPORTED_ALGORITHM, E_UNSUPPORTED_ALGORITHM, "[E_UNSUPPORTED_ALGORITHM] The input algorithm is not supported.");
100
101                 pEncParam = std::unique_ptr< IAlgorithmParameters >(_PkcsUtility::GernerateParametersFromOidN(prfOid, pPkcs8Key->algor));
102                 SysTryCatch(NID_SEC_CRYPTO, pEncParam, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
103
104                 r = __encryptionAlgorithm.Construct(prfOid, pEncParam.get());
105                 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
106
107         }
108
109         pDigestValue = pPkcs8Key->digest->data;
110         SysTryCatch(NID_SEC_CRYPTO, pDigestValue, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
111
112         digestLength = pPkcs8Key->digest->length;
113         SysTryCatch(NID_SEC_CRYPTO, digestLength > 0, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
114
115         r = encryptedKeyBuffer.Construct(digestLength);
116         SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
117
118         r = encryptedKeyBuffer.SetArray(pDigestValue, 0, digestLength);
119         SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
120
121         encryptedKeyBuffer.Flip();
122         r = __encryptedData.Construct(encryptedKeyBuffer);
123         SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
124
125 CATCH:
126
127         X509_SIG_free(pPkcs8Key);
128         return r;
129
130 }
131
132 // Encrypted Private Key Info Class Operations
133 result
134 _Pkcs08EncryptedPrivateKeyInfoImpl::Construct(const AlgorithmIdentifier& algorithmId, const Tizen::Base::ByteBuffer& encryptedData)
135 {
136         result r = E_SUCCESS;
137
138         SysAssertf(__encryptedData.GetRemaining() <= 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
139
140         SysTryReturn(NID_SEC_CRYPTO, encryptedData.GetRemaining() > 0, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
141
142         r = __encryptionAlgorithm.Construct(algorithmId.GetAlgorithmObjectId(), algorithmId.GetParametersN());
143         SysTryReturn(NID_SEC_CRYPTO, !IsFailed(r), r, r, "[%s] Failed to construct the algorithm identifier instance for encryption algorithm.", GetErrorMessage(r));
144
145         r = __encryptedData.Construct(encryptedData);
146         SysTryReturn(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
147
148         return r;
149
150 }
151
152
153 result
154 _Pkcs08EncryptedPrivateKeyInfoImpl::Construct(const AlgorithmIdentifier& algorithmId, const Tizen::Base::ByteBuffer& key, const Tizen::Base::ByteBuffer& encodedPrivateKeyInfoBuffer)
155 {
156         result r = E_SUCCESS;
157
158         SysAssertf(__encryptedData.GetRemaining() <= 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
159
160         SysTryReturnResult(NID_SEC_CRYPTO, key.GetRemaining() > 0, E_INVALID_ARG, "The specified input parameter is invalid.");
161         SysTryReturnResult(NID_SEC_CRYPTO, encodedPrivateKeyInfoBuffer.GetRemaining() > 0, E_INVALID_ARG, "The specified input parameter is invalid.");
162
163         std::unique_ptr< IAlgorithmParameters > pParam(algorithmId.GetParametersN());
164         SysTryReturnResult(NID_SEC_CRYPTO, pParam, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
165
166         r = __encryptionAlgorithm.Construct(algorithmId.GetAlgorithmObjectId(), pParam.get());
167         SysTryReturn(NID_SEC_CRYPTO, !IsFailed(r), r, r, "[%s] Failed to construct algorithm identifier instance for encryption algorithm..", GetErrorMessage(r));
168
169         std::unique_ptr< ByteBuffer > pEncData(_PkcsUtility::EncryptDecryptN(algorithmId, key, encodedPrivateKeyInfoBuffer, 1));
170         SysTryReturnResult(NID_SEC_CRYPTO, pEncData, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
171
172         r = __encryptedData.Construct(*pEncData);
173         SysTryReturnResult(NID_SEC_CRYPTO, !IsFailed(r), E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
174
175         return r;
176 }
177
178 const AlgorithmIdentifier&
179 _Pkcs08EncryptedPrivateKeyInfoImpl::GetAlgorithm(void) const
180 {
181         ClearLastResult();
182         return __encryptionAlgorithm;
183 }
184
185 ByteBuffer*
186 _Pkcs08EncryptedPrivateKeyInfoImpl::GetEncryptedDataN(void) const
187 {
188         result r = E_SUCCESS;
189
190         ClearLastResult();
191
192         SysAssertf(__encryptedData.GetRemaining() > 0, "Not yet constructed. Construct () should be called before use.");
193         SysAssertf(__encryptionAlgorithm.GetAlgorithmObjectId().GetLength() > 0, "Not yet constructed. Construct () should be called before use.");
194
195         std::unique_ptr< ByteBuffer > pEncryptedData(new (std::nothrow) ByteBuffer());
196         SysTryReturn(NID_SEC_CRYPTO, pEncryptedData, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
197
198         r = pEncryptedData->Construct(__encryptedData);
199         SysTryReturn(NID_SEC_CRYPTO, !IsFailed(r), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
200
201         return pEncryptedData.release();
202
203 }
204
205 ByteBuffer*
206 _Pkcs08EncryptedPrivateKeyInfoImpl::DecryptN(const Tizen::Base::ByteBuffer& key)
207 {
208         std::unique_ptr< ByteBuffer > pDecryptedData;
209
210         ClearLastResult();
211
212         SysAssertf(__encryptedData.GetRemaining() > 0, "Not yet constructed. Construct () should be called before use.");
213         SysAssertf(__encryptionAlgorithm.GetAlgorithmObjectId().GetLength() > 0, "Not yet constructed. Construct () should be called before use.");
214
215         SysTryReturn(NID_SEC_CRYPTO, key.GetRemaining() > 0, null, E_INVALID_ARG, "[E_INVALID_ARG]  The specified input parameter is invalid.");
216
217         pDecryptedData = std::unique_ptr< ByteBuffer >(_PkcsUtility::EncryptDecryptN(__encryptionAlgorithm, key, __encryptedData, 0));
218         SysTryReturn(NID_SEC_CRYPTO, pDecryptedData, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
219
220         return pDecryptedData.release();
221 }
222
223 ByteBuffer*
224 _Pkcs08EncryptedPrivateKeyInfoImpl::GetEncodedDataN(void) const
225 {
226
227         result r = E_SUCCESS;
228         X509_SIG* sig = null;
229         ASN1_OCTET_STRING* pDigest = null;
230         std::unique_ptr< ByteBuffer > pEncPrivKey;
231         int digestLength = 0;
232         int prf_nid = 0;
233         int value = 0;
234         byte* pDigestData = null;
235         byte* pTemp = null;
236
237         std::unique_ptr< IAlgorithmParameters > pParam;
238
239         ClearLastResult();
240
241         SysAssertf(__encryptedData.GetRemaining() > 0, "Not yet constructed. Construct () should be called before use.");
242         SysAssertf(__encryptionAlgorithm.GetAlgorithmObjectId().GetLength() > 0, "Not yet constructed. Construct () should be called before use.");
243
244         sig = X509_SIG_new();
245         SysTryReturn(NID_SEC_CRYPTO, sig != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
246
247         pDigest = M_ASN1_OCTET_STRING_new();
248         SysTryReturn(NID_SEC_CRYPTO, pDigest != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
249
250         digestLength = __encryptedData.GetRemaining();
251
252         pDigest->data = static_cast< unsigned char* >(OPENSSL_malloc(digestLength));
253         SysTryReturn(NID_SEC_CRYPTO, pDigest->data != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
254
255         pDigest->length = digestLength;
256
257         pDigestData = const_cast< byte* >(__encryptedData.GetPointer());
258         memcpy(pDigest->data, pDigestData, digestLength);
259
260         sig->digest = pDigest;
261
262         prf_nid = _PkcsUtility::ConvertToNid(__encryptionAlgorithm.GetAlgorithmObjectId());
263
264         sig->algor = X509_ALGOR_new();
265         SysTryReturn(NID_SEC_CRYPTO, sig->algor != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
266
267         pParam = std::unique_ptr< IAlgorithmParameters >(__encryptionAlgorithm.GetParametersN());
268         SysTryCatch(NID_SEC_CRYPTO, pParam, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
269
270         sig->algor = _PkcsUtility::GenerateAlgorithmIdentifierStructureN(__encryptionAlgorithm.GetAlgorithmObjectId(), pParam.get());
271         SysTryCatch(NID_SEC_CRYPTO, sig->algor != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
272
273         value = i2d_X509_SIG(sig, &pTemp);
274         SysTryCatch(NID_SEC_CRYPTO, value > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
275
276         pEncPrivKey = std::unique_ptr< ByteBuffer >(new (std::nothrow) ByteBuffer());
277         SysTryCatch(NID_SEC_CRYPTO, pEncPrivKey, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
278
279         r = pEncPrivKey->Construct(value);
280         SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
281
282         r = pEncPrivKey->SetArray(pTemp, 0, value);
283         SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
284
285         pEncPrivKey->Flip();
286
287 CATCH:
288
289         if (IsFailed(r))
290         {
291                 pEncPrivKey.reset(null);
292         }
293         X509_SIG_free(sig);
294         SetLastResult(r);
295         return pEncPrivKey.release();
296
297 }
298
299 _Pkcs08EncryptedPrivateKeyInfoImpl*
300 _Pkcs08EncryptedPrivateKeyInfoImpl::GetInstance(Pkcs08EncryptedPrivateKeyInfo& pkcs08EncryptedPrivateKeyInfo)
301 {
302         return pkcs08EncryptedPrivateKeyInfo.__pPkcs08EncryptedPrivateKeyInfoImpl;
303 }
304
305 const _Pkcs08EncryptedPrivateKeyInfoImpl*
306 _Pkcs08EncryptedPrivateKeyInfoImpl::GetInstance(const Pkcs08EncryptedPrivateKeyInfo& pkcs08EncryptedPrivateKeyInfo)
307 {
308         return pkcs08EncryptedPrivateKeyInfo.__pPkcs08EncryptedPrivateKeyInfoImpl;
309 }
310
311 } } }