Aegis/app/src/main/java/me/impy/aegis/crypto/KeyInfo.java

99 lines
2.8 KiB
Java
Raw Normal View History

2016-08-15 23:31:26 +02:00
package me.impy.aegis.crypto;
import android.net.Uri;
import java.io.Serializable;
2016-08-15 23:31:26 +02:00
import me.impy.aegis.encoding.Base32;
public class KeyInfo implements Serializable {
2016-08-15 23:55:03 +02:00
private String type;
private String label;
private byte[] secret;
private String issuer;
private String algorithm = "HmacSHA1";
private int digits = 6;
2016-08-15 23:55:03 +02:00
private long counter;
private int period = 30;
2016-08-15 23:55:03 +02:00
public String getType() {
return type;
}
public String getLabel() {
return label;
}
public byte[] getSecret() {
return secret;
}
public String getIssuer() {
return issuer;
}
public String getAlgorithm() {
return algorithm;
2016-08-15 23:55:03 +02:00
}
public int getDigits() {
return digits;
}
public long getCounter() {
return counter;
}
public int getPeriod() {
return period;
}
private KeyInfo() { }
2016-08-15 23:31:26 +02:00
public static KeyInfo FromURL(String s) throws Exception {
final Uri url = Uri.parse(s);
if (!url.getScheme().equals("otpauth")) {
throw new Exception("unsupported protocol");
}
KeyInfo info = new KeyInfo();
// only 'totp' and 'hotp' are supported
2016-08-15 23:55:03 +02:00
info.type = url.getHost();
if (info.type.equals("totp") && info.type.equals("hotp")) {
throw new Exception("unsupported type");
}
2016-08-15 23:31:26 +02:00
// 'secret' is a required parameter
2016-08-15 23:31:26 +02:00
String secret = url.getQueryParameter("secret");
if (secret == null) {
throw new Exception("'secret' is not set");
}
2016-08-15 23:55:03 +02:00
info.secret = Base32.decode(secret);
// provider info used to disambiguate accounts
// these parameters are not required but I don't want them to be null either
String issuer = url.getQueryParameter("issuer");
String label = url.getPath();
info.issuer = issuer != null ? issuer : "";
info.label = label != null ? label.substring(1) : "";
// just use the defaults if these parameters aren't set
String algorithm = url.getQueryParameter("algorithm");
if (algorithm != null) {
info.algorithm = "Hmac" + algorithm;
}
String period = url.getQueryParameter("period");
if (period != null) {
info.period = Integer.getInteger(period);
}
String digits = url.getQueryParameter("digits");
if (digits != null) {
info.digits = Integer.getInteger(digits);
}
// 'counter' is required if the type is 'hotp'
String counter = url.getQueryParameter("counter");
if (counter != null) {
info.counter = Long.getLong(counter);
} else if (info.type.equals("hotp")) {
throw new Exception("'counter' was not set which is required for 'hotp'");
}
2016-08-15 23:31:26 +02:00
return info;
}
}