function decrypt($packet) { if (!is_object($packet)) { $packet = OpenPGP_Message::parse($packet); } if ($packet instanceof OpenPGP_SecretKeyPacket || $packet instanceof Crypt_RSA || $packet instanceof ArrayAccess && $packet[0] instanceof OpenPGP_SecretKeyPacket) { $keys = $packet; $message = $this->message; } else { $keys = $this->key; $message = $packet; } if (!$keys || !$message) { return NULL; } // Missing some data if (!$keys instanceof Crypt_RSA) { $keys = new self($keys); } foreach ($message as $p) { if ($p instanceof OpenPGP_AsymmetricSessionKeyPacket) { if ($keys instanceof Crypt_RSA) { $sk = self::try_decrypt_session($keys, substr($p->encyrpted_data, 2)); } else { if (strlen(str_replace('0', '', $p->keyid)) < 1) { foreach ($keys->key as $k) { $sk = self::try_decrypt_session(self::convert_private_key($k), substr($p->encyrpted_data, 2)); if ($sk) { break; } } } else { $key = $keys->private_key($p->keyid); $sk = self::try_decrypt_session($key, substr($p->encrypted_data, 2)); } } if (!$sk) { continue; } $r = OpenPGP_Crypt_Symmetric::decryptPacket(OpenPGP_Crypt_Symmetric::getEncryptedData($message), $sk[0], $sk[1]); if ($r) { return $r; } } } return NULL; /* Failed */ }
/** */ public function decrypt($msg, $key) { $decryptor = new OpenPGP_Crypt_RSA($key->message); $elgamal = null; foreach ($msg->message as $val) { if ($val instanceof OpenPGP_AsymmetricSessionKeyPacket) { $pkey = $decryptor->key($val->keyid); if (!$pkey instanceof OpenPGP_PublicKeyPacket) { continue; } switch ($pkey->algorithm) { case 1: case 2: return new Horde_Pgp_Element_Message($decryptor->decrypt($msg->message)); case 16: $elgamal = new Horde_Pgp_Crypt_Elgamal($pkey); /* Put encrypted data into a packet object to take * advantage of built-in MPI read methods. */ $edata = new OpenPGP_Packet(); $edata->input = $val->encrypted_data; $sk_data = $elgamal->decrypt($edata->read_mpi() . $edata->read_mpi()); $sk = substr($sk_data, 1, strlen($sk_data) - 3); /* Last 2 bytes are checksum */ $chk = unpack('n', substr($sk_data, -2)); $chk = reset($chk); $sk_chk = 0; for ($i = 0, $j = strlen($sk); $i < $j; ++$i) { $sk_chk = ($sk_chk + ord($sk[$i])) % 65536; } if ($sk_chk != $chk) { throw new RuntimeException(); } return new Horde_Pgp_Element_Message(OpenPGP_Crypt_Symmetric::decryptPacket(OpenPGP_Crypt_Symmetric::getEncryptedData($msg->message), ord($sk_data[0]), $sk)); } } } throw new RuntimeException(); }