Search in sources :

Example 1 with GpgSignatureVerifierFactory

use of org.eclipse.jgit.lib.GpgSignatureVerifierFactory in project omegat by omegat-org.

the class GITExternalGpgSigner method signWithGpg.

private byte[] signWithGpg(byte[] data, String keySpec, String gpgProgram) throws IOException, CanceledException {
    // Sign an object with an external GPG executable. GPG handles
    // passphrase entry, including gpg-agent and native keychain
    // integration.
    String program = gpgProgram;
    if (StringUtils.isEmptyOrNull(program)) {
        program = FROM_PATH.getGpg();
        if (StringUtils.isEmptyOrNull(program)) {
            throw new IOException(OStrings.getString(ExternalGpgSigner_gpgNotFound));
        }
    }
    ProcessBuilder process = new ProcessBuilder();
    process.command(program, // $NON-NLS-1$
    "-bsau", keySpec, // $NON-NLS-1$
    "--batch", // $NON-NLS-1$
    "--no-tty", // $NON-NLS-1$
    "--status-fd", // $NON-NLS-1$
    "2", // $NON-NLS-1$
    "--output", // $NON-NLS-1$
    "-");
    gpgEnvironment(process);
    try (ByteArrayInputStream dataIn = new ByteArrayInputStream(data)) {
        class Holder {

            byte[] rawData;
        }
        Holder result = new Holder();
        runProcess(process, dataIn, b -> {
            // Sanity check: do we have a signature?
            GpgSignatureVerifierFactory factory = GpgSignatureVerifierFactory.getDefault();
            boolean isValid;
            if (factory == null) {
                byte[] fromGpg = b.toByteArray(SIGNATURE_START.length);
                isValid = Arrays.equals(fromGpg, SIGNATURE_START);
                if (isValid) {
                    result.rawData = b.toByteArray();
                }
            } else {
                byte[] fromGpg = b.toByteArray();
                GpgSignatureVerifier verifier = factory.getVerifier();
                try {
                    GpgSignatureVerifier.SignatureVerification verification = verifier.verify(data, fromGpg);
                    isValid = verification != null && verification.getVerified();
                    if (isValid) {
                        result.rawData = fromGpg;
                    }
                } catch (JGitInternalException e) {
                    throw new IOException(e.getLocalizedMessage(), e);
                } finally {
                    verifier.clear();
                }
            }
            if (!isValid) {
                throw new IOException(MessageFormat.format(OStrings.getString(ExternalGpgSigner_noSignature), toString(b)));
            }
        }, e -> {
            // https://github.com/gpg/gnupg/blob/master/doc/DETAILS
            try (BufferedReader r = new BufferedReader(new InputStreamReader(e.openInputStream(), StandardCharsets.UTF_8))) {
                String line;
                boolean pinentry = false;
                while ((line = r.readLine()) != null) {
                    if (!pinentry && line.startsWith("[GNUPG:] PINENTRY_LAUNCHED")) {
                        pinentry = true;
                    } else if (pinentry) {
                        if (line.startsWith("[GNUPG:] FAILURE sign")) {
                            throw new CanceledException(OStrings.getString(ExternalGpgSigner_signingCanceled));
                        }
                        if (line.startsWith("[GNUPG:]")) {
                            pinentry = false;
                        }
                    }
                }
            } catch (IOException ex) {
            // Swallow it here; runProcess will raise one anyway.
            }
        });
        return result.rawData;
    }
}
Also used : CanceledException(org.eclipse.jgit.api.errors.CanceledException) GpgSignatureVerifierFactory(org.eclipse.jgit.lib.GpgSignatureVerifierFactory) GpgSignatureVerifier(org.eclipse.jgit.lib.GpgSignatureVerifier) InputStreamReader(java.io.InputStreamReader) IOException(java.io.IOException) ByteArrayInputStream(java.io.ByteArrayInputStream) BufferedReader(java.io.BufferedReader) JGitInternalException(org.eclipse.jgit.api.errors.JGitInternalException)

Aggregations

BufferedReader (java.io.BufferedReader)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1 IOException (java.io.IOException)1 InputStreamReader (java.io.InputStreamReader)1 CanceledException (org.eclipse.jgit.api.errors.CanceledException)1 JGitInternalException (org.eclipse.jgit.api.errors.JGitInternalException)1 GpgSignatureVerifier (org.eclipse.jgit.lib.GpgSignatureVerifier)1 GpgSignatureVerifierFactory (org.eclipse.jgit.lib.GpgSignatureVerifierFactory)1