[Pkcs] Fixed the TC's failure
[platform/framework/native/appfw.git] / src / security / pkcs / FSecPkcs_Pkcs08AttributeImpl.cpp
1 ///
2 // Open Service Platform
3 // Copyright (c) 2013 Samsung Electronics Co., Ltd.
4 //
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
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
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.
16 //
17
18 /**
19  * @file                FSecPkcs_Pkcs08AttributeValueImpl.cpp
20  * @brief               This is the implementation file for _Pkcs08AttributeValueImpl class.
21  *
22  * This header file contains the implementation of _Pkcs08AttributeValueImpl class.
23  *
24  */
25
26 #include <new>
27 #include <openssl/x509.h>
28 #include <openssl/objects.h>
29 #include <openssl/obj_mac.h>
30 #include <openssl/evp.h>
31 #include <unique_ptr.h>
32 #include <FBaseByteBuffer.h>
33 #include <FBaseResult.h>
34 #include <FBaseSysLog.h>
35 #include <FSecPkcsPkcs08Attribute.h>
36 #include <FSecPkcsPkcs08AttributeValue.h>
37
38 #include "FSecPkcs_PkcsUtility.h"
39 #include "FSecPkcs_Pkcs08AttributeImpl.h"
40
41
42 using namespace Tizen::Base;
43
44 namespace Tizen { namespace Security { namespace Pkcs
45 {
46
47 _Pkcs08AttributeImpl::_Pkcs08AttributeImpl(void)
48 {
49         //do nothing
50 }
51
52 _Pkcs08AttributeImpl::~_Pkcs08AttributeImpl(void)
53 {
54         //do nothing
55 }
56
57 result
58 _Pkcs08AttributeImpl::Construct(const Tizen::Base::ByteBuffer& encodedData)
59 {
60         result r = E_SUCCESS;
61         int bufferLen = 0;
62         int value = 0;
63         int attrNid = 0;
64         byte* pTemp = {0, };
65         const byte* pBuffer = null;
66         ByteBuffer asn1TypeBuffer;
67         Tizen::Base::String attrOid = null;
68         X509_ATTRIBUTE* pAttribute = null;
69         ASN1_OBJECT* pObject = null;
70         ASN1_TYPE* pAsnType = null;
71
72         SysAssertf(__attributeType.GetLength() <= 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
73
74         pBuffer = encodedData.GetPointer();
75         SysTryReturnResult(NID_SEC_CRYPTO, pBuffer != null, E_INVALID_ARG, "The specified input parameter is invalid.");
76
77         bufferLen = encodedData.GetRemaining();
78         SysTryReturnResult(NID_SEC_CRYPTO, bufferLen > 0, E_INVALID_ARG, "The specified input parameter is invalid.");
79
80         pAttribute = d2i_X509_ATTRIBUTE(null, reinterpret_cast< const unsigned char** >(&pBuffer), bufferLen);
81         SysTryReturnResult(NID_SEC_CRYPTO, pAttribute != null, E_INVALID_ARG, "The specified input parameter is invalid.");
82
83         pObject = pAttribute->object;
84         SysTryCatch(NID_SEC_CRYPTO, pObject != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
85
86         attrNid = OBJ_obj2nid(pObject);
87         attrOid = _PkcsUtility::ConvertToOid(attrNid);
88
89         r = GetLastResult();
90         SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), , r, "[%s] Failed to get the object id of an attribute.", GetErrorMessage(r));
91
92         __attributeType = attrOid;
93
94         for (int i = 0; i < X509_ATTRIBUTE_count(pAttribute); i++)
95         {
96
97                 pAsnType = sk_ASN1_TYPE_value(pAttribute->value.set, i);
98                 SysTryCatch(NID_SEC_CRYPTO, pAsnType != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
99
100                 std::unique_ptr< Pkcs08AttributeValue > pNewObj(new (std::nothrow) Pkcs08AttributeValue());
101                 SysTryCatch(NID_SEC_CRYPTO, pNewObj != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
102
103                 value = i2d_ASN1_TYPE(pAsnType, &pTemp);
104                 SysTryCatch(NID_SEC_CRYPTO, value > 0, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
105
106                 r = asn1TypeBuffer.Construct(value);
107                 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
108
109                 r = asn1TypeBuffer.SetArray(pTemp, 0, value);
110                 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
111
112                 asn1TypeBuffer.Flip();
113
114                 r = pNewObj->Construct(asn1TypeBuffer);
115                 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
116
117                 r = AddAttributeValue(*pNewObj.release());
118                 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), , r, "[%s] Failed to add attribute", GetErrorMessage(r));
119
120         }
121
122 CATCH:
123
124         X509_ATTRIBUTE_free(pAttribute);
125         return r;
126 }
127
128 result
129 _Pkcs08AttributeImpl::Construct(const Tizen::Base::String& attrType)
130 {
131         //Variables local to function
132
133         SysAssertf(__attributeType.GetLength() <= 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
134
135         //Initialize the Attribute instance with Attribute type
136         __attributeType = attrType;
137
138         //Return SUCCESS
139         return E_SUCCESS;
140 }
141
142
143 result
144 _Pkcs08AttributeImpl::AddAttributeValue(const Pkcs08AttributeValue& value)
145 {
146         SysAssertf(__attributeType.GetLength() > 0, "Not yet constructed. Construct () should be called before use.");
147
148         return __attributeValues.Add(value);
149 }
150
151 result
152 _Pkcs08AttributeImpl::RemoveAttributeValue(const Pkcs08AttributeValue& value)
153 {
154         SysAssertf(__attributeType.GetLength() > 0, "Not yet constructed. Construct () should be called before use.");
155
156         return __attributeValues.Remove(value);
157 }
158
159 const Tizen::Base::Collection::ArrayList&
160 _Pkcs08AttributeImpl::GetAttributeValues(void) const
161 {
162         SysAssertf(__attributeType.GetLength() > 0, "Not yet constructed. Construct () should be called before use.");
163
164         return __attributeValues;
165 }
166
167 ByteBuffer*
168 _Pkcs08AttributeImpl::GetEncodedDataN(void) const
169 {
170         result r = E_SUCCESS;
171         int attrNid = 0;
172         int count = 0;
173         int value = 0;
174         byte* pTemp = {0, };
175         X509_ATTRIBUTE* pAttribute;
176         std::unique_ptr< ByteBuffer > pAttrVal;
177         std::unique_ptr< ByteBuffer > pAttributeBuffer;
178         Pkcs08TagValue tagType;
179         ASN1_TYPE* pAsn1Type = null;
180         ASN1_STRING* pString = null;
181
182         ClearLastResult();
183
184         SysAssertf(__attributeType.GetLength() > 0, "Not yet constructed. Construct () should be called before use.");
185
186         pAttribute = X509_ATTRIBUTE_new();
187         SysTryReturn(NID_SEC_CRYPTO, pAttribute != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
188
189         attrNid = _PkcsUtility::ConvertToNid(__attributeType);
190
191         value = X509_ATTRIBUTE_set1_object(pAttribute, OBJ_nid2obj(attrNid));
192         SysTryCatch(NID_SEC_CRYPTO, value == 1, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
193
194         pAttribute->value.set = sk_ASN1_TYPE_new_null();
195         SysTryCatch(NID_SEC_CRYPTO, pAttribute != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
196
197         pAttribute->single = 0;
198
199         count = __attributeValues.GetCount();
200         SysTryCatch(NID_SEC_CRYPTO, count > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
201
202         for (int i = 0; i < count; i++)
203         {
204                 Pkcs08AttributeValue* pObj = const_cast< Pkcs08AttributeValue* >(static_cast< const Pkcs08AttributeValue* >(__attributeValues.GetAt(i)));
205                 SysTryCatch(NID_SEC_CRYPTO, pObj != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
206
207                 tagType = pObj->GetTag();
208
209                 pAttrVal = std::unique_ptr< ByteBuffer >(new (std::nothrow) ByteBuffer());
210                 SysTryCatch(NID_SEC_CRYPTO, pAttrVal != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
211
212                 SysTryCatch(NID_SEC_CRYPTO, pObj->GetValue().GetRemaining() > 0, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
213
214                 r = pAttrVal->Construct(pObj->GetValue());
215                 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
216
217                 pString = ASN1_STRING_type_new(tagType);
218                 SysTryCatch(NID_SEC_CRYPTO, pString != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
219
220                 ASN1_STRING_set(pString, pAttrVal->GetPointer(), pAttrVal->GetRemaining());
221
222                 pAsn1Type = ASN1_TYPE_new();
223                 SysTryCatch(NID_SEC_CRYPTO, pString != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
224
225                 ASN1_TYPE_set(pAsn1Type, tagType, pString);
226
227                 value = sk_ASN1_TYPE_push(pAttribute->value.set, pAsn1Type);
228                 SysTryCatch(NID_SEC_CRYPTO, value > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
229         }
230
231         count = X509_ATTRIBUTE_count(pAttribute);
232
233         value = i2d_X509_ATTRIBUTE(pAttribute, &pTemp);
234         SysTryCatch(NID_SEC_CRYPTO, value > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
235
236         pAttributeBuffer = std::unique_ptr< ByteBuffer >(new (std::nothrow) ByteBuffer());
237         SysTryCatch(NID_SEC_CRYPTO, pAttributeBuffer, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
238
239         r = pAttributeBuffer->Construct(value);
240         SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
241
242         r = pAttributeBuffer->SetArray(pTemp, 0, value);
243         SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
244
245         pAttributeBuffer->Flip();
246
247 CATCH:
248
249         if (IsFailed(r))
250         {
251                 pAttributeBuffer.reset(null);
252         }
253         X509_ATTRIBUTE_free(pAttribute);
254         OPENSSL_free(pTemp);
255
256         return pAttributeBuffer.release();
257
258 }
259
260 _Pkcs08AttributeImpl*
261 _Pkcs08AttributeImpl::GetInstance(Pkcs08Attribute& pkcs08Attribute)
262 {
263         return pkcs08Attribute.__pPkcs08AttributeImpl;
264 }
265
266 const _Pkcs08AttributeImpl*
267 _Pkcs08AttributeImpl::GetInstance(const Pkcs08Attribute& pkcs08Attribute)
268 {
269         return pkcs08Attribute.__pPkcs08AttributeImpl;
270 }
271
272 } } }