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