1<?php 2 3/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ 4 5/** 6 * Signing 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 SignTestCase 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-2008 silverorange 38 * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 39 * @version CVS: $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 signing abilities of Crypt_GPG. 50 * 51 * @category Encryption 52 * @package Crypt_GPG 53 * @author Michael Gauthier <mike@silverorange.com> 54 * @copyright 2005-2008 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 SignTest extends Crypt_GPG_TestCase 59{ 60 public function testHasSignKeys() 61 { 62 $this->assertFalse($this->gpg->hasSignKeys()); 63 $this->gpg->addSignKey('no-passphrase@example.com'); 64 $this->assertTrue($this->gpg->hasSignKeys()); 65 } 66 67 /** 68 * @group string 69 */ 70 public function testSignKeyNotFoundException_invalid() 71 { 72 $this->expectException('Crypt_GPG_KeyNotFoundException'); 73 74 $data = 'Hello, Alice! Goodbye, Bob!'; 75 $this->gpg->addSignKey('non-existent-key@example.com'); 76 $this->gpg->sign($data); 77 } 78 79 /** 80 * @group string 81 */ 82 public function testSignKeyNotFoundException_none() 83 { 84 $this->expectException('Crypt_GPG_KeyNotFoundException'); 85 86 $data = 'Hello, Alice! Goodbye, Bob!'; 87 $this->gpg->sign($data); 88 } 89 90 /** 91 * @group string 92 */ 93 public function testSignBadPassphraseException_missing() 94 { 95 $this->expectException('Crypt_GPG_BadPassphraseException'); 96 97 $data = 'Hello, Alice! Goodbye, Bob!'; 98 $this->gpg->addSignKey('first-keypair@example.com'); 99 $this->gpg->sign($data); 100 } 101 102 /** 103 * @group string 104 */ 105 public function testSignBadPassphraseException_bad() 106 { 107 $this->expectException('Crypt_GPG_BadPassphraseException'); 108 109 $data = 'Hello, Alice! Goodbye, Bob!'; 110 $this->gpg->addSignKey('first-keypair@example.com', 'incorrect'); 111 $this->gpg->sign($data); 112 } 113 114 /** 115 * @group string 116 */ 117 public function testSignNoPassphrase() 118 { 119 $this->gpg->setEngineOptions(array('sign' => '--emit-version')); 120 121 $data = 'Hello, Alice! Goodbye, Bob!'; 122 $this->gpg->addSignKey('no-passphrase@example.com'); 123 $signedData = $this->gpg->sign($data); 124 125 // Check if --emit-version option works 126 $this->assertTrue(strpos($signedData, 'Version:') !== false); 127 $this->gpg->setEngineOptions(array()); 128 129 $signatures = $this->gpg->verify($signedData); 130 $this->assertEquals(1, count($signatures)); 131 foreach ($signatures as $signature) { 132 $this->assertTrue($signature->isValid()); 133 } 134 } 135 136 /** 137 * @group string 138 */ 139 public function testSignNormal() 140 { 141 $data = 'Hello, Alice! Goodbye, Bob!'; 142 $this->gpg->addSignKey('first-keypair@example.com', 'test1'); 143 $signedData = $this->gpg->sign($data); 144 145 $signatures = $this->gpg->verify($signedData); 146 $this->assertEquals(1, count($signatures)); 147 foreach ($signatures as $signature) { 148 $this->assertTrue($signature->isValid()); 149 } 150 } 151 152 /** 153 * @group string 154 */ 155 public function testSignClear() 156 { 157 $data = 'Hello, Alice! Goodbye, Bob!'; 158 $this->gpg->addSignKey('first-keypair@example.com', 'test1'); 159 $signedData = $this->gpg->sign($data, Crypt_GPG::SIGN_MODE_CLEAR); 160 161 $signatures = $this->gpg->verify($signedData); 162 $this->assertEquals(1, count($signatures)); 163 foreach ($signatures as $signature) { 164 $this->assertTrue($signature->isValid()); 165 } 166 } 167 168 /** 169 * @group string 170 */ 171 public function testSignDetached() 172 { 173 $data = 'Hello, Alice! Goodbye, Bob!'; 174 $this->gpg->addSignKey('first-keypair@example.com', 'test1'); 175 $signatureData = $this->gpg->sign($data, 176 Crypt_GPG::SIGN_MODE_DETACHED); 177 178 $signatures = $this->gpg->verify($data, $signatureData); 179 $this->assertEquals(1, count($signatures)); 180 foreach ($signatures as $signature) { 181 $this->assertTrue($signature->isValid()); 182 } 183 } 184 185 /** 186 * @group string 187 */ 188 public function testSignDualOnePassphrase() 189 { 190 $data = 'Hello, Alice! Goodbye, Bob!'; 191 $this->gpg->addSignKey('no-passphrase@example.com'); 192 $this->gpg->addSignKey('first-keypair@example.com', 'test1'); 193 $signedData = $this->gpg->sign($data); 194 195 $signatures = $this->gpg->verify($signedData); 196 $this->assertEquals(2, count($signatures)); 197 foreach ($signatures as $signature) { 198 $this->assertTrue($signature->isValid()); 199 } 200 } 201 202 /** 203 * @group string 204 */ 205 public function testSignDualNormal() 206 { 207 $data = 'Hello, Alice! Goodbye, Bob!'; 208 $this->gpg->addSignKey('first-keypair@example.com', 'test1'); 209 $this->gpg->addSignKey('second-keypair@example.com', 'test2'); 210 $signedData = $this->gpg->sign($data); 211 212 $signatures = $this->gpg->verify($signedData); 213 $this->assertEquals(2, count($signatures)); 214 foreach ($signatures as $signature) { 215 $this->assertTrue($signature->isValid()); 216 } 217 } 218 219 /** 220 * @group string 221 */ 222 public function testSignDualClear() 223 { 224 $data = 'Hello, Alice! Goodbye, Bob!'; 225 $this->gpg->addSignKey('first-keypair@example.com', 'test1'); 226 $this->gpg->addSignKey('second-keypair@example.com', 'test2'); 227 $signedData = $this->gpg->sign($data, Crypt_GPG::SIGN_MODE_CLEAR); 228 229 $signatures = $this->gpg->verify($signedData); 230 $this->assertEquals(2, count($signatures)); 231 foreach ($signatures as $signature) { 232 $this->assertTrue($signature->isValid()); 233 } 234 } 235 236 /** 237 * @group string 238 */ 239 public function testSignDualDetached() 240 { 241 $data = 'Hello, Alice! Goodbye, Bob!'; 242 $this->gpg->addSignKey('first-keypair@example.com', 'test1'); 243 $this->gpg->addSignKey('second-keypair@example.com', 'test2'); 244 $signatureData = $this->gpg->sign($data, 245 Crypt_GPG::SIGN_MODE_DETACHED); 246 247 $signatures = $this->gpg->verify($data, $signatureData); 248 $this->assertEquals(2, count($signatures)); 249 foreach ($signatures as $signature) { 250 $this->assertTrue($signature->isValid()); 251 } 252 } 253 254 /** 255 * @group string 256 */ 257 public function testSignEmpty() 258 { 259 $data = ''; 260 261 $this->gpg->addSignKey('first-keypair@example.com', 'test1'); 262 263 $signedData = $this->gpg->sign($data); 264 $signatures = $this->gpg->verify($signedData); 265 266 $this->assertEquals(1, count($signatures)); 267 foreach ($signatures as $signature) { 268 $this->assertTrue($signature->isValid()); 269 } 270 } 271 272 /** 273 * @group string 274 */ 275 public function testSignDetachedTextmode() 276 { 277 // data with Unix line endings 278 $data = "It was the best of times,\n" 279 . "it was the worst of times,\n" 280 . "it was the age of wisdom,\n" 281 . "it was the age of foolishness,\n" 282 . "it was the epoch of belief,\n" 283 . "it was the epoch of incredulity,\n" 284 . "it was the season of Light,\n" 285 . "it was the season of Darkness,\n" 286 . "it was the spring of hope,\n" 287 . "it was the winter of despair,"; 288 289 $this->gpg->addSignKey('first-keypair@example.com', 'test1'); 290 $signatureData = $this->gpg->sign( 291 $data, 292 Crypt_GPG::SIGN_MODE_DETACHED, 293 true, 294 true 295 ); 296 297 // convert data to Windows line endings 298 $data = str_replace("\n", "\r\n", $data); 299 300 // verify data 301 $signatures = $this->gpg->verify($data, $signatureData); 302 $this->assertEquals(1, count($signatures)); 303 foreach ($signatures as $signature) { 304 $this->assertTrue( 305 $signature->isValid(), 306 'Failed asserting textmode signature is valid.' 307 ); 308 } 309 } 310 311 /** 312 * @group file 313 */ 314 public function testSignFileNoPassphrase() 315 { 316 $inputFilename = $this->getDataFilename('testFileMedium.plain'); 317 $outputFilename = 318 $this->getTempFilename('testSignFileNoPassphrase.asc'); 319 320 $this->gpg->addSignKey('no-passphrase@example.com'); 321 $this->gpg->signFile($inputFilename, $outputFilename); 322 323 $signatures = $this->gpg->verifyFile($outputFilename); 324 $this->assertEquals(1, count($signatures)); 325 foreach ($signatures as $signature) { 326 $this->assertTrue($signature->isValid()); 327 } 328 } 329 330 /** 331 * @group file 332 */ 333 public function testSignFileNormal() 334 { 335 $inputFilename = $this->getDataFilename('testFileMedium.plain'); 336 $outputFilename = $this->getTempFilename('testSignFileNormal.asc'); 337 338 $this->gpg->addSignKey('first-keypair@example.com', 'test1'); 339 $this->gpg->signFile($inputFilename, $outputFilename); 340 341 $signatures = $this->gpg->verifyFile($outputFilename); 342 $this->assertEquals(1, count($signatures)); 343 foreach ($signatures as $signature) { 344 $this->assertTrue($signature->isValid()); 345 } 346 } 347 348 /** 349 * @group file 350 */ 351 public function testSignFileClear() 352 { 353 $inputFilename = $this->getDataFilename('testFileMedium.plain'); 354 $outputFilename = $this->getTempFilename('testSignFileClear.asc'); 355 356 $this->gpg->addSignKey('first-keypair@example.com', 'test1'); 357 $this->gpg->signFile($inputFilename, $outputFilename, 358 Crypt_GPG::SIGN_MODE_CLEAR); 359 360 $signatures = $this->gpg->verifyFile($outputFilename); 361 $this->assertEquals(1, count($signatures)); 362 foreach ($signatures as $signature) { 363 $this->assertTrue($signature->isValid()); 364 } 365 } 366 367 /** 368 * @group file 369 */ 370 public function testSignFileDetached() 371 { 372 $inputFilename = $this->getDataFilename('testFileMedium.plain'); 373 $outputFilename = $this->getTempFilename('testSignFileDetached.asc'); 374 375 $this->gpg->addSignKey('first-keypair@example.com', 'test1'); 376 $this->gpg->signFile($inputFilename, $outputFilename, 377 Crypt_GPG::SIGN_MODE_DETACHED); 378 379 $signatureData = file_get_contents($outputFilename); 380 381 $signatures = $this->gpg->verifyFile($inputFilename, $signatureData); 382 $this->assertEquals(1, count($signatures)); 383 foreach ($signatures as $signature) { 384 $this->assertTrue($signature->isValid()); 385 } 386 } 387 388 /** 389 * @group file 390 */ 391 public function testSignFileDetachedToString() 392 { 393 $filename = $this->getDataFilename('testFileMedium.plain'); 394 395 $this->gpg->addSignKey('first-keypair@example.com', 'test1'); 396 $signatureData = $this->gpg->signFile($filename, null, 397 Crypt_GPG::SIGN_MODE_DETACHED); 398 399 $signatures = $this->gpg->verifyFile($filename, $signatureData); 400 $this->assertEquals(1, count($signatures)); 401 foreach ($signatures as $signature) { 402 $this->assertTrue($signature->isValid()); 403 } 404 } 405 406 /** 407 * @group file 408 */ 409 public function testSignFileDualOnePassphrase() 410 { 411 $inputFilename = $this->getDataFilename('testFileMedium.plain'); 412 $outputFilename = 413 $this->getTempFilename('testSignFileDualOnePassphrase.asc'); 414 415 $this->gpg->addSignKey('no-passphrase@example.com'); 416 $this->gpg->addSignKey('first-keypair@example.com', 'test1'); 417 $this->gpg->signFile($inputFilename, $outputFilename); 418 419 $signatures = $this->gpg->verifyFile($outputFilename); 420 $this->assertEquals(2, count($signatures)); 421 foreach ($signatures as $signature) { 422 $this->assertTrue($signature->isValid()); 423 } 424 } 425 426 /** 427 * @group file 428 */ 429 public function testSignFileDualNormal() 430 { 431 $inputFilename = $this->getDataFilename('testFileMedium.plain'); 432 $outputFilename = $this->getTempFilename('testSignFileDualNormal.asc'); 433 434 $this->gpg->addSignKey('first-keypair@example.com', 'test1'); 435 $this->gpg->addSignKey('second-keypair@example.com', 'test2'); 436 $this->gpg->signFile($inputFilename, $outputFilename); 437 438 $signatures = $this->gpg->verifyFile($outputFilename); 439 $this->assertEquals(2, count($signatures)); 440 foreach ($signatures as $signature) { 441 $this->assertTrue($signature->isValid()); 442 } 443 } 444 445 /** 446 * @group file 447 */ 448 public function testSignFileDualClear() 449 { 450 $inputFilename = $this->getDataFilename('testFileMedium.plain'); 451 $outputFilename = $this->getTempFilename('testSignFileDualClear.asc'); 452 453 $this->gpg->addSignKey('first-keypair@example.com', 'test1'); 454 $this->gpg->addSignKey('second-keypair@example.com', 'test2'); 455 $this->gpg->signFile($inputFilename, $outputFilename, 456 Crypt_GPG::SIGN_MODE_CLEAR); 457 458 $signatures = $this->gpg->verifyFile($outputFilename); 459 $this->assertEquals(2, count($signatures)); 460 foreach ($signatures as $signature) { 461 $this->assertTrue($signature->isValid()); 462 } 463 } 464 465 /** 466 * @group file 467 */ 468 public function testSignFileDualDetached() 469 { 470 $inputFilename = $this->getDataFilename('testFileMedium.plain'); 471 $outputFilename = 472 $this->getTempFilename('testSignFileDualDetached.asc'); 473 474 $this->gpg->addSignKey('first-keypair@example.com', 'test1'); 475 $this->gpg->addSignKey('second-keypair@example.com', 'test2'); 476 $this->gpg->signFile($inputFilename, $outputFilename, 477 Crypt_GPG::SIGN_MODE_DETACHED); 478 479 $signatureData = file_get_contents($outputFilename); 480 481 $signatures = $this->gpg->verifyFile($inputFilename, $signatureData); 482 $this->assertEquals(2, count($signatures)); 483 foreach ($signatures as $signature) { 484 $this->assertTrue($signature->isValid()); 485 } 486 } 487 488 /** 489 * @group file 490 */ 491 public function testSignFileFileException_input() 492 { 493 $this->expectException('Crypt_GPG_FileException'); 494 495 // input file does not exist 496 $inputFilename = 497 $this->getDataFilename('testSignFileFileFileException_input.plain'); 498 499 $this->gpg->addSignKey('first-keypair@example.com', 'test1'); 500 $this->gpg->signFile($inputFilename); 501 } 502 503 /** 504 * @group file 505 */ 506 public function testSignFileFileException_output() 507 { 508 $this->expectException('Crypt_GPG_FileException'); 509 510 // input file is encrypted with first-keypair@example.com 511 // output file does not exist 512 $inputFilename = $this->getDataFilename('testFileMedium.plain'); 513 $outputFilename = './non-existent' . 514 '/testSignFileFileException_output.plain'; 515 516 $this->gpg->addSignKey('first-keypair@example.com', 'test1'); 517 $this->gpg->signFile($inputFilename, $outputFilename); 518 } 519 520 /** 521 * @group file 522 */ 523 public function testSignFileEmpty() 524 { 525 $filename = $this->getDataFilename('testFileEmpty.plain'); 526 527 $this->gpg->addSignKey('first-keypair@example.com', 'test1'); 528 529 $signedData = $this->gpg->signFile($filename); 530 $signatures = $this->gpg->verify($signedData); 531 532 $this->assertEquals(1, count($signatures)); 533 foreach ($signatures as $signature) { 534 $this->assertTrue($signature->isValid()); 535 } 536 } 537 538 public function testGetLastSignatureInfo() 539 { 540 $this->gpg->addSignKey('first-keypair@example.com', 'test1'); 541 $signedData = $this->gpg->sign('test', Crypt_GPG::SIGN_MODE_DETACHED); 542 543 $sigInfo = $this->gpg->getLastSignatureInfo(); 544 $this->assertInstanceOf('Crypt_GPG_SignatureCreationInfo', $sigInfo); 545 $this->assertTrue($sigInfo->isValid()); 546 $this->assertEquals(date('Y-m-d'), date('Y-m-d', $sigInfo->getTimestamp())); 547 $this->assertEquals(Crypt_GPG::SIGN_MODE_DETACHED, $sigInfo->getMode()); 548 $this->assertEquals( 549 '8D2299D9C5C211128B32BBB0C097D9EC94C06363', 550 $sigInfo->getKeyFingerprint() 551 ); 552 $this->assertNotNull($sigInfo->getHashAlgorithmName()); 553 } 554} 555