2 * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (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://www.apache.org/licenses/LICENSE-2.0
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.
17 * @file detail_info_cert.c
18 * @author Janusz Kozerski (j.kozerski@samsung.com)
22 #include <cert-svc/ccert.h>
23 #include <cert-svc/cinstance.h>
24 #include <cert-svc/cpkcs12.h>
25 #include <cert-svc/cstring.h>
28 #include <vconf-keys.h>
29 #include <unicode/udat.h>
30 #include <unicode/ustring.h>
31 #include <unicode/uloc.h>
32 #include <unicode/ucal.h>
33 #include <unicode/udatpg.h>
34 #include <unicode/utmscale.h>
35 #include <system_settings.h>
37 #include "common-utils.h"
38 #include "certificates/certificate_util.h"
40 static char *format_key (char *key);
41 Eina_Bool _back(void *data, Elm_Object_Item *it);
43 #define UG_ICU_ARR_LENGTH 256
44 #define UG_DATE_FORMAT_12 "yMMMdEhhmms"
45 #define UG_DATE_FORMAT_24 "yMMMdEHHmms"
47 /* for language instance */
48 CertSvcCertificate certInstance;
50 #define NUMBER_OF_CERT_FIELDS 12
51 static const CertSvcCertificateField field_name[NUMBER_OF_CERT_FIELDS] = {
52 CERTSVC_SUBJECT_COMMON_NAME,
53 CERTSVC_SUBJECT_ORGANIZATION_NAME,
54 CERTSVC_ISSUER_COMMON_NAME,
55 CERTSVC_ISSUER_ORGANIZATION_NAME,
57 CERTSVC_SUBJECT, /* Filler for CERTSVC_VALID_TO */
58 CERTSVC_SUBJECT, /* Filler for CERTSVC_VALID_FROM */
59 CERTSVC_SERIAL_NUMBER,
60 CERTSVC_SIGNATURE_ALGORITHM,
62 CERTSVC_SUBJECT, /* Filler for "is CA certificate?" */
66 typedef enum __cert_info_group {
72 static char *_get_icu_time_string(const char *locale, const char *customSkeleton, const char *timezone, UDate date)
75 Copy a byte string encoded in the default codepage to a ustring.
76 Copies at most n characters. The result will be null terminated if the length of src is less than n. Performs a host byte to UChar conversion
78 UChar ucustomSkeleton[UG_ICU_ARR_LENGTH] = {0,};
80 if (u_uastrncpy(ucustomSkeleton, customSkeleton, UG_ICU_ARR_LENGTH) == NULL) {
81 LOGE("u_uastrncpy() error.");
85 UChar utimezone[UG_ICU_ARR_LENGTH] = {0,};
87 if (u_uastrncpy(utimezone, timezone, UG_ICU_ARR_LENGTH) == NULL) {
88 LOGE("u_uastrncpy() error.");
92 UErrorCode status = U_ZERO_ERROR;
93 ucal_setDefaultTimeZone(utimezone, &status);
95 if (U_FAILURE(status)) {
96 LOGE("ucal_setDefaultTimeZone() is failed");
100 uloc_setDefault(secure_getenv("LC_TIME"), &status);
102 if (U_FAILURE(status)) {
103 LOGE("ucal_setDefaultTimeZone() is failed");
107 UDateTimePatternGenerator *generator = udatpg_open(locale, &status);
108 if (generator == NULL)
111 UChar bestPattern[UG_ICU_ARR_LENGTH] = {0,};
112 int32_t bestPatternLength = udatpg_getBestPattern(generator, ucustomSkeleton, u_strlen(ucustomSkeleton), bestPattern, UG_ICU_ARR_LENGTH, &status);
113 if (bestPatternLength <= 0)
116 UDateFormat *formatter = udat_open(UDAT_IGNORE, UDAT_IGNORE, locale, NULL, -1, bestPattern, -1, &status);
120 UChar formatted[UG_ICU_ARR_LENGTH] = {0,};
121 int32_t formattedLength = udat_format(formatter, date, formatted, UG_ICU_ARR_LENGTH, NULL, &status);
122 if (formattedLength <= 0)
125 char formattedString[UG_ICU_ARR_LENGTH] = {0,};
126 u_austrcpy(formattedString, formatted);
127 udatpg_close(generator);
128 udat_close(formatter);
130 if (strlen(formattedString) == 0)
133 return strdup(formattedString);
136 static char *_get_icu_date(time_t mtime)
138 char *skeleton = NULL;
139 bool hours_24 = false;
142 ret = system_settings_get_value_bool(SYSTEM_SETTINGS_KEY_LOCALE_TIMEFORMAT_24HOUR, &hours_24);
143 if (ret != SYSTEM_SETTINGS_ERROR_NONE) {
144 LOGE("Cannot get 24 hours format");
149 if (hours_24 == true)
150 skeleton = UG_DATE_FORMAT_24;
152 skeleton = UG_DATE_FORMAT_12;
155 char *locale = vconf_get_str(VCONFKEY_REGIONFORMAT);
156 if (locale == NULL) {
157 LOGE("Cannot get region format.");
158 /* default value : en_US */
159 locale = strdup("en_US");
162 char *timezone = vconf_get_str(VCONFKEY_SETAPPL_TIMEZONE_ID);
163 if (timezone == NULL) {
164 /* TODO : How to get default time zone? */
165 LOGE("Cannot get time zone");
171 LOGD("Locale:%s TimeZone:%s TimeFormat:%s", locale, skeleton, timezone);
173 char *datestr = _get_icu_time_string(locale, skeleton, timezone, (UDate)mtime * 1000);
178 if (datestr == NULL) {
179 LOGE("Cannot get time string");
187 * This function fill Cert_Data_Field with proper text.
188 * These texts are labels to certificate details
190 static char *_getCertFieldLabel(int index)
192 const char *cert_data_field = NULL;
195 cert_data_field = "IDS_ST_BODY_COMMON_NAME_C";
198 cert_data_field = "IDS_ST_BODY_ORGANISATION_C";
201 cert_data_field = "IDS_ST_BODY_COMMON_NAME_C";
204 cert_data_field = "IDS_ST_BODY_ORGANISATION_C";
207 cert_data_field = "IDS_ST_BODY_VERSION_C";
210 cert_data_field = "IDS_ST_BODY_VALID_FROM_C";
213 cert_data_field = "IDS_ST_BODY_VALID_TO_C";
216 cert_data_field = "IDS_ST_BODY_SERIAL_NUMBER_COLON";
219 cert_data_field = "IDS_ST_BODY_SIGNATURE_ALGORITHM_C";
222 cert_data_field = "IDS_ST_BODY_KEY_USAGE_C";
225 cert_data_field = "IDS_ST_BODY_CERTIFICATION_AUTHORITY_C";
228 cert_data_field = "IDS_ST_BODY_PUBLIC_KEY_C";
231 LOGE("Invalid index of cert field");
235 return strdup(dgettext(PACKAGE, cert_data_field));
238 static void put_no_data_text_if_empty(char **text)
242 } else if (*text == NULL) {
243 *text = strdup(dgettext(PACKAGE, "IDS_ST_BODY_NO_DATA"));
244 } else if (strlen(*text) == 0) {
246 *text = strdup(dgettext(PACKAGE, "IDS_ST_BODY_NO_DATA"));
250 static char *getInfoFromCert(CertSvcCertificate cert, CertSvcCertificateField field, char **buffer)
252 CertSvcString certSvcString_buffer;
253 const char *certSvc_buffer;
256 certsvc_certificate_get_string_field(cert, field, &certSvcString_buffer);
257 certsvc_string_to_cstring(certSvcString_buffer, &certSvc_buffer, &len);
258 *buffer = strndup(certSvc_buffer, len);
259 certsvc_string_free(certSvcString_buffer);
260 LOGD("Cert string field: %s", *buffer);
265 static char *_getCertFieldData(int index)
267 LOGD("fillCertData");
270 CertSvcString buffer;
271 char *char_buffer = NULL;
272 char *cert_Data = NULL;
276 certsvc_certificate_get_not_before(certInstance, &time);
277 cert_Data = _get_icu_date(time);
278 LOGD("Valid from: %s", cert_Data);
282 certsvc_certificate_get_not_after(certInstance, &time);
283 cert_Data = _get_icu_date(time);
284 LOGD("Valid to: %s", cert_Data);
288 certsvc_certificate_is_root_ca(certInstance, &status);
289 if (status == CERTSVC_TRUE)
290 cert_Data = strdup(dgettext(PACKAGE, "IDS_ST_BODY_TRUE"));
291 else if (status == CERTSVC_FALSE)
292 cert_Data = strdup(dgettext(PACKAGE, "IDS_ST_BODY_FALSE"));
297 certsvc_certificate_get_string_field(certInstance, CERTSVC_KEY, &buffer);
298 char_buffer = strndup(buffer.privateHandler, buffer.privateLength);
299 if (char_buffer != NULL) {
300 LOGD("char_buffer : %s", char_buffer);
301 cert_Data = format_key(char_buffer);
303 certsvc_string_free(buffer);
305 if (cert_Data == NULL)
306 SECURE_LOGD("Fail to get cert_Data");
308 SECURE_LOGD("Public Key: %s", cert_Data);
315 * ---- SUBJECT COMMON NAME ----
316 * ---- SUBJECT ORGANIZATION NAME ----
317 * ---- ISSUER COMMON NAME ----
318 * ---- ISSUER ORGANIZATION NAME ----
320 * ---- SERIAL NUMBER ----
321 * ---- SIGNATURE ALGORITHM ----
322 * ---- KEY USAGE ----
324 getInfoFromCert(certInstance, field_name[index], &cert_Data);
328 put_no_data_text_if_empty(&cert_Data);
333 static char *format_key(char *key)
338 int len = strlen(key);
339 const char *public_key_label = "Public-Key: ";
341 char *formated_key = malloc(sizeof(char) * len);
343 if (formated_key == NULL)
346 /* remove whitespaces at the beginning */
347 while ((i < len - 1) && (' ' == key[i]))
350 /* remove the "Public-key: " string at the beginning */
351 if (strncmp(public_key_label, &(key[i]), strlen(public_key_label)) == 0)
352 i += strlen(public_key_label);
354 while (i < len - 1) {
355 if (key[i] == ':' && key[i + 1] == '\n') {
356 formated_key[j] = key[i];
359 } else if (key[i] == ' ' && key[i + 1] == ' ') {
362 formated_key[j++] = key[i++];
365 if (key[i] == 'E' || key[i] == 'M') {
366 formated_key[j++] = '<';
367 formated_key[j++] = 'b';
368 formated_key[j++] = 'r';
369 formated_key[j++] = '>';
373 if (i < len && key[i] != '\n') {
374 formated_key[j++] = key[i++];
377 result = strndup(formated_key, j);
382 static void _gl_realized(void *data, Evas_Object *obj, void *ei)
384 int id = (int)elm_object_item_data_get(ei);
388 else if ((id == 0) || (id == 2) || (id == 4))
389 elm_object_item_signal_emit(ei, "elm,state,top", "");
390 else if ((id == 1) || (id == 3) || (id == 11))
391 elm_object_item_signal_emit(ei, "elm,state,bottom", "");
393 elm_object_item_signal_emit(ei, "elm,state,center", "");
396 static char *_gl_get_text(void *data, Evas_Object *obj, const char *part)
398 int index = (int)data;
399 char *cert_data = NULL;
401 if (strcmp(part, "elm.text.main") == 0)
402 cert_data = _getCertFieldLabel(index);
403 else if (strcmp(part, "elm.text.multiline") == 0)
404 cert_data = _getCertFieldData(index);
406 LOGD("%s", cert_data);
410 static char *_gl_get_text_group(void *data, Evas_Object *obj, const char *part)
412 cert_info_group_e group = (cert_info_group_e)data;
413 const char *text = NULL;
415 if (safeStrCmp(part, "elm.text.main") != 0)
420 text = "IDS_SCP_BODY_OWNER_ABB";
424 text = "IDS_ST_BODY_ISSUER";
428 text = "IDS_ST_BODY_CERTIFICATE_INFORMATION";
432 LOGE("Wrong *index - return NULL");
436 return strdup(dgettext(PACKAGE, text));
439 static Elm_Genlist_Item_Class itc_group = {
440 .item_style = "groupindex",
441 .func.text_get = _gl_get_text_group,
442 .func.content_get = NULL,
443 .func.state_get = NULL,
447 static Elm_Genlist_Item_Class itc_2text = {
448 .item_style = "multiline_sub.main",
449 .func.text_get = _gl_get_text,
450 .func.content_get = NULL,
451 .func.state_get = NULL,
455 static Elm_Genlist_Item_Class separator = {
456 .item_style = "dialogue/separator",
460 void show_detail_info(void)
464 Evas_Object *genlist;
465 struct ug_data *ad = get_ug_data();
470 if (!ad->more_popup2)
471 ad->more_popup2 = (Evas_Object *)(-1);
473 genlist = common_genlist(ad->win_main);
474 evas_object_smart_callback_add(genlist, "realized", _gl_realized, NULL);
475 evas_object_smart_callback_add(genlist, "selected", genlist_clicked_cb, NULL);
477 for (i = 0; i < NUMBER_OF_CERT_FIELDS; i++) {
478 if (field_name[i] == CERTSVC_SUBJECT_COMMON_NAME) {
479 it = elm_genlist_item_append(genlist, &separator, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
480 elm_genlist_item_select_mode_set(it, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
482 it = elm_genlist_item_append(genlist, &itc_group, (void *)OWNER, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
483 elm_genlist_item_select_mode_set(it, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
484 } else if (field_name[i] == CERTSVC_ISSUER_COMMON_NAME) {
485 it = elm_genlist_item_append(genlist, &itc_group, (void *)ISSUER, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
486 elm_genlist_item_select_mode_set(it, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
487 } else if (field_name[i] == CERTSVC_VERSION) {
488 it = elm_genlist_item_append(genlist, &itc_group, (void *)DATA, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
489 elm_genlist_item_select_mode_set(it, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
492 LOGD("Try to append %d genlist item...", i);
494 it = elm_genlist_item_append(genlist, &itc_2text, (void *)i, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
495 elm_genlist_item_select_mode_set(it, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
497 if (field_name[i] == CERTSVC_SUBJECT_ORGANIZATION_NAME
498 || field_name[i] == CERTSVC_ISSUER_ORGANIZATION_NAME
499 || field_name[i] == CERTSVC_KEY) {
500 it = elm_genlist_item_append(genlist, &separator, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
501 elm_genlist_item_select_mode_set(it, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
504 elm_genlist_item_select_mode_set(it, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
505 LOGD("Succesful append %d genlist", i);
508 LOGD("Push genlist");
509 Elm_Object_Item *nf_it = elm_naviframe_item_push(ad->navi_bar, "IDS_ST_BODY_CERTIFICATE_DETAILS", common_back_btn(ad), NULL, genlist, NULL);
510 elm_object_item_domain_text_translatable_set(nf_it, PACKAGE, EINA_TRUE);
511 elm_naviframe_item_pop_cb_set(nf_it, _back, (struct Evas_Object *)ad);
514 #ifdef TIZEN_FEAT_STORE_CAPABILITY
515 void get_info_cert_from_file_cb(struct ug_data *ad, void *list)
517 LOGD("get_info_cert_from_file_cb()");
518 struct ListElement *current = (struct ListElement *)list;
519 if (certsvc_pkcs12_get_certificate_from_store(
523 &certInstance) != CERTSVC_SUCCESS) {
524 LOGE("Unable to load certificate information into the certInstance.");
533 void get_info_cert_from_file_cb(struct ug_data *ad)
535 LOGD("get_info_cert_from_file_cb()");
536 char *cert_path = NULL;
538 if (ad == NULL || ad->data == NULL) {
539 LOGD("ad->data is NULL; return");
543 cert_path = (char *)ad->data;
544 SECURE_LOGD("cert_path = %s", cert_path);
546 LOGD("Get certificate data...");
547 if (CERTSVC_SUCCESS != certsvc_certificate_new_from_file(ad->instance, cert_path, &certInstance)) {
548 SECURE_LOGD("Error in certsvc_certificate_new_from_file( %s )", cert_path);
560 void get_info_cert_from_certificate_cb(CertSvcCertificate cert)
562 LOGD("get_info_cert_from_certificate_cb()");
569 Eina_Bool _back(void *data, Elm_Object_Item *it)
571 struct ug_data *ad = (struct ug_data *) data;
572 ad->more_popup2 = NULL;
573 certsvc_certificate_free(certInstance);
574 memset(&certInstance, 0, sizeof(certInstance));