/** * Encode file for email, encryption results in ASCII armored data which removed need for base 64 encoding step. * * @todo test with filename instead of array passed as $file, see Email::attachFile() and ::attachFileFromString() * @todo test with $destFilename * @todo test with disposition set to inline * @todo test with contentLocation param, see Mailer::encodeFileForEmail() * * @param mixed $file Array of file data including content or just string indicating filename * @param string $destFileName Destination filename * @param string $disposition Disposition of attachment, inline or attachment * @param string $extraHeaders Extra headers for attachement * @return string Contents for attachement including headers and ASCII armored file content */ public function encodeFileForEmail($file, $destFileName = false, $disposition = NULL, $extraHeaders = "") { if (!$file) { user_error("encodeFileForEmail: not passed a filename and/or data", E_USER_WARNING); return; } if (is_string($file)) { $file = array('filename' => $file); $fh = fopen($file['filename'], "rb"); if ($fh) { $file['contents'] = ""; while (!feof($fh)) { $file['contents'] .= fread($fh, 10000); } fclose($fh); } } // Build headers, including content type if (!$destFileName) { $base = basename($file['filename']); } else { $base = $destFileName; } // Force base and MIME type for encrypted attachements $base = $base . '.pgp'; $mimeType = 'application/octet-stream'; // TODO Need to test with contentLocation param if (empty($disposition)) { $disposition = isset($file['contentLocation']) ? 'inline' : 'attachment'; } // Encode for emailing. Only accepts binary|8bit|7bit not quoted-printable|base64 // ASCII armored output *should* be base64 though? $encoding = "7bit"; // GPG encryption and signing if necessary if ($this->sign) { $file['contents'] = $this->gpg->encryptAndSign($file['contents']); } else { $file['contents'] = $this->gpg->encrypt($file['contents']); } $headers = "Content-type: {$mimeType};\n\tname=\"{$base}\"\n" . "Content-Transfer-Encoding: {$encoding}\n" . "Content-Disposition: {$disposition};\n\tfilename=\"{$base}\"\n"; // TODO Need to test with contentLocation param if (isset($file['contentLocation'])) { $headers .= 'Content-Location: ' . $file['contentLocation'] . "\n"; } $headers .= $extraHeaders . "\n"; return $headers . $file['contents']; }
/** * Encrypt and sign given string to one or more recipients * * @param string $string * @param string|array $encryptKeyID * @param string $signkeyPassword * @param string $signkeyID * @param boolean $mode * @param boolean $armor * @return string */ public static function encryptAndSign($string, $encryptKeyID, $signkeyPassword = null, $signkeyID = null, $mode = null, $armor = true) { $gpg = new Crypt_GPG(); if ($mode === null) { $mode = Crypt_GPG::SIGN_MODE_CLEAR; } if ($signkeyID === null) { $signkeyID = ConfigManager::getConfig("Crypto", "GPG")->AuxConfig->defaultKey; } if ($signkeyPassword === null) { $signkeyPassword = ConfigManager::getConfig("Crypto", "GPG")->AuxConfig->defaultKeyPasswd; } $gpg->addSignKey($signkeyID, $signkeyPassword); if (is_array($encryptKeyID)) { foreach ($encryptKeyID as $keyId) { $gpg->addEncryptKey($keyId); } } else { $gpg->addEncryptKey($encryptKeyID); } return $gpg->encryptAndSign($string, $armor); }
/** * Encrypt and sign the body of an email. * * @param Message $message * @param string $fingerprint * @return Message * @throws \Exception */ public function encryptAndSign(Message $message, string $fingerprint) : Message { if (!$this->serverKeyFingerprint) { throw new \Exception('No signing key provided'); } $gnupg = new \Crypt_GPG($this->options); $gnupg->addEncryptKey($fingerprint); $gnupg->addSignKey($this->serverKeyFingerprint); // Replace the message with its encrypted counterpart $encrypted = $gnupg->encryptAndSign($message->getBodyText(), true); return $message->setBody($encrypted); }