mirror of
https://github.com/beemdevelopment/Aegis.git
synced 2025-04-20 05:49:13 +00:00
This fixes an issue where Steam OTP's were displayed in the wrong
format. The underlying issue has been present for a while, but it first
became apparent in e4c9a584f4
.
98 lines
2.6 KiB
Java
98 lines
2.6 KiB
Java
package com.beemdevelopment.aegis.otp;
|
|
|
|
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 {
|
|
public static final String ID = "totp";
|
|
public static final int DEFAULT_PERIOD = 30;
|
|
|
|
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 {
|
|
return getOtp(System.currentTimeMillis() / 1000);
|
|
}
|
|
|
|
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() {
|
|
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();
|
|
}
|
|
}
|