<?php

/////////////////////////////////////////////////////
// gpg_encrypt v1.3                                //
// http://Business-PHP.com/opensource/gpg_encrypt/ //
//                                                 //
// this PHP function provides a way to easily      //
// encrypt messages using GnuPG. See the above URL //
// for more information.                           //
//                                                 //
// should run on PHP 4.3.0 or later                //
//                                                 //
// Copyright (C) 15 Jan 2004 Atom Emet             //
// Copyright (C) 17 Feb 2006 Atom Emet             //
// Atom {at} Business-PHP.com                      //
//                                                 //
// Distributed under the terms of the              //
// GNU General Public License                      //
//                                                 //
// Other licenses available on request             //
//                                                 //
// This program is free software; you can          //
// redistribute it and/or modify it under the      //
// terms of the GNU General Public License as      //
// published by the Free Software Foundation;      //
// either version 2 of the License, or             //   
// (at your option) any later version.             //
//                                                 //
// This program is distributed in the hope         //
// that it will be useful, but WITHOUT ANY         //
// WARRANTY; without even the implied warranty     //
// of MERCHANTABILITY or FITNESS FOR A             //
// PARTICULAR PURPOSE. See the GNU General         //
// Public License for more details.                //
//                                                 //
// You should have received a copy of the          //
// GNU General Public License along with this      //
// program; if not, write to                       //
//    the Free Software Foundation, Inc.           //
//    59 Temple Place - Suite 330                  //
//    Boston, MA  02111-1307, USA                  //
/////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////
// usage - see: http://business-php.com/opensource/gpg_encrypt/
// array gpg_gpg_encrypt(secret-message, /path/to/gpg, /path/to/.gnupg/, 0x123456);

