2 * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
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
8 * http://floralicense.org/license/
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.
18 #include <sys/param.h>
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"
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))
33 #define IS_EMPTY_RECORD(__x) \
34 ((__x->TNF == NET_NFC_RECORD_EMPTY))
36 #define __FILL_SUB_FIELD(__dst, __buf, __len) \
37 (__dst)->length = (__len); \
38 memcpy((__dst)->value, (__buf), (__dst)->length);
40 #define __NEXT_SUB_FIELD(__dst) ((__dst)->value + (__dst)->length)
42 bool _get_records_data_buffer(ndef_record_s *begin_record,
43 ndef_record_s *end_record, uint8_t **buffer, uint32_t *length)
47 ndef_record_s *current_record = NULL;
49 RETV_IF(NULL == begin_record, result);
50 RETV_IF(begin_record == end_record, result);
52 /* count total buffer length */
53 current_record = begin_record;
56 while (current_record != NULL && current_record != end_record)
59 if (current_record->type_s.buffer != NULL && current_record->type_s.length > 0)
60 len += current_record->type_s.length;
63 if (current_record->id_s.buffer != NULL && current_record->id_s.length > 0)
64 len += current_record->id_s.length;
67 if (current_record->payload_s.buffer != NULL &&
68 current_record->payload_s.length > 0)
70 len += current_record->payload_s.length;
73 current_record = current_record->next;
80 _net_nfc_util_alloc_mem(buf, len);
85 current_record = begin_record;
87 while (offset < len && current_record != NULL && current_record != end_record)
90 if (current_record->type_s.buffer != NULL &&
91 current_record->type_s.length > 0)
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);
99 if (current_record->id_s.buffer != NULL && current_record->id_s.length > 0)
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);
107 if (current_record->payload_s.buffer != NULL &&
108 current_record->payload_s.length > 0)
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);
115 current_record = current_record->next;
128 net_nfc_error_e net_nfc_util_verify_signature_records(ndef_record_s *begin_record,
129 ndef_record_s *sign_record)
133 uint8_t *buffer = NULL;
134 net_nfc_error_e result = NET_NFC_UNKNOWN_ERROR;
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);
140 /* get signed data */
141 if (_get_records_data_buffer(begin_record, sign_record, &buffer, &length) == true)
143 net_nfc_signature_record_s *sign_info = NULL;
144 net_nfc_certificate_chain_s *chain_info = NULL;
146 /* parse signature info */
147 sign_info = (net_nfc_signature_record_s *)sign_record->payload_s.buffer;
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);
154 if (true == sign_info->uri_present)
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);
163 /* parse certificate chain info */
165 (net_nfc_certificate_chain_s *)__NEXT_SUB_FIELD(&(sign_info->signature));
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);
172 if (chain_info->num_of_certs > 0)
174 net_nfc_sub_field_s *data_info = NULL;
176 data_info = (net_nfc_sub_field_s *)chain_info->cert_store;
177 NFC_DBG("certficate length : %d", data_info->length);
179 // DEBUG_MSG_PRINT_BUFFER(data_info->value, data_info->length);
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,
188 sign_info->signature.value,
189 sign_info->signature.length);
193 if (chain_info->num_of_certs > 1)
196 net_nfc_openssl_verify_context_h context = NULL;
198 /* initialize context of verifying certificate */
199 context = net_nfc_util_openssl_init_verify_certificate();
201 /* add signer's certificate */
202 net_nfc_util_openssl_add_certificate_of_signer(context, data_info->value,
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))
210 NFC_DBG("certficate length : %d", data_info->length);
211 //DEBUG_MSG_PRINT_BUFFER(data_info->value, data_info->length);
213 net_nfc_util_openssl_add_certificate_of_ca(context, data_info->value,
217 /* if the CA_Uri is present, continue adding certificate from uri */
218 if (true == chain_info->uri_present)
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);
226 //NFC_DBG("certficate length : %d", data_info->length);
227 //DEBUG_MSG_PRINT_BUFFER(data_info->value, data_info->length);
230 /* verify buffer with cert chain and signature bytes */
231 if (net_nfc_util_openssl_verify_certificate(context) == true)
234 net_nfc_util_openssl_release_verify_certificate(context);
238 /* TODO : test certificate??? */
242 NFC_DBG("verifying signature %d", result);
246 NFC_ERR("verifying signature failed");
251 NFC_ERR("certificate not found");
254 _net_nfc_util_free_mem(buffer);
259 _net_nfc_util_free_mem(buffer);
261 NFC_ERR("_get_records_data_buffer failed");
267 net_nfc_error_e net_nfc_util_verify_signature_ndef_message(ndef_message_s *msg)
269 ndef_record_s *begin_record = NULL;
270 ndef_record_s *current_record = NULL;
271 net_nfc_error_e result = NET_NFC_UNKNOWN_ERROR;
274 begin_record = msg->records;
275 current_record = msg->records;
277 while (current_record != NULL)
279 if (NULL == begin_record)
280 begin_record = current_record;
282 if (IS_EMPTY_RECORD(current_record))
286 else if (IS_SIGN_RECORD(current_record))
288 result = net_nfc_util_verify_signature_records(begin_record, current_record);
293 current_record = current_record->next;
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)
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;
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);
320 NFC_DBG("total record count : %d, begin_index : %d, end_index : %d", msg->recordCount,
321 begin_index, end_index);
323 /* get target data */
324 _get_records_data_buffer(begin_record, end_record->next, &data_buffer, &data_len);
326 DEBUG_MSG_PRINT_BUFFER(data_buffer, data_len);
328 net_nfc_util_openssl_sign_buffer(NET_NFC_SIGN_TYPE_PKCS_1, data_buffer, data_len,
329 cert_file, password, signature, &sign_len);
332 net_nfc_util_get_cert_list_from_file(cert_file, password, &cert_buffer, &cert_len,
336 payload.length = sizeof(net_nfc_signature_record_s) + sign_len +
337 sizeof(net_nfc_certificate_chain_s) + cert_len;
339 _net_nfc_util_alloc_mem(payload.buffer, payload.length);
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;
347 if (sign_record->uri_present)
353 __FILL_SUB_FIELD(&(sign_record->signature), signature, sign_len);
356 net_nfc_certificate_chain_s *chain =
357 (net_nfc_certificate_chain_s *)__NEXT_SUB_FIELD(&(sign_record->signature));
360 chain->uri_present = 0;
362 chain->uri_present = 1;
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);
368 if (chain->uri_present)
371 NFC_ERR("num_of_certs is greater than 15 [%d]", cert_count);
375 data_s type = { (uint8_t *)"Sig", 3 };
377 net_nfc_util_create_record(NET_NFC_RECORD_WELL_KNOWN_TYPE, &type, NULL,
380 /* get last record index */
381 net_nfc_util_append_record_by_index(msg, end_index + 1, record);
383 _net_nfc_util_free_mem(payload.buffer);
384 _net_nfc_util_free_mem(cert_buffer);
385 _net_nfc_util_free_mem(data_buffer);
390 net_nfc_error_e net_nfc_util_sign_ndef_message(ndef_message_s *msg,
391 char *cert_file, char *password)
393 net_nfc_error_e result = NET_NFC_UNKNOWN_ERROR;
395 if (msg->recordCount > 0)
397 net_nfc_util_sign_records(msg, 0, msg->recordCount - 1, cert_file, password);