All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.predic8.membrane.core.interceptor.authentication.session.totp.TotpCounter Maven / Gradle / Ivy

There is a newer version: 5.5.0
Show newest version
/*
 * Copyright 2011 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.predic8.membrane.core.interceptor.authentication.session.totp;

/**
 * Counter whose value is a deterministic function of time as described in RFC 6238
 * "TOTP: Time-Based One-Time Password Algorithm".
 *
 * 

The 64-bit counter assumes the value {@code 0} at a predefined point in time and periodically * increments its value by one periodically. * *

The value {@code V} of the counter at time instant {@code T} is: *

 * V = (T - T0) / TimeStep
 * 
* where {@code T0} is the earliest time instant at which the counter assumes the value {@code 0}, * and {@code TimeStep} is the duration of time for which the values of the counter remain constant. * *

Note: All time instants are in seconds since UNIX epoch, and all time durations are * in seconds. * *

Note: All time instants must be non-negative. * *

Thread-safety: Instances of this class are immutable and are thus thread-safe. *

* Source: ... * License: ASL 2.0 * * @author [email protected] (Alex Klyubin) */ public class TotpCounter { /** Interval of time (seconds) between successive changes of this counter's value. */ private final long mTimeStep; /** * Earliest time instant (seconds since UNIX epoch) at which this counter assumes the value of * {@code 0}. */ private final long mStartTime; /** * Constructs a new {@code TotpCounter} that starts with the value {@code 0} at time instant * {@code 0} (seconds since UNIX epoch) and increments its value with the specified frequency. * * @param timeStep interval of time (seconds) between successive changes of this counter's value. */ public TotpCounter(long timeStep) { this(timeStep, 0); } /** * Constructs a new {@code TotpCounter} that starts with the value {@code 0} at the specified * time and increments its value with the specified frequency. * * @param timeStep interval of time (seconds) between successive changes of this counter's value. * @param startTime the earliest time instant (seconds since UNIX epoch) at which this counter * assumes the value {@code 0}. */ public TotpCounter(long timeStep, long startTime) { if (timeStep < 1) { throw new IllegalArgumentException("Time step must be positive: " + timeStep); } assertValidTime(startTime); mTimeStep = timeStep; mStartTime = startTime; } /** * Gets the frequency with which the value of this counter changes. * * @return interval of time (seconds) between successive changes of this counter's value. */ public long getTimeStep() { return mTimeStep; } /** * Gets the earliest time instant at which this counter assumes the value {@code 0}. * * @return time (seconds since UNIX epoch). */ public long getStartTime() { return mStartTime; } /** * Gets the value of this counter at the specified time. * * @param time time instant (seconds since UNIX epoch) for which to obtain the value. * * @return value of the counter at the {@code time}. */ public long getValueAtTime(long time) { assertValidTime(time); // According to the RFC: // T = (Current Unix time - T0) / X, where the default floor function is used. // T - counter value, // T0 - start time. // X - time step. // It's important to use a floor function instead of simple integer division. For example, // assuming a time step of 3: // Time since start time: -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 // Correct value: -2 -2 -2 -1 -1 -1 0 0 0 1 1 1 2 // Simple division / 3: -2 -1 -1 -1 0 0 0 0 0 1 1 1 2 // // To avoid using Math.floor which requires imprecise floating-point arithmetic, we // we compute the value using integer division, but using a different equation for // negative and non-negative time since start time. long timeSinceStartTime = time - mStartTime; if (timeSinceStartTime >= 0) { return timeSinceStartTime / mTimeStep; } else { return (timeSinceStartTime - (mTimeStep - 1)) / mTimeStep; } } /** * Gets the time when the counter assumes the specified value. * * @param value value. * * @return earliest time instant (seconds since UNIX epoch) when the counter assumes the value. */ public long getValueStartTime(long value) { return mStartTime + (value * mTimeStep); } private static void assertValidTime(long time) { if (time < 0) { throw new IllegalArgumentException("Negative time: " + time); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy