Compare commits
192 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
67aba78699 | ||
|
c0e6aeb163 | ||
|
5e6a097677 | ||
|
f8e0e997fc | ||
|
fb671e183d | ||
|
f43fbdc053 | ||
|
cd33ba1af1 | ||
|
34ffc765ec | ||
|
752d80f14a | ||
|
575baaf3f2 | ||
|
aeb919abc3 | ||
|
cba1ecce8a | ||
|
f2e1710da5 | ||
|
44e1bb2902 | ||
|
43497a15c0 | ||
|
5a6b605710 | ||
|
d756110821 | ||
|
724d5b16f3 | ||
|
26560f7bca | ||
|
498e60602b | ||
|
413741fa84 | ||
|
a9fc3f9322 | ||
|
facaaa4dbb | ||
|
ba3c3fd42d | ||
|
ebce9c014c | ||
|
f42afa0ca3 | ||
|
e8a56241a5 | ||
|
69d935435c | ||
|
541328576a | ||
|
a8e7690a69 | ||
|
c9ae8251b6 | ||
|
95facfb57f | ||
|
6006111bbc | ||
|
2561004fcd | ||
|
cea5b176fc | ||
|
a61fb279c3 | ||
|
7538c62edd | ||
|
741fec24a6 | ||
|
4531815ef2 | ||
|
46ec5079e8 | ||
|
02fbcbf7e6 | ||
|
6d9ed34224 | ||
|
de41f143e6 | ||
|
859efcbee3 | ||
|
15baf1db70 | ||
|
a87e6ac0c9 | ||
|
08ae2c57d1 | ||
|
cefaef242d | ||
|
6340379ffe | ||
|
bcc9c920a0 | ||
|
57ab2811c4 | ||
|
b260774147 | ||
|
a1fe3a6e58 | ||
|
ff4bd67e6b | ||
|
d37e91efda | ||
|
f4fabd04e7 | ||
|
cc52cb9dab | ||
|
4281c8fa97 | ||
|
01a1f00edb | ||
|
4fe3c5db72 | ||
|
9bffda3ef2 | ||
|
5291a06b97 | ||
|
055b5c5459 | ||
|
cb4fe9c632 | ||
|
4756c82118 | ||
|
9d6d736a5d | ||
|
2fb1666bb5 | ||
|
3835a48db8 | ||
|
ec8df93d19 | ||
|
6287ba89d0 | ||
|
ae21dd0f56 | ||
|
68514c11c2 | ||
|
d6568d4925 | ||
|
0262b038f1 | ||
|
775aa96118 | ||
|
d2913ccb8a | ||
|
e1181bd25e | ||
|
6075d057d0 | ||
|
82ed7d85bd | ||
|
7ae4d539f2 | ||
|
e78424131e | ||
|
e27f9e236f | ||
|
26860d3b98 | ||
|
c341d7f09e | ||
|
58d1b5cee0 | ||
|
05b757ab6c | ||
|
3afd401688 | ||
|
04b89decd1 | ||
|
1ecb990a02 | ||
|
778c83dbc3 | ||
|
aab2a5e12b | ||
|
216ee4156d | ||
|
2a331f7403 | ||
|
cb9f918022 | ||
|
7d776fd605 | ||
|
a56799955f | ||
|
ae062433b7 | ||
|
cd15aec6f9 | ||
|
641c07835b | ||
|
8c60f4e37b | ||
|
47a7f6e25c | ||
|
567b18c1b2 | ||
|
bf8201f432 | ||
|
06cf887846 | ||
|
68b2047508 | ||
|
dffa0ecaa2 | ||
|
74afee6266 | ||
|
7a1510f2e1 | ||
|
4263d03188 | ||
|
f9ea5ee0e5 | ||
|
8d19f70bb1 | ||
|
22585344c0 | ||
|
7d44211fc8 | ||
|
995a9d7840 | ||
|
f4af8a010b | ||
|
825452e123 | ||
|
c5600d2812 | ||
|
057c79440a | ||
|
5cba4f2697 | ||
|
ae7454c504 | ||
|
379c79d3ad | ||
|
b84a2a8752 | ||
|
fb9fddde16 | ||
|
4dbfbcb88d | ||
|
6bf8e8cb6b | ||
|
c2c934fa6a | ||
|
69ade89111 | ||
|
0f5742ba0d | ||
|
dab71c1854 | ||
|
82fb19cc31 | ||
|
1322f45ded | ||
|
951ff2cacc | ||
|
af3643c919 | ||
|
6b8445737e | ||
|
1f04075ef5 | ||
|
6cbd7f6634 | ||
|
66ab5ccf46 | ||
|
377a86aee9 | ||
|
5756085e85 | ||
|
9cdc2500b1 | ||
|
99debc4540 | ||
|
39e1d5c231 | ||
|
417c206bee | ||
|
e931ebed25 | ||
|
b42ec74ab4 | ||
|
1e81ed0bb1 | ||
|
6dc7c1eb2a | ||
|
191aeaa4d9 | ||
|
0b2942e382 | ||
|
86c476807c | ||
|
ec4b5c5f72 | ||
|
1e2db5b249 | ||
|
1c7f759798 | ||
|
e3bc3757d1 | ||
|
fe7121efe3 | ||
|
eb7aaf490e | ||
|
5829037d0b | ||
|
36fba1596d | ||
|
6ac274b8ec | ||
|
6e8dc4799f | ||
|
8265522323 | ||
|
3b6b29127f | ||
|
bd9c9db00b | ||
|
8019d3c564 | ||
|
b41bc2c533 | ||
|
1a1b8980e6 | ||
|
975fc2ff7e | ||
|
0a85e214a6 | ||
|
355ea44301 | ||
|
1333a1a035 | ||
|
acdf5d1ac0 | ||
|
408c912e12 | ||
|
7fc49b3530 | ||
|
d4babbb948 | ||
|
5f6a93daca | ||
|
97ad2cf72d | ||
|
3c84dce8f9 | ||
|
a78b6dc8c1 | ||
|
b7122bbb5f | ||
|
b0f4e73111 | ||
|
c7a5ec04fd | ||
|
93569f967c | ||
|
079eb984a7 | ||
|
8feb922a45 | ||
|
417ac85088 | ||
|
2948aa3b77 | ||
|
4a287f7321 | ||
|
f67dab6053 | ||
|
f09335de1d | ||
|
e3f332c6ca | ||
|
dc7bc432ea | ||
|
73f93e70fd |
51
.travis.yml
Normal file
51
.travis.yml
Normal file
@@ -0,0 +1,51 @@
|
||||
---
|
||||
language: php
|
||||
php:
|
||||
- 7.0
|
||||
- 7.1
|
||||
- 7.2
|
||||
- 5.6
|
||||
|
||||
dist: trusty
|
||||
|
||||
env:
|
||||
- PHPSECLIB='^2.0 !=2.0.8'
|
||||
- PHPSECLIB="2.0.0"
|
||||
- PHPSECLIB="2.0.1"
|
||||
- PHPSECLIB="2.0.2"
|
||||
- PHPSECLIB="2.0.3"
|
||||
- PHPSECLIB="2.0.4"
|
||||
- PHPSECLIB="2.0.5"
|
||||
- PHPSECLIB="2.0.6"
|
||||
- PHPSECLIB="2.0.7"
|
||||
- PHPSECLIB="2.0.9"
|
||||
- PHPSECLIB="2.0.10"
|
||||
- PHPSECLIB="2.0.11"
|
||||
|
||||
matrix:
|
||||
exclude:
|
||||
- php: 7.1
|
||||
- env: PHPSECLIB="2.0.0"
|
||||
- php: 7.2
|
||||
- env: PHPSECLIB="2.0.0"
|
||||
- php: 7.1
|
||||
- env: PHPSECLIB="2.0.1"
|
||||
- php: 7.2
|
||||
- env: PHPSECLIB="2.0.1"
|
||||
- php: 7.1
|
||||
- env: PHPSECLIB="2.0.2"
|
||||
- php: 7.2
|
||||
- env: PHPSECLIB="2.0.2"
|
||||
- php: 7.1
|
||||
- env: PHPSECLIB="2.0.3"
|
||||
- php: 7.2
|
||||
- env: PHPSECLIB="2.0.3"
|
||||
- php: 7.2
|
||||
- env: PHPSECLIB="2.0.4"
|
||||
- php: 7.2
|
||||
- env: PHPSECLIB="2.0.5"
|
||||
- php: 7.2
|
||||
- env: PHPSECLIB="2.0.6"
|
||||
fast_finish: true
|
||||
|
||||
before_script: 'sed -i "s/\"phpseclib\/phpseclib\": \"[^\"]*/\"phpseclib\/phpseclib\": \"$PHPSECLIB/" composer.json && composer install --prefer-source'
|
1
AUTHORS
1
AUTHORS
@@ -1 +1,2 @@
|
||||
* Arto Bendiken <arto.bendiken@gmail.com>
|
||||
* Stephen Paul Weber <singpolyma@singpolyma.net>
|
||||
|
41
README.md
41
README.md
@@ -1,11 +1,14 @@
|
||||
[](https://travis-ci.org/singpolyma/openpgp-php)
|
||||
|
||||
OpenPGP.php: OpenPGP for PHP
|
||||
============================
|
||||
|
||||
This is a pure-PHP implementation of the OpenPGP Message Format (RFC 4880).
|
||||
|
||||
* <http://github.com/bendiken/openpgp-php>
|
||||
* <https://github.com/singpolyma/openpgp-php>
|
||||
|
||||
### About OpenPGP
|
||||
About OpenPGP
|
||||
-------------
|
||||
|
||||
OpenPGP is the most widely-used e-mail encryption standard in the world. It
|
||||
is defined by the OpenPGP Working Group of the Internet Engineering Task
|
||||
@@ -13,8 +16,8 @@ Force (IETF) Proposed Standard RFC 4880. The OpenPGP standard was originally
|
||||
derived from PGP (Pretty Good Privacy), first created by Phil Zimmermann in
|
||||
1991.
|
||||
|
||||
* <http://tools.ietf.org/html/rfc4880>
|
||||
* <http://www.openpgp.org/>
|
||||
* <https://tools.ietf.org/html/rfc4880>
|
||||
* <https://www.openpgp.org/>
|
||||
|
||||
Features
|
||||
--------
|
||||
@@ -22,26 +25,48 @@ Features
|
||||
* Encodes and decodes ASCII-armored OpenPGP messages.
|
||||
* Parses OpenPGP messages into their constituent packets.
|
||||
* Supports both old-format (PGP 2.6.x) and new-format (RFC 4880) packets.
|
||||
* Helper class for verifying, signing, encrypting, and decrypting messages <http://phpseclib.sourceforge.net>
|
||||
* Helper class for encrypting and decrypting messages and keys using <http://phpseclib.sourceforge.net>
|
||||
* openssl or mcrypt required for CAST5 encryption and decryption
|
||||
|
||||
Bugs, Feature Requests, Patches
|
||||
-------------------------------
|
||||
|
||||
This project is primarily maintained by a single volunteer with many other
|
||||
things vying for their attention, please be patient.
|
||||
|
||||
Bugs, feature request, pull requests, patches, and general discussion may
|
||||
be submitted publicly via email to: dev@singpolyma.net
|
||||
|
||||
Github users may alternately submit on the web there.
|
||||
|
||||
Users
|
||||
-----
|
||||
|
||||
OpenPGP.php is currently being used in the following projects:
|
||||
|
||||
* <https://wordpress.org/plugins/wp-pgp-encrypted-emails/>
|
||||
|
||||
Download
|
||||
--------
|
||||
|
||||
To get a local working copy of the development repository, do:
|
||||
|
||||
% git clone git://github.com/bendiken/openpgp-php.git
|
||||
git clone https://github.com/singpolyma/openpgp-php.git
|
||||
|
||||
Alternatively, you can download the latest development version as a tarball
|
||||
as follows:
|
||||
|
||||
% wget http://github.com/bendiken/openpgp-php/tarball/master
|
||||
wget https://github.com/singpolyma/openpgp-php/tarball/master
|
||||
|
||||
Authors
|
||||
-------
|
||||
|
||||
* [Arto Bendiken](mailto:arto.bendiken@gmail.com) - <http://ar.to/>
|
||||
* [Arto Bendiken](mailto:arto.bendiken@gmail.com) (Original author) - <http://ar.to/>
|
||||
* [Stephen Paul Weber](mailto:singpolyma@singpolyma.net) (Maintainer) - <https://singpolyma.net/>
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
OpenPGP.php is free and unencumbered public domain software. For more
|
||||
information, see <http://unlicense.org/> or the accompanying UNLICENSE file.
|
||||
information, see <https://unlicense.org/> or the accompanying UNLICENSE file.
|
||||
|
28
composer.json
Normal file
28
composer.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "singpolyma/openpgp-php",
|
||||
"description": "Pure-PHP implementation of the OpenPGP Message Format (RFC 4880)",
|
||||
"license": "Unlicense",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Arto Bendiken",
|
||||
"email": "arto.bendiken@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Stephen Paul Weber",
|
||||
"email": "singpolyma@singpolyma.net"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^5.6 || ^7.0",
|
||||
"phpseclib/phpseclib": "^2.0 !=2.0.8"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^5.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-mcrypt": "required if you use encryption cast5"
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": ["lib/"]
|
||||
}
|
||||
}
|
22
examples/README.md
Normal file
22
examples/README.md
Normal file
@@ -0,0 +1,22 @@
|
||||
OpenPGP.php Examples
|
||||
====================
|
||||
|
||||
The scripts in this folder show how to use this library to perform various tasks
|
||||
such as [generating a new key](keygen.php), [signing a message](sign.php), and
|
||||
[verifying a message](verify.php) that has been signed.
|
||||
|
||||
To use these examples, make sure [`phpseclib`](http://phpseclib.sourceforge.net/) is available. You can install it
|
||||
using [Composer](https://getcomposer.org/):
|
||||
|
||||
```sh
|
||||
git clone https://github.com/singpolyma/openpgp-php.git # Clone the repository.
|
||||
cd openpgp-php
|
||||
composer install # Use Composer to install the requirements.
|
||||
```
|
||||
|
||||
Once Composer has installed the requirements, run the examples using PHP:
|
||||
|
||||
```sh
|
||||
# Generate a new OpenPGP key; see the `keygen.php` file for parameters.
|
||||
php ./examples/keygen.php > mykey.gpg
|
||||
```
|
30
examples/clearsign.php
Normal file
30
examples/clearsign.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
@include_once dirname(__FILE__).'/../vendor/autoload.php';
|
||||
require_once dirname(__FILE__).'/../lib/openpgp.php';
|
||||
require_once dirname(__FILE__).'/../lib/openpgp_crypt_rsa.php';
|
||||
|
||||
/* Parse secret key from STDIN, the key must not be password protected */
|
||||
$wkey = OpenPGP_Message::parse(file_get_contents('php://stdin'));
|
||||
$wkey = $wkey[0];
|
||||
|
||||
$string = "This\nis\na\ntest.";
|
||||
|
||||
/* Create a new literal data packet */
|
||||
$data = new OpenPGP_LiteralDataPacket($string, array('format' => 'u', 'filename' => 'stuff.txt'));
|
||||
$data->normalize(true); // Clearsign-style normalization of the LiteralDataPacket
|
||||
|
||||
/* Create a signer from the key */
|
||||
$sign = new OpenPGP_Crypt_RSA($wkey);
|
||||
|
||||
/* The message is the signed data packet */
|
||||
$m = $sign->sign($data);
|
||||
|
||||
/* Generate clearsigned data */
|
||||
$packets = $m->signatures()[0];
|
||||
echo "-----BEGIN PGP SIGNED MESSAGE-----\nHash: SHA256\n\n";
|
||||
// Output normalised data. You could convert line endings here
|
||||
// without breaking the signature, but do not add any
|
||||
// trailing whitespace to lines.
|
||||
echo preg_replace("/^-/", "- -", $packets[0]->data)."\n";
|
||||
echo OpenPGP::enarmor($packets[1][0]->to_bytes(), "PGP SIGNATURE");
|
28
examples/deASCIIdeCrypt.php
Normal file
28
examples/deASCIIdeCrypt.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
// USAGE: php examples/deASCIIdeCrypt.php secretkey.asc password message.asc
|
||||
// This will fail if the algo on key or message is not 3DES or AES
|
||||
|
||||
@include_once dirname(__FILE__).'/../vendor/autoload.php';
|
||||
require_once dirname(__FILE__).'/../lib/openpgp.php';
|
||||
require_once dirname(__FILE__).'/../lib/openpgp_crypt_rsa.php';
|
||||
require_once dirname(__FILE__).'/../lib/openpgp_crypt_symmetric.php';
|
||||
|
||||
$keyASCII = file_get_contents($argv[1]);
|
||||
$msgASCII = file_get_contents($argv[3]);
|
||||
|
||||
$keyEncrypted = OpenPGP_Message::parse(OpenPGP::unarmor($keyASCII, 'PGP PRIVATE KEY BLOCK'));
|
||||
|
||||
// Try each secret key packet
|
||||
foreach($keyEncrypted as $p) {
|
||||
if(!($p instanceof OpenPGP_SecretKeyPacket)) continue;
|
||||
|
||||
$key = OpenPGP_Crypt_Symmetric::decryptSecretKey($argv[2], $p);
|
||||
|
||||
$msg = OpenPGP_Message::parse(OpenPGP::unarmor($msgASCII, 'PGP MESSAGE'));
|
||||
|
||||
$decryptor = new OpenPGP_Crypt_RSA($key);
|
||||
$decrypted = $decryptor->decrypt($msg);
|
||||
|
||||
var_dump($decrypted);
|
||||
}
|
16
examples/encryptDecrypt.php
Normal file
16
examples/encryptDecrypt.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
@include_once dirname(__FILE__).'/../vendor/autoload.php';
|
||||
require_once dirname(__FILE__).'/../lib/openpgp.php';
|
||||
require_once dirname(__FILE__).'/../lib/openpgp_crypt_rsa.php';
|
||||
require_once dirname(__FILE__).'/../lib/openpgp_crypt_symmetric.php';
|
||||
|
||||
$key = OpenPGP_Message::parse(file_get_contents(dirname(__FILE__) . '/../tests/data/helloKey.gpg'));
|
||||
$data = new OpenPGP_LiteralDataPacket('This is text.', array('format' => 'u', 'filename' => 'stuff.txt'));
|
||||
$encrypted = OpenPGP_Crypt_Symmetric::encrypt($key, new OpenPGP_Message(array($data)));
|
||||
|
||||
// Now decrypt it with the same key
|
||||
$decryptor = new OpenPGP_Crypt_RSA($key);
|
||||
$decrypted = $decryptor->decrypt($encrypted);
|
||||
|
||||
var_dump($decrypted);
|
32
examples/keygen.php
Normal file
32
examples/keygen.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
@include_once dirname(__FILE__).'/../vendor/autoload.php';
|
||||
require_once dirname(__FILE__).'/../lib/openpgp.php';
|
||||
require_once dirname(__FILE__).'/../lib/openpgp_crypt_rsa.php';
|
||||
|
||||
$rsa = new \phpseclib\Crypt\RSA();
|
||||
$k = $rsa->createKey(512);
|
||||
$rsa->loadKey($k['privatekey']);
|
||||
|
||||
$nkey = new OpenPGP_SecretKeyPacket(array(
|
||||
'n' => $rsa->modulus->toBytes(),
|
||||
'e' => $rsa->publicExponent->toBytes(),
|
||||
'd' => $rsa->exponent->toBytes(),
|
||||
'p' => $rsa->primes[2]->toBytes(),
|
||||
'q' => $rsa->primes[1]->toBytes(),
|
||||
'u' => $rsa->coefficients[2]->toBytes()
|
||||
));
|
||||
|
||||
$uid = new OpenPGP_UserIDPacket('Test <test@example.com>');
|
||||
|
||||
$wkey = new OpenPGP_Crypt_RSA($nkey);
|
||||
$m = $wkey->sign_key_userid(array($nkey, $uid));
|
||||
|
||||
// Serialize private key
|
||||
print $m->to_bytes();
|
||||
|
||||
// Serialize public key message
|
||||
$pubm = clone($m);
|
||||
$pubm[0] = new OpenPGP_PublicKeyPacket($pubm[0]);
|
||||
|
||||
$public_bytes = $pubm->to_bytes();
|
21
examples/sign.php
Normal file
21
examples/sign.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
@include_once dirname(__FILE__).'/../vendor/autoload.php';
|
||||
require_once dirname(__FILE__).'/../lib/openpgp.php';
|
||||
require_once dirname(__FILE__).'/../lib/openpgp_crypt_rsa.php';
|
||||
|
||||
/* Parse secret key from STDIN, the key must not be password protected */
|
||||
$wkey = OpenPGP_Message::parse(file_get_contents('php://stdin'));
|
||||
$wkey = $wkey[0];
|
||||
|
||||
/* Create a new literal data packet */
|
||||
$data = new OpenPGP_LiteralDataPacket('This is text.', array('format' => 'u', 'filename' => 'stuff.txt'));
|
||||
|
||||
/* Create a signer from the key */
|
||||
$sign = new OpenPGP_Crypt_RSA($wkey);
|
||||
|
||||
/* The message is the signed data packet */
|
||||
$m = $sign->sign($data);
|
||||
|
||||
/* Output the raw message bytes to STDOUT */
|
||||
echo $m->to_bytes();
|
17
examples/verify.php
Normal file
17
examples/verify.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
@include_once dirname(__FILE__).'/../vendor/autoload.php';
|
||||
require_once dirname(__FILE__).'/../lib/openpgp.php';
|
||||
require_once dirname(__FILE__).'/../lib/openpgp_crypt_rsa.php';
|
||||
|
||||
/* Parse public key from STDIN */
|
||||
$wkey = OpenPGP_Message::parse(file_get_contents('php://stdin'));
|
||||
|
||||
/* Parse signed message from file named "t" */
|
||||
$m = OpenPGP_Message::parse(file_get_contents('t'));
|
||||
|
||||
/* Create a verifier for the key */
|
||||
$verify = new OpenPGP_Crypt_RSA($wkey);
|
||||
|
||||
/* Dump verification information to STDOUT */
|
||||
var_dump($verify->verify($m));
|
1411
lib/openpgp.php
1411
lib/openpgp.php
File diff suppressed because it is too large
Load Diff
276
lib/openpgp_crypt_rsa.php
Normal file
276
lib/openpgp_crypt_rsa.php
Normal file
@@ -0,0 +1,276 @@
|
||||
<?php
|
||||
// This is free and unencumbered software released into the public domain.
|
||||
/**
|
||||
* OpenPGP_Crypt_RSA.php is a wrapper for using the classes from OpenPGP.php with Crypt_RSA
|
||||
*
|
||||
* @package OpenPGP
|
||||
*/
|
||||
|
||||
// From http://phpseclib.sourceforge.net/
|
||||
use phpseclib\Crypt\RSA as Crypt_RSA;
|
||||
use phpseclib\Math\BigInteger as Math_BigInteger;
|
||||
|
||||
define('CRYPT_RSA_ENCRYPTION_PKCS1', Crypt_RSA::ENCRYPTION_PKCS1);
|
||||
define('CRYPT_RSA_SIGNATURE_PKCS1', Crypt_RSA::SIGNATURE_PKCS1);
|
||||
|
||||
require_once dirname(__FILE__).'/openpgp.php';
|
||||
@include_once dirname(__FILE__).'/openpgp_crypt_symmetric.php'; /* For encrypt/decrypt */
|
||||
|
||||
class OpenPGP_Crypt_RSA {
|
||||
protected $key, $message;
|
||||
|
||||
// Construct a wrapper object from a key or a message packet
|
||||
function __construct($packet) {
|
||||
if(!is_object($packet)) $packet = OpenPGP_Message::parse($packet);
|
||||
if($packet instanceof OpenPGP_PublicKeyPacket || $packet[0] instanceof OpenPGP_PublicKeyPacket) { // If it's a key (other keys are subclasses of this one)
|
||||
$this->key = $packet;
|
||||
} else {
|
||||
$this->message = $packet;
|
||||
}
|
||||
}
|
||||
|
||||
function key($keyid=NULL) {
|
||||
if(!$this->key) return NULL; // No key
|
||||
if($this->key instanceof OpenPGP_Message) {
|
||||
foreach($this->key as $p) {
|
||||
if($p instanceof OpenPGP_PublicKeyPacket) {
|
||||
if(!$keyid || strtoupper(substr($p->fingerprint, strlen($keyid)*-1)) == strtoupper($keyid)) return $p;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
// Get Crypt_RSA for the public key
|
||||
function public_key($keyid=NULL) {
|
||||
return self::convert_public_key($this->key($keyid));
|
||||
}
|
||||
|
||||
// Get Crypt_RSA for the private key
|
||||
function private_key($keyid=NULL) {
|
||||
return self::convert_private_key($this->key($keyid));
|
||||
}
|
||||
|
||||
// Pass a message to verify with this key, or a key (OpenPGP or Crypt_RSA) to check this message with
|
||||
// Second optional parameter to specify which signature to verify (if there is more than one)
|
||||
function verify($packet) {
|
||||
$self = $this; // For old PHP
|
||||
if(!is_object($packet)) $packet = OpenPGP_Message::parse($packet);
|
||||
if(!$this->message) {
|
||||
$m = $packet;
|
||||
$verifier = function($m, $s) use($self) {
|
||||
$key = $self->public_key($s->issuer());
|
||||
if(!$key) return false;
|
||||
$key->setHash(strtolower($s->hash_algorithm_name()));
|
||||
return $key->verify($m, reset($s->data));
|
||||
};
|
||||
} else {
|
||||
if(!($packet instanceof Crypt_RSA)) {
|
||||
$packet = new self($packet);
|
||||
}
|
||||
|
||||
$m = $this->message;
|
||||
$verifier = function($m, $s) use($self, $packet) {
|
||||
if(!($packet instanceof Crypt_RSA)) {
|
||||
$key = $packet->public_key($s->issuer());
|
||||
}
|
||||
if(!$key) return false;
|
||||
$key->setHash(strtolower($s->hash_algorithm_name()));
|
||||
return $key->verify($m, reset($s->data));
|
||||
};
|
||||
}
|
||||
|
||||
return $m->verified_signatures(array('RSA' => array(
|
||||
'MD5' => $verifier,
|
||||
'SHA1' => $verifier,
|
||||
'SHA224' => $verifier,
|
||||
'SHA256' => $verifier,
|
||||
'SHA384' => $verifier,
|
||||
'SHA512' => $verifier
|
||||
)));
|
||||
}
|
||||
|
||||
// Pass a message to sign with this key, or a secret key to sign this message with
|
||||
// Second parameter is hash algorithm to use (default SHA256)
|
||||
// Third parameter is the 16-digit key ID to use... defaults to the key id in the key packet
|
||||
function sign($packet, $hash='SHA256', $keyid=NULL) {
|
||||
if(!is_object($packet)) {
|
||||
if($this->key) {
|
||||
$packet = new OpenPGP_LiteralDataPacket($packet);
|
||||
} else {
|
||||
$packet = OpenPGP_Message::parse($packet);
|
||||
}
|
||||
}
|
||||
|
||||
if($packet instanceof OpenPGP_SecretKeyPacket || $packet instanceof Crypt_RSA
|
||||
|| ($packet instanceof ArrayAccess && $packet[0] instanceof OpenPGP_SecretKeyPacket)) {
|
||||
$key = $packet;
|
||||
$message = $this->message;
|
||||
} else {
|
||||
$key = $this->key;
|
||||
$message = $packet;
|
||||
}
|
||||
|
||||
if(!$key || !$message) return NULL; // Missing some data
|
||||
|
||||
if($message instanceof OpenPGP_Message) {
|
||||
$sign = $message->signatures();
|
||||
$message = $sign[0][0];
|
||||
}
|
||||
|
||||
if(!($key instanceof Crypt_RSA)) {
|
||||
$key = new self($key);
|
||||
if(!$keyid) $keyid = substr($key->key()->fingerprint, -16, 16);
|
||||
$key = $key->private_key($keyid);
|
||||
}
|
||||
$key->setHash(strtolower($hash));
|
||||
|
||||
$sig = new OpenPGP_SignaturePacket($message, 'RSA', strtoupper($hash));
|
||||
$sig->hashed_subpackets[] = new OpenPGP_SignaturePacket_IssuerPacket($keyid);
|
||||
$sig->sign_data(array('RSA' => array($hash => function($data) use($key) {return array($key->sign($data));})));
|
||||
|
||||
return new OpenPGP_Message(array($sig, $message));
|
||||
}
|
||||
|
||||
/** Pass a message with a key and userid packet to sign */
|
||||
// TODO: merge this with the normal sign function
|
||||
function sign_key_userid($packet, $hash='SHA256', $keyid=NULL) {
|
||||
if(is_array($packet)) {
|
||||
$packet = new OpenPGP_Message($packet);
|
||||
} else if(!is_object($packet)) {
|
||||
$packet = OpenPGP_Message::parse($packet);
|
||||
}
|
||||
|
||||
$key = $this->private_key($keyid);
|
||||
if(!$key || !$packet) return NULL; // Missing some data
|
||||
|
||||
if(!$keyid) $keyid = substr($this->key->fingerprint, -16);
|
||||
$key->setHash(strtolower($hash));
|
||||
|
||||
$sig = NULL;
|
||||
foreach($packet as $p) {
|
||||
if($p instanceof OpenPGP_SignaturePacket) $sig = $p;
|
||||
}
|
||||
if(!$sig) {
|
||||
$sig = new OpenPGP_SignaturePacket($packet, 'RSA', strtoupper($hash));
|
||||
$sig->signature_type = 0x13;
|
||||
$sig->hashed_subpackets[] = new OpenPGP_SignaturePacket_KeyFlagsPacket(array(0x01 | 0x02));
|
||||
$sig->hashed_subpackets[] = new OpenPGP_SignaturePacket_IssuerPacket($keyid);
|
||||
$packet[] = $sig;
|
||||
}
|
||||
|
||||
$sig->sign_data(array('RSA' => array($hash => function($data) use($key) {return array($key->sign($data));})));
|
||||
|
||||
return $packet;
|
||||
}
|
||||
|
||||
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->encrypted_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->encrypted_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 */
|
||||
}
|
||||
|
||||
static function try_decrypt_session($key, $edata) {
|
||||
$key->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
|
||||
$data = @$key->decrypt($edata);
|
||||
if(!$data) return NULL;
|
||||
$sk = substr($data, 1, strlen($data)-3);
|
||||
$chk = unpack('n', substr($data, -2));
|
||||
$chk = reset($chk);
|
||||
|
||||
$sk_chk = 0;
|
||||
for($i = 0; $i < strlen($sk); $i++) {
|
||||
$sk_chk = ($sk_chk + ord($sk{$i})) % 65536;
|
||||
}
|
||||
|
||||
if($sk_chk != $chk) return NULL;
|
||||
return array(ord($data{0}), $sk);
|
||||
}
|
||||
|
||||
static function crypt_rsa_key($mod, $exp, $hash='SHA256') {
|
||||
$rsa = new Crypt_RSA();
|
||||
$rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
|
||||
$rsa->setHash(strtolower($hash));
|
||||
$rsa->modulus = new Math_BigInteger($mod, 256);
|
||||
$rsa->k = strlen($rsa->modulus->toBytes());
|
||||
$rsa->exponent = new Math_BigInteger($exp, 256);
|
||||
$rsa->setPublicKey();
|
||||
return $rsa;
|
||||
}
|
||||
|
||||
static function convert_key($packet, $private=false) {
|
||||
if(!is_object($packet)) $packet = OpenPGP_Message::parse($packet);
|
||||
if($packet instanceof OpenPGP_Message) $packet = $packet[0];
|
||||
|
||||
$mod = $packet->key['n'];
|
||||
$exp = $packet->key['e'];
|
||||
if($private) $exp = $packet->key['d'];
|
||||
if(!$exp) return NULL; // Packet doesn't have needed data
|
||||
|
||||
$rsa = self::crypt_rsa_key($mod, $exp);
|
||||
|
||||
if($private) {
|
||||
/**
|
||||
* @see https://github.com/phpseclib/phpseclib/issues/1113
|
||||
* Primes and coefficients now use BigIntegers.
|
||||
**/
|
||||
//set the primes
|
||||
if($packet->key['p'] && $packet->key['q'])
|
||||
$rsa->primes = array(
|
||||
1 => new Math_BigInteger($packet->key['p'], 256),
|
||||
2 => new Math_BigInteger($packet->key['q'], 256)
|
||||
);
|
||||
// set the coefficients
|
||||
if($packet->key['u']) $rsa->coefficients = array(2 => new Math_BigInteger($packet->key['u'], 256));
|
||||
}
|
||||
|
||||
return $rsa;
|
||||
}
|
||||
|
||||
static function convert_public_key($packet) {
|
||||
return self::convert_key($packet, false);
|
||||
}
|
||||
|
||||
static function convert_private_key($packet) {
|
||||
return self::convert_key($packet, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
210
lib/openpgp_crypt_symmetric.php
Normal file
210
lib/openpgp_crypt_symmetric.php
Normal file
@@ -0,0 +1,210 @@
|
||||
<?php
|
||||
|
||||
use phpseclib\Crypt\AES as Crypt_AES;
|
||||
use phpseclib\Crypt\Blowfish as Crypt_Blowfish;
|
||||
use phpseclib\Crypt\TripleDES as Crypt_TripleDES;
|
||||
use phpseclib\Crypt\Twofish as Crypt_Twofish;
|
||||
use phpseclib\Crypt\Random;
|
||||
|
||||
require_once dirname(__FILE__).'/openpgp.php';
|
||||
@include_once dirname(__FILE__).'/openpgp_crypt_rsa.php';
|
||||
@include_once dirname(__FILE__).'/openpgp_mcrypt_wrapper.php';
|
||||
@include_once dirname(__FILE__).'/openpgp_openssl_wrapper.php';
|
||||
|
||||
class OpenPGP_Crypt_Symmetric {
|
||||
public static function encrypt($passphrases_and_keys, $message, $symmetric_algorithm=9) {
|
||||
list($cipher, $key_bytes, $key_block_bytes) = self::getCipher($symmetric_algorithm);
|
||||
if(!$cipher) throw new Exception("Unsupported cipher");
|
||||
$prefix = Random::string($key_block_bytes);
|
||||
$prefix .= substr($prefix, -2);
|
||||
|
||||
$key = Random::string($key_bytes);
|
||||
$cipher->setKey($key);
|
||||
|
||||
$to_encrypt = $prefix . $message->to_bytes();
|
||||
$mdc = new OpenPGP_ModificationDetectionCodePacket(hash('sha1', $to_encrypt . "\xD3\x14", true));
|
||||
$to_encrypt .= $mdc->to_bytes();
|
||||
$encrypted = array(new OpenPGP_IntegrityProtectedDataPacket($cipher->encrypt($to_encrypt)));
|
||||
|
||||
if(!is_array($passphrases_and_keys) && !($passphrases_and_keys instanceof IteratorAggregate)) {
|
||||
$passphrases_and_keys = (array)$passphrases_and_keys;
|
||||
}
|
||||
|
||||
foreach($passphrases_and_keys as $pass) {
|
||||
if($pass instanceof OpenPGP_PublicKeyPacket) {
|
||||
if(!in_array($pass->algorithm, array(1,2,3))) throw new Exception("Only RSA keys are supported.");
|
||||
$crypt_rsa = new OpenPGP_Crypt_RSA($pass);
|
||||
$rsa = $crypt_rsa->public_key();
|
||||
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
|
||||
$esk = $rsa->encrypt(chr($symmetric_algorithm) . $key . pack('n', self::checksum($key)));
|
||||
$esk = pack('n', OpenPGP::bitlength($esk)) . $esk;
|
||||
array_unshift($encrypted, new OpenPGP_AsymmetricSessionKeyPacket($pass->algorithm, $pass->fingerprint(), $esk));
|
||||
} else if(is_string($pass)) {
|
||||
$s2k = new OpenPGP_S2K(Random::string(8));
|
||||
$cipher->setKey($s2k->make_key($pass, $key_bytes));
|
||||
$esk = $cipher->encrypt(chr($symmetric_algorithm) . $key);
|
||||
array_unshift($encrypted, new OpenPGP_SymmetricSessionKeyPacket($s2k, $esk, $symmetric_algorithm));
|
||||
}
|
||||
}
|
||||
|
||||
return new OpenPGP_Message($encrypted);
|
||||
}
|
||||
|
||||
public static function decryptSymmetric($pass, $m) {
|
||||
$epacket = self::getEncryptedData($m);
|
||||
|
||||
foreach($m as $p) {
|
||||
if($p instanceof OpenPGP_SymmetricSessionKeyPacket) {
|
||||
if(strlen($p->encrypted_data) > 0) {
|
||||
list($cipher, $key_bytes, $key_block_bytes) = self::getCipher($p->symmetric_algorithm);
|
||||
if(!$cipher) continue;
|
||||
$cipher->setKey($p->s2k->make_key($pass, $key_bytes));
|
||||
|
||||
$padAmount = $key_block_bytes - (strlen($p->encrypted_data) % $key_block_bytes);
|
||||
$data = substr($cipher->decrypt($p->encrypted_data . str_repeat("\0", $padAmount)), 0, strlen($p->encrypted_data));
|
||||
$decrypted = self::decryptPacket($epacket, ord($data{0}), substr($data, 1));
|
||||
} else {
|
||||
list($cipher, $key_bytes, $key_block_bytes) = self::getCipher($p->symmetric_algorithm);
|
||||
$decrypted = self::decryptPacket($epacket, $p->symmetric_algorithm, $p->s2k->make_key($pass, $key_bytes));
|
||||
}
|
||||
|
||||
if($decrypted) return $decrypted;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL; /* If we get here, we failed */
|
||||
}
|
||||
|
||||
public static function decryptSecretKey($pass, $packet) {
|
||||
$packet = clone $packet; // Do not mutate orinigal
|
||||
|
||||
list($cipher, $key_bytes, $key_block_bytes) = self::getCipher($packet->symmetric_algorithm);
|
||||
if(!$cipher) throw new Exception("Unsupported cipher");
|
||||
$cipher->setKey($packet->s2k->make_key($pass, $key_bytes));
|
||||
$cipher->setIV(substr($packet->encrypted_data, 0, $key_block_bytes));
|
||||
$material = $cipher->decrypt(substr($packet->encrypted_data, $key_block_bytes));
|
||||
|
||||
if($packet->s2k_useage == 254) {
|
||||
$chk = substr($material, -20);
|
||||
$material = substr($material, 0, -20);
|
||||
if($chk != hash('sha1', $material, true)) return NULL;
|
||||
} else {
|
||||
$chk = unpack('n', substr($material, -2));
|
||||
$chk = reset($chk);
|
||||
$material = substr($material, 0, -2);
|
||||
|
||||
$mkChk = self::checksum($material);
|
||||
if($chk != $mkChk) return NULL;
|
||||
}
|
||||
|
||||
$packet->s2k_useage = 0;
|
||||
$packet->symmetric_algorithm = 0;
|
||||
$packet->encrypted_data = NULL;
|
||||
$packet->input = $material;
|
||||
$packet->key_from_input();
|
||||
unset($packet->input);
|
||||
return $packet;
|
||||
}
|
||||
|
||||
public static function decryptPacket($epacket, $symmetric_algorithm, $key) {
|
||||
list($cipher, $key_bytes, $key_block_bytes) = self::getCipher($symmetric_algorithm);
|
||||
if(!$cipher) return NULL;
|
||||
$cipher->setKey($key);
|
||||
|
||||
if($epacket instanceof OpenPGP_IntegrityProtectedDataPacket) {
|
||||
$padAmount = $key_block_bytes - (strlen($epacket->data) % $key_block_bytes);
|
||||
$data = substr($cipher->decrypt($epacket->data . str_repeat("\0", $padAmount)), 0, strlen($epacket->data));
|
||||
$prefix = substr($data, 0, $key_block_bytes + 2);
|
||||
$mdc = substr(substr($data, -22, 22), 2);
|
||||
$data = substr($data, $key_block_bytes + 2, -22);
|
||||
|
||||
$mkMDC = hash("sha1", $prefix . $data . "\xD3\x14", true);
|
||||
if($mkMDC !== $mdc) return false;
|
||||
|
||||
try {
|
||||
$msg = OpenPGP_Message::parse($data);
|
||||
} catch (Exception $ex) { $msg = NULL; }
|
||||
if($msg) return $msg; /* Otherwise keep trying */
|
||||
} else {
|
||||
// No MDC mean decrypt with resync
|
||||
$iv = substr($epacket->data, 2, $key_block_bytes);
|
||||
$edata = substr($epacket->data, $key_block_bytes + 2);
|
||||
$padAmount = $key_block_bytes - (strlen($edata) % $key_block_bytes);
|
||||
|
||||
$cipher->setIV($iv);
|
||||
$data = substr($cipher->decrypt($edata . str_repeat("\0", $padAmount)), 0, strlen($edata));
|
||||
|
||||
try {
|
||||
$msg = OpenPGP_Message::parse($data);
|
||||
} catch (Exception $ex) { $msg = NULL; }
|
||||
if($msg) return $msg; /* Otherwise keep trying */
|
||||
}
|
||||
|
||||
return NULL; /* Failed */
|
||||
}
|
||||
|
||||
public static function getCipher($algo) {
|
||||
$cipher = NULL;
|
||||
switch($algo) {
|
||||
case NULL:
|
||||
case 0:
|
||||
throw new Exception("Data is already unencrypted");
|
||||
case 2:
|
||||
$cipher = new Crypt_TripleDES(Crypt_TripleDES::MODE_CFB);
|
||||
$key_bytes = 24;
|
||||
$key_block_bytes = 8;
|
||||
break;
|
||||
case 3:
|
||||
if(class_exists('OpenSSLWrapper')) {
|
||||
$cipher = new OpenSSLWrapper("CAST5-CFB");
|
||||
} else if(defined('MCRYPT_CAST_128')) {
|
||||
$cipher = new MCryptWrapper(MCRYPT_CAST_128);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
$cipher = new Crypt_Blowfish(Crypt_Blowfish::MODE_CFB);
|
||||
$key_bytes = 16;
|
||||
$key_block_bytes = 8;
|
||||
break;
|
||||
case 7:
|
||||
$cipher = new Crypt_AES(Crypt_AES::MODE_CFB);
|
||||
$cipher->setKeyLength(128);
|
||||
break;
|
||||
case 8:
|
||||
$cipher = new Crypt_AES(Crypt_AES::MODE_CFB);
|
||||
$cipher->setKeyLength(192);
|
||||
break;
|
||||
case 9:
|
||||
$cipher = new Crypt_AES(Crypt_AES::MODE_CFB);
|
||||
$cipher->setKeyLength(256);
|
||||
break;
|
||||
case 10:
|
||||
$cipher = new Crypt_Twofish(Crypt_Twofish::MODE_CFB);
|
||||
if(method_exists($cipher, 'setKeyLength')) {
|
||||
$cipher->setKeyLength(256);
|
||||
} else {
|
||||
$cipher = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(!$cipher) return array(NULL, NULL, NULL); // Unsupported cipher
|
||||
if(!isset($key_bytes)) $key_bytes = isset($cipher->key_size)?$cipher->key_size:$cipher->key_length;
|
||||
if(!isset($key_block_bytes)) $key_block_bytes = $cipher->block_size;
|
||||
return array($cipher, $key_bytes, $key_block_bytes);
|
||||
}
|
||||
|
||||
public static function getEncryptedData($m) {
|
||||
foreach($m as $p) {
|
||||
if($p instanceof OpenPGP_EncryptedDataPacket) return $p;
|
||||
}
|
||||
throw new Exception("Can only decrypt EncryptedDataPacket");
|
||||
}
|
||||
|
||||
public static function checksum($s) {
|
||||
$mkChk = 0;
|
||||
for($i = 0; $i < strlen($s); $i++) {
|
||||
$mkChk = ($mkChk + ord($s{$i})) % 65536;
|
||||
}
|
||||
return $mkChk;
|
||||
}
|
||||
}
|
31
lib/openpgp_mcrypt_wrapper.php
Normal file
31
lib/openpgp_mcrypt_wrapper.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
if(function_exists('mcrypt_encrypt') && defined('MCRYPT_MODE_CFB')) {
|
||||
class MCryptWrapper {
|
||||
public $cipher, $key, $iv, $key_size, $block_size;
|
||||
|
||||
|
||||
function __construct($cipher) {
|
||||
$this->cipher = $cipher;
|
||||
$this->key_size = mcrypt_module_get_algo_key_size($cipher);
|
||||
$this->block_size = mcrypt_module_get_algo_block_size($cipher);
|
||||
$this->iv = str_repeat("\0", mcrypt_get_iv_size($cipher, 'ncfb'));
|
||||
}
|
||||
|
||||
function setKey($key) {
|
||||
$this->key = $key;
|
||||
}
|
||||
|
||||
function setIV($iv) {
|
||||
$this->iv = $iv;
|
||||
}
|
||||
|
||||
function encrypt($data) {
|
||||
return mcrypt_encrypt($this->cipher, $this->key, $data, 'ncfb', $this->iv);
|
||||
}
|
||||
|
||||
function decrypt($data) {
|
||||
return mcrypt_decrypt($this->cipher, $this->key, $data, 'ncfb', $this->iv);
|
||||
}
|
||||
}
|
||||
}
|
33
lib/openpgp_openssl_wrapper.php
Normal file
33
lib/openpgp_openssl_wrapper.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
if(function_exists('openssl_encrypt')) {
|
||||
class OpenSSLWrapper {
|
||||
public $cipher, $key, $iv, $key_size, $block_size;
|
||||
|
||||
|
||||
function __construct($cipher) {
|
||||
if($cipher != "CAST5-CFB") throw Exception("OpenSSLWrapper is only used for CAST5 right now");
|
||||
|
||||
$this->cipher = $cipher;
|
||||
$this->key_size = 16;
|
||||
$this->block_size = 8;
|
||||
$this->iv = str_repeat("\0", 8);
|
||||
}
|
||||
|
||||
function setKey($key) {
|
||||
$this->key = $key;
|
||||
}
|
||||
|
||||
function setIV($iv) {
|
||||
$this->iv = $iv;
|
||||
}
|
||||
|
||||
function encrypt($data) {
|
||||
return openssl_encrypt($data, $this->cipher, $this->key, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $this->iv);
|
||||
}
|
||||
|
||||
function decrypt($data) {
|
||||
return openssl_decrypt($data, $this->cipher, $this->key, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $this->iv);
|
||||
}
|
||||
}
|
||||
}
|
27
phpunit.xml
Normal file
27
phpunit.xml
Normal file
@@ -0,0 +1,27 @@
|
||||
<phpunit bootstrap="tests/bootstrap.php">
|
||||
<testsuites>
|
||||
<testsuite name="Serialization">
|
||||
<file>tests/suite.php</file>
|
||||
</testsuite>
|
||||
|
||||
<testsuite name="Fingerprint">
|
||||
<file>tests/suite.php</file>
|
||||
</testsuite>
|
||||
|
||||
<testsuite name="MessageVerification">
|
||||
<file>tests/phpseclib_suite.php</file>
|
||||
</testsuite>
|
||||
|
||||
<testsuite name="KeyVerification">
|
||||
<file>tests/phpseclib_suite.php</file>
|
||||
</testsuite>
|
||||
|
||||
<testsuite name="Decryption">
|
||||
<file>tests/phpseclib_suite.php</file>
|
||||
</testsuite>
|
||||
|
||||
<testsuite name="Encryption">
|
||||
<file>tests/phpseclib_suite.php</file>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
</phpunit>
|
2
tests/bootstrap.php
Normal file
2
tests/bootstrap.php
Normal file
@@ -0,0 +1,2 @@
|
||||
<?php
|
||||
@include_once dirname(__FILE__) . '/../vendor/autoload.php';
|
BIN
tests/data/000001-006.public_key
Normal file
BIN
tests/data/000001-006.public_key
Normal file
Binary file not shown.
1
tests/data/000002-013.user_id
Normal file
1
tests/data/000002-013.user_id
Normal file
@@ -0,0 +1 @@
|
||||
<EFBFBD>$Test Key (RSA) <testkey@example.org>
|
BIN
tests/data/000003-002.sig
Normal file
BIN
tests/data/000003-002.sig
Normal file
Binary file not shown.
BIN
tests/data/000004-012.ring_trust
Normal file
BIN
tests/data/000004-012.ring_trust
Normal file
Binary file not shown.
BIN
tests/data/000005-002.sig
Normal file
BIN
tests/data/000005-002.sig
Normal file
Binary file not shown.
BIN
tests/data/000006-012.ring_trust
Normal file
BIN
tests/data/000006-012.ring_trust
Normal file
Binary file not shown.
BIN
tests/data/000007-002.sig
Normal file
BIN
tests/data/000007-002.sig
Normal file
Binary file not shown.
BIN
tests/data/000008-012.ring_trust
Normal file
BIN
tests/data/000008-012.ring_trust
Normal file
Binary file not shown.
BIN
tests/data/000009-002.sig
Normal file
BIN
tests/data/000009-002.sig
Normal file
Binary file not shown.
BIN
tests/data/000010-012.ring_trust
Normal file
BIN
tests/data/000010-012.ring_trust
Normal file
Binary file not shown.
BIN
tests/data/000011-002.sig
Normal file
BIN
tests/data/000011-002.sig
Normal file
Binary file not shown.
BIN
tests/data/000012-012.ring_trust
Normal file
BIN
tests/data/000012-012.ring_trust
Normal file
Binary file not shown.
BIN
tests/data/000013-014.public_subkey
Normal file
BIN
tests/data/000013-014.public_subkey
Normal file
Binary file not shown.
BIN
tests/data/000014-002.sig
Normal file
BIN
tests/data/000014-002.sig
Normal file
Binary file not shown.
BIN
tests/data/000015-012.ring_trust
Normal file
BIN
tests/data/000015-012.ring_trust
Normal file
Binary file not shown.
BIN
tests/data/000016-006.public_key
Normal file
BIN
tests/data/000016-006.public_key
Normal file
Binary file not shown.
BIN
tests/data/000017-002.sig
Normal file
BIN
tests/data/000017-002.sig
Normal file
Binary file not shown.
BIN
tests/data/000018-012.ring_trust
Normal file
BIN
tests/data/000018-012.ring_trust
Normal file
Binary file not shown.
1
tests/data/000019-013.user_id
Normal file
1
tests/data/000019-013.user_id
Normal file
@@ -0,0 +1 @@
|
||||
<EFBFBD>$Test Key (DSA) <testkey@example.com>
|
BIN
tests/data/000020-002.sig
Normal file
BIN
tests/data/000020-002.sig
Normal file
Binary file not shown.
BIN
tests/data/000021-012.ring_trust
Normal file
BIN
tests/data/000021-012.ring_trust
Normal file
Binary file not shown.
BIN
tests/data/000022-002.sig
Normal file
BIN
tests/data/000022-002.sig
Normal file
Binary file not shown.
BIN
tests/data/000023-012.ring_trust
Normal file
BIN
tests/data/000023-012.ring_trust
Normal file
Binary file not shown.
BIN
tests/data/000024-014.public_subkey
Normal file
BIN
tests/data/000024-014.public_subkey
Normal file
Binary file not shown.
BIN
tests/data/000025-002.sig
Normal file
BIN
tests/data/000025-002.sig
Normal file
Binary file not shown.
BIN
tests/data/000026-012.ring_trust
Normal file
BIN
tests/data/000026-012.ring_trust
Normal file
Binary file not shown.
BIN
tests/data/000027-006.public_key
Normal file
BIN
tests/data/000027-006.public_key
Normal file
Binary file not shown.
BIN
tests/data/000028-002.sig
Normal file
BIN
tests/data/000028-002.sig
Normal file
Binary file not shown.
BIN
tests/data/000029-012.ring_trust
Normal file
BIN
tests/data/000029-012.ring_trust
Normal file
Binary file not shown.
1
tests/data/000030-013.user_id
Normal file
1
tests/data/000030-013.user_id
Normal file
@@ -0,0 +1 @@
|
||||
<EFBFBD>+Test Key (DSA sign-only) <test@example.net>
|
BIN
tests/data/000031-002.sig
Normal file
BIN
tests/data/000031-002.sig
Normal file
Binary file not shown.
BIN
tests/data/000032-012.ring_trust
Normal file
BIN
tests/data/000032-012.ring_trust
Normal file
Binary file not shown.
BIN
tests/data/000033-002.sig
Normal file
BIN
tests/data/000033-002.sig
Normal file
Binary file not shown.
BIN
tests/data/000034-012.ring_trust
Normal file
BIN
tests/data/000034-012.ring_trust
Normal file
Binary file not shown.
BIN
tests/data/000035-006.public_key
Normal file
BIN
tests/data/000035-006.public_key
Normal file
Binary file not shown.
1
tests/data/000036-013.user_id
Normal file
1
tests/data/000036-013.user_id
Normal file
@@ -0,0 +1 @@
|
||||
<EFBFBD>.Test Key (RSA sign-only) <testkey@example.net>
|
BIN
tests/data/000037-002.sig
Normal file
BIN
tests/data/000037-002.sig
Normal file
Binary file not shown.
BIN
tests/data/000038-012.ring_trust
Normal file
BIN
tests/data/000038-012.ring_trust
Normal file
Binary file not shown.
BIN
tests/data/000039-002.sig
Normal file
BIN
tests/data/000039-002.sig
Normal file
Binary file not shown.
BIN
tests/data/000040-012.ring_trust
Normal file
BIN
tests/data/000040-012.ring_trust
Normal file
Binary file not shown.
BIN
tests/data/000041-017.attribute
Normal file
BIN
tests/data/000041-017.attribute
Normal file
Binary file not shown.
BIN
tests/data/000042-002.sig
Normal file
BIN
tests/data/000042-002.sig
Normal file
Binary file not shown.
BIN
tests/data/000043-012.ring_trust
Normal file
BIN
tests/data/000043-012.ring_trust
Normal file
Binary file not shown.
BIN
tests/data/000044-014.public_subkey
Normal file
BIN
tests/data/000044-014.public_subkey
Normal file
Binary file not shown.
BIN
tests/data/000045-002.sig
Normal file
BIN
tests/data/000045-002.sig
Normal file
Binary file not shown.
BIN
tests/data/000046-012.ring_trust
Normal file
BIN
tests/data/000046-012.ring_trust
Normal file
Binary file not shown.
BIN
tests/data/000047-005.secret_key
Normal file
BIN
tests/data/000047-005.secret_key
Normal file
Binary file not shown.
1
tests/data/000048-013.user_id
Normal file
1
tests/data/000048-013.user_id
Normal file
@@ -0,0 +1 @@
|
||||
<EFBFBD>$Test Key (RSA) <testkey@example.org>
|
BIN
tests/data/000049-002.sig
Normal file
BIN
tests/data/000049-002.sig
Normal file
Binary file not shown.
BIN
tests/data/000050-012.ring_trust
Normal file
BIN
tests/data/000050-012.ring_trust
Normal file
Binary file not shown.
BIN
tests/data/000051-007.secret_subkey
Normal file
BIN
tests/data/000051-007.secret_subkey
Normal file
Binary file not shown.
BIN
tests/data/000052-002.sig
Normal file
BIN
tests/data/000052-002.sig
Normal file
Binary file not shown.
BIN
tests/data/000053-012.ring_trust
Normal file
BIN
tests/data/000053-012.ring_trust
Normal file
Binary file not shown.
BIN
tests/data/000054-005.secret_key
Normal file
BIN
tests/data/000054-005.secret_key
Normal file
Binary file not shown.
BIN
tests/data/000055-002.sig
Normal file
BIN
tests/data/000055-002.sig
Normal file
Binary file not shown.
BIN
tests/data/000056-012.ring_trust
Normal file
BIN
tests/data/000056-012.ring_trust
Normal file
Binary file not shown.
1
tests/data/000057-013.user_id
Normal file
1
tests/data/000057-013.user_id
Normal file
@@ -0,0 +1 @@
|
||||
<EFBFBD>$Test Key (DSA) <testkey@example.com>
|
BIN
tests/data/000058-002.sig
Normal file
BIN
tests/data/000058-002.sig
Normal file
Binary file not shown.
BIN
tests/data/000059-012.ring_trust
Normal file
BIN
tests/data/000059-012.ring_trust
Normal file
Binary file not shown.
BIN
tests/data/000060-007.secret_subkey
Normal file
BIN
tests/data/000060-007.secret_subkey
Normal file
Binary file not shown.
BIN
tests/data/000061-002.sig
Normal file
BIN
tests/data/000061-002.sig
Normal file
Binary file not shown.
BIN
tests/data/000062-012.ring_trust
Normal file
BIN
tests/data/000062-012.ring_trust
Normal file
Binary file not shown.
BIN
tests/data/000063-005.secret_key
Normal file
BIN
tests/data/000063-005.secret_key
Normal file
Binary file not shown.
BIN
tests/data/000064-002.sig
Normal file
BIN
tests/data/000064-002.sig
Normal file
Binary file not shown.
BIN
tests/data/000065-012.ring_trust
Normal file
BIN
tests/data/000065-012.ring_trust
Normal file
Binary file not shown.
1
tests/data/000066-013.user_id
Normal file
1
tests/data/000066-013.user_id
Normal file
@@ -0,0 +1 @@
|
||||
<EFBFBD>+Test Key (DSA sign-only) <test@example.net>
|
BIN
tests/data/000067-002.sig
Normal file
BIN
tests/data/000067-002.sig
Normal file
Binary file not shown.
BIN
tests/data/000068-012.ring_trust
Normal file
BIN
tests/data/000068-012.ring_trust
Normal file
Binary file not shown.
BIN
tests/data/000069-005.secret_key
Normal file
BIN
tests/data/000069-005.secret_key
Normal file
Binary file not shown.
1
tests/data/000070-013.user_id
Normal file
1
tests/data/000070-013.user_id
Normal file
@@ -0,0 +1 @@
|
||||
<EFBFBD>.Test Key (RSA sign-only) <testkey@example.net>
|
BIN
tests/data/000071-002.sig
Normal file
BIN
tests/data/000071-002.sig
Normal file
Binary file not shown.
BIN
tests/data/000072-012.ring_trust
Normal file
BIN
tests/data/000072-012.ring_trust
Normal file
Binary file not shown.
BIN
tests/data/000073-017.attribute
Normal file
BIN
tests/data/000073-017.attribute
Normal file
Binary file not shown.
BIN
tests/data/000074-002.sig
Normal file
BIN
tests/data/000074-002.sig
Normal file
Binary file not shown.
BIN
tests/data/000075-012.ring_trust
Normal file
BIN
tests/data/000075-012.ring_trust
Normal file
Binary file not shown.
BIN
tests/data/000076-007.secret_subkey
Normal file
BIN
tests/data/000076-007.secret_subkey
Normal file
Binary file not shown.
BIN
tests/data/000077-002.sig
Normal file
BIN
tests/data/000077-002.sig
Normal file
Binary file not shown.
BIN
tests/data/000078-012.ring_trust
Normal file
BIN
tests/data/000078-012.ring_trust
Normal file
Binary file not shown.
BIN
tests/data/002182-002.sig
Normal file
BIN
tests/data/002182-002.sig
Normal file
Binary file not shown.
BIN
tests/data/compressedsig-bzip2.gpg
Normal file
BIN
tests/data/compressedsig-bzip2.gpg
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user