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 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;
136 /* parse signature info */
137 sign_info = (net_nfc_signature_record_s *)sign_record->payload_s.buffer;
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);
144 if (sign_info->uri_present == true)
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);
154 signature = sign_info->signature.value;
155 sign_len = sign_info->signature.length;
158 /* parse certificate chain info */
159 chain_info = (net_nfc_certificate_chain_s *)__NEXT_SUB_FIELD(&(sign_info->signature));
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);
165 if (chain_info->num_of_certs > 0)
167 net_nfc_sub_field_s *data_info = NULL;
169 data_info = (net_nfc_sub_field_s *)chain_info->cert_store;
170 DEBUG_MSG("certficate length : %d", data_info->length);
172 // DEBUG_MSG_PRINT_BUFFER(data_info->value, data_info->length);
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)
178 if (chain_info->num_of_certs > 1)
181 net_nfc_openssl_verify_context_h context = NULL;
183 /* initialize context of verifying certificate */
184 context = net_nfc_util_openssl_init_verify_certificate();
186 /* add signer's certificate */
187 net_nfc_util_openssl_add_certificate_of_signer(context, data_info->value, data_info->length);
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))
194 DEBUG_MSG("certficate length : %d", data_info->length);
195 //DEBUG_MSG_PRINT_BUFFER(data_info->value, data_info->length);
197 net_nfc_util_openssl_add_certificate_of_ca(context, data_info->value, data_info->length);
200 /* if the CA_Uri is present, continue adding certificate from uri */
201 if (chain_info->uri_present == true)
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);
209 //DEBUG_MSG("certficate length : %d", data_info->length);
210 //DEBUG_MSG_PRINT_BUFFER(data_info->value, data_info->length);
213 /* verify buffer with cert chain and signature bytes */
214 if (net_nfc_util_openssl_verify_certificate(context) == true)
217 net_nfc_util_openssl_release_verify_certificate(context);
221 /* TODO : test certificate??? */
225 DEBUG_MSG("verifying signature %d", result);
229 DEBUG_ERR_MSG("verifying signature failed");
234 DEBUG_ERR_MSG("certificate not found");
237 _net_nfc_util_free_mem(buffer);
243 _net_nfc_util_free_mem(buffer);
245 DEBUG_ERR_MSG("_get_records_data_buffer failed");
251 net_nfc_error_e net_nfc_util_verify_signature_ndef_message(ndef_message_s *msg)
253 net_nfc_error_e result = NET_NFC_UNKNOWN_ERROR;
254 ndef_record_s *begin_record = NULL;
255 ndef_record_s *current_record = NULL;
257 begin_record = msg->records;
258 current_record = msg->records;
260 while (current_record != NULL)
262 if (begin_record == NULL)
264 begin_record = current_record;
267 if (IS_EMPTY_RECORD(current_record))
271 else if (IS_SIGN_RECORD(current_record))
273 result = net_nfc_util_verify_signature_records(begin_record, current_record);
278 current_record = current_record->next;
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)
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;
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);
303 DEBUG_MSG("total record count : %d, begin_index : %d, end_index : %d", msg->recordCount, begin_index, end_index);
305 /* get target data */
306 _get_records_data_buffer(begin_record, end_record->next, &data_buffer, &data_len);
308 DEBUG_MSG_PRINT_BUFFER(data_buffer, data_len);
310 net_nfc_util_openssl_sign_buffer(NET_NFC_SIGN_TYPE_PKCS_1, data_buffer, data_len, cert_file, password, signature, &sign_len);
313 net_nfc_util_get_cert_list_from_file(cert_file, password, &cert_buffer, &cert_len, &cert_count);
316 payload.length = sizeof(net_nfc_signature_record_s) + sign_len + sizeof(net_nfc_certificate_chain_s) + cert_len;
318 _net_nfc_util_alloc_mem(payload.buffer, payload.length);
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;
325 if (sign_record->uri_present)
331 __FILL_SUB_FIELD(&(sign_record->signature), signature, sign_len);
334 net_nfc_certificate_chain_s *chain = (net_nfc_certificate_chain_s *)__NEXT_SUB_FIELD(&(sign_record->signature));
337 chain->uri_present = 0;
341 chain->uri_present = 1;
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);
348 if (chain->uri_present)
351 DEBUG_ERR_MSG("num_of_certs is greater than 15 [%d]", cert_count);
355 data_s type = { (uint8_t *)"Sig", 3 };
357 net_nfc_util_create_record(NET_NFC_RECORD_WELL_KNOWN_TYPE, &type, NULL, &payload, &record);
359 /* get last record index */
360 net_nfc_util_append_record_by_index(msg, end_index + 1, record);
362 _net_nfc_util_free_mem(payload.buffer);
363 _net_nfc_util_free_mem(cert_buffer);
364 _net_nfc_util_free_mem(data_buffer);
369 net_nfc_error_e net_nfc_util_sign_ndef_message(ndef_message_s *msg, char *cert_file, char *password)
371 net_nfc_error_e result = NET_NFC_UNKNOWN_ERROR;
373 if (msg->recordCount > 0)
375 net_nfc_util_sign_records(msg, 0, msg->recordCount - 1, cert_file, password);