public static PlayerDataObject findSigningPlayer(String signedMessage) throws InternalException, IllegalArgumentException, NotFoundException {
try {
ByteArrayInputStream bis = new ByteArrayInputStream(signedMessage.getBytes("ASCII"));
PGPInspectLib inspect = new PGPInspectLib();
PGPLib pgp = new PGPLib();
ByteArrayInputStream serverKeyStream = new ByteArrayInputStream(CryptoManager.getInstance().getMyPublicKey().getBytes("ASCII"));
String serverKeyPass = CryptoManager.getInstance().getSecretKeyPass();
List<PlayerDataObject> potentials = new ArrayList<>();
boolean isSignedOnly = inspect.isSignedOnly(bis);
bis.reset();
if (isSignedOnly) {
long[] signingKeyIds = inspect.listSigningKeyIds(bis);
bis.reset();
for (long keyID : signingKeyIds) {
try {
potentials.addAll(PlayerDataObject.lookupByKeyID(keyID));
} catch (Exception e) {
__l.warn("Problem looking up player for key {}", Long.valueOf(keyID));
}
}
} else {
// assume it's signed and encrypted
// This call throws a PGPException, claiming that the library couldn't find the key to decrypt the message. However, GPG is able to decrypt it just fine.
SignatureItem[] signatures = inspect.listSignatures(bis, serverKeyStream, serverKeyPass);
bis.reset();
serverKeyStream.reset();
for (SignatureItem item : signatures) {
long keyID = item.getKeyId();
try {
potentials.addAll(PlayerDataObject.lookupByKeyID(keyID));
} catch (Exception e) {
__l.warn("Problem looking up player for key {}", Long.valueOf(keyID));
}
}
}
// now, we have a list of potential players
for (PlayerDataObject pdo : potentials) {
// see if the player's key is the one that signed the message
KeyStore playerKey = new KeyStore();
ByteArrayInputStream playerKeyStream = new ByteArrayInputStream(pdo.getPublicKey().getBytes("ASCII"));
playerKey.loadFromStream(playerKeyStream);
playerKeyStream.reset();
if (isSignedOnly) {
SignatureCheckResult result = pgp.verifyWithoutExtracting(bis, playerKey);
bis.reset();
if (result == SignatureVerified) {
return pdo;
}
} else {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SignatureCheckResult result = pgp.decryptAndVerify(bis, serverKeyStream, serverKeyPass, playerKeyStream, baos);
bis.reset();
serverKeyStream.reset();
if (result == SignatureVerified) {
return pdo;
}
}
}
} catch (UnsupportedEncodingException uee) {
__l.error("Check JVM - ASCII isn't supported", uee);
throw new InternalException("Unsupported encoding; check JVM installation", uee);
} catch (IOException ioe) {
__l.error("Exception reading memory!", ioe);
throw new InternalException("Unable to read from memory", ioe);
} catch (PGPException pe) {
__l.error("signed data is malformed", pe);
throw new IllegalArgumentException("Malformed data provided", pe);
}
throw new NotFoundException("No qualifying player key found");
}