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, ndef_record_s *end_record, uint8_t **buffer, uint32_t *length)
46 ndef_record_s *current_record = NULL;
48 if (begin_record == NULL || begin_record == end_record)
51 /* count total buffer length */
52 current_record = begin_record;
55 while (current_record != NULL && current_record != end_record)
58 if (current_record->type_s.buffer != NULL && current_record->type_s.length > 0)
59 len += current_record->type_s.length;
62 if (current_record->id_s.buffer != NULL && current_record->id_s.length > 0)
63 len += current_record->id_s.length;
66 if (current_record->payload_s.buffer != NULL && current_record->payload_s.length > 0)
67 len += current_record->payload_s.length;
69 current_record = current_record->next;
76 _net_nfc_util_alloc_mem(buf, len);
81 current_record = begin_record;
83 while (offset < len && current_record != NULL && current_record != end_record)
86 if (current_record->type_s.buffer != NULL && current_record->type_s.length > 0)
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);
93 if (current_record->id_s.buffer != NULL && current_record->id_s.length > 0)
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);
100 if (current_record->payload_s.buffer != NULL && current_record->payload_s.length > 0)
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);
106 current_record = current_record->next;
119 net_nfc_error_e net_nfc_util_verify_signature_records(ndef_record_s *begin_record, ndef_record_s *sign_record)
121 net_nfc_error_e result = NET_NFC_UNKNOWN_ERROR;
122 uint8_t *buffer = NULL;
125 if (begin_record == NULL || sign_record == NULL || begin_record == sign_record)
126 return NET_NFC_INVALID_PARAM;
128 /* get signed data */
129 if (_get_records_data_buffer(begin_record, sign_record, &buffer, &length) == true)
131 net_nfc_signature_record_s *sign_info = NULL;
132 net_nfc_certificate_chain_s *chain_info = NULL;
134 /* parse signature info */
135 sign_info = (net_nfc_signature_record_s *)sign_record->payload_s.buffer;
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);
142 if (sign_info->uri_present == true)
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);
151 /* parse certificate chain info */
152 chain_info = (net_nfc_certificate_chain_s *)__NEXT_SUB_FIELD(&(sign_info->signature));
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);
158 if (chain_info->num_of_certs > 0)
160 net_nfc_sub_field_s *data_info = NULL;
162 data_info = (net_nfc_sub_field_s *)chain_info->cert_store;
163 DEBUG_MSG("certficate length : %d", data_info->length);
165 // DEBUG_MSG_PRINT_BUFFER(data_info->value, data_info->length);
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)
171 if (chain_info->num_of_certs > 1)
174 net_nfc_openssl_verify_context_h context = NULL;
176 /* initialize context of verifying certificate */
177 context = net_nfc_util_openssl_init_verify_certificate();
179 /* add signer's certificate */
180 net_nfc_util_openssl_add_certificate_of_signer(context, data_info->value, data_info->length);
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))
187 DEBUG_MSG("certficate length : %d", data_info->length);
188 //DEBUG_MSG_PRINT_BUFFER(data_info->value, data_info->length);
190 net_nfc_util_openssl_add_certificate_of_ca(context, data_info->value, data_info->length);
193 /* if the CA_Uri is present, continue adding certificate from uri */
194 if (chain_info->uri_present == true)
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);
202 //DEBUG_MSG("certficate length : %d", data_info->length);
203 //DEBUG_MSG_PRINT_BUFFER(data_info->value, data_info->length);
206 /* verify buffer with cert chain and signature bytes */
207 if (net_nfc_util_openssl_verify_certificate(context) == true)
210 net_nfc_util_openssl_release_verify_certificate(context);
214 /* TODO : test certificate??? */
218 DEBUG_MSG("verifying signature %d", result);
222 DEBUG_ERR_MSG("verifying signature failed");
227 DEBUG_ERR_MSG("certificate not found");
230 _net_nfc_util_free_mem(buffer);
236 _net_nfc_util_free_mem(buffer);
238 DEBUG_ERR_MSG("_get_records_data_buffer failed");
244 net_nfc_error_e net_nfc_util_verify_signature_ndef_message(ndef_message_s *msg)
246 net_nfc_error_e result = NET_NFC_UNKNOWN_ERROR;
247 ndef_record_s *begin_record = NULL;
248 ndef_record_s *current_record = NULL;
250 begin_record = msg->records;
251 current_record = msg->records;
253 while (current_record != NULL)
255 if (begin_record == NULL)
257 begin_record = current_record;
260 if (IS_EMPTY_RECORD(current_record))
264 else if (IS_SIGN_RECORD(current_record))
266 result = net_nfc_util_verify_signature_records(begin_record, current_record);
271 current_record = current_record->next;
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)
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;
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);
296 DEBUG_MSG("total record count : %d, begin_index : %d, end_index : %d", msg->recordCount, begin_index, end_index);
298 /* get target data */
299 _get_records_data_buffer(begin_record, end_record->next, &data_buffer, &data_len);
301 DEBUG_MSG_PRINT_BUFFER(data_buffer, data_len);
303 net_nfc_util_openssl_sign_buffer(NET_NFC_SIGN_TYPE_PKCS_1, data_buffer, data_len, cert_file, password, signature, &sign_len);
306 net_nfc_util_get_cert_list_from_file(cert_file, password, &cert_buffer, &cert_len, &cert_count);
309 payload.length = sizeof(net_nfc_signature_record_s) + sign_len + sizeof(net_nfc_certificate_chain_s) + cert_len;
311 _net_nfc_util_alloc_mem(payload.buffer, payload.length);
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;
318 if (sign_record->uri_present)
324 __FILL_SUB_FIELD(&(sign_record->signature), signature, sign_len);
327 net_nfc_certificate_chain_s *chain = (net_nfc_certificate_chain_s *)__NEXT_SUB_FIELD(&(sign_record->signature));
330 chain->uri_present = 0;
334 chain->uri_present = 1;
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);
341 if (chain->uri_present)
344 DEBUG_ERR_MSG("num_of_certs is greater than 15 [%d]", cert_count);
348 data_s type = { (uint8_t *)"Sig", 3 };
350 net_nfc_util_create_record(NET_NFC_RECORD_WELL_KNOWN_TYPE, &type, NULL, &payload, &record);
352 /* get last record index */
353 net_nfc_util_append_record_by_index(msg, end_index + 1, record);
355 _net_nfc_util_free_mem(payload.buffer);
356 _net_nfc_util_free_mem(cert_buffer);
357 _net_nfc_util_free_mem(data_buffer);
362 net_nfc_error_e net_nfc_util_sign_ndef_message(ndef_message_s *msg, char *cert_file, char *password)
364 net_nfc_error_e result = NET_NFC_UNKNOWN_ERROR;
366 if (msg->recordCount > 0)
368 net_nfc_util_sign_records(msg, 0, msg->recordCount - 1, cert_file, password);