1<?php
2
3/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4
5/**
6 * Encrypt and sign tests for the Crypt_GPG package.
7 *
8 * These tests require the PHPUnit 3.6 or greater package to be installed.
9 * PHPUnit is installable using PEAR. See the
10 * {@link http://www.phpunit.de/manual/3.6/en/installation.html manual}
11 * for detailed installation instructions.
12 *
13 * To run these tests, use:
14 * <code>
15 * $ phpunit EncryptSignTestCase
16 * </code>
17 *
18 * LICENSE:
19 *
20 * This library is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU Lesser General Public License as
22 * published by the Free Software Foundation; either version 2.1 of the
23 * License, or (at your option) any later version.
24 *
25 * This library is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 * Lesser General Public License for more details.
29 *
30 * You should have received a copy of the GNU Lesser General Public
31 * License along with this library; if not, see
32 * <http://www.gnu.org/licenses/>
33 *
34 * @category  Encryption
35 * @package   Crypt_GPG
36 * @author    Michael Gauthier <mike@silverorange.com>
37 * @copyright 2005-2009 silverorange
38 * @license   http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
39 * @version   $Id$
40 * @link      http://pear.php.net/package/Crypt_GPG
41 */
42
43/**
44 * Base test case.
45 */
46require_once 'TestCase.php';
47
48/**
49 * Tests encrypt and sign abilities of Crypt_GPG.
50 *
51 * @category  Encryption
52 * @package   Crypt_GPG
53 * @author    Michael Gauthier <mike@silverorange.com>
54 * @copyright 2005-2009 silverorange
55 * @license   http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
56 * @link      http://pear.php.net/package/Crypt_GPG
57 */
58class EncryptAndSignTest extends Crypt_GPG_TestCase
59{
60    /**
61     * @group string
62     */
63    public function testEncryptAndSignKeyNotFoundException_invalid_sign_key()
64    {
65        $this->expectException('Crypt_GPG_KeyNotFoundException');
66
67        $data = 'Hello, Alice! Goodbye, Bob!';
68        $this->gpg->addSignKey('non-existent-key@example.com');
69        $this->gpg->addEncryptKey('first-keypair@example.com');
70        $this->gpg->encryptAndSign($data);
71    }
72
73    /**
74     * @group string
75     */
76    public function testEncryptAndSignKeyNotFoundException_no_sign_key()
77    {
78        $this->expectException('Crypt_GPG_KeyNotFoundException');
79
80        $data = 'Hello, Alice! Goodbye, Bob!';
81        $this->gpg->addEncryptKey('first-keypair@example.com');
82        $this->gpg->encryptAndSign($data);
83    }
84
85    /**
86     * @group string
87     */
88    public function testEncryptAndSignKeyNotFoundException_invalid_encrypt_key()
89    {
90        $this->expectException('Crypt_GPG_KeyNotFoundException');
91
92        $data = 'Hello, Alice! Goodbye, Bob!';
93        $this->gpg->addSignKey('first-keypair@example.com', 'test1');
94        $this->gpg->addEncryptKey('non-existent-key@example.com');
95        $this->gpg->encryptAndSign($data);
96    }
97
98    /**
99     * @group string
100     */
101    public function testEncryptAndSignKeyNotFoundException_no_encrypt_key()
102    {
103        $this->expectException('Crypt_GPG_KeyNotFoundException');
104
105        $data = 'Hello, Alice! Goodbye, Bob!';
106        $this->gpg->addSignKey('first-keypair@example.com', 'test1');
107        $this->gpg->encryptAndSign($data);
108    }
109
110    /**
111     * @group string
112     */
113    public function testEncryptAndSignBadPassphraseException_missing_sign_key()
114    {
115        $this->expectException('Crypt_GPG_BadPassphraseException');
116
117        $data = 'Hello, Alice! Goodbye, Bob!';
118        $this->gpg->addSignKey('first-keypair@example.com');
119        $this->gpg->addEncryptKey('first-keypair@example.com');
120        $this->gpg->encryptAndSign($data);
121    }
122
123    /**
124     * @group string
125     */
126    public function testEncryptAndSignBadPassphraseException_bad_sign_key()
127    {
128        $this->expectException('Crypt_GPG_BadPassphraseException');
129
130        $data = 'Hello, Alice! Goodbye, Bob!';
131        $this->gpg->addSignKey('first-keypair@example.com', 'incorrect');
132        $this->gpg->addEncryptKey('first-keypair@example.com');
133        $this->gpg->encryptAndSign($data);
134    }
135
136    /**
137     * @group string
138     */
139    public function testEncryptAndSignNoPassphrase()
140    {
141        $data = 'Hello, Alice! Goodbye, Bob!';
142
143        $signKey           = 'no-passphrase@example.com';
144        $encryptKey        = 'first-keypair@example.com';
145        $decryptPassphrase = 'test1';
146
147        $this->gpg->addSignKey($signKey);
148        $this->gpg->addEncryptKey($encryptKey);
149        $encryptedSignedData = $this->gpg->encryptAndSign($data);
150
151        $this->gpg->addDecryptKey($encryptKey, $decryptPassphrase);
152        $results = $this->gpg->decryptAndVerify($encryptedSignedData);
153
154        $this->assertEquals($data, $results['data']);
155        $this->assertEquals(1, count($results['signatures']));
156        foreach ($results['signatures'] as $signature) {
157            $this->assertTrue($signature->isValid());
158        }
159    }
160
161    /**
162     * @group string
163     */
164    public function testEncryptAndSign()
165    {
166        $data = 'Hello, Alice! Goodbye, Bob!';
167
168        $signKey           = 'first-keypair@example.com';
169        $signPassphrase    = 'test1';
170        $encryptKey        = 'first-keypair@example.com';
171        $decryptPassphrase = 'test1';
172
173        $this->gpg->addSignKey($signKey, $signPassphrase);
174        $this->gpg->addEncryptKey($encryptKey);
175        $encryptedSignedData = $this->gpg->encryptAndSign($data);
176
177        $this->gpg->addDecryptKey($encryptKey, $decryptPassphrase);
178        $results = $this->gpg->decryptAndVerify($encryptedSignedData);
179
180        $this->assertEquals($data, $results['data']);
181        $this->assertEquals(1, count($results['signatures']));
182        foreach ($results['signatures'] as $signature) {
183            $this->assertTrue($signature->isValid());
184        }
185    }
186
187    /**
188     * @group string
189     */
190    public function testEncryptAndSignDualOnePassphrase()
191    {
192        $data = 'Hello, Alice! Goodbye, Bob!';
193
194        $signKey1          = 'first-keypair@example.com';
195        $signPassphrase1   = 'test1';
196        $signKey2          = 'no-passphrase@example.com';
197        $encryptKey        = 'first-keypair@example.com';
198        $decryptPassphrase = 'test1';
199
200        $this->gpg->addSignKey($signKey1, $signPassphrase1);
201        $this->gpg->addSignKey($signKey2);
202        $this->gpg->addEncryptKey($encryptKey);
203        $encryptedSignedData = $this->gpg->encryptAndSign($data);
204
205        $this->gpg->addDecryptKey($encryptKey, $decryptPassphrase);
206        $results = $this->gpg->decryptAndVerify($encryptedSignedData);
207
208        $this->assertEquals($data, $results['data']);
209        $this->assertEquals(2, count($results['signatures']));
210        foreach ($results['signatures'] as $signature) {
211            $this->assertTrue($signature->isValid());
212        }
213    }
214
215    /**
216     * @group string
217     */
218    public function testEncryptAndSignDual()
219    {
220        $data = 'Hello, Alice! Goodbye, Bob!';
221
222        $signKey1          = 'first-keypair@example.com';
223        $signPassphrase1   = 'test1';
224        $signKey2          = 'second-keypair@example.com';
225        $signPassphrase2   = 'test2';
226        $encryptKey        = 'first-keypair@example.com';
227        $decryptPassphrase = 'test1';
228
229        $this->gpg->addSignKey($signKey1, $signPassphrase1);
230        $this->gpg->addSignKey($signKey2, $signPassphrase2);
231        $this->gpg->addEncryptKey($encryptKey);
232        $encryptedSignedData = $this->gpg->encryptAndSign($data);
233
234        $this->gpg->addDecryptKey($encryptKey, $decryptPassphrase);
235        $results = $this->gpg->decryptAndVerify($encryptedSignedData);
236
237        $this->assertEquals($data, $results['data']);
238        $this->assertEquals(2, count($results['signatures']));
239        foreach ($results['signatures'] as $signature) {
240            $this->assertTrue($signature->isValid());
241        }
242    }
243
244    /**
245     * @group string
246     */
247    public function testEncryptAndSignEmpty()
248    {
249        $data = '';
250
251        $this->gpg->addSignKey('first-keypair@example.com', 'test1');
252        $this->gpg->addEncryptKey('first-keypair@example.com');
253        $encryptedSignedData = $this->gpg->encryptAndSign($data);
254
255        $this->gpg->addDecryptKey('first-keypair@example.com', 'test1');
256        $results = $this->gpg->decryptAndVerify($encryptedSignedData);
257
258        $this->assertEquals('', $results['data']);
259        $this->assertEquals(1, count($results['signatures']));
260        foreach ($results['signatures'] as $signature) {
261            $this->assertTrue($signature->isValid());
262        }
263    }
264
265    /**
266     * @group file
267     */
268    public function testEncryptAndSignFileNoPassphrase()
269    {
270        $expectedMd5Sum    = 'f96267d87551ee09bfcac16921e351c1';
271        $originalFilename  = $this->getDataFilename('testFileMedium.plain');
272        $encryptedFilename =
273            $this->getTempFilename('testEncryptAndSignFileNoPassphrase.asc');
274
275        $decryptedFilename =
276            $this->getTempFilename('testEncryptAndSignFileNoPassphrase.plain');
277
278        $this->gpg->addSignKey('no-passphrase@example.com');
279        $this->gpg->addEncryptKey('first-keypair@example.com');
280        $this->gpg->encryptAndSignFile($originalFilename, $encryptedFilename);
281
282        $this->gpg->addDecryptKey('first-keypair@example.com', 'test1');
283        $results = $this->gpg->decryptAndVerifyFile($encryptedFilename,
284            $decryptedFilename);
285
286        $md5Sum = $this->getMd5Sum($decryptedFilename);
287        $this->assertEquals($expectedMd5Sum, $md5Sum);
288
289        $this->assertEquals(1, count($results['signatures']));
290        foreach ($results['signatures'] as $signature) {
291            $this->assertTrue($signature->isValid());
292        }
293    }
294
295    /**
296     * @group file
297     */
298    public function testEncryptAndSignFile()
299    {
300        $expectedMd5Sum    = 'f96267d87551ee09bfcac16921e351c1';
301        $originalFilename  = $this->getDataFilename('testFileMedium.plain');
302        $encryptedFilename =
303            $this->getTempFilename('testEncryptAndSignFileNoPassphrase.asc');
304
305        $decryptedFilename =
306            $this->getTempFilename('testEncryptAndSignFileNoPassphrase.plain');
307
308        $this->gpg->addSignKey('first-keypair@example.com', 'test1');
309        $this->gpg->addEncryptKey('first-keypair@example.com');
310        $this->gpg->encryptAndSignFile($originalFilename, $encryptedFilename);
311
312        $this->gpg->addDecryptKey('first-keypair@example.com', 'test1');
313        $results = $this->gpg->decryptAndVerifyFile($encryptedFilename,
314            $decryptedFilename);
315
316        $md5Sum = $this->getMd5Sum($decryptedFilename);
317        $this->assertEquals($expectedMd5Sum, $md5Sum);
318
319        $this->assertEquals(1, count($results['signatures']));
320        foreach ($results['signatures'] as $signature) {
321            $this->assertTrue($signature->isValid());
322        }
323    }
324
325    /**
326     * @group file
327     */
328    public function testEncryptAndSignFileDualOnePassphrase()
329    {
330        $expectedMd5Sum    = 'f96267d87551ee09bfcac16921e351c1';
331        $originalFilename  = $this->getDataFilename('testFileMedium.plain');
332        $encryptedFilename =
333            $this->getTempFilename('testEncryptAndSignFileNoPassphrase.asc');
334
335        $decryptedFilename =
336            $this->getTempFilename('testEncryptAndSignFileNoPassphrase.plain');
337
338        $this->gpg->addSignKey('first-keypair@example.com', 'test1');
339        $this->gpg->addSignKey('no-passphrase@example.com');
340        $this->gpg->addEncryptKey('first-keypair@example.com');
341        $this->gpg->encryptAndSignFile($originalFilename, $encryptedFilename);
342
343        $this->gpg->addDecryptKey('first-keypair@example.com', 'test1');
344        $results = $this->gpg->decryptAndVerifyFile($encryptedFilename,
345            $decryptedFilename);
346
347        $md5Sum = $this->getMd5Sum($decryptedFilename);
348        $this->assertEquals($expectedMd5Sum, $md5Sum);
349
350        $this->assertEquals(2, count($results['signatures']));
351        foreach ($results['signatures'] as $signature) {
352            $this->assertTrue($signature->isValid());
353        }
354    }
355
356    /**
357     * @group file
358     */
359    public function testEncryptAndSignFileDual()
360    {
361        $expectedMd5Sum    = 'f96267d87551ee09bfcac16921e351c1';
362        $originalFilename  = $this->getDataFilename('testFileMedium.plain');
363        $encryptedFilename =
364            $this->getTempFilename('testEncryptAndSignFileNoPassphrase.asc');
365
366        $decryptedFilename =
367            $this->getTempFilename('testEncryptAndSignFileNoPassphrase.plain');
368
369        $this->gpg->addSignKey('first-keypair@example.com', 'test1');
370        $this->gpg->addSignKey('second-keypair@example.com', 'test2');
371        $this->gpg->addEncryptKey('first-keypair@example.com');
372        $this->gpg->encryptAndSignFile($originalFilename, $encryptedFilename);
373
374        $this->gpg->addDecryptKey('first-keypair@example.com', 'test1');
375        $results = $this->gpg->decryptAndVerifyFile($encryptedFilename,
376            $decryptedFilename);
377
378        $md5Sum = $this->getMd5Sum($decryptedFilename);
379        $this->assertEquals($expectedMd5Sum, $md5Sum);
380
381        $this->assertEquals(2, count($results['signatures']));
382        foreach ($results['signatures'] as $signature) {
383            $this->assertTrue($signature->isValid());
384        }
385    }
386
387    /**
388     * @group file
389     */
390    public function testEncryptAndSignFileFileException_input()
391    {
392        $this->expectException('Crypt_GPG_FileException');
393
394        // input file does not exist
395        $inputFilename = $this->getDataFilename(
396            'testEncryptAndSignFileFileFileException_input.plain');
397
398        $this->gpg->addSignKey('first-keypair@example.com', 'test1');
399        $this->gpg->addEncryptKey('first-keypair@example.com');
400        $this->gpg->encryptAndSignFile($inputFilename);
401    }
402
403    /**
404     * @group file
405     */
406    public function testEncryptAndSignFileFileException_output()
407    {
408        $this->expectException('Crypt_GPG_FileException');
409
410        // input file is plaintext
411        // output file does not exist
412        $inputFilename  = $this->getDataFilename('testFileMedium.plain');
413        $outputFilename = './non-existent' .
414            '/testEncryptAndSignFileFileException_output.plain';
415
416        $this->gpg->addSignKey('first-keypair@example.com', 'test1');
417        $this->gpg->addEncryptKey('first-keypair@example.com');
418        $this->gpg->encryptAndSignFile($inputFilename, $outputFilename);
419    }
420
421    /**
422     * @group file
423     */
424    public function testEncryptAndSignFileEmpty()
425    {
426        $originalFilename  = $this->getDataFilename('testFileEmpty.plain');
427        $encryptedFilename =
428            $this->getTempFilename('testEncryptAndSignFileEmpty.asc');
429
430        $this->gpg->addSignKey('first-keypair@example.com', 'test1');
431        $this->gpg->addEncryptKey('first-keypair@example.com');
432        $this->gpg->encryptAndSignFile($originalFilename, $encryptedFilename);
433
434        $this->gpg->addDecryptKey('first-keypair@example.com', 'test1');
435        $results = $this->gpg->decryptAndVerifyFile($encryptedFilename);
436
437        $this->assertEquals('', $results['data']);
438
439        $this->assertEquals(1, count($results['signatures']));
440        foreach ($results['signatures'] as $signature) {
441            $this->assertTrue($signature->isValid());
442        }
443    }
444}
445