summaryrefslogtreecommitdiff
path: root/utils/sbtools/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils/sbtools/misc.c')
-rw-r--r--utils/sbtools/misc.c127
1 files changed, 83 insertions, 44 deletions
diff --git a/utils/sbtools/misc.c b/utils/sbtools/misc.c
index 09a8919aef..39934951ae 100644
--- a/utils/sbtools/misc.c
+++ b/utils/sbtools/misc.c
@@ -29,13 +29,6 @@ bool g_debug = false;
29/** 29/**
30 * Misc 30 * Misc
31 */ 31 */
32
33char *s_getenv(const char *name)
34{
35 char *s = getenv(name);
36 return s ? s : "";
37}
38
39void generate_random_data(void *buf, size_t sz) 32void generate_random_data(void *buf, size_t sz)
40{ 33{
41 FILE *rand_fd = fopen("/dev/urandom", "rb"); 34 FILE *rand_fd = fopen("/dev/urandom", "rb");
@@ -74,12 +67,73 @@ int convxdigit(char digit, byte *val)
74 return 1; 67 return 1;
75} 68}
76 69
70/* helper function to augment an array, free old array */
71void *augment_array(void *arr, size_t elem_sz, size_t cnt, void *aug, size_t aug_cnt)
72{
73 void *p = xmalloc(elem_sz * (cnt + aug_cnt));
74 memcpy(p, arr, elem_sz * cnt);
75 memcpy(p + elem_sz * cnt, aug, elem_sz * aug_cnt);
76 free(arr);
77 return p;
78}
79
77/** 80/**
78 * Key file parsing 81 * Key file parsing
79 */ 82 */
80int g_nr_keys; 83int g_nr_keys;
81key_array_t g_key_array; 84key_array_t g_key_array;
82 85
86bool parse_key(char **pstr, struct crypto_key_t *key)
87{
88 char *str = *pstr;
89 /* ignore spaces */
90 while(isspace(*str))
91 str++;
92 /* CRYPTO_KEY: 32 hex characters
93 * CRYPTO_USBOTP: usbotp(vid:pid) where vid and pid are hex numbers */
94 if(isxdigit(str[0]))
95 {
96 if(strlen(str) < 32)
97 return false;
98 for(int j = 0; j < 16; j++)
99 {
100 byte a, b;
101 if(convxdigit(str[2 * j], &a) || convxdigit(str[2 * j + 1], &b))
102 return false;
103 key->u.key[j] = (a << 4) | b;
104 }
105 /* skip key */
106 *pstr = str + 32;
107 key->method = CRYPTO_KEY;
108 return true;
109 }
110 else
111 {
112 const char *prefix = "usbotp(";
113 if(strlen(str) < strlen(prefix))
114 return false;
115 if(strncmp(str, prefix, strlen(prefix)) != 0)
116 return false;
117 str += strlen(prefix);
118 /* vid */
119 long vid = strtol(str, &str, 16);
120 if(vid < 0 || vid > 0xffff)
121 return false;
122 if(*str++ != ':')
123 return false;
124 /* pid */
125 long pid = strtol(str, &str, 16);
126 if(pid < 0 || pid > 0xffff)
127 return false;
128 if(*str++ != ')')
129 return false;
130 *pstr = str;
131 key->method = CRYPTO_USBOTP;
132 key->u.vid_pid = vid << 16 | pid;
133 return true;
134 }
135}
136
83void add_keys(key_array_t ka, int kac) 137void add_keys(key_array_t ka, int kac)
84{ 138{
85 key_array_t new_ka = xmalloc((g_nr_keys + kac) * sizeof(struct crypto_key_t)); 139 key_array_t new_ka = xmalloc((g_nr_keys + kac) * sizeof(struct crypto_key_t));
@@ -90,61 +144,46 @@ void add_keys(key_array_t ka, int kac)
90 g_nr_keys += kac; 144 g_nr_keys += kac;
91} 145}
92 146
93key_array_t read_keys(const char *key_file, int *num_keys) 147void add_keys_from_file(const char *key_file)
94{ 148{
95 int size; 149 int size;
96 FILE *fd = fopen(key_file, "r"); 150 FILE *fd = fopen(key_file, "r");
97 if(fd == NULL) 151 if(fd == NULL)
98 bugp("opening key file failed"); 152 bug("opening key file failed");
99 fseek(fd, 0, SEEK_END); 153 fseek(fd, 0, SEEK_END);
100 size = ftell(fd); 154 size = ftell(fd);
101 fseek(fd, 0, SEEK_SET); 155 fseek(fd, 0, SEEK_SET);
102 char *buf = xmalloc(size); 156 char *buf = xmalloc(size + 1);
103 if(fread(buf, size, 1, fd) != (size_t)size) 157 if(fread(buf, 1, size, fd) != (size_t)size)
104 bugp("reading key file"); 158 bug("reading key file");
159 buf[size] = 0;
105 fclose(fd); 160 fclose(fd);
106 161
107 if(g_debug) 162 if(g_debug)
108 printf("Parsing key file '%s'...\n", key_file); 163 printf("Parsing key file '%s'...\n", key_file);
109 *num_keys = size ? 1 : 0; 164 char *p = buf;
110 char *ptr = buf; 165 while(1)
111 /* allow trailing newline at the end (but no space after it) */
112 while(ptr != buf + size && (ptr + 1) != buf + size)
113 {
114 if(*ptr++ == '\n')
115 (*num_keys)++;
116 }
117
118 key_array_t keys = xmalloc(sizeof(struct crypto_key_t) * *num_keys);
119 int pos = 0;
120 for(int i = 0; i < *num_keys; i++)
121 { 166 {
122 /* skip ws */ 167 struct crypto_key_t k;
123 while(pos < size && isspace(buf[pos])) 168 /* parse key */
124 pos++; 169 if(!parse_key(&p, &k))
125 /* enough space ? */ 170 bug("invalid key file");
126 if((pos + 32) > size)
127 bugp("invalid key file");
128 keys[i].method = CRYPTO_KEY;
129 for(int j = 0; j < 16; j++)
130 {
131 byte a, b;
132 if(convxdigit(buf[pos + 2 * j], &a) || convxdigit(buf[pos + 2 * j + 1], &b))
133 bugp(" invalid key, it should be a 128-bit key written in hexadecimal\n");
134 keys[i].u.key[j] = (a << 4) | b;
135 }
136 if(g_debug) 171 if(g_debug)
137 { 172 {
138 printf("Add key: "); 173 printf("Add key: ");
139 for(int j = 0; j < 16; j++) 174 print_key(&k, true);
140 printf("%02x", keys[i].u.key[j]);
141 printf("\n");
142 } 175 }
143 pos += 32; 176 add_keys(&k, 1);
177 /* request at least one space character before next key, or end of file */
178 if(*p != 0 && !isspace(*p))
179 bug("invalid key file");
180 /* skip whitespace */
181 while(isspace(*p))
182 p++;
183 if(*p == 0)
184 break;
144 } 185 }
145 free(buf); 186 free(buf);
146
147 return keys;
148} 187}
149 188
150void print_hex(byte *data, int len, bool newline) 189void print_hex(byte *data, int len, bool newline)