//////////////////////
// define the function
function gpg_encrypt() {

    
//////////////////////////////////////////////////////////
    // sanity check - make sure there are at least 4 arguments
    // any extra arguments are considered to be additional key IDs
    
if(func_num_args() < 4) {
        
trigger_error("gpg_encrypt.php requires at least 4 arguments"E_USER_ERROR);
        
// if an error message directs you to the line above please
        // double check that you are providing at least 4 arguments
        
die();
    }

    
////////////////////////////////
    // assign arguments to variables
    
$gpg_encrypt_args func_get_args();
    
$gpg_encrypt_secret_message array_shift($gpg_encrypt_args);    // 1st argument - secret message
    
$gpg_encrypt_gpg_path array_shift($gpg_encrypt_args);        // 2nd argument - full path to gpg
    
$gpg_encrypt_gpg_home array_shift($gpg_encrypt_args);        // 3rd argument - keyring directory

    ///////////////////////////////////////////////////////////////////////
    // make sure that each recipient has the message encrypted to their key
    // the 4th argument, and any subsequent arguments, are key IDs
    
foreach($gpg_encrypt_args as $gpg_encrypt_recipient) {
        
$gpg_encrypt_recipient_list .= " -r ${gpg_encrypt_recipient}";
    }

    
//////////////////////////////////////////////////////////////////////////////
    // sanity check - make sure "$gpg_encrypt_gpg_home" is pointing to a directory
    
if(!is_dir($gpg_encrypt_gpg_home)) {
        
trigger_error("gpg homedir is not a directory: \"${gpg_encrypt_gpg_home}\""E_USER_ERROR);
        
// if an error message directs you to the line above please
        // double check that your full path to the .gnupg directory is correct
        
die();
    }

    
////////////////////////////////////////////////////////////////////////////////////////
    // sanity check - make sure "$gpg_encrypt_gpg_path" is pointing to an executable program
    
if(!is_executable($gpg_encrypt_gpg_path)) {
        
trigger_error("gpg is not executable: \"${gpg_encrypt_gpg_path}\" :: or you may need to comment out this sanity check - see the source"E_USER_ERROR);
        
// if an error message directs you to the line above please
        // double check that your full path to gpg is correct
        // ////////////////////////////////////////////////////////////////////////////////////////////
        // it has been reported that some (older) configurations of php will choke on this sanity check
        // if this is causing an error, try to comment out this test
        
die();
    }

    
//////////////////////////////////////////
    // find which version of GnuPG we're using
    //////////////////////////////////////////

    ///////////////////////////////////////////
    // first we'll set up a pipe to read STDOUT
    
$gpg_encrypt_version_descriptorspec = array(
        
=> array("pipe""w")  // STDOUT is a pipe that GnuPG will write to
    
);

    
////////////////////////////////////////////////////////
    // open a process for gpg to tell us which version it is
    
$gpg_encrypt_version_process proc_open("${gpg_encrypt_gpg_path} --version",
        
$gpg_encrypt_version_descriptorspec,
        
$gpg_encrypt_version_pipes);

    
/////////////////////////////////////////////////////
    // we're only concerned with the first line of output
    
$gpg_encrypt_version_output fgets($gpg_encrypt_version_pipes[1], 1024);

    
/////////////////////////////////////////
    // close the $gpg_encrypt_version_process
    
proc_close($gpg_encrypt_version_process);

    
///////////////////////////////////////////////
    // sanity check - see if we're working with gpg
    
if(!ereg('^gpg '$gpg_encrypt_version_output)) {
    
trigger_error("gpg executable is not GnuPG: \"${gpg_encrypt_gpg_path}\""E_USER_ERROR);
        
// if an error message directs you to the line above please
        // double check that your path to gpg is really GnuPG
        
die();
    }

    
/////////////////////////////////////////////////////////////
    // pick the version number out of $gpg_encrypt_version_output
    // we'll need this so we can determine the correct
    // way to tell GnuPG how to "always trust"
    
$gpg_encrypt_gpg_version eregi_replace('^.* '''$gpg_encrypt_version_output);

    
////////////////////////////////////////////////////////
    // depending on which version of GnuPG we're using there
    // are two different ways to specify "always trust"
    
if("$gpg_encrypt_gpg_version" '1.2.3') {
        
$gpg_encrypt_trust '--always-trust';        // the old way
    
} else {
        
$gpg_encrypt_trust '--trust-model always';    // the new way
    
}

    
/////////////////////////////////////////////
    // unset variables that we don't need anymore
    
unset($gpg_encrypt_version_output,
        
$gpg_encrypt_gpg_version);

    
////////////////////////////////////////
    // we're done checking the GnuPG version
    ////////////////////////////////////////

    //////////////////////////////////////////////
    // set up pipes for handling I/O to/from GnuPG
    
$gpg_encrypt_descriptorspec = array(
        
=> array("pipe""r"),  // STDIN is a pipe that GnuPG will read from
        
=> array("pipe""w"),  // STDOUT is a pipe that GnuPG will write to
        
=> array("pipe""w")   // STDERR is a pipe that GnuPG will write to
    
);

    
///////////////////////////////
    // this opens the GnuPG process
    
$gpg_encrypt_gpg_process proc_open("${gpg_encrypt_gpg_path} --no-random-seed-file --lock-never --homedir ${gpg_encrypt_gpg_home} ${gpg_encrypt_trust} -ea ${gpg_encrypt_recipient_list}",
        
$gpg_encrypt_descriptorspec,
        
$gpg_encrypt_pipes);

    
//////////////////////////////////////////////////////////////////
    // this writes the "$gpg_encrypt_secret_message" to GnuPG on STDIN
    
if(is_resource($gpg_encrypt_gpg_process)) {
        
fwrite($gpg_encrypt_pipes[0], ${gpg_encrypt_secret_message});
        
fclose($gpg_encrypt_pipes[0]);

    
/////////////////////////////////////////////////////////
    // this reads the encrypted output from GnuPG from STDOUT
    
while(!feof($gpg_encrypt_pipes[1])) {
        
$gpg_encrypt_encrypted_message .= fgets($gpg_encrypt_pipes[1], 1024);
    }
    
fclose($gpg_encrypt_pipes[1]);

    
/////////////////////////////////////////////////////////
    // this reads warnings and notices from GnuPG from STDERR
    
while(!feof($gpg_encrypt_pipes[2])) {
        
$gpg_encrypt_error_message .= fgets($gpg_encrypt_pipes[2], 1024);
    }
    
fclose($gpg_encrypt_pipes[2]);

    
/////////////////////////////////////////
    // this collects the exit status of GnuPG
    
$gpg_encrypt_exit_status proc_close($gpg_encrypt_gpg_process);

    
////////////////////////////////////////////
    // unset variables that are no longer needed
    // and can only cause trouble
    
unset($gpg_encrypt_args,
        
$gpg_encrypt_secret_message,
        
$gpg_encrypt_recipient_list,
        
$gpg_encrypt_recipient,
        
$gpg_encrypt_gpg_path,
        
$gpg_encrypt_gpg_home,
        
$gpg_encrypt_trust);

    
////////////////////////////////////
    // this returns an array containing:
    // [0] encrypted output (STDOUT)
    // [1] warnings and notices (STDERR)
    // [2] exit status
    
return array($gpg_encrypt_encrypted_message$gpg_encrypt_error_message$gpg_encrypt_exit_status);
    }
}
?>