protected function assertValidVerify($expected, Swift_ByteStream_TemporaryFileByteStream $messageStream)
 {
     $actual = $messageStream->getContent();
     // File is UNIX encoded so convert them to correct line ending
     $expected = str_replace("\n", "\r\n", $expected);
     $actual = trim(self::getBodyOfMessage($actual));
     if (!$this->assertRegExp('%^' . $expected . '$\\s*%m', $actual)) {
         return false;
     }
     $opensslOutput = new Swift_ByteStream_TemporaryFileByteStream();
     $verify = openssl_pkcs7_verify($messageStream->getPath(), null, $opensslOutput->getPath(), array($this->samplesDir . 'smime/ca.crt'));
     if (false === $verify) {
         $this->fail('Verification of the message failed.');
         return false;
     } elseif (-1 === $verify) {
         $this->fail(sprintf('Verification of the message failed. Internal error "%s".', openssl_error_string()));
         return false;
     }
     return true;
 }
示例#2
0
    public function testEncryptThenSignMessage()
    {
        $message = Swift_SignedMessage::newInstance('Wonderful Subject')->setFrom(array('*****@*****.**' => 'John Doe'))->setTo(array('*****@*****.**', '*****@*****.**' => 'A name'))->setBody('Here is the message itself');
        $originalMessage = $this->cleanMessage($message->toString());
        $signer = Swift_Signers_SMimeSigner::newInstance();
        $signer->setSignCertificate($this->samplesDir . 'smime/sign.crt', $this->samplesDir . 'smime/sign.key');
        $signer->setEncryptCertificate($this->samplesDir . 'smime/encrypt.crt');
        $signer->setSignThenEncrypt(false);
        $message->attachSigner($signer);
        $messageStream = $this->newFilteredStream();
        $message->toByteStream($messageStream);
        $messageStream->commit();
        $entityString = $messageStream->getContent();
        $headers = self::getHeadersOfMessage($entityString);
        if (!($boundary = $this->getBoundary($headers['content-type']))) {
            return false;
        }
        $expectedBody = <<<OEL
This is an S/MIME signed message

--{$boundary}
(?P<encrypted_message>MIME-Version: 1\\.0
Content-Disposition: attachment; filename="smime\\.p7m"
Content-Type: application/(x\\-)?pkcs7-mime; smime-type=enveloped-data; name="smime\\.p7m"
Content-Transfer-Encoding: base64

(?:^[a-zA-Z0-9\\/\\r\\n+]*={0,2})


)--{$boundary}
Content-Type: application/(x\\-)?pkcs7-signature; name="smime\\.p7s"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="smime\\.p7s"

(?:^[a-zA-Z0-9\\/\\r\\n+]*={0,2})

--{$boundary}--
OEL;
        if (!$this->assertValidVerify($expectedBody, $messageStream)) {
            return false;
        }
        $expectedBody = str_replace("\n", "\r\n", $expectedBody);
        if (!preg_match('%' . $expectedBody . '*%m', $entityString, $entities)) {
            $this->fail('Failed regex match.');
            return false;
        }
        $messageStreamClean = new Swift_ByteStream_TemporaryFileByteStream();
        $messageStreamClean->write($entities['encrypted_message']);
        $decryptedMessageStream = new Swift_ByteStream_TemporaryFileByteStream();
        if (!openssl_pkcs7_decrypt($messageStreamClean->getPath(), $decryptedMessageStream->getPath(), 'file://' . $this->samplesDir . 'smime/encrypt.crt', array('file://' . $this->samplesDir . 'smime/encrypt.key', 'swift'))) {
            $this->fail(sprintf('Decrypt of the message failed. Internal error "%s".', openssl_error_string()));
        }
        $this->assertEquals($originalMessage, $decryptedMessageStream->getContent());
        unset($messageStreamClean, $messageStream, $decryptedMessageStream);
    }