1
0
mirror of https://github.com/mitb-archive/filebot synced 2025-03-09 22:09:47 -04:00

Experiment with PGP signed messages

This commit is contained in:
Reinhard Pointner 2018-06-09 09:18:39 +07:00
parent 7207e98bd7
commit 9857627782

View File

@ -8,7 +8,6 @@ import static net.filebot.util.RegularExpressions.*;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.File; import java.io.File;
import java.io.InputStream;
import java.io.Serializable; import java.io.Serializable;
import java.net.URL; import java.net.URL;
import java.time.Instant; import java.time.Instant;
@ -35,44 +34,34 @@ public class License implements Serializable {
public static final File LICENSE_FILE = ApplicationFolder.AppData.resolve("license.txt"); public static final File LICENSE_FILE = ApplicationFolder.AppData.resolve("license.txt");
public static final Resource<License> INSTANCE = Resource.lazy(() -> new License(readFile(LICENSE_FILE))); public static final Resource<License> INSTANCE = Resource.lazy(() -> new License(readFile(LICENSE_FILE)));
private byte[] bytes;
private int id; private int id;
private long expires; private long expires;
public License(byte[] bytes) throws Exception { public License(byte[] bytes) throws Exception {
String content = verifyClearSignMessage(new ByteArrayInputStream(bytes), License.class.getResourceAsStream("license.key")); this.bytes = bytes;
// parse properties file // verify and get clear sign content
Map<String, String> properties = NEWLINE.splitAsStream(content).map(s -> s.split(": ", 2)).collect(toMap(a -> a[0], a -> a[1])); Map<String, String> properties = getProperties();
this.id = Integer.parseInt(properties.get("Order")); this.id = Integer.parseInt(properties.get("Order"));
this.expires = LocalDate.parse(properties.get("Valid-Until"), DateTimeFormatter.ISO_LOCAL_DATE).atStartOfDay(ZoneOffset.UTC).plusDays(1).minusSeconds(1).toInstant().toEpochMilli(); this.expires = LocalDate.parse(properties.get("Valid-Until"), DateTimeFormatter.ISO_LOCAL_DATE).atStartOfDay(ZoneOffset.UTC).plusDays(1).minusSeconds(1).toInstant().toEpochMilli();
System.out.println(properties); // verify license online
verifyLicense();
// verify license online first
verifyLicense(id, bytes);
}
@Override
public String toString() {
return String.format("%s (Valid-Until: %s)", id, Instant.ofEpochMilli(expires).atZone(ZoneOffset.UTC).format(DateTimeFormatter.ISO_LOCAL_DATE));
} }
public boolean isValid() { public boolean isValid() {
return expires < System.currentTimeMillis(); return expires < System.currentTimeMillis();
} }
private void verifyLicense(int id, byte[] file) throws Exception { public Map<String, String> getProperties() throws Exception {
Cache cache = CacheManager.getInstance().getCache("license", CacheType.Persistent); return NEWLINE.splitAsStream(verifyClearSignMessage()).map(s -> s.split(": ", 2)).collect(toMap(a -> a[0], a -> a[1]));
String message = new CachedResource<Integer, String>(id, i -> new URL("https://license.filebot.net/verify.cgi?order=" + id), (url, modified) -> WebRequest.post(url, file, "application/octet-stream", null), getText(UTF_8), String.class::cast, Cache.ONE_MONTH, cache).get().trim();
if (!message.equals("OK")) {
throw new PGPException(message);
}
} }
private String verifyClearSignMessage(InputStream clearSignFile, InputStream publicKeyFile) throws Exception { public String verifyClearSignMessage() throws Exception {
ArmoredInputStream armoredInput = new ArmoredInputStream(clearSignFile); ArmoredInputStream armoredInput = new ArmoredInputStream(new ByteArrayInputStream(bytes));
// read content // read content
ByteBufferOutputStream content = new ByteBufferOutputStream(256); ByteBufferOutputStream content = new ByteBufferOutputStream(256);
@ -83,7 +72,7 @@ public class License implements Serializable {
} }
// read public key // read public key
PGPPublicKeyRing publicKeyRing = new PGPPublicKeyRing(publicKeyFile, new JcaKeyFingerprintCalculator()); PGPPublicKeyRing publicKeyRing = new PGPPublicKeyRing(License.class.getResourceAsStream("license.key"), new JcaKeyFingerprintCalculator());
PGPPublicKey publicKey = publicKeyRing.getPublicKey(); PGPPublicKey publicKey = publicKeyRing.getPublicKey();
// read signature // read signature
@ -104,4 +93,18 @@ public class License implements Serializable {
return clearSignMessage; return clearSignMessage;
} }
private void verifyLicense() throws Exception {
Cache cache = CacheManager.getInstance().getCache("license", CacheType.Persistent);
String message = new CachedResource<Integer, String>(id, i -> new URL("https://license.filebot.net/verify/" + id), (url, modified) -> WebRequest.post(url, bytes, "application/octet-stream", null), getText(UTF_8), String.class::cast, Cache.ONE_MONTH, cache).get().trim();
if (!message.equals("OK")) {
throw new PGPException(message);
}
}
@Override
public String toString() {
return String.format("%s (Valid-Until: %s)", id, Instant.ofEpochMilli(expires).atZone(ZoneOffset.UTC).format(DateTimeFormatter.ISO_LOCAL_DATE));
}
} }