revise directory organization.
[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                 uint8_t *signature = NULL;
132                 uint32_t sign_len = 0;
133                 net_nfc_signature_record_s *sign_info = NULL;
134                 net_nfc_certificate_chain_s *chain_info = NULL;
135
136                 /* parse signature info */
137                 sign_info = (net_nfc_signature_record_s *)sign_record->payload_s.buffer;
138
139                 DEBUG_MSG("record version : %d", sign_info->version);
140                 DEBUG_MSG("signature URI present? : %s", sign_info->uri_present ? "true" : "false");
141                 DEBUG_MSG("signature type : %d", sign_info->sign_type);
142                 DEBUG_MSG("signature length : %d", sign_info->signature.length);
143
144                 if (sign_info->uri_present == true)
145                 {
146                         /* TODO */
147                         /* receive the signature data directed by uri */
148                         DEBUG_ERR_MSG("NOT IMPLEMENTED (sign_info->uri_present == true)");
149                         _net_nfc_util_free_mem(buffer);
150                         return result;
151                 }
152                 else
153                 {
154                         signature = sign_info->signature.value;
155                         sign_len = sign_info->signature.length;
156                 }
157
158                 /* parse certificate chain info */
159                 chain_info = (net_nfc_certificate_chain_s *)__NEXT_SUB_FIELD(&(sign_info->signature));
160
161                 SECURE_LOGD("certificate URI present? : %s", chain_info->uri_present ? "true" : "false");
162                 DEBUG_MSG("certificate format : %d", chain_info->cert_format);
163                 DEBUG_MSG("number of certificates : %d", chain_info->num_of_certs);
164
165                 if (chain_info->num_of_certs > 0)
166                 {
167                         net_nfc_sub_field_s *data_info = NULL;
168
169                         data_info = (net_nfc_sub_field_s *)chain_info->cert_store;
170                         DEBUG_MSG("certficate length : %d", data_info->length);
171
172                         //              DEBUG_MSG_PRINT_BUFFER(data_info->value, data_info->length);
173
174                         /* the first certificate is signer's one
175                          * verify signature of content */
176                         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)
177                         {
178                                 if (chain_info->num_of_certs > 1)
179                                 {
180                                         int32_t i = 0;
181                                         net_nfc_openssl_verify_context_h context = NULL;
182
183                                         /* initialize context of verifying certificate */
184                                         context = net_nfc_util_openssl_init_verify_certificate();
185
186                                         /* add signer's certificate */
187                                         net_nfc_util_openssl_add_certificate_of_signer(context, data_info->value, data_info->length);
188
189                                         /* verify certificate using certificate chain */
190                                         for (i = 1, data_info = (net_nfc_sub_field_s *)__NEXT_SUB_FIELD(data_info);
191                                                         i < chain_info->num_of_certs;
192                                                         i++, data_info = (net_nfc_sub_field_s *)__NEXT_SUB_FIELD(data_info))
193                                         {
194                                                 DEBUG_MSG("certficate length : %d", data_info->length);
195                                                 //DEBUG_MSG_PRINT_BUFFER(data_info->value, data_info->length);
196
197                                                 net_nfc_util_openssl_add_certificate_of_ca(context, data_info->value, data_info->length);
198                                         }
199
200                                         /* if the CA_Uri is present, continue adding certificate from uri */
201                                         if (chain_info->uri_present == true)
202                                         {
203                                                 /* TODO : Need to implement */
204                                                 DEBUG_ERR_MSG("NOT IMPLEMENTED (found_root == false && chain_info->uri_present == true)");
205                                                 net_nfc_util_openssl_release_verify_certificate(context);
206                                                 _net_nfc_util_free_mem(buffer);
207                                                 return result;
208
209                                                 //DEBUG_MSG("certficate length : %d", data_info->length);
210                                                 //DEBUG_MSG_PRINT_BUFFER(data_info->value, data_info->length);
211                                         }
212
213                                         /* verify buffer with cert chain and signature bytes */
214                                         if (net_nfc_util_openssl_verify_certificate(context) == true)
215                                                 result = NET_NFC_OK;
216
217                                         net_nfc_util_openssl_release_verify_certificate(context);
218                                 }
219                                 else
220                                 {
221                                         /* TODO : test certificate??? */
222                                         result = NET_NFC_OK;
223                                 }
224
225                                 DEBUG_MSG("verifying signature %d", result);
226                         }
227                         else
228                         {
229                                 DEBUG_ERR_MSG("verifying signature failed");
230                         }
231                 }
232                 else
233                 {
234                         DEBUG_ERR_MSG("certificate not found");
235                 }
236
237                 _net_nfc_util_free_mem(buffer);
238         }
239         else
240         {
241                 if(buffer != NULL)
242                 {
243                         _net_nfc_util_free_mem(buffer);
244                 }
245                 DEBUG_ERR_MSG("_get_records_data_buffer failed");
246         }
247
248         return result;
249 }
250
251 net_nfc_error_e net_nfc_util_verify_signature_ndef_message(ndef_message_s *msg)
252 {
253         net_nfc_error_e result = NET_NFC_UNKNOWN_ERROR;
254         ndef_record_s *begin_record = NULL;
255         ndef_record_s *current_record = NULL;
256
257         begin_record = msg->records;
258         current_record = msg->records;
259
260         while (current_record != NULL)
261         {
262                 if (begin_record == NULL)
263                 {
264                         begin_record = current_record;
265                 }
266
267                 if (IS_EMPTY_RECORD(current_record))
268                 {
269                         begin_record = NULL;
270                 }
271                 else if (IS_SIGN_RECORD(current_record))
272                 {
273                         result = net_nfc_util_verify_signature_records(begin_record, current_record);
274
275                         begin_record = NULL;
276                 }
277
278                 current_record = current_record->next;
279         }
280
281         return result;
282 }
283
284 /*
285  * sign method
286  */
287 net_nfc_error_e net_nfc_util_sign_records(ndef_message_s *msg, int begin_index, int end_index, char *cert_file, char *password)
288 {
289         net_nfc_error_e result = NET_NFC_UNKNOWN_ERROR;
290         ndef_record_s *begin_record = NULL, *end_record = NULL, *record = NULL;
291         data_s payload = { NULL, 0 };
292         uint8_t *data_buffer = NULL;
293         uint32_t data_len = 0;
294         uint8_t signature[1024] = { 0, };
295         uint32_t sign_len = sizeof(signature);
296         uint8_t *cert_buffer = NULL;
297         uint32_t cert_len = 0;
298         uint32_t cert_count = 0;
299
300         net_nfc_util_get_record_by_index(msg, begin_index, &begin_record);
301         net_nfc_util_get_record_by_index(msg, end_index, &end_record);
302
303         DEBUG_MSG("total record count : %d, begin_index : %d, end_index : %d", msg->recordCount, begin_index, end_index);
304
305         /* get target data */
306         _get_records_data_buffer(begin_record, end_record->next, &data_buffer, &data_len);
307
308         DEBUG_MSG_PRINT_BUFFER(data_buffer, data_len);
309
310         net_nfc_util_openssl_sign_buffer(NET_NFC_SIGN_TYPE_PKCS_1, data_buffer, data_len, cert_file, password, signature, &sign_len);
311
312         /* get cert chain */
313         net_nfc_util_get_cert_list_from_file(cert_file, password, &cert_buffer, &cert_len, &cert_count);
314
315         /* create payload */
316         payload.length = sizeof(net_nfc_signature_record_s) + sign_len + sizeof(net_nfc_certificate_chain_s) + cert_len;
317
318         _net_nfc_util_alloc_mem(payload.buffer, payload.length);
319
320         net_nfc_signature_record_s *sign_record = (net_nfc_signature_record_s *)payload.buffer;
321         sign_record->version = 1;
322         sign_record->uri_present = 0;
323         sign_record->sign_type = NET_NFC_SIGN_TYPE_PKCS_1;
324
325         if (sign_record->uri_present)
326         {
327                 /* TODO */
328         }
329         else
330         {
331                 __FILL_SUB_FIELD(&(sign_record->signature), signature, sign_len);
332         }
333
334         net_nfc_certificate_chain_s *chain = (net_nfc_certificate_chain_s *)__NEXT_SUB_FIELD(&(sign_record->signature));
335         if (cert_count < 16)
336         {
337                 chain->uri_present = 0;
338         }
339         else
340         {
341                 chain->uri_present = 1;
342         }
343
344         chain->cert_format = NET_NFC_CERT_FORMAT_X_509;
345         chain->num_of_certs = cert_count;
346         memcpy(chain->cert_store, cert_buffer, cert_len);
347
348         if (chain->uri_present)
349         {
350                 /* TODO */
351                 DEBUG_ERR_MSG("num_of_certs is greater than 15 [%d]", cert_count);
352         }
353
354         /* create record */
355         data_s type = { (uint8_t *)"Sig", 3 };
356
357         net_nfc_util_create_record(NET_NFC_RECORD_WELL_KNOWN_TYPE, &type, NULL, &payload, &record);
358
359         /* get last record index */
360         net_nfc_util_append_record_by_index(msg, end_index + 1, record);
361
362         _net_nfc_util_free_mem(payload.buffer);
363         _net_nfc_util_free_mem(cert_buffer);
364         _net_nfc_util_free_mem(data_buffer);
365
366         return result;
367 }
368
369 net_nfc_error_e net_nfc_util_sign_ndef_message(ndef_message_s *msg, char *cert_file, char *password)
370 {
371         net_nfc_error_e result = NET_NFC_UNKNOWN_ERROR;
372
373         if (msg->recordCount > 0)
374         {
375                 net_nfc_util_sign_records(msg, 0, msg->recordCount - 1, cert_file, password);
376
377                 result = NET_NFC_OK;
378         }
379
380         return result;
381 }