bool parse_key(char **pstr, struct crypto_key_t *key) { char *str = *pstr; /* ignore spaces */ while(isspace(*str)) str++; /* CRYPTO_KEY: 32 hex characters * CRYPTO_USBOTP: usbotp(vid:pid) where vid and pid are hex numbers */ if(isxdigit(str[0])) { if(strlen(str) < 32) return false; for(int j = 0; j < 16; j++) { byte a, b; if(convxdigit(str[2 * j], &a) || convxdigit(str[2 * j + 1], &b)) return false; key->u.key[j] = (a << 4) | b; } /* skip key */ *pstr = str + 32; key->method = CRYPTO_KEY; return true; } else { const char *prefix = "usbotp("; if(strlen(str) < strlen(prefix)) return false; if(strncmp(str, prefix, strlen(prefix)) != 0) return false; str += strlen(prefix); /* vid */ long vid = strtol(str, &str, 16); if(vid < 0 || vid > 0xffff) return false; if(*str++ != ':') return false; /* pid */ long pid = strtol(str, &str, 16); if(pid < 0 || pid > 0xffff) return false; if(*str++ != ')') return false; *pstr = str; key->method = CRYPTO_USBOTP; key->u.vid_pid = vid << 16 | pid; return true; } }
static key_array_t read_keys(int num_keys) { int size; struct stat st; int fd = open(key_file,O_RDONLY); if(fd == -1) bugp("opening key file failed"); if(fstat(fd,&st) == -1) bugp("key file stat() failed"); size = st.st_size; char *buf = xmalloc(size); if(read(fd, buf, size) != (ssize_t)size) bugp("reading key file"); close(fd); key_array_t keys = xmalloc(sizeof(byte[16]) * num_keys); int pos = 0; for(int i = 0; i < num_keys; i++) { /* skip ws */ while(pos < size && isspace(buf[pos])) pos++; /* enough space ? */ if((pos + 32) > size) bugp("invalid key file (not enough keys)"); for(int j = 0; j < 16; j++) { byte a, b; if(convxdigit(buf[pos + 2 * j], &a) || convxdigit(buf[pos + 2 * j + 1], &b)) bugp(" invalid key, it should be a 128-bit key written in hexadecimal\n"); keys[i][j] = (a << 4) | b; } pos += 32; } free(buf); return keys; }
static void cgi_unescape_url(const char *s, const char *l, char *&r_s, char*& r_l) { char *rs, *rl; rs = new char[l - s + 1]; rl = rs; while(s < l) { if (*s == '+') { *rl++ = ' '; s += 1; } else if (*s == '%') { if (l - s < 3) break; if (isxdigit(s[1]) && isxdigit(s[2])) *rl++ = (convxdigit(s[1]) << 4) | (convxdigit(s[2])); s += 3; if (rl - rs >= 2 && rl[-1] == 10 && rl[-2] == 13) { rl[-2] = 10; rl -= 1; } } else *rl++ = *s++; } r_s = rs; r_l = rl; }
static void parse_number(struct context_t *ctx, struct lexem_t *lexem) { locate_lexem(lexem, ctx); /* check base */ int base = 10; if(cur_char(ctx) == '0' && next_valid(ctx, 1) && next_char(ctx, 1) == 'x') { advance(ctx, 2); base = 16; } lexem->type = LEX_NUMBER; lexem->num = 0; while(!eof(ctx) && isxdigit(cur_char(ctx))) { if(base == 10 && !isdigit(cur_char(ctx))) break; byte v; if(convxdigit(cur_char(ctx), &v)) break; lexem->num = base * lexem->num + v; advance(ctx, 1); } }