mirror of
https://github.com/cryb-to/cryb-otp.git
synced 2024-11-21 13:05:45 +00:00
Move verify and resync into the library.
This commit is contained in:
parent
d5dc054392
commit
6bd043cac5
10 changed files with 240 additions and 38 deletions
|
@ -45,6 +45,7 @@
|
||||||
|
|
||||||
#include <cryb/ctype.h>
|
#include <cryb/ctype.h>
|
||||||
#include <cryb/oath.h>
|
#include <cryb/oath.h>
|
||||||
|
#include <cryb/otp.h>
|
||||||
#include <cryb/strlcmp.h>
|
#include <cryb/strlcmp.h>
|
||||||
|
|
||||||
#define MAX_KEYURI_SIZE 4096
|
#define MAX_KEYURI_SIZE 4096
|
||||||
|
@ -267,7 +268,7 @@ otpkey_verify(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
oath_key key;
|
oath_key key;
|
||||||
unsigned long counter;
|
unsigned long counter;
|
||||||
unsigned int response;
|
unsigned long response;
|
||||||
char *end;
|
char *end;
|
||||||
int match, ret;
|
int match, ret;
|
||||||
|
|
||||||
|
@ -278,27 +279,18 @@ otpkey_verify(int argc, char *argv[])
|
||||||
response = strtoul(*argv, &end, 10);
|
response = strtoul(*argv, &end, 10);
|
||||||
if (end == *argv || *end != '\0')
|
if (end == *argv || *end != '\0')
|
||||||
response = UINT_MAX; /* never valid */
|
response = UINT_MAX; /* never valid */
|
||||||
switch (key.mode) {
|
if (key.mode == om_hotp)
|
||||||
case om_hotp:
|
|
||||||
counter = key.counter;
|
counter = key.counter;
|
||||||
match = oath_hotp_match(&key, response, HOTP_WINDOW);
|
match = otp_verify(&key, response);
|
||||||
if (verbose && match > 0 && key.counter > counter + 1)
|
|
||||||
warnx("skipped %lu codes", key.counter - counter - 1);
|
|
||||||
break;
|
|
||||||
case om_totp:
|
|
||||||
match = oath_totp_match(&key, response, TOTP_WINDOW);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
match = -1;
|
|
||||||
}
|
|
||||||
/* oath_*_match() return -1 on error, 0 on failure, 1 on success */
|
|
||||||
if (match < 0) {
|
if (match < 0) {
|
||||||
warnx("OATH error");
|
warnx("OATH error");
|
||||||
match = 0;
|
match = 0;
|
||||||
}
|
}
|
||||||
if (verbose)
|
if (verbose) {
|
||||||
warnx("response: %u %s", response,
|
warnx("response %s", match ? "matched" : "did not match");
|
||||||
match ? "matched" : "did not match");
|
if (key.mode == om_hotp && key.counter > counter + 1)
|
||||||
|
warnx("skipped %lu codes", key.counter - counter - 1);
|
||||||
|
}
|
||||||
ret = match ? readonly ? RET_SUCCESS : otpkey_save(&key) : RET_FAILURE;
|
ret = match ? readonly ? RET_SUCCESS : otpkey_save(&key) : RET_FAILURE;
|
||||||
oath_key_destroy(&key);
|
oath_key_destroy(&key);
|
||||||
return (ret);
|
return (ret);
|
||||||
|
@ -365,7 +357,7 @@ otpkey_resync(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
oath_key key;
|
oath_key key;
|
||||||
unsigned long counter;
|
unsigned long counter;
|
||||||
unsigned int response[3];
|
unsigned long response[3];
|
||||||
char *end;
|
char *end;
|
||||||
int i, match, n, ret, w;
|
int i, match, n, ret, w;
|
||||||
|
|
||||||
|
@ -381,31 +373,18 @@ otpkey_resync(int argc, char *argv[])
|
||||||
w -= n;
|
w -= n;
|
||||||
if ((ret = otpkey_load(&key)) != RET_SUCCESS)
|
if ((ret = otpkey_load(&key)) != RET_SUCCESS)
|
||||||
return (ret);
|
return (ret);
|
||||||
switch (key.mode) {
|
if (key.mode == om_hotp)
|
||||||
case om_hotp:
|
|
||||||
/* this should be a library function */
|
|
||||||
counter = key.counter;
|
counter = key.counter;
|
||||||
match = 0;
|
match = otp_resync(&key, response, n);
|
||||||
while (key.counter < counter + w && match == 0) {
|
|
||||||
match = oath_hotp_match(&key, response[0],
|
|
||||||
counter + w - key.counter - 1);
|
|
||||||
if (match <= 0)
|
|
||||||
break;
|
|
||||||
for (i = 1; i < n && match > 0; ++i)
|
|
||||||
match = oath_hotp_match(&key, response[i], 0);
|
|
||||||
}
|
|
||||||
if (verbose && match > 0)
|
|
||||||
warnx("skipped %lu codes", key.counter - counter);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
match = -1;
|
|
||||||
}
|
|
||||||
if (match < 0) {
|
if (match < 0) {
|
||||||
warnx("OATH error");
|
warnx("OATH error");
|
||||||
match = 0;
|
match = 0;
|
||||||
}
|
}
|
||||||
if (verbose)
|
if (verbose) {
|
||||||
warnx("resynchronization %s", match ? "succeeded" : "failed");
|
warnx("resynchronization %s", match ? "succeeded" : "failed");
|
||||||
|
if (counter > key.counter + 1)
|
||||||
|
warnx("skipped %lu codes", key.counter - counter);
|
||||||
|
}
|
||||||
ret = match ? readonly ? RET_SUCCESS : otpkey_save(&key) : RET_FAILURE;
|
ret = match ? readonly ? RET_SUCCESS : otpkey_save(&key) : RET_FAILURE;
|
||||||
oath_key_destroy(&key);
|
oath_key_destroy(&key);
|
||||||
return (ret);
|
return (ret);
|
||||||
|
|
|
@ -38,6 +38,12 @@ CRYB_BEGIN
|
||||||
|
|
||||||
const char *cryb_otp_version(void);
|
const char *cryb_otp_version(void);
|
||||||
|
|
||||||
|
#define otp_verify cryb_otp_verify
|
||||||
|
#define otp_resync cryb_otp_resync
|
||||||
|
|
||||||
|
int otp_verify(oath_key *, unsigned long);
|
||||||
|
int otp_resync(oath_key *, unsigned long *, unsigned int);
|
||||||
|
|
||||||
CRYB_END
|
CRYB_END
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,6 +3,8 @@ AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||||
lib_LTLIBRARIES = libcryb-otp.la
|
lib_LTLIBRARIES = libcryb-otp.la
|
||||||
|
|
||||||
libcryb_otp_la_SOURCES = \
|
libcryb_otp_la_SOURCES = \
|
||||||
|
cryb_otp_resync.c \
|
||||||
|
cryb_otp_verify.c \
|
||||||
\
|
\
|
||||||
cryb_otp.c
|
cryb_otp.c
|
||||||
|
|
||||||
|
|
|
@ -29,9 +29,10 @@
|
||||||
|
|
||||||
#include "cryb/impl.h"
|
#include "cryb/impl.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
|
#include <cryb/oath.h>
|
||||||
#include <cryb/otp.h>
|
#include <cryb/otp.h>
|
||||||
|
|
||||||
static const char *cryb_otp_version_string = PACKAGE_VERSION;
|
static const char *cryb_otp_version_string = PACKAGE_VERSION;
|
||||||
|
|
40
lib/otp/cryb_otp_impl.h
Normal file
40
lib/otp/cryb_otp_impl.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2018 The University of Oslo
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CRYB_OTP_IMPL_H_INCLUDED
|
||||||
|
#define CRYB_OTP_IMPL_H_INCLUDED
|
||||||
|
|
||||||
|
/* XXX hardcoded windows */
|
||||||
|
#define HOTP_WINDOW 9
|
||||||
|
#define TOTP_WINDOW 2
|
||||||
|
|
||||||
|
struct otp_store {
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
96
lib/otp/cryb_otp_resync.c
Normal file
96
lib/otp/cryb_otp_resync.c
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2013-2018 The University of Oslo
|
||||||
|
* Copyright (c) 2016-2018 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryb/impl.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <cryb/assert.h>
|
||||||
|
#include <cryb/oath.h>
|
||||||
|
#include <cryb/otp.h>
|
||||||
|
|
||||||
|
#include "cryb_otp_impl.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Resynchronize a desynchronized event-mode key.
|
||||||
|
*
|
||||||
|
* XXX review carefully for off-by-one errors, and write unit tests
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
otp_resync_recursive(oath_key *key, unsigned long *response,
|
||||||
|
unsigned int n, unsigned int w)
|
||||||
|
{
|
||||||
|
uint64_t first, prev, last;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
first = key->counter;
|
||||||
|
last = first + w;
|
||||||
|
while (w > 0) {
|
||||||
|
prev = key->counter;
|
||||||
|
ret = oath_hotp_match(key, response[0], last - key->counter);
|
||||||
|
if (ret < 1)
|
||||||
|
return (ret);
|
||||||
|
assertf(key->counter > prev, "counter did not advance");
|
||||||
|
w -= key->counter - prev;
|
||||||
|
if (n == 1)
|
||||||
|
return (key->counter - prev);
|
||||||
|
prev = key->counter;
|
||||||
|
ret = otp_resync_recursive(key, response + 1, n - 1, w);
|
||||||
|
if (ret > 0)
|
||||||
|
return (ret);
|
||||||
|
key->counter = prev;
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
otp_resync(oath_key *key, unsigned long *response, unsigned int n)
|
||||||
|
{
|
||||||
|
unsigned int i, w;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* only applicable to RFC 4226 HOTP for now */
|
||||||
|
/* note: n == 1 is identical to otp_verify() */
|
||||||
|
if (key->mode != om_hotp || n < 1)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
/* compute window size based on number of responses */
|
||||||
|
for (i = 0, w = 1; i < n; ++i)
|
||||||
|
w = w * (HOTP_WINDOW + 1);
|
||||||
|
|
||||||
|
/* recursive search within window */
|
||||||
|
ret = otp_resync_recursive(key, response, n, w);
|
||||||
|
|
||||||
|
/* ... */
|
||||||
|
|
||||||
|
return (ret);
|
||||||
|
}
|
75
lib/otp/cryb_otp_verify.c
Normal file
75
lib/otp/cryb_otp_verify.c
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2013-2018 The University of Oslo
|
||||||
|
* Copyright (c) 2016-2018 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryb/impl.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <cryb/assert.h>
|
||||||
|
#include <cryb/oath.h>
|
||||||
|
#include <cryb/otp.h>
|
||||||
|
|
||||||
|
#include "cryb_otp_impl.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check whether a given response is correct for the given keyfile.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
otp_verify(oath_key *key, unsigned long response)
|
||||||
|
{
|
||||||
|
uint64_t prev;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
switch (key->mode) {
|
||||||
|
case om_hotp:
|
||||||
|
prev = key->counter;
|
||||||
|
ret = oath_hotp_match(key, response, HOTP_WINDOW);
|
||||||
|
assertf(key->counter >= prev, "counter went backwads");
|
||||||
|
if (ret > 0) {
|
||||||
|
assertf(key->counter > prev, "counter did not advance");
|
||||||
|
ret = key->counter - prev - 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case om_totp:
|
||||||
|
prev = key->lastused;
|
||||||
|
ret = oath_totp_match(key, response, TOTP_WINDOW);
|
||||||
|
assertf(key->lastused >= prev, "lastused went backwards");
|
||||||
|
if (ret > 0) {
|
||||||
|
assertf(key->lastused > prev, "lastused did not advance");
|
||||||
|
ret = key->lastused - prev / key->timestep;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
/* oath_*_ret() return -1 on error, 0 on failure, 1 on success */
|
||||||
|
return (ret);
|
||||||
|
}
|
|
@ -33,6 +33,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <cryb/oath.h>
|
||||||
#include <cryb/otp.h>
|
#include <cryb/otp.h>
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include <security/pam_modules.h>
|
#include <security/pam_modules.h>
|
||||||
#include <security/pam_appl.h>
|
#include <security/pam_appl.h>
|
||||||
|
|
||||||
|
#include <cryb/oath.h>
|
||||||
#include <cryb/otp.h>
|
#include <cryb/otp.h>
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <cryb/oath.h>
|
||||||
#include <cryb/otp.h>
|
#include <cryb/otp.h>
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
Loading…
Reference in a new issue