e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen/*
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen * OTP password scheme.
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen *
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen * Copyright (c) 2006 Andrey Panin <pazke@donpac.ru>
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen *
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen * This software is released under the MIT license.
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen */
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen#include "lib.h"
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen#include "hex-binary.h"
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen#include "password-scheme.h"
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen#include "randgen.h"
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen#include "otp.h"
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainenint password_generate_otp(const char *pw, const char *state_data,
06d948c4adc2bfd2934f74c8046bcc1d567426d8Timo Sirainen unsigned int algo, const char **result_r)
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen{
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen struct otp_state state;
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen if (state_data != NULL) {
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen if (otp_parse_dbentry(state_data, &state) != 0)
06d948c4adc2bfd2934f74c8046bcc1d567426d8Timo Sirainen return -1;
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen } else {
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen /* Generate new OTP credentials from plaintext */
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen unsigned char random_data[OTP_MAX_SEED_LEN / 2];
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen const char *random_hex;
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen random_fill(random_data, sizeof(random_data));
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen random_hex = binary_to_hex(random_data, sizeof(random_data));
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen if (i_strocpy(state.seed, random_hex, sizeof(state.seed)) < 0)
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen i_unreached();
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen state.seq = 1024;
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen state.algo = algo;
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen }
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen otp_hash(state.algo, state.seed, pw, state.seq, state.hash);
06d948c4adc2bfd2934f74c8046bcc1d567426d8Timo Sirainen *result_r = otp_print_dbentry(&state);
06d948c4adc2bfd2934f74c8046bcc1d567426d8Timo Sirainen return 0;
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen}