otp-parse.c revision f0339f522dc9c8e2e8a29ef9a3f937c431c6bd1b
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher/*
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher * OTP extended response parser.
ee359fe1384507fed6c2274e7bfe81d288de4542Stephen Gallagher *
33396dc46ea52c18f47db1b5d590880806521005Sumit Bose * Copyright (c) 2006 Andrey Panin <pazke@donpac.ru>
ee359fe1384507fed6c2274e7bfe81d288de4542Stephen Gallagher *
33396dc46ea52c18f47db1b5d590880806521005Sumit Bose * This software is released under the MIT license.
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher */
324fb26ba803a999bedc29e93c46c84f27abf5b7Sumit Bose
324fb26ba803a999bedc29e93c46c84f27abf5b7Sumit Bose#include "lib.h"
324fb26ba803a999bedc29e93c46c84f27abf5b7Sumit Bose#include "buffer.h"
324fb26ba803a999bedc29e93c46c84f27abf5b7Sumit Bose#include "str.h"
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher#include "strfuncs.h"
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher#include "hex-binary.h"
84ae5edab16ad6be5e3be956cb6fa031c1428eb5Stephen Gallagher
84ae5edab16ad6be5e3be956cb6fa031c1428eb5Stephen Gallagher#include "otp.h"
84ae5edab16ad6be5e3be956cb6fa031c1428eb5Stephen Gallagher
e65df5b966b27e13283c65f59f99ac44781e0333Simo Sorce#include <ctype.h>
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
002f84aea86371aa079b867c0ec39396b97109d3Lukas Slebodnik#define IS_LWS(c) ((c) == ' ' || (c) == '\t')
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic inline const char *otp_skip_lws(const char *data)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher{
ccf340e56364851f2e5b75e52d3d63701b662954Lukas Slebodnik while (*data != '\0' && IS_LWS(*data))
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher data++;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return data;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher}
84ae5edab16ad6be5e3be956cb6fa031c1428eb5Stephen Gallagher
cc98edd9479d4622634a1275c98058916c14059aStephen Gallagherstatic inline bool otp_check_tail(const char *data)
ee359fe1384507fed6c2274e7bfe81d288de4542Stephen Gallagher{
cc98edd9479d4622634a1275c98058916c14059aStephen Gallagher data = otp_skip_lws(data);
d3da1c165cdb4c1ec126a8f4b6b544ca415b9d20Pavel Březina
d3da1c165cdb4c1ec126a8f4b6b544ca415b9d20Pavel Březina return *data != 0;
d3da1c165cdb4c1ec126a8f4b6b544ca415b9d20Pavel Březina}
c481179da5d5b53ce16d8784c0bd2857ffc2f061Lukas Slebodnik
1183d29d87c5c7439cf2364b7d7324d4a13b6e35Stephen Gallagherint otp_read_hex(const char *data, const char **endptr, unsigned char *hash)
002f84aea86371aa079b867c0ec39396b97109d3Lukas Slebodnik{
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher string_t *str;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher buffer_t buf;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher unsigned int i = 0;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (data == NULL)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return -1;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher str = t_str_new(18);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher buffer_create_from_data(&buf, hash, OTP_HASH_SIZE);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher while (*data != '\0') {
c89589fa349f38214c9cb8d9389c0fd557e5dca2Simo Sorce char c = *data;
c89589fa349f38214c9cb8d9389c0fd557e5dca2Simo Sorce
c89589fa349f38214c9cb8d9389c0fd557e5dca2Simo Sorce if (i_isxdigit(c)) {
86b61156743b7ebdc049450a6f88452890fd9a61Jakub Hrozek str_append_c(str, c);
86b61156743b7ebdc049450a6f88452890fd9a61Jakub Hrozek if (++i == OTP_HASH_SIZE * 2) {
86b61156743b7ebdc049450a6f88452890fd9a61Jakub Hrozek data++;
c89589fa349f38214c9cb8d9389c0fd557e5dca2Simo Sorce break;
c89589fa349f38214c9cb8d9389c0fd557e5dca2Simo Sorce }
86b61156743b7ebdc049450a6f88452890fd9a61Jakub Hrozek } else if (!IS_LWS(c)) {
86b61156743b7ebdc049450a6f88452890fd9a61Jakub Hrozek *endptr = data;
86b61156743b7ebdc049450a6f88452890fd9a61Jakub Hrozek return -1;
86b61156743b7ebdc049450a6f88452890fd9a61Jakub Hrozek }
86b61156743b7ebdc049450a6f88452890fd9a61Jakub Hrozek data++;
86b61156743b7ebdc049450a6f88452890fd9a61Jakub Hrozek }
86b61156743b7ebdc049450a6f88452890fd9a61Jakub Hrozek
86b61156743b7ebdc049450a6f88452890fd9a61Jakub Hrozek *endptr = data;
86b61156743b7ebdc049450a6f88452890fd9a61Jakub Hrozek
86b61156743b7ebdc049450a6f88452890fd9a61Jakub Hrozek if (i < OTP_HASH_SIZE * 2)
86b61156743b7ebdc049450a6f88452890fd9a61Jakub Hrozek return -1;
48130eef6c5c64a07094b9e8582ba358b2048f24Jakub Hrozek
48130eef6c5c64a07094b9e8582ba358b2048f24Jakub Hrozek return hex_to_binary(str_c(str), &buf);
48130eef6c5c64a07094b9e8582ba358b2048f24Jakub Hrozek}
48130eef6c5c64a07094b9e8582ba358b2048f24Jakub Hrozek
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher#define add_word() do { \
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher tmp = otp_lookup_word(str_c(word)); \
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher buffer_append(&buf, &tmp, sizeof(tmp)); \
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher count++; \
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher} while (0)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
1658c567191c35beaddffafdb079abe33248037bLukas Slebodnikint otp_read_words(const char *data, const char **endptr, unsigned char *hash)
1658c567191c35beaddffafdb079abe33248037bLukas Slebodnik{
1658c567191c35beaddffafdb079abe33248037bLukas Slebodnik bool space = FALSE;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher unsigned int len = 0, count = 0;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher unsigned int parity = 0, bits[OTP_WORDS_NUMBER], tmp;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher string_t *word;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher buffer_t buf;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (data == NULL)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return -1;
d921c1eba437662437847279f251a0a5d8f70127Maxim
d921c1eba437662437847279f251a0a5d8f70127Maxim word = t_str_new(8);
d921c1eba437662437847279f251a0a5d8f70127Maxim
d921c1eba437662437847279f251a0a5d8f70127Maxim data = otp_skip_lws(data);
d921c1eba437662437847279f251a0a5d8f70127Maxim
d921c1eba437662437847279f251a0a5d8f70127Maxim buffer_create_from_data(&buf, bits, sizeof(bits));
d921c1eba437662437847279f251a0a5d8f70127Maxim
327127bb7fcc07f882209f029e14026de1b23c94Maxim for (; *data != '\0' && (count < OTP_WORDS_NUMBER); data++) {
327127bb7fcc07f882209f029e14026de1b23c94Maxim char c = *data;
327127bb7fcc07f882209f029e14026de1b23c94Maxim
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (space) {
d3da1c165cdb4c1ec126a8f4b6b544ca415b9d20Pavel Březina if (IS_LWS(c))
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher continue;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher else if (i_isalpha(c)) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher str_append_c(word, c);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher space = FALSE;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher len = 1;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher continue;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce }
bc9235cfb80bd64a3bfa959e8d26d5ad1be0bdf4Jakub Hrozek } else {
bc9235cfb80bd64a3bfa959e8d26d5ad1be0bdf4Jakub Hrozek if (i_isalpha(c)) {
07d82f79d2970a08628ebf71343441ec55faa6faPavel Březina if (++len > OTP_MAX_WORD_LEN) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher count = 0;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher break;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher str_append_c(word, c);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher continue;
4b6a0d0b3d42e5fdb457f47d9adfa5e66b160256Stephen Gallagher } else if (IS_LWS(c)) {
90fd1bbd6035cdab46faa3a695a2fb2be6508b17Sumit Bose add_word();
03713859dffacc7142393e53c73d8d4cf7dee8d5Pavel Březina str_truncate(word, 0);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher space = TRUE;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher continue;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
068dbee9ca7bf5b37330eff91c94ae10f288d09fJakub Hrozek break;
98ce3c3e85a4bb2e1822bf8ab2a1c2ab9e3dd61dJakub Hrozek }
be65f065fef1d387281096ef095a2acef39ecc12Jakub Hrozek
e124844907ed6973915e4d56f5442ecd07535a12Jakub Hrozek if ((str_len(word) > 0) && (count == OTP_WORDS_NUMBER - 1))
f36078af138f052cd9a30360867b0ebd0805af5eJakub Hrozek add_word();
34c78b745eb349eef2b0f13ef2b722632aebe619Jan Cholasta
e07a94a66985b674c5df11ca466792902164c4e2George McCollister if (endptr != NULL)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher *endptr = data;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (count < OTP_WORDS_NUMBER)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return -1;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher hash[0] = bits[0] >> 3;
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[3] = (bits[2] >> 1) & 0xff;
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 Gallagher hash[7] = (bits[5] >> 2) & 0xff;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher parity = bits[5] & 3;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
a5077712fc8c24e8cad08207b7b5a6603bde6a7cJakub Hrozek return otp_parity(hash) != parity ? 1 : 0;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherint otp_read_new_params(const char *data, const char **endptr,
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher struct otp_state *state)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher{
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher const char *p, *s;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher unsigned int i = 0;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher int algo;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
2a5790216f57e9bdfb2930d52860bb5300366536Jakub Hrozek s = p = data;
b9e5bd09a5ff7009537a18914dbebcf10498f592Sumit Bose
6b0a7c72bb841d6885a620c68bd51d55109b66c7Jakub Hrozek while ((*p != 0) && !IS_LWS(*p)) p++;
a679f0167b646cffdae86546ed77e105576991b0Pavel Březina if (*p == 0)
b32159300fea63222d8dd9200ed634087704ea74Stephen Gallagher return -1;
b32159300fea63222d8dd9200ed634087704ea74Stephen Gallagher
b32159300fea63222d8dd9200ed634087704ea74Stephen Gallagher algo = digest_find(t_strdup_until(s, p++));
9dbdf62243f01f6aee41c2b5f2976c56da47f25dLukas Slebodnik if (algo < 0)
9dbdf62243f01f6aee41c2b5f2976c56da47f25dLukas Slebodnik return -2;
9dbdf62243f01f6aee41c2b5f2976c56da47f25dLukas Slebodnik state->algo = algo;
b32159300fea63222d8dd9200ed634087704ea74Stephen Gallagher
9dbdf62243f01f6aee41c2b5f2976c56da47f25dLukas Slebodnik s = p;
9dbdf62243f01f6aee41c2b5f2976c56da47f25dLukas Slebodnik if (str_parse_int(s, &state->seq, &p) < 0 || !IS_LWS(*p))
9dbdf62243f01f6aee41c2b5f2976c56da47f25dLukas Slebodnik return -3;
b32159300fea63222d8dd9200ed634087704ea74Stephen Gallagher p++;
9dbdf62243f01f6aee41c2b5f2976c56da47f25dLukas Slebodnik
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher while (i_isalnum(*p) && (i < OTP_MAX_SEED_LEN))
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos state->seed[i++] = i_tolower(*p++);
539b1be3507abdf8ac235b06eeed5011b0b5cde2Ondrej Kos state->seed[i] = 0;
574a1c20f114851071ae74112b34488c3d1aeeb3Ondrej Kos
574a1c20f114851071ae74112b34488c3d1aeeb3Ondrej Kos *endptr = p;
574a1c20f114851071ae74112b34488c3d1aeeb3Ondrej Kos return 0;
574a1c20f114851071ae74112b34488c3d1aeeb3Ondrej Kos}
2a5790216f57e9bdfb2930d52860bb5300366536Jakub Hrozek
e6e26182d58c05d896f72f2925426658a6dc70b5Jakub Hrozekint otp_parse_response(const char *data, unsigned char *hash, bool hex)
e6e26182d58c05d896f72f2925426658a6dc70b5Jakub Hrozek{
e6e26182d58c05d896f72f2925426658a6dc70b5Jakub Hrozek const char *end;
2a5790216f57e9bdfb2930d52860bb5300366536Jakub Hrozek int ret = hex ? otp_read_hex(data, &end, hash) :
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher otp_read_words(data, &end, hash);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (ret < 0)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return ret;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return otp_check_tail(end) ? 1 : 0;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
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{
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher const char *end;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher int ret = hex ? otp_read_hex(data, &end, hash) :
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher otp_read_words(data, &end, hash);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (ret < 0) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher *error = "invalid current OTP";
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return ret;
b50dffea929ee5cd0c59ba3c4822337cc162ff92Kamil Dudka }
b50dffea929ee5cd0c59ba3c4822337cc162ff92Kamil Dudka
b50dffea929ee5cd0c59ba3c4822337cc162ff92Kamil Dudka end = otp_skip_lws(end);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (*end++ != ':') {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher *error = "missing colon";
4d81fe27ced3d2e96866aeaf61661a925cb8edf1Jakub Hrozek return -1;
4d81fe27ced3d2e96866aeaf61661a925cb8edf1Jakub Hrozek }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
4d81fe27ced3d2e96866aeaf61661a925cb8edf1Jakub Hrozek ret = otp_read_new_params(end, &end, new_state);
4d81fe27ced3d2e96866aeaf61661a925cb8edf1Jakub Hrozek if (ret < 0) {
4d81fe27ced3d2e96866aeaf61661a925cb8edf1Jakub Hrozek *error = "invalid OTP parameters";
4d81fe27ced3d2e96866aeaf61661a925cb8edf1Jakub Hrozek return -1;
4d81fe27ced3d2e96866aeaf61661a925cb8edf1Jakub Hrozek }
4d81fe27ced3d2e96866aeaf61661a925cb8edf1Jakub Hrozek
4d81fe27ced3d2e96866aeaf61661a925cb8edf1Jakub Hrozek end = otp_skip_lws(end);
4d81fe27ced3d2e96866aeaf61661a925cb8edf1Jakub Hrozek if (*end++ != ':') {
4d81fe27ced3d2e96866aeaf61661a925cb8edf1Jakub Hrozek *error = "missing colon";
4d81fe27ced3d2e96866aeaf61661a925cb8edf1Jakub Hrozek return -1;
4d81fe27ced3d2e96866aeaf61661a925cb8edf1Jakub Hrozek }
4d81fe27ced3d2e96866aeaf61661a925cb8edf1Jakub Hrozek
4d81fe27ced3d2e96866aeaf61661a925cb8edf1Jakub Hrozek ret = hex ? otp_read_hex(end, &end, new_state->hash) :
4d81fe27ced3d2e96866aeaf61661a925cb8edf1Jakub Hrozek otp_read_words(end, &end, new_state->hash);
6f51c802311fd81a409a26763ed45b28a3234d0dJakub Hrozek if (ret < 0) {
4d81fe27ced3d2e96866aeaf61661a925cb8edf1Jakub Hrozek *error = "invalid new OTP";
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return -1;
4d81fe27ced3d2e96866aeaf61661a925cb8edf1Jakub Hrozek }
8b1f525acd20f36c836e827de3c251088961c5d9Stephen Gallagher
f5b6f977d4144c28e9c66f3f1c9d634d595d1117Marko Myllynen if (otp_check_tail(end)) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher *error = "trailing garbage found";
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return -1;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return 0;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher}
72e60fd4eabcfbcdbfe01e8c38b94052bc6c2067Jakub Hrozek
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherint otp_parse_dbentry(const char *text, struct otp_state *state)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher{
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher const char *end;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher int ret;
3d038d2e0dc7af04ec2f7c85ae325accb39f6237Jakub Hrozek
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher ret = otp_read_new_params(text, &end, state);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (ret != 0)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return ret;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (*end++ != ' ')
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return -1;
2a5790216f57e9bdfb2930d52860bb5300366536Jakub Hrozek
2a5790216f57e9bdfb2930d52860bb5300366536Jakub Hrozek return otp_read_hex(end, &end, state->hash);
2a5790216f57e9bdfb2930d52860bb5300366536Jakub Hrozek}
2a5790216f57e9bdfb2930d52860bb5300366536Jakub Hrozek
e07a94a66985b674c5df11ca466792902164c4e2George McCollisterconst char *otp_print_dbentry(const struct otp_state *state)
e07a94a66985b674c5df11ca466792902164c4e2George McCollister{
e07a94a66985b674c5df11ca466792902164c4e2George McCollister return t_strdup_printf("%s %d %s %s", digest_name(state->algo),
e07a94a66985b674c5df11ca466792902164c4e2George McCollister state->seq, state->seed,
e07a94a66985b674c5df11ca466792902164c4e2George McCollister binary_to_hex(state->hash, 8));
e07a94a66985b674c5df11ca466792902164c4e2George McCollister}
172c07013d1ea99447a780fd36f49d5c3a76981bJakub Hrozek