Aegis/app/src/main/java/com/beemdevelopment/aegis/otp/TotpInfo.java

106 lines
2.8 KiB
Java
Raw Normal View History

package com.beemdevelopment.aegis.otp;
2019-03-31 22:15:03 +02:00
import com.beemdevelopment.aegis.crypto.otp.OTP;
import com.beemdevelopment.aegis.crypto.otp.TOTP;
import org.json.JSONException;
import org.json.JSONObject;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
public class TotpInfo extends OtpInfo {
2019-03-31 22:15:03 +02:00
public static final String ID = "totp";
public static final int DEFAULT_PERIOD = 30;
2019-03-31 22:15:03 +02:00
private int _period;
public TotpInfo(byte[] secret) throws OtpInfoException {
super(secret);
setPeriod(DEFAULT_PERIOD);
}
public TotpInfo(byte[] secret, String algorithm, int digits, int period) throws OtpInfoException {
super(secret, algorithm, digits);
setPeriod(period);
}
@Override
public String getOtp() throws OtpInfoException {
checkSecret();
try {
2019-03-31 22:15:03 +02:00
OTP otp = TOTP.generateOTP(getSecret(), getAlgorithm(true), getDigits(), getPeriod());
return otp.toString();
} catch (InvalidKeyException | NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
public String getOtp(long time) throws OtpInfoException {
checkSecret();
try {
OTP otp = TOTP.generateOTP(getSecret(), getAlgorithm(true), getDigits(), getPeriod(), time);
return otp.toString();
} catch (InvalidKeyException | NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
@Override
public String getTypeId() {
2019-03-31 22:15:03 +02:00
return ID;
}
@Override
public JSONObject toJson() {
JSONObject obj = super.toJson();
try {
obj.put("period", getPeriod());
} catch (JSONException e) {
throw new RuntimeException(e);
}
return obj;
}
public int getPeriod() {
return _period;
}
public static boolean isPeriodValid(int period) {
if (period <= 0) {
return false;
}
// check for the possibility of an overflow when converting to milliseconds
return period <= Integer.MAX_VALUE / 1000;
}
public void setPeriod(int period) throws OtpInfoException {
if (!isPeriodValid(period)) {
throw new OtpInfoException(String.format("bad period: %d", period));
}
_period = period;
}
public long getMillisTillNextRotation() {
return TotpInfo.getMillisTillNextRotation(_period);
}
public static long getMillisTillNextRotation(int period) {
long p = period * 1000;
return p - (System.currentTimeMillis() % p);
}
@Override
public boolean equals(Object o) {
if (!(o instanceof TotpInfo)) {
return false;
}
TotpInfo info = (TotpInfo) o;
return super.equals(o) && getPeriod() == info.getPeriod();
}
}