revise logging and coding style
[platform/core/connectivity/nfc-manager-neard.git] / common / net_nfc_util_sign_record.c
1 /*
2  * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Flora License, Version 1.1 (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://floralicense.org/license/
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 #include <sys/param.h>
19
20 #include "net_nfc_debug_internal.h"
21 #include "net_nfc_util_defines.h"
22 #include "net_nfc_util_internal.h"
23 #include "net_nfc_util_ndef_message.h"
24 #include "net_nfc_util_ndef_record.h"
25 #include "net_nfc_util_openssl_internal.h"
26 #include "net_nfc_util_sign_record.h"
27
28 #define IS_SIGN_RECORD(__x) \
29         (((__x)->TNF == NET_NFC_RECORD_WELL_KNOWN_TYPE) && \
30          ((__x)->type_s.length == 3) && \
31          (memcmp((__x)->type_s.buffer, "Sig", 3) == 0))
32
33 #define IS_EMPTY_RECORD(__x) \
34         ((__x->TNF == NET_NFC_RECORD_EMPTY))
35
36 #define __FILL_SUB_FIELD(__dst, __buf, __len) \
37         (__dst)->length = (__len); \
38         memcpy((__dst)->value, (__buf), (__dst)->length);
39
40 #define __NEXT_SUB_FIELD(__dst) ((__dst)->value + (__dst)->length)
41
42 bool _get_records_data_buffer(ndef_record_s *begin_record,
43         ndef_record_s *end_record, uint8_t **buffer, uint32_t *length)
44 {
45         uint32_t len = 0;
46         bool result = false;
47         ndef_record_s *current_record = NULL;
48
49         RETV_IF(NULL == begin_record, result);
50         RETV_IF(begin_record == end_record, result);
51
52         /* count total buffer length */
53         current_record = begin_record;
54         len = 0;
55
56         while (current_record != NULL && current_record != end_record)
57         {
58                 /* type length */
59                 if (current_record->type_s.buffer != NULL && current_record->type_s.length > 0)
60                         len += current_record->type_s.length;
61
62                 /* ID length */
63                 if (current_record->id_s.buffer != NULL && current_record->id_s.length > 0)
64                         len += current_record->id_s.length;
65
66                 /* payload length */
67                 if (current_record->payload_s.buffer != NULL &&
68                                 current_record->payload_s.length > 0)
69                 {
70                         len += current_record->payload_s.length;
71                 }
72
73                 current_record = current_record->next;
74         }
75
76         if (len > 0)
77         {
78                 uint8_t *buf = NULL;
79
80                 _net_nfc_util_alloc_mem(buf, len);
81                 if (buf != NULL)
82                 {
83                         uint32_t offset = 0;
84
85                         current_record = begin_record;
86
87                         while (offset < len && current_record != NULL && current_record != end_record)
88                         {
89                                 /* type length */
90                                 if (current_record->type_s.buffer != NULL &&
91                                         current_record->type_s.length > 0)
92                                 {
93                                         memcpy(buf + offset, current_record->type_s.buffer,
94                                                 MIN(current_record->type_s.length, len - offset));
95                                         offset += MIN(current_record->type_s.length, len - offset);
96                                 }
97
98                                 /* ID length */
99                                 if (current_record->id_s.buffer != NULL && current_record->id_s.length > 0)
100                                 {
101                                         memcpy(buf + offset, current_record->id_s.buffer,
102                                                 MIN(current_record->id_s.length, len - offset));
103                                         offset += MIN(current_record->id_s.length, len - offset);
104                                 }
105
106                                 /* payload length */
107                                 if (current_record->payload_s.buffer != NULL &&
108                                         current_record->payload_s.length > 0)
109                                 {
110                                         memcpy(buf + offset, current_record->payload_s.buffer,
111                                                 MIN(current_record->payload_s.length, len - offset));
112                                         offset += MIN(current_record->payload_s.length, len - offset);
113                                 }
114
115                                 current_record = current_record->next;
116                         }
117
118                         *buffer = buf;
119                         *length = offset;
120
121                         result = true;
122                 }
123         }
124
125         return result;
126 }
127
128 net_nfc_error_e net_nfc_util_verify_signature_records(ndef_record_s *begin_record,
129         ndef_record_s *sign_record)
130 {
131         int ret;
132         uint32_t length = 0;
133         uint8_t *buffer = NULL;
134         net_nfc_error_e result = NET_NFC_UNKNOWN_ERROR;
135
136         RETV_IF(NULL == sign_record, NET_NFC_INVALID_PARAM);
137         RETV_IF(NULL == begin_record, NET_NFC_INVALID_PARAM);
138         RETV_IF(begin_record == sign_record, NET_NFC_INVALID_PARAM);
139
140         /* get signed data */
141         if (_get_records_data_buffer(begin_record, sign_record, &buffer, &length) == true)
142         {
143                 net_nfc_signature_record_s *sign_info = NULL;
144                 net_nfc_certificate_chain_s *chain_info = NULL;
145
146                 /* parse signature info */
147                 sign_info = (net_nfc_signature_record_s *)sign_record->payload_s.buffer;
148
149                 NFC_DBG("record version : %d", sign_info->version);
150                 NFC_DBG("signature URI present? : %s", sign_info->uri_present ? "true" : "false");
151                 NFC_DBG("signature type : %d", sign_info->sign_type);
152                 NFC_DBG("signature length : %d", sign_info->signature.length);
153
154                 if (true == sign_info->uri_present)
155                 {
156                         /* TODO */
157                         /* receive the signature data directed by uri */
158                         NFC_ERR("NOT IMPLEMENTED (sign_info->uri_present == true)");
159                         _net_nfc_util_free_mem(buffer);
160                         return result;
161                 }
162
163                 /* parse certificate chain info */
164                 chain_info =
165                         (net_nfc_certificate_chain_s *)__NEXT_SUB_FIELD(&(sign_info->signature));
166
167                 SECURE_LOGD("certificate URI present? : %s",
168                         chain_info->uri_present ? "true" : "false");
169                 NFC_DBG("certificate format : %d", chain_info->cert_format);
170                 NFC_DBG("number of certificates : %d", chain_info->num_of_certs);
171
172                 if (chain_info->num_of_certs > 0)
173                 {
174                         net_nfc_sub_field_s *data_info = NULL;
175
176                         data_info = (net_nfc_sub_field_s *)chain_info->cert_store;
177                         NFC_DBG("certficate length : %d", data_info->length);
178
179                         //              DEBUG_MSG_PRINT_BUFFER(data_info->value, data_info->length);
180
181                         /* the first certificate is signer's one
182                          * verify signature of content */
183                         ret = net_nfc_util_openssl_verify_signature(sign_info->sign_type,
184                                                 buffer,
185                                                 length,
186                                                 data_info->value,
187                                                 data_info->length,
188                                                 sign_info->signature.value,
189                                                 sign_info->signature.length);
190
191                         if (true == ret)
192                         {
193                                 if (chain_info->num_of_certs > 1)
194                                 {
195                                         int32_t i = 0;
196                                         net_nfc_openssl_verify_context_h context = NULL;
197
198                                         /* initialize context of verifying certificate */
199                                         context = net_nfc_util_openssl_init_verify_certificate();
200
201                                         /* add signer's certificate */
202                                         net_nfc_util_openssl_add_certificate_of_signer(context, data_info->value,
203                                                 data_info->length);
204
205                                         /* verify certificate using certificate chain */
206                                         for (i = 1, data_info = (net_nfc_sub_field_s *)__NEXT_SUB_FIELD(data_info);
207                                                         i < chain_info->num_of_certs;
208                                                         i++, data_info = (net_nfc_sub_field_s *)__NEXT_SUB_FIELD(data_info))
209                                         {
210                                                 NFC_DBG("certficate length : %d", data_info->length);
211                                                 //DEBUG_MSG_PRINT_BUFFER(data_info->value, data_info->length);
212
213                                                 net_nfc_util_openssl_add_certificate_of_ca(context, data_info->value,
214                                                         data_info->length);
215                                         }
216
217                                         /* if the CA_Uri is present, continue adding certificate from uri */
218                                         if (true == chain_info->uri_present)
219                                         {
220                                                 /* TODO : Need to implement */
221                                                 NFC_ERR("NOT IMPLEMENTED (found_root == false && chain_info->uri_present == true)");
222                                                 net_nfc_util_openssl_release_verify_certificate(context);
223                                                 _net_nfc_util_free_mem(buffer);
224                                                 return result;
225
226                                                 //NFC_DBG("certficate length : %d", data_info->length);
227                                                 //DEBUG_MSG_PRINT_BUFFER(data_info->value, data_info->length);
228                                         }
229
230                                         /* verify buffer with cert chain and signature bytes */
231                                         if (net_nfc_util_openssl_verify_certificate(context) == true)
232                                                 result = NET_NFC_OK;
233
234                                         net_nfc_util_openssl_release_verify_certificate(context);
235                                 }
236                                 else
237                                 {
238                                         /* TODO : test certificate??? */
239                                         result = NET_NFC_OK;
240                                 }
241
242                                 NFC_DBG("verifying signature %d", result);
243                         }
244                         else
245                         {
246                                 NFC_ERR("verifying signature failed");
247                         }
248                 }
249                 else
250                 {
251                         NFC_ERR("certificate not found");
252                 }
253
254                 _net_nfc_util_free_mem(buffer);
255         }
256         else
257         {
258                 if(buffer != NULL)
259                         _net_nfc_util_free_mem(buffer);
260
261                 NFC_ERR("_get_records_data_buffer failed");
262         }
263
264         return result;
265 }
266
267 net_nfc_error_e net_nfc_util_verify_signature_ndef_message(ndef_message_s *msg)
268 {
269         ndef_record_s *begin_record = NULL;
270         ndef_record_s *current_record = NULL;
271         net_nfc_error_e result = NET_NFC_UNKNOWN_ERROR;
272
273
274         begin_record = msg->records;
275         current_record = msg->records;
276
277         while (current_record != NULL)
278         {
279                 if (NULL == begin_record)
280                         begin_record = current_record;
281
282                 if (IS_EMPTY_RECORD(current_record))
283                 {
284                         begin_record = NULL;
285                 }
286                 else if (IS_SIGN_RECORD(current_record))
287                 {
288                         result = net_nfc_util_verify_signature_records(begin_record, current_record);
289
290                         begin_record = NULL;
291                 }
292
293                 current_record = current_record->next;
294         }
295
296         return result;
297 }
298
299 /*
300  * sign method
301  */
302 net_nfc_error_e net_nfc_util_sign_records(ndef_message_s *msg, int begin_index,
303         int end_index, char *cert_file, char *password)
304 {
305         uint32_t cert_len = 0;
306         uint32_t data_len = 0;
307         uint32_t cert_count = 0;
308         uint8_t *data_buffer = NULL;
309         uint8_t *cert_buffer = NULL;
310         data_s payload = { NULL, 0 };
311         uint8_t signature[1024] = { 0, };
312         uint32_t sign_len = sizeof(signature);
313         net_nfc_error_e result = NET_NFC_UNKNOWN_ERROR;
314         ndef_record_s *begin_record = NULL, *end_record = NULL, *record = NULL;
315
316
317         net_nfc_util_get_record_by_index(msg, begin_index, &begin_record);
318         net_nfc_util_get_record_by_index(msg, end_index, &end_record);
319
320         NFC_DBG("total record count : %d, begin_index : %d, end_index : %d", msg->recordCount,
321                 begin_index, end_index);
322
323         /* get target data */
324         _get_records_data_buffer(begin_record, end_record->next, &data_buffer, &data_len);
325
326         DEBUG_MSG_PRINT_BUFFER(data_buffer, data_len);
327
328         net_nfc_util_openssl_sign_buffer(NET_NFC_SIGN_TYPE_PKCS_1, data_buffer, data_len,
329                 cert_file, password, signature, &sign_len);
330
331         /* get cert chain */
332         net_nfc_util_get_cert_list_from_file(cert_file, password, &cert_buffer, &cert_len,
333                 &cert_count);
334
335         /* create payload */
336         payload.length = sizeof(net_nfc_signature_record_s) + sign_len +
337                 sizeof(net_nfc_certificate_chain_s) + cert_len;
338
339         _net_nfc_util_alloc_mem(payload.buffer, payload.length);
340
341         net_nfc_signature_record_s *sign_record =
342                 (net_nfc_signature_record_s *)payload.buffer;
343         sign_record->version = 1;
344         sign_record->uri_present = 0;
345         sign_record->sign_type = NET_NFC_SIGN_TYPE_PKCS_1;
346
347         if (sign_record->uri_present)
348         {
349                 /* TODO */
350         }
351         else
352         {
353                 __FILL_SUB_FIELD(&(sign_record->signature), signature, sign_len);
354         }
355
356         net_nfc_certificate_chain_s *chain =
357                 (net_nfc_certificate_chain_s *)__NEXT_SUB_FIELD(&(sign_record->signature));
358
359         if (cert_count < 16)
360                 chain->uri_present = 0;
361         else
362                 chain->uri_present = 1;
363
364         chain->cert_format = NET_NFC_CERT_FORMAT_X_509;
365         chain->num_of_certs = cert_count;
366         memcpy(chain->cert_store, cert_buffer, cert_len);
367
368         if (chain->uri_present)
369         {
370                 /* TODO */
371                 NFC_ERR("num_of_certs is greater than 15 [%d]", cert_count);
372         }
373
374         /* create record */
375         data_s type = { (uint8_t *)"Sig", 3 };
376
377         net_nfc_util_create_record(NET_NFC_RECORD_WELL_KNOWN_TYPE, &type, NULL,
378                 &payload, &record);
379
380         /* get last record index */
381         net_nfc_util_append_record_by_index(msg, end_index + 1, record);
382
383         _net_nfc_util_free_mem(payload.buffer);
384         _net_nfc_util_free_mem(cert_buffer);
385         _net_nfc_util_free_mem(data_buffer);
386
387         return result;
388 }
389
390 net_nfc_error_e net_nfc_util_sign_ndef_message(ndef_message_s *msg,
391         char *cert_file, char *password)
392 {
393         net_nfc_error_e result = NET_NFC_UNKNOWN_ERROR;
394
395         if (msg->recordCount > 0)
396         {
397                 net_nfc_util_sign_records(msg, 0, msg->recordCount - 1, cert_file, password);
398
399                 result = NET_NFC_OK;
400         }
401
402         return result;
403 }