package org.jivesoftware.smackx.ikey_ox; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.util.io.Streams; import org.jivesoftware.smackx.ikey.IkeySignatureVerificationMechanism; import org.jivesoftware.smackx.ikey.IkeyType; import org.pgpainless.PGPainless; import org.pgpainless.decryption_verification.DecryptionStream; import org.pgpainless.decryption_verification.OpenPgpMetadata; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Collections; public class OxIkeySignatureVerificationMechanism implements IkeySignatureVerificationMechanism { private PGPPublicKeyRing contactIdentityKey; public OxIkeySignatureVerificationMechanism(PGPPublicKeyRing contactIdentityKey) { this.contactIdentityKey = contactIdentityKey; } @Override public boolean isSignatureValid(byte[] data, byte[] signature) throws IOException { try { DecryptionStream decryptionInputStream = PGPainless.createDecryptor() .onInputStream(new ByteArrayInputStream(data)) .doNotDecrypt() .verifyDetachedSignature(new ByteArrayInputStream(signature)) .verifyWith(Collections.singleton(contactIdentityKey)) .ignoreMissingPublicKeys() .build(); ByteArrayOutputStream decryptionOutputStream = new ByteArrayOutputStream(data.length); Streams.pipeAll(decryptionInputStream, decryptionOutputStream); decryptionInputStream.close(); decryptionOutputStream.close(); OpenPgpMetadata metadata = decryptionInputStream.getResult(); return !metadata.getVerifiedSignatures().isEmpty(); } catch (PGPException e) { throw new IOException(e); } } @Override public IkeyType getType() { return IkeyType.OX; } }