#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
-#include <openssl/evp.h>
-#include <openssl/rand.h>
+#include <uuid.h>
#include <glib.h>
#define _D(fmt, args...) fprintf(stdout, fmt, ##args)
#define _I(fmt, args...) fprintf(stdout, fmt, ##args)
#define KEY_MAX 20
+#define ID_LEN 28 // ID may be 28 byte or 32 byte. This definition is used as simple checker.
-#define CHAR_POOL "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,.-#'?!"
-
-static int get_pw_key(char *pw, unsigned int len)
-{
- int i, val, poolsize;
- char *charpool = CHAR_POOL;
- unsigned int seed;
-
- if (!pw)
- return -EINVAL;
-
- poolsize = strlen(charpool);
- seed = time(NULL);
-
- for (i = 0 ; i < len ; i++) {
- val = rand_r(&seed) % poolsize;
- pw[i] = *(charpool + val);
- }
-
- return 0;
-}
-
-static int get_salt_by_model(char *salt, unsigned int len)
-{
- int i;
- char *str = NULL, *start, *stop;
- char buf[256];
- char *key = "tizen.org/system/model_name";
- FILE *fp;
-
- if (!salt)
- return -EINVAL;
-
- fp = fopen(CONFIG_FILE_PATH, "r");
- if (!fp) {
- _E("Failed to open (%s)", CONFIG_FILE_PATH);
- return -ENOENT;
- }
-
- while (fgets(buf, sizeof(buf), fp) != NULL) {
- str = strstr(buf, key);
- if (!str)
- continue;
-
- start = strchr(str, '>');
- if (!start)
- continue;
- stop = strchr(str, '<');
- if (!stop)
- continue;
- if (start >= stop)
- continue;
-
- for (start += 1, i = 0; (start < stop) && (i < len-1) ; start++, i++)
- salt[i] = start[i];
-
- salt[i] = '\0';
-
- break;
- }
-
- fclose(fp);
-
- return 0;
-}
+#define ID_SUFFIX "R6SUQ="
+#define ID_SUFFIX_LEN 6
static int store_tizen_id(char *id)
{
return 0;
}
+/***************************************************************************
+ Using uuid to generate New Tizen ID
+
+ 1) uuid generation -> 16 byte
+ 2) add trailing TizenID 4 byte (TzID) -> 20 byte
+ 3) converting to base64 -> (len / 3 + 1) * 4 + 4 byte (Generally, 28 byte)
+
+ uuid_unpars uses base16 encoding.
+ Thus, we will not use uuid_unparse because we want to keep base64 format of TizenID
+
+ You can generate uuid from TizenID by using following method
+ 1) converting to byte array by using base64 decoding
+ 2) remove trailing TizenID 4 byte
+ **************************************************************************/
static int make_tizen_id(void)
{
- char salt[KEY_MAX], pw_key[KEY_MAX];
- char *id = NULL;
- gchar *id_64 = NULL;
+ uuid_t uuid;
+ char id[KEY_MAX];
int ret;
+ gchar *id_64 = NULL;
- ret = get_salt_by_model(salt, sizeof(salt));
- if (ret < 0) {
- _E("Failed to get salt value (%d)", ret);
- return ret;
- }
-
- ret = get_pw_key(pw_key, sizeof(pw_key));
- if (ret < 0) {
- _E("Failed to get pw key value (%d)", ret);
- return ret;
- }
-
- id = (char *)malloc(sizeof(char) * KEY_MAX);
- if (!id) {
- _E("malloc() failed");
- return -ENOMEM;
- }
+ uuid_generate(uuid);
- ret = PKCS5_PBKDF2_HMAC_SHA1(pw_key, strlen(pw_key), /* pw key */
- (unsigned char *)salt, sizeof(salt), /*salt*/
- 1, /* nr of iteration */
- KEY_MAX, (unsigned char *)id); /* output */
- if (ret == 0) { /* 0: failed, 1: successful */
- _E("PKCS5_PBKDF2_HMAC_SHA1() failed");
- ret = -ENOENT;
- goto out;
- }
+ memset(id, 0, KEY_MAX);
+ memcpy(id, uuid, 16);
- id[KEY_MAX-1] = '\0';
- _I("ID: (%s)", id);
+ id[16] = 'T';
+ id[17] = 'z';
+ id[18] = 'I';
+ id[19] = 'D';
id_64 = g_base64_encode((const guchar *)id, KEY_MAX);
}
ret = 0;
-
out:
- if (id)
- free(id);
if (id_64)
g_free(id_64);
return ret;
}
+// : After reading data, we need to decode base64 and we should check TizenID byte "TzID" to check whether the id is correct or not.
+// : Or it can be checked directly because based64-encoded TizenID should include "R6SUQ=" as trailer.
static int check_tizen_id_content(void)
{
FILE *fp;
int ret;
- char id[KEY_MAX] = {0, };
+ char id[ID_LEN + 1] = {0, };
+ int len;
fp = fopen(TIZEN_ID_PATH, "r");
if (!fp) {
fclose(fp);
- if (strlen(id) == 0) {
- _E("Invalid Tizen ID (empty)");
- return -ENOENT;
+ len = strlen(id);
+ if (len != ID_LEN && len != (ID_LEN + 4)) {
+ _E("Invalid Tizen ID (invalid length)");
+ return -EINVAL;
+ }
+
+ if (strncmp(id + (len - ID_SUFFIX_LEN), ID_SUFFIX, ID_SUFFIX_LEN)) {
+ _E("Invalid Tizen ID (invalid suffix)");
+ return -EINVAL;
}
return 0;
switch (mode) {
case S_IFREG:
if (check_tizen_id_content() < 0) {
- _I("Tizen ID is empty");
+ _I("Invalid Tizen ID");
break;
}
_I("Tizen ID already exists");