otp-parse.c revision f0339f522dc9c8e2e8a29ef9a3f937c431c6bd1b
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher * OTP extended response parser.
33396dc46ea52c18f47db1b5d590880806521005Sumit Bose * Copyright (c) 2006 Andrey Panin <pazke@donpac.ru>
33396dc46ea52c18f47db1b5d590880806521005Sumit Bose * This software is released under the MIT license.
002f84aea86371aa079b867c0ec39396b97109d3Lukas Slebodnik#define IS_LWS(c) ((c) == ' ' || (c) == '\t')
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic inline const char *otp_skip_lws(const char *data)
cc98edd9479d4622634a1275c98058916c14059aStephen Gallagherstatic inline bool otp_check_tail(const char *data)
d3da1c165cdb4c1ec126a8f4b6b544ca415b9d20Pavel Březina return *data != 0;
1183d29d87c5c7439cf2364b7d7324d4a13b6e35Stephen Gallagherint otp_read_hex(const char *data, const char **endptr, unsigned char *hash)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher unsigned int i = 0;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher buffer_create_from_data(&buf, hash, OTP_HASH_SIZE);
86b61156743b7ebdc049450a6f88452890fd9a61Jakub Hrozek } else if (!IS_LWS(c)) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher#define add_word() do { \
1658c567191c35beaddffafdb079abe33248037bLukas Slebodnikint otp_read_words(const char *data, const char **endptr, unsigned char *hash)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher unsigned int parity = 0, bits[OTP_WORDS_NUMBER], tmp;
327127bb7fcc07f882209f029e14026de1b23c94Maxim for (; *data != '\0' && (count < OTP_WORDS_NUMBER); data++) {
4b6a0d0b3d42e5fdb457f47d9adfa5e66b160256Stephen Gallagher } else if (IS_LWS(c)) {
e124844907ed6973915e4d56f5442ecd07535a12Jakub Hrozek if ((str_len(word) > 0) && (count == OTP_WORDS_NUMBER - 1))
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher hash[1] = ((bits[0] & 7) << 5) | (bits[1] >> 6);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher hash[2] = ((bits[1] & 0x3f) << 2) | (bits[2] >> 9);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher hash[4] = ((bits[2] & 3) << 7) | (bits[3] >> 4);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher hash[5] = ((bits[3] & 15) << 4) | (bits[4] >> 7);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher hash[6] = ((bits[4] & 0x7f) << 1) | (bits[5] >> 10);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherint otp_read_new_params(const char *data, const char **endptr,
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher const char *p, *s;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher unsigned int i = 0;
6b0a7c72bb841d6885a620c68bd51d55109b66c7Jakub Hrozek while ((*p != 0) && !IS_LWS(*p)) p++;
b32159300fea63222d8dd9200ed634087704ea74Stephen Gallagher algo = digest_find(t_strdup_until(s, p++));
9dbdf62243f01f6aee41c2b5f2976c56da47f25dLukas Slebodnik if (str_parse_int(s, &state->seq, &p) < 0 || !IS_LWS(*p))
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher while (i_isalnum(*p) && (i < OTP_MAX_SEED_LEN))
e6e26182d58c05d896f72f2925426658a6dc70b5Jakub Hrozekint otp_parse_response(const char *data, unsigned char *hash, bool hex)
e6e26182d58c05d896f72f2925426658a6dc70b5Jakub Hrozek const char *end;
2a5790216f57e9bdfb2930d52860bb5300366536Jakub Hrozek int ret = hex ? otp_read_hex(data, &end, hash) :
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherint otp_parse_init_response(const char *data, struct otp_state *new_state,
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher unsigned char *hash, bool hex, const char **error)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher int ret = hex ? otp_read_hex(data, &end, hash) :
4d81fe27ced3d2e96866aeaf61661a925cb8edf1Jakub Hrozek ret = otp_read_new_params(end, &end, new_state);
4d81fe27ced3d2e96866aeaf61661a925cb8edf1Jakub Hrozek ret = hex ? otp_read_hex(end, &end, new_state->hash) :
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherint otp_parse_dbentry(const char *text, struct otp_state *state)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher ret = otp_read_new_params(text, &end, state);
e07a94a66985b674c5df11ca466792902164c4e2George McCollisterconst char *otp_print_dbentry(const struct otp_state *state)
e07a94a66985b674c5df11ca466792902164c4e2George McCollister return t_strdup_printf("%s %d %s %s", digest_name(state->algo),