blob: 7271ca8ab777bcd476c91ed6fd4c47396b6f3862 [file] [log] [blame]
Amaury Pouly9fe029b2011-10-29 14:22:17 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2010 Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include <stdlib.h>
22#include <stdio.h>
23#include <time.h>
24#include <ctype.h>
25#include "misc.h"
26
27bool g_debug = false;
28
29/**
30 * Misc
31 */
Amaury Pouly58279372011-11-06 01:49:13 +000032
Amaury Poulyad9e2802011-11-06 19:41:25 +000033void *memdup(const void *p, size_t len)
Amaury Pouly58279372011-11-06 01:49:13 +000034{
35 void *cpy = xmalloc(len);
36 memcpy(cpy, p, len);
37 return cpy;
38}
39
Amaury Pouly9fe029b2011-10-29 14:22:17 +000040void generate_random_data(void *buf, size_t sz)
41{
42 FILE *rand_fd = fopen("/dev/urandom", "rb");
43 if(rand_fd == NULL)
44 bugp("failed to open /dev/urandom");
45 if(fread(buf, 1, sz, rand_fd) != sz)
46 bugp("failed to read /dev/urandom");
47 fclose(rand_fd);
48}
49
50void *xmalloc(size_t s)
51{
52 void * r = malloc(s);
53 if(!r) bugp("malloc");
54 return r;
55}
56
57int convxdigit(char digit, byte *val)
58{
59 if(digit >= '0' && digit <= '9')
60 {
61 *val = digit - '0';
62 return 0;
63 }
64 else if(digit >= 'A' && digit <= 'F')
65 {
66 *val = digit - 'A' + 10;
67 return 0;
68 }
69 else if(digit >= 'a' && digit <= 'f')
70 {
71 *val = digit - 'a' + 10;
72 return 0;
73 }
74 else
75 return 1;
76}
77
Amaury Poulyd2a58f32011-10-29 17:01:47 +000078/* helper function to augment an array, free old array */
79void *augment_array(void *arr, size_t elem_sz, size_t cnt, void *aug, size_t aug_cnt)
80{
81 void *p = xmalloc(elem_sz * (cnt + aug_cnt));
82 memcpy(p, arr, elem_sz * cnt);
83 memcpy(p + elem_sz * cnt, aug, elem_sz * aug_cnt);
84 free(arr);
85 return p;
86}
87
Amaury Pouly9fe029b2011-10-29 14:22:17 +000088/**
89 * Key file parsing
90 */
91int g_nr_keys;
92key_array_t g_key_array;
93
Amaury Poulyd2a58f32011-10-29 17:01:47 +000094bool parse_key(char **pstr, struct crypto_key_t *key)
95{
96 char *str = *pstr;
97 /* ignore spaces */
98 while(isspace(*str))
99 str++;
100 /* CRYPTO_KEY: 32 hex characters
101 * CRYPTO_USBOTP: usbotp(vid:pid) where vid and pid are hex numbers */
102 if(isxdigit(str[0]))
103 {
104 if(strlen(str) < 32)
105 return false;
106 for(int j = 0; j < 16; j++)
107 {
108 byte a, b;
109 if(convxdigit(str[2 * j], &a) || convxdigit(str[2 * j + 1], &b))
110 return false;
111 key->u.key[j] = (a << 4) | b;
112 }
113 /* skip key */
114 *pstr = str + 32;
115 key->method = CRYPTO_KEY;
116 return true;
117 }
118 else
119 {
120 const char *prefix = "usbotp(";
121 if(strlen(str) < strlen(prefix))
122 return false;
123 if(strncmp(str, prefix, strlen(prefix)) != 0)
124 return false;
125 str += strlen(prefix);
126 /* vid */
127 long vid = strtol(str, &str, 16);
128 if(vid < 0 || vid > 0xffff)
129 return false;
130 if(*str++ != ':')
131 return false;
132 /* pid */
133 long pid = strtol(str, &str, 16);
134 if(pid < 0 || pid > 0xffff)
135 return false;
136 if(*str++ != ')')
137 return false;
138 *pstr = str;
139 key->method = CRYPTO_USBOTP;
140 key->u.vid_pid = vid << 16 | pid;
141 return true;
142 }
143}
144
Amaury Pouly9fe029b2011-10-29 14:22:17 +0000145void add_keys(key_array_t ka, int kac)
146{
147 key_array_t new_ka = xmalloc((g_nr_keys + kac) * sizeof(struct crypto_key_t));
148 memcpy(new_ka, g_key_array, g_nr_keys * sizeof(struct crypto_key_t));
149 memcpy(new_ka + g_nr_keys, ka, kac * sizeof(struct crypto_key_t));
150 free(g_key_array);
151 g_key_array = new_ka;
152 g_nr_keys += kac;
153}
154
Amaury Pouly58279372011-11-06 01:49:13 +0000155void clear_keys()
156{
157 free(g_key_array);
158 g_nr_keys = 0;
Amaury Poulyad9e2802011-11-06 19:41:25 +0000159 g_key_array = NULL;
Amaury Pouly58279372011-11-06 01:49:13 +0000160}
161
Amaury Poulyd2a58f32011-10-29 17:01:47 +0000162void add_keys_from_file(const char *key_file)
Amaury Pouly9fe029b2011-10-29 14:22:17 +0000163{
164 int size;
165 FILE *fd = fopen(key_file, "r");
166 if(fd == NULL)
Amaury Poulyd2a58f32011-10-29 17:01:47 +0000167 bug("opening key file failed");
Amaury Pouly9fe029b2011-10-29 14:22:17 +0000168 fseek(fd, 0, SEEK_END);
169 size = ftell(fd);
170 fseek(fd, 0, SEEK_SET);
Amaury Poulyd2a58f32011-10-29 17:01:47 +0000171 char *buf = xmalloc(size + 1);
172 if(fread(buf, 1, size, fd) != (size_t)size)
173 bug("reading key file");
174 buf[size] = 0;
Amaury Pouly9fe029b2011-10-29 14:22:17 +0000175 fclose(fd);
176
177 if(g_debug)
178 printf("Parsing key file '%s'...\n", key_file);
Amaury Poulyd2a58f32011-10-29 17:01:47 +0000179 char *p = buf;
180 while(1)
Amaury Pouly9fe029b2011-10-29 14:22:17 +0000181 {
Amaury Poulyd2a58f32011-10-29 17:01:47 +0000182 struct crypto_key_t k;
183 /* parse key */
184 if(!parse_key(&p, &k))
185 bug("invalid key file");
Amaury Pouly9fe029b2011-10-29 14:22:17 +0000186 if(g_debug)
187 {
188 printf("Add key: ");
Amaury Poulyd2a58f32011-10-29 17:01:47 +0000189 print_key(&k, true);
Amaury Pouly9fe029b2011-10-29 14:22:17 +0000190 }
Amaury Poulyd2a58f32011-10-29 17:01:47 +0000191 add_keys(&k, 1);
192 /* request at least one space character before next key, or end of file */
193 if(*p != 0 && !isspace(*p))
194 bug("invalid key file");
195 /* skip whitespace */
196 while(isspace(*p))
197 p++;
198 if(*p == 0)
199 break;
Amaury Pouly9fe029b2011-10-29 14:22:17 +0000200 }
201 free(buf);
Amaury Pouly9fe029b2011-10-29 14:22:17 +0000202}
203
204void print_hex(byte *data, int len, bool newline)
205{
206 for(int i = 0; i < len; i++)
207 printf("%02X ", data[i]);
208 if(newline)
209 printf("\n");
210}
211
212void print_key(struct crypto_key_t *key, bool newline)
213{
214 switch(key->method)
215 {
216 case CRYPTO_KEY:
217 print_hex(key->u.key, 16, false);
218 break;
219 case CRYPTO_USBOTP:
220 printf("USB-OTP(%04x:%04x)", key->u.vid_pid >> 16, key->u.vid_pid & 0xffff);
221 break;
222 case CRYPTO_NONE:
223 printf("none");
224 break;
225 }
226 if(newline)
227 printf("\n");
228}
Amaury Pouly591ec032011-11-01 11:23:24 +0000229
230char OFF[] = { 0x1b, 0x5b, 0x31, 0x3b, '0', '0', 0x6d, '\0' };
231
232char GREY[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '0', 0x6d, '\0' };
233char RED[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '1', 0x6d, '\0' };
234char GREEN[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '2', 0x6d, '\0' };
235char YELLOW[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '3', 0x6d, '\0' };
236char BLUE[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '4', 0x6d, '\0' };
237
238static bool g_color_enable = true;
239
240void enable_color(bool enable)
241{
242 g_color_enable = enable;
243}
244
245void color(color_t c)
246{
247 if(g_color_enable)
248 printf("%s", (char *)c);
249}