import java.util.*; import java.io.*; /** * A class that implements PGP interface for Java. *

* It calls gpg (GnuPG) program to do all the PGP processing. * $Id:$ * * @author Yaniv Yemini, January 2004. * @author Please include this text with any copy of this code. * @author . * @author License: GPL v3 * @author Latest version of this code can be found at: * @author http://www.macnews.co.il/mageworks/java/gnupg/ * @author . * @author Based on a class GnuPG by John Anderson, which can be found * @author at: http://lists.gnupg.org/pipermail/gnupg-devel/2002-February/018098.html * @version 0.5 * @see GnuPG - http://www.gnupg.org/ */ public class GnuPG { // Konstants: private final String kGnuPGCommand = "/usr/local/bin/gpg --batch --armor --output -"; // Class vars: private File tmpFile; private int gpg_exitCode = -1; private String gpg_result; private String gpg_err; /** * Reads an output stream from an external process. * Imeplemented as a thred. */ class ProcessStreamReader extends Thread { StringBuffer stream; InputStreamReader in; final static int BUFFER_SIZE = 1024; /** * Creates new ProcessStreamReader object. * * @param in */ ProcessStreamReader (InputStream in) { super(); this.in = new InputStreamReader(in); this.stream = new StringBuffer(); } public void run() { try { int read; char[] c = new char[BUFFER_SIZE]; while ((read = in.read(c, 0, BUFFER_SIZE - 1)) > 0) { stream.append(c, 0, read); if (read < BUFFER_SIZE - 1) break; } } catch(IOException io) {} } String getString() { return stream.toString(); } } /** * Sign * * @param inStr input string to sign * @param passPhrase passphrase for the personal private key to sign with * @return true upon success */ public boolean sign (String inStr, String passPhrase) { boolean success; success = createTempFile (inStr); if (success) { success = runGnuPG ("--passphrase-fd 0 --sign " + this.tmpFile.getAbsolutePath (), passPhrase); this.tmpFile.delete (); if (success && this.gpg_exitCode != 0) success = false; } return success; } /** * ClearSign * * @param inStr input string to sign * @param passPhrase passphrase for the personal private key to sign with * @return true upon success */ public boolean clearSign (String inStr, String passPhrase) { boolean success; success = createTempFile (inStr); if (success) { success = runGnuPG ("--passphrase-fd 0 --clearsign " + this.tmpFile.getAbsolutePath (), passPhrase); this.tmpFile.delete (); if (success && this.gpg_exitCode != 0) success = false; } return success; } /** * Signs and encrypts a string * * @param inStr input string to encrypt * @param keyID key ID of the key in GnuPG's key database to encrypt with * @param passPhrase passphrase for the personal private key to sign with * @return true upon success */ public boolean signAndEncrypt (String inStr, String keyID, String passPhrase) { boolean success; success = createTempFile (inStr); if (success) { success = runGnuPG ("--passphrase-fd 0 -se " + this.tmpFile.getAbsolutePath (), passPhrase); this.tmpFile.delete (); if (success && this.gpg_exitCode != 0) success = false; } return success; } /** * Encrypt * * @param inStr input string to encrypt * @param keyID key ID of the key in GnuPG's key database to encrypt with * @return true upon success */ public boolean encrypt (String inStr, String keyID) { boolean success; success = runGnuPG ("-r " + keyID + " --encrypt", inStr); if (success && this.gpg_exitCode != 0) success = false; return success; } /** * Decrypt * * @param inStr input string to decrypt * @param passPhrase passphrase for the personal private key to sign with * @return true upon success */ public boolean decrypt (String inStr, String passPhrase) { boolean success; success = createTempFile (inStr); if (success) { success = runGnuPG ("--passphrase-fd 0 --decrypt " + this.tmpFile.getAbsolutePath (), passPhrase); this.tmpFile.delete (); if (success && this.gpg_exitCode != 0) success = false; } return success; } /** * Verify a signature * * @param inStr signature to verify * @param keyID key ID of the key in GnuPG's key database * @return true if verified. */ /* public boolean verifySignature (String inStr, String keyID) { boolean success; success = runGnuPG ("--sign " + keyID, inStr); if (success && this.gpg_exitCode != 0) success = false; return success; } */ /** * Get processing result * * @return result string. */ public String getResult () { return gpg_result; } /** * Get error output from GnuPG process * * @return error string. */ public String getErrorString () { return gpg_err; } /** * Get GnuPG exit code * * @return exit code. */ public int getExitCode () { return gpg_exitCode; } /** * Runs GnuPG external program * * @param commandArgs command line arguments * @param inputStr key ID of the key in GnuPG's key database * @return true if success. */ private boolean runGnuPG (String commandArgs, String inputStr) { Process p; String fullCommand = kGnuPGCommand + " " + commandArgs; // String fullCommand = commandArgs; System.out.println (fullCommand); try { p = Runtime.getRuntime().exec(fullCommand); } catch(IOException io) { System.out.println ("io Error" + io.getMessage ()); return false; } ProcessStreamReader psr_stdout = new ProcessStreamReader(p.getInputStream()); ProcessStreamReader psr_stderr = new ProcessStreamReader(p.getErrorStream()); psr_stdout.start(); psr_stderr.start(); if (inputStr != null) { BufferedWriter out = new BufferedWriter(new OutputStreamWriter(p.getOutputStream())); try { out.write(inputStr); out.close(); } catch(IOException io) { System.out.println("Exception at write! " + io.getMessage ()); return false; } } try { p.waitFor(); psr_stdout.join(); psr_stderr.join(); } catch(InterruptedException i) { System.out.println("Exception at waitfor! " + i.getMessage ()); return false; } try { gpg_exitCode = p.exitValue (); } catch (IllegalThreadStateException itse) { return false; } gpg_result = psr_stdout.getString(); gpg_err = psr_stdout.getString(); return true; } /** * A utility method for creating a unique temporary file when needed by one of * the main methods.
* The file handle is store in tmpFile object var. * * @param inStr data to write into the file. * @return true if success */ private boolean createTempFile (String inStr) { this.tmpFile = null; FileWriter fw; try { this.tmpFile = File.createTempFile ("YGnuPG", null); } catch (Exception e) { System.out.println("Cannot create temp file " + e.getMessage ()); return false; } try { fw = new FileWriter (this.tmpFile); fw.write (inStr); fw.flush (); fw.close (); } catch (Exception e) { // delete our file: tmpFile.delete (); System.out.println("Cannot write temp file " + e.getMessage ()); return false; } return true; } /* public static void main (String args[]) { // use this to check: System.out.println("Hello World!"); GnuPG pgp = new GnuPG (); if (args[0].equals ("sign")) pgp.sign (args[1], args[2]); else if (args[0].equals ("clearsign")) pgp.clearSign (args[1], args[2]); else if (args[0].equals ("se")) pgp.signAndEncrypt (args[1], args[2],args[3]); else if (args[0].equals ("encrypt")) pgp.encrypt (args[1], args[2]); else if (args[0].equals ("decrypt")) pgp.decrypt (args[1], args[2]); System.out.println("result: " + pgp.gpg_result + "\n\n"); System.out.println("error: " + pgp.gpg_err + "\n\n"); System.out.println("exit: " + pgp.gpg_exitCode + "\n\n"); } */ }