[ Index ]
 

Code source de IMP H3 (4.1.5)

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/lib/Crypt/ -> SMIME.php (source)

   1  <?php
   2  
   3  require_once 'Horde/Crypt/smime.php';
   4  
   5  /**
   6   * Name of the S/MIME public key field in addressbook.
   7   */
   8  define('IMP_SMIME_PUBKEY_FIELD', 'smimePublicKey');
   9  
  10  /**
  11   * The IMP_SMIME:: class contains all functions related to handling
  12   * S/MIME messages within IMP.
  13   *
  14   * $Horde: imp/lib/Crypt/SMIME.php,v 1.45.2.16 2007/01/02 13:54:57 jan Exp $
  15   *
  16   * Copyright 2002-2007 Mike Cochrane <mike@graftonhall.co.nz>
  17   *
  18   * See the enclosed file COPYING for license information (GPL). If you
  19   * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
  20   *
  21   * @author  Mike Cochrane <mike@graftonhall.co.nz>
  22   * @since   IMP 4.0
  23   * @package IMP
  24   */
  25  class IMP_SMIME extends Horde_Crypt_smime {
  26  
  27      /**
  28       * The list of available sources to search for keys.
  29       *
  30       * @var array
  31       */
  32      var $_sources = array();
  33  
  34      /**
  35       * Constructor.
  36       */
  37      function IMP_SMIME()
  38      {
  39          /* Get the listing of all sources we search for public keys. */
  40          if (($sources = $GLOBALS['prefs']->getValue('search_sources'))) {
  41              $this->_sources = explode("\t", $sources);
  42              if ((count($this->_sources) == 1) && empty($this->_sources[0])) {
  43                  $this->_sources = array();
  44              }
  45          }
  46  
  47          parent::Horde_Crypt_smime(array('temp' => Horde::getTempDir()));
  48      }
  49  
  50      /**
  51       * Add the personal public key to the prefs.
  52       *
  53       * @param mixed $key  The public key to add (either string or array).
  54       */
  55      function addPersonalPublicKey($key)
  56      {
  57          $GLOBALS['prefs']->setValue('smime_public_key', (is_array($key)) ? implode('', $key) : $key);
  58      }
  59  
  60      /**
  61       * Add the personal private key to the prefs.
  62       *
  63       * @param mixed $key  The private key to add (either string or array).
  64       */
  65      function addPersonalPrivateKey($key)
  66      {
  67          $GLOBALS['prefs']->setValue('smime_private_key', (is_array($key)) ? implode('', $key) : $key);
  68      }
  69  
  70      /**
  71       * Add the list of additional certs to the prefs.
  72       *
  73       * @param mixed $key  The private key to add (either string or array).
  74       */
  75      function addAdditionalCert($key)
  76      {
  77          $GLOBALS['prefs']->setValue('smime_additional_cert', (is_array($key)) ? implode('', $key) : $key);
  78      }
  79  
  80      /**
  81       * Get the personal public key from the prefs.
  82       *
  83       * @return string  The personal S/MIME public key.
  84       */
  85      function getPersonalPublicKey()
  86      {
  87          return $GLOBALS['prefs']->getValue('smime_public_key');
  88      }
  89  
  90      /**
  91       * Get the personal private key from the prefs.
  92       *
  93       * @return string  The personal S/MIME private key.
  94       */
  95      function getPersonalPrivateKey()
  96      {
  97          return $GLOBALS['prefs']->getValue('smime_private_key');
  98      }
  99  
 100      /**
 101       * Get any additional certificates from the prefs.
 102       *
 103       * @return string  Additional signing certs for inclusion.
 104       */
 105      function getAdditionalCert()
 106      {
 107          return $GLOBALS['prefs']->getValue('smime_additional_cert');
 108      }
 109  
 110      /**
 111       * Deletes the specified personal keys from the prefs.
 112       */
 113      function deletePersonalKeys()
 114      {
 115          $GLOBALS['prefs']->setValue('smime_public_key', '');
 116          $GLOBALS['prefs']->setValue('smime_private_key', '');
 117          $GLOBALS['prefs']->setValue('smime_additional_cert', '');
 118          $this->unsetPassphrase();
 119      }
 120  
 121      /**
 122       * Add a public key to an address book.
 123       *
 124       * @param string $cert  A public certificate to add.
 125       *
 126       * @return boolean  True on successful add.
 127       *                  Returns PEAR_Error or error.
 128       */
 129      function addPublicKey($cert)
 130      {
 131          /* Make sure the certificate is valid. */
 132          $key_info = openssl_x509_parse($cert);
 133          if (!is_array($key_info) || !isset($key_info['subject'])) {
 134              return PEAR::raiseError(_("Not a valid public key."), 'horde.error');
 135          }
 136  
 137          /* Add key to the user's address book. */
 138          $email = $this->getEmailFromKey($cert);
 139          if (is_null($email)) {
 140              return PEAR::raiseError(_("No email information located in the public key."), 'horde.error');
 141          }
 142  
 143          /* Get the name corresponding to this key. */
 144          if (isset($key_info['subject']['OU'])) {
 145              $name = $key_info['subject']['OU'];
 146          } elseif (isset($key_info['subject']['CN'])) {
 147              $name = $key_info['subject']['CN'];
 148          } else {
 149              return PEAR::raiseError(_("Not a valid public key."), 'horde.error');
 150          }
 151  
 152          $res = $GLOBALS['registry']->call('contacts/addField', array($email, $name, IMP_SMIME_PUBKEY_FIELD, $cert, $GLOBALS['prefs']->getValue('add_source')));
 153          if (is_a($res, 'PEAR_Error')) {
 154              return $res;
 155          }
 156  
 157          return $key_info;
 158      }
 159  
 160      /**
 161       * Returns the params needed to encrypt a message being sent to the
 162       * specified email address.
 163       *
 164       * @access private
 165       *
 166       * @param string $address  The e-mail address of the recipient.
 167       *
 168       * @return array  The list of parameters needed by encrypt().
 169       *                Returns PEAR_Error object on error.
 170       */
 171      function _encryptParameters($address)
 172      {
 173          /* We can only encrypt if we are sending to a single person. */
 174          $addrOb = IMP::bareAddress($address, true);
 175          $key_addr = array_pop($addrOb);
 176  
 177          $public_key = $this->getPublicKey($key_addr);
 178          if (is_a($public_key, 'PEAR_Error')) {
 179              return $public_key;
 180          }
 181  
 182          return array('type' => 'message', 'pubkey' => $public_key, 'email'  => $address);
 183      }
 184  
 185      /**
 186       * Retrieves a public key by e-mail.
 187       * The key will be retrieved from a user's address book(s).
 188       *
 189       * @param string $address  The e-mail address to search for.
 190       *
 191       * @return string  The S/MIME public key requested.
 192       *                 Returns PEAR_Error object on error.
 193       */
 194      function getPublicKey($address)
 195      {
 196          $key = $GLOBALS['registry']->call('contacts/getField', array($address, IMP_SMIME_PUBKEY_FIELD, $this->_sources, false, true));
 197          if (is_a($key, 'PEAR_Error')) {
 198              require_once 'Horde/Identity.php';
 199              $identity = &Identity::singleton(array('imp', 'imp'));
 200              $personal_pubkey = $this->getPersonalPublicKey();
 201              if (!empty($personal_pubkey) && $identity->hasAddress($address)) {
 202                  return $personal_pubkey;
 203              }
 204          }
 205  
 206          /* If more than one public key is returned, just return the first in
 207           * the array. There is no way of knowing which is the "preferred" key,
 208           * if the keys are different. */
 209          if (is_array($key)) {
 210              return reset($key);
 211          }
 212  
 213          return $key;
 214      }
 215  
 216      /**
 217       * Retrieves all public keys from a user's address book(s).
 218       *
 219       * @return array  All PGP public keys available.
 220       *                Returns PEAR_Error object on error.
 221       *
 222       */
 223      function listPublicKeys()
 224      {
 225          if (empty($this->_sources)) {
 226              return array();
 227          } else {
 228              return $GLOBALS['registry']->call('contacts/getAllAttributeValues', array(IMP_SMIME_PUBKEY_FIELD, $this->_sources));
 229          }
 230      }
 231  
 232      /**
 233       * Deletes a public key from a user's address book(s) by e-mail.
 234       *
 235       * @param string $email  The e-mail address to delete.
 236       *
 237       * @return PEAR_Error  Returns PEAR_Error object on error.
 238       */
 239      function deletePublicKey($email)
 240      {
 241          return $GLOBALS['registry']->call('contacts/deleteField', array($email, IMP_SMIME_PUBKEY_FIELD, $this->_sources));
 242      }
 243  
 244      /**
 245       * Returns the parameters needed for signing a message.
 246       *
 247       * @access private
 248       *
 249       * @return array  The list of parameters needed by encrypt().
 250       */
 251      function _signParameters()
 252      {
 253          return array(
 254              'type' => 'signature',
 255              'pubkey' => $this->getPersonalPublicKey(),
 256              'privkey' => $this->getPersonalPrivateKey(),
 257              'passphrase' => $this->getPassphrase(),
 258              'sigtype' => 'detach',
 259              'certs' => $this->getAdditionalCert()
 260          );
 261      }
 262  
 263      /**
 264       * Verifies a signed message with a given public key.
 265       *
 266       * @param string $text  The text to verify.
 267       *
 268       * @return stdClass  See Horde_Crypt_smime::verify().
 269       */
 270      function verifySignature($text)
 271      {
 272          return $this->verify($text, $GLOBALS['conf']['utils']['openssl_cafile']);
 273      }
 274  
 275  
 276      /**
 277       * Decrypt a message with user's public/private keypair.
 278       *
 279       * @param string $text  The text to decrypt.
 280       *
 281       * @return string  See Horde_Crypt_smime::decrypt().
 282       *                 Returns PEAR_Error object on error.
 283       */
 284      function decryptMessage($text)
 285      {
 286          /* decrypt() returns a PEAR_Error object on error. */
 287          return $this->decrypt($text, array('type' => 'message', 'pubkey' => $this->getPersonalPublicKey(), 'privkey' => $this->getPersonalPrivateKey(), 'passphrase' => $this->getPassphrase()));
 288      }
 289  
 290      /**
 291       * Gets the user's passphrase from the session cache.
 292       *
 293       * @return mixed  The passphrase, if set.  Returns false if the passphrase
 294       *                has not been loaded yet.  Returns null if no passphrase
 295       *                is needed.
 296       */
 297      function getPassphrase()
 298      {
 299          $private_key = $GLOBALS['prefs']->getValue('smime_private_key');
 300          if (empty($private_key)) {
 301              return false;
 302          }
 303  
 304          if (isset($GLOBALS['imp']['smime']['passphrase'])) {
 305              return Secret::read(Secret::getKey('imp'), $GLOBALS['imp']['smime']['passphrase']);
 306          } elseif (isset($GLOBALS['imp']['smime']['null_passphrase'])) {
 307              return ($GLOBALS['imp']['smime']['null_passphrase']) ? null : false;
 308          } else {
 309              $res = $this->verifyPassphrase($private_key, null);
 310              if (!isset($GLOBALS['imp']['smime'])) {
 311                  $GLOBALS['imp']['smime'] = array();
 312              }
 313              $GLOBALS['imp']['smime']['null_passphrase'] = ($res) ? null : false;
 314              return $GLOBALS['imp']['smime']['null_passphrase'];
 315          }
 316      }
 317  
 318      /**
 319       * Store's the user's passphrase in the session cache.
 320       *
 321       * @param string $passphrase  The user's passphrase.
 322       *
 323       * @return boolean  Returns true if correct passphrase, false if incorrect.
 324       */
 325      function storePassphrase($passphrase)
 326      {
 327          if ($this->verifyPassphrase($this->getPersonalPrivateKey(), $passphrase) === false) {
 328              return false;
 329          }
 330  
 331          if (!isset($GLOBALS['imp']['smime'])) {
 332              $GLOBALS['imp']['smime'] = array();
 333          }
 334          $GLOBALS['imp']['smime']['passphrase'] = Secret::write(Secret::getKey('imp'), $passphrase);
 335  
 336          return true;
 337      }
 338  
 339      /**
 340       * Clear the passphrase from the session cache.
 341       */
 342      function unsetPassphrase()
 343      {
 344          unset($GLOBALS['imp']['smime']['null_passphrase']);
 345          unset($GLOBALS['imp']['smime']['passphrase']);
 346      }
 347  
 348      /**
 349       * Generates the javascript code for viewing public keys.
 350       *
 351       * @since IMP 4.1.3
 352       *
 353       * @param MIME_Part &$mime_part  The MIME_Part containing the public key.
 354       * @param string $cache          The MIME_Part identifier.
 355       *
 356       * @return string  The URL for saving public keys.
 357       */
 358      function viewPublicKeyURL($mime_part, $from)
 359      {
 360          if (empty($cache)) {
 361              require_once 'Horde/SessionObjects.php';
 362              $cacheSess = &Horde_SessionObjects::singleton();
 363              $oid = $cacheSess->storeOid($mime_part);
 364          }
 365  
 366          return $this->getJSOpenWinCode('view_attachment_public_key', false, array('from' => $from, 'cert' => $oid));
 367      }
 368  
 369      /**
 370       * Generates the javascript code for saving public keys.
 371       *
 372       * @param MIME_Part &$mime_part  The MIME_Part containing the public key.
 373       * @param string $cache          The MIME_Part identifier.
 374       *
 375       * @return string  The URL for saving public keys.
 376       */
 377      function savePublicKeyURL($mime_part, $from)
 378      {
 379          if (empty($cache)) {
 380              require_once 'Horde/SessionObjects.php';
 381              $cacheSess = &Horde_SessionObjects::singleton();
 382              $oid = $cacheSess->storeOid($mime_part);
 383          }
 384  
 385          return $this->getJSOpenWinCode('save_attachment_public_key', false, array('from' => $from, 'cert' => $oid));
 386      }
 387  
 388      /**
 389       * Print out the link for the javascript SMIME popup.
 390       *
 391       * @param integer $actionid  The actionID to perform.
 392       * @param mixed $reload      If true, reload base window on close. If text,
 393       *                           run this JS on close. If false, don't do
 394       *                           anything on close.
 395       * @param array $params      Additional parameters needed for the reload
 396       *                           page.
 397       *
 398       * @return string  The javascript link.
 399       */
 400      function getJSOpenWinCode($actionid, $reload = true, $params = null)
 401      {
 402          $popup_url = Horde::applicationUrl('smime.php');
 403          $popup_url = Util::addParameter($popup_url, 'actionID', $actionid, false);
 404          if (!empty($reload)) {
 405              if (is_bool($reload)) {
 406                  $popup_url = Util::addParameter($popup_url, 'reload', Util::removeParameter(Horde::selfUrl(true), array('actionID')), false);
 407              } else {
 408                  require_once 'Horde/SessionObjects.php';
 409                  $cacheSess = &Horde_SessionObjects::singleton();
 410                  $popup_url = Util::addParameter($popup_url, 'passphrase_action', $cacheSess->storeOid($reload, false), false);
 411              }
 412          }
 413  
 414          if (is_array($params)) {
 415              $popup_url = Util::addParameter($popup_url, $params, null, false);
 416          }
 417  
 418          return "popup_imp('" . $popup_url . "',450,200);";
 419      }
 420  
 421      /**
 422       * Encrypt a MIME_Part using S/MIME using IMP defaults.
 423       *
 424       * @param MIME_Part $mime_part  The MIME_Part object to encrypt.
 425       * @param mixed $to_address     The e-mail address of the key to use for
 426       *                              encryption.
 427       *
 428       * @return MIME_Part  See Horde_Crypt_smime::encryptMIMEPart(). Returns
 429       *                    PEAR_Error on error.
 430       */
 431      function IMPencryptMIMEPart($mime_part, $to_address)
 432      {
 433          $params = $this->_encryptParameters($to_address);
 434          if (is_a($params, 'PEAR_Error')) {
 435              return $params;
 436          }
 437          return $this->encryptMIMEPart($mime_part, $params);
 438      }
 439  
 440      /**
 441       * Sign a MIME_Part using S/MIME using IMP defaults.
 442       *
 443       * @param MIME_Part $mime_part  The MIME_Part object to sign.
 444       *
 445       * @return MIME_Part  See Horde_Crypt_smime::signMIMEPart(). Returns
 446       *                    PEAR_Error on error.
 447       */
 448      function IMPsignMIMEPart($mime_part)
 449      {
 450          return $this->signMIMEPart($mime_part, $this->_signParameters());
 451      }
 452  
 453      /**
 454       * Sign and encrypt a MIME_Part using S/MIME using IMP defaults.
 455       *
 456       * @acccess public
 457       *
 458       * @param MIME_Part $mime_part  The MIME_Part object to sign and encrypt.
 459       * @param string $to_address    The e-mail address of the key to use for
 460       *                              encryption.
 461       *
 462       * @return MIME_Part  See Horde_Crypt_smime::signAndencryptMIMEPart().
 463       *                    Returns PEAR_Error on error.
 464       */
 465      function IMPsignAndEncryptMIMEPart($mime_part, $to_address)
 466      {
 467          $encrypt_params = $this->_encryptParameters($to_address);
 468          if (is_a($encrypt_params, 'PEAR_Error')) {
 469              return $encrypt_params;
 470          }
 471          return $this->signAndEncryptMIMEPart($mime_part, $this->_signParameters(), $encrypt_params);
 472      }
 473  
 474      /**
 475       * Store the public/private/additional certificates in the preferences
 476       * from a given PKCS 12 file.
 477       *
 478       * @acccess public
 479       *
 480       * @param string $pkcs12    The PKCS 12 data.
 481       * @param string $password  The password of the PKCS 12 file.
 482       * @param string $pkpass    The password to use to encrypt the private key.
 483       *
 484       * @return boolean  True on success, PEAR_Error on error.
 485       */
 486      function addFromPKCS12($pkcs12, $password, $pkpass = null)
 487      {
 488          $openssl = IMP_SMIME::checkForOpenSSL();
 489          if (is_a($openssl, 'PEAR_Error')) {
 490              return $openssl;
 491          }
 492  
 493          $sslpath = (empty($GLOBALS['conf']['utils']['openssl_binary'])) ? null : $GLOBALS['conf']['utils']['openssl_binary'];
 494          $params = array('sslpath' => $sslpath, 'password' => $password);
 495          if (!empty($pkpass)) {
 496              $params['newpassword'] = $pkpass;
 497          }
 498          $res = $this->parsePKCS12Data($pkcs12, $params);
 499          if (is_a($res, 'PEAR_Error')) {
 500              return $res;
 501          }
 502  
 503          $this->addPersonalPrivateKey($res->private);
 504          $this->addPersonalPublicKey($res->public);
 505          $this->addAdditionalCert($res->certs);
 506  
 507          return true;
 508      }
 509  
 510      /**
 511       * Extract the contents from signed S/MIME data.
 512       *
 513       * @param string $data  The signed S/MIME data.
 514       *
 515       * @return string  The contents embedded in the signed data.
 516       *                 Returns PEAR_Error on error.
 517       */
 518      function extractSignedContents($data)
 519      {
 520          $sslpath = (empty($GLOBALS['conf']['utils']['openssl_binary'])) ? null : $GLOBALS['conf']['utils']['openssl_binary'];
 521          return parent::extractSignedContents($data, $sslpath);
 522      }
 523  
 524  }


Généré le : Thu Nov 29 12:30:07 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics