New experimental plugin 'secure mail'

This commit is contained in:
fabrixxm 2014-12-29 18:10:32 +01:00
commit e17cb70379
14 changed files with 3199 additions and 0 deletions

11
securemail/README.md Normal file
View file

@ -0,0 +1,11 @@
Secure Mail
-----------
Send notification mails to user encrypted with GPG.
Each user can enable it and submit his public key under Settings-> Addon
-> "Secure Mail" Settings.
Use 'php-gpg' library, a pure PHP implementation of GPG/PGP, released
under GPL. See [project repo](https://github.com/jasonhinkle/php-gpg).
This plugin need Friendica version > 3.3.2 to work.

3
securemail/php-gpg/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
/.buildpath
/.settings
.DS_Store

View file

@ -0,0 +1,39 @@
php-gpg
=======
php-gpg is a pure PHP implementation of GPG/PGP (currently supports encryption only). The library does not require PGP/GPG binaries and should run on any platform that supports PHP.
This library is useful for encrypting data before it is sent over an insecure protocol (for example email). Messages encrypted with this library are compatible and can be decrypted by standard GPG/PGP clients.
Features/Limitations
--------------------
* Supports RSA, DSA public key length of 2,4,8,16,512,1024,2048 or 4096
* Currently supports only encrypt
Hey You! If you have a good understanding of public key encryption and want to implement signing or decryption your pull request would be welcome.
Usage
-----
```php
require_once 'libs/GPG.php';
$gpg = new GPG();
// create an instance of a GPG public key object based on ASCII key
$pub_key = new GPG_Public_Key($public_key_ascii);
// using the key, encrypt your plain text using the public key
$encrypted = $gpg->encrypt($pub_key,$plain_text_string);
echo $encrypted;
```
License
-------
GPL http://www.gnu.org/copyleft/gpl.html
I'd like to release this under a more permissive license, but since PGP & GPG itself are GPL, I think this library is likely bound to the terms of GPL as well.

View file

@ -0,0 +1,186 @@
<?php
/** @package php-gpg */
/** require supporting files */
require_once("GPG/Expanded_Key.php");
require_once("GPG/Public_Key.php");
require_once("GPG/AES.php");
require_once("GPG/globals.php");
/**
* Pure PHP implementation of PHP/GPG encryption.
* Supports RSA, DSA public key length of 2,4,8,16,512,1024,2048 or 4096
* Currently supports only encrypt
*
* @package php-gpg::Encryption
* @link http://www.verysimple.com/
* @copyright 1997-2012 VerySimple, Inc.
* @license http://www.gnu.org/licenses/gpl.html GPL
* @todo implement decryption
* @version 1.1
*
* @example
* require_once 'libs/GPG.php';
* $gpg = new GPG();
* $pub_key = new GPG_Public_Key($public_key_ascii);
* $encrypted = $gpg->encrypt($pub_key,$plain_text_string);
*/
class GPG
{
private $width = 16;
private $el = array(3, 5, 9, 17, 513, 1025, 2049, 4097);
private $version = "1.4.7";
private function gpg_encrypt($key, $text) {
$i = 0;
$i = 0;
$len = strlen($text);
$len = strlen($text);
$iblock = array_fill(0, $this->width, 0);
$rblock = array_fill(0, $this->width, 0);
$ct = array_fill(0, $this->width + 2, 0);
$cipher = "";
if($len % $this->width) {
for($i = ($len % $this->width); $i < $this->width; $i++) $text .= "\0";
}
$ekey = new Expanded_Key($key);
for($i = 0; $i < $this->width; $i++) {
$iblock[$i] = 0;
$rblock[$i] = GPG_Utility::c_random();
}
$iblock = GPG_AES::encrypt($iblock, $ekey);
for($i = 0; $i < $this->width; $i++) {
$ct[$i] = ($iblock[$i] ^= $rblock[$i]);
}
$iblock = GPG_AES::encrypt($iblock, $ekey);
$ct[$this->width] = ($iblock[0] ^ $rblock[$this->width - 2]);
$ct[$this->width + 1] = ($iblock[1] ^ $rblock[$this->width - 1]);
for($i = 0; $i < $this->width + 2; $i++) $cipher .= chr($ct[$i]);
$iblock = array_slice($ct, 2, $this->width + 2);
for($n = 0; $n < strlen($text); $n += $this->width) {
$iblock = GPG_AES::encrypt($iblock, $ekey);
for($i = 0; $i < $this->width; $i++) {
$iblock[$i] ^= ord($text[$n + $i]);
$cipher .= chr($iblock[$i]);
}
}
return substr($cipher, 0, $len + $this->width + 2);
}
private function gpg_header($tag, $len)
{
if ($len > 0xff) $tag += 1;
$h = chr($tag);
if ($len > 0xff) $h .= chr($len / 0x100);
$h .= chr($len % 0x100);
return $h;
}
private function gpg_session($key_id, $key_type, $session_key, $public_key)
{
$mod = array();
$exp = array();
$enc = "";
$s = base64_decode($public_key);
$l = floor((ord($s[0]) * 256 + ord($s[1]) + 7) / 8);
$mod = mpi2b(substr($s, 0, $l + 2));
if($key_type) {
$grp = array();
$y = array();
$B = array();
$C = array();
$l2 = floor((ord($s[$l + 2]) * 256 + ord($s[$l + 3]) + 7) / 8) + 2;
$grp = mpi2b(substr($s, $l + 2, $l2));
$y = mpi2b(substr($s, $l + 2 + $l2));
$exp[0] = $this->el[GPG_Utility::c_random() & 7];
$B = bmodexp($grp, $exp, $mod);
$C = bmodexp($y, $exp, $mod);
} else {
$exp = mpi2b(substr($s, $l + 2));
}
$c = 0;
$lsk = strlen($session_key);
for($i = 0; $i < $lsk; $i++) $c += ord($session_key[$i]);
$c &= 0xffff;
$lm = ($l - 2) * 8 + 2;
$m = chr($lm / 256) . chr($lm % 256) .
chr(2) . GPG_Utility::s_random($l - $lsk - 6, 1) . "\0" .
chr(7) . $session_key .
chr($c / 256) . chr($c & 0xff);
if($key_type) {
$enc = b2mpi($B) . b2mpi(bmod(bmul(mpi2b($m), $C), $mod));
return $this->gpg_header(0x84,strlen($enc) + 10) .
chr(3) . $key_id . chr(16) . $enc;
} else {
$enc = b2mpi(bmodexp(mpi2b($m), $exp, $mod));
return $this->gpg_header(0x84, strlen($enc) + 10) .
chr(3) . $key_id . chr(1) . $enc;
}
}
private function gpg_literal($text)
{
if (strpos($text, "\r\n") === false)
$text = str_replace("\n", "\r\n", $text);
return
$this->gpg_header(0xac, strlen($text) + 10) . "t" .
chr(4) . "file\0\0\0\0" . $text;
}
private function gpg_data($key, $text)
{
$enc = $this->gpg_encrypt($key, $this->gpg_literal($text));
return $this->gpg_header(0xa4, strlen($enc)) . $enc;
}
/**
* GPG Encypts a message to the provided public key
*
* @param GPG_Public_Key $pk
* @param string $plaintext
* @return string encrypted text
*/
function encrypt($pk, $plaintext)
{
// normalize the public key
$key_id = $pk->GetKeyId();
$key_type = $pk->GetKeyType();
$public_key = $pk->GetPublicKey();
$session_key = GPG_Utility::s_random($this->width, 0);
$key_id = GPG_Utility::hex2bin($key_id);
$cp = $this->gpg_session($key_id, $key_type, $session_key, $public_key) .
$this->gpg_data($session_key, $plaintext);
$code = base64_encode($cp);
$code = wordwrap($code, 60, "\n", 1);
return
"-----BEGIN PGP MESSAGE-----\nVersion: VerySimple PHP-GPG v".$this->version."\n\n" .
$code . "\n=" . base64_encode(GPG_Utility::crc24($cp)) .
"\n-----END PGP MESSAGE-----\n";
}
}
?>

View file

@ -0,0 +1,63 @@
<?php
/** @package php-gpg::GPG */
/** require supporting files */
require_once("Cipher.php");
/**
* @package php-gpg::GPG
*/
class GPG_AES
{
static function encrypt($block, $ctx)
{
$RCON = GPG_Cipher::$RCON;
$S = GPG_Cipher::$S;
$T1 = GPG_Cipher::$T1;
$T2 = GPG_Cipher::$T2;
$T3 = GPG_Cipher::$T3;
$T4 = GPG_Cipher::$T4;
$r = 0;
$t0 = 0;
$t1 = 0;
$t2 = 0;
$t3 = 0;
$b = GPG_Utility::pack_octets($block);
$rounds = $ctx->rounds;
$b0 = $b[0];
$b1 = $b[1];
$b2 = $b[2];
$b3 = $b[3];
for($r = 0; $r < $rounds - 1; $r++) {
$t0 = $b0 ^ $ctx->rk[$r][0];
$t1 = $b1 ^ $ctx->rk[$r][1];
$t2 = $b2 ^ $ctx->rk[$r][2];
$t3 = $b3 ^ $ctx->rk[$r][3];
$b0 = $T1[$t0 & 255] ^ $T2[($t1 >> 8) & 255] ^ $T3[($t2 >> 16) & 255] ^ $T4[GPG_Utility::zshift($t3, 24)];
$b1 = $T1[$t1 & 255] ^ $T2[($t2 >> 8) & 255] ^ $T3[($t3 >> 16) & 255] ^ $T4[GPG_Utility::zshift($t0, 24)];
$b2 = $T1[$t2 & 255] ^ $T2[($t3 >> 8) & 255] ^ $T3[($t0 >> 16) & 255] ^ $T4[GPG_Utility::zshift($t1, 24)];
$b3 = $T1[$t3 & 255] ^ $T2[($t0 >> 8) & 255] ^ $T3[($t1 >> 16) & 255] ^ $T4[GPG_Utility::zshift($t2, 24)];
}
$r = $rounds - 1;
$t0 = $b0 ^ $ctx->rk[$r][0];
$t1 = $b1 ^ $ctx->rk[$r][1];
$t2 = $b2 ^ $ctx->rk[$r][2];
$t3 = $b3 ^ $ctx->rk[$r][3];
$b[0] = GPG_Cipher::F1($t0, $t1, $t2, $t3) ^ $ctx->rk[$rounds][0];
$b[1] = GPG_Cipher::F1($t1, $t2, $t3, $t0) ^ $ctx->rk[$rounds][1];
$b[2] = GPG_Cipher::F1($t2, $t3, $t0, $t1) ^ $ctx->rk[$rounds][2];
$b[3] = GPG_Cipher::F1($t3, $t0, $t1, $t2) ^ $ctx->rk[$rounds][3];
return GPG_Utility::unpack_octets($b);
}
}
?>

View file

@ -0,0 +1,335 @@
<?php
/** @package php-gpg::GPG */
/** require supporting files */
require_once("Utility.php");
/**
* @package php-gpg::GPG
*/
class GPG_Cipher
{
/*
global $RCON;
global $S;
global $T1;
global $T2;
global $T3;
global $T4;
global $maxkc;
global $maxrk;
*/
static $maxkc = 8;
static $maxrk = 14;
static $RCON = array(
0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc,
0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4,
0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91
);
static $S = array(
99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171,
118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164,
114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113,
216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226,
235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214,
179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203,
190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69,
249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245,
188, 182, 218, 33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68,
23, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42,
144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73,
6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109,
141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37,
46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62,
181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225,
248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223,
140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187,
22
);
static $T1 = array(
0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6,
0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591,
0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56,
0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec,
0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa,
0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb,
0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45,
0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b,
0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c,
0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83,
0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9,
0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a,
0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d,
0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f,
0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df,
0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea,
0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34,
0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b,
0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d,
0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413,
0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1,
0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6,
0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972,
0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85,
0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed,
0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511,
0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe,
0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b,
0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05,
0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1,
0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142,
0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf,
0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3,
0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e,
0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a,
0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6,
0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3,
0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b,
0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428,
0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad,
0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14,
0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8,
0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4,
0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2,
0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda,
0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949,
0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf,
0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810,
0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c,
0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697,
0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e,
0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f,
0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc,
0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c,
0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969,
0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27,
0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122,
0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433,
0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9,
0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5,
0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a,
0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0,
0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e,
0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c
);
static $T2 = array(
0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d,
0xf2f2ff0d, 0x6b6bd6bd, 0x6f6fdeb1, 0xc5c59154,
0x30306050, 0x01010203, 0x6767cea9, 0x2b2b567d,
0xfefee719, 0xd7d7b562, 0xabab4de6, 0x7676ec9a,
0xcaca8f45, 0x82821f9d, 0xc9c98940, 0x7d7dfa87,
0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b,
0xadad41ec, 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea,
0x9c9c23bf, 0xa4a453f7, 0x7272e496, 0xc0c09b5b,
0xb7b775c2, 0xfdfde11c, 0x93933dae, 0x26264c6a,
0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f,
0x3434685c, 0xa5a551f4, 0xe5e5d134, 0xf1f1f908,
0x7171e293, 0xd8d8ab73, 0x31316253, 0x15152a3f,
0x0404080c, 0xc7c79552, 0x23234665, 0xc3c39d5e,
0x18183028, 0x969637a1, 0x05050a0f, 0x9a9a2fb5,
0x07070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d,
0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f,
0x0909121b, 0x83831d9e, 0x2c2c5874, 0x1a1a342e,
0x1b1b362d, 0x6e6edcb2, 0x5a5ab4ee, 0xa0a05bfb,
0x5252a4f6, 0x3b3b764d, 0xd6d6b761, 0xb3b37dce,
0x2929527b, 0xe3e3dd3e, 0x2f2f5e71, 0x84841397,
0x5353a6f5, 0xd1d1b968, 0x00000000, 0xededc12c,
0x20204060, 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed,
0x6a6ad4be, 0xcbcb8d46, 0xbebe67d9, 0x3939724b,
0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, 0xcfcf854a,
0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16,
0x434386c5, 0x4d4d9ad7, 0x33336655, 0x85851194,
0x45458acf, 0xf9f9e910, 0x02020406, 0x7f7ffe81,
0x5050a0f0, 0x3c3c7844, 0x9f9f25ba, 0xa8a84be3,
0x5151a2f3, 0xa3a35dfe, 0x404080c0, 0x8f8f058a,
0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104,
0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263,
0x10102030, 0xffffe51a, 0xf3f3fd0e, 0xd2d2bf6d,
0xcdcd814c, 0x0c0c1814, 0x13132635, 0xececc32f,
0x5f5fbee1, 0x979735a2, 0x444488cc, 0x17172e39,
0xc4c49357, 0xa7a755f2, 0x7e7efc82, 0x3d3d7a47,
0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695,
0x6060c0a0, 0x81811998, 0x4f4f9ed1, 0xdcdca37f,
0x22224466, 0x2a2a547e, 0x90903bab, 0x88880b83,
0x46468cca, 0xeeeec729, 0xb8b86bd3, 0x1414283c,
0xdedea779, 0x5e5ebce2, 0x0b0b161d, 0xdbdbad76,
0xe0e0db3b, 0x32326456, 0x3a3a744e, 0x0a0a141e,
0x494992db, 0x06060c0a, 0x2424486c, 0x5c5cb8e4,
0xc2c29f5d, 0xd3d3bd6e, 0xacac43ef, 0x6262c4a6,
0x919139a8, 0x959531a4, 0xe4e4d337, 0x7979f28b,
0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7,
0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0,
0x6c6cd8b4, 0x5656acfa, 0xf4f4f307, 0xeaeacf25,
0x6565caaf, 0x7a7af48e, 0xaeae47e9, 0x08081018,
0xbaba6fd5, 0x7878f088, 0x25254a6f, 0x2e2e5c72,
0x1c1c3824, 0xa6a657f1, 0xb4b473c7, 0xc6c69751,
0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21,
0x4b4b96dd, 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85,
0x7070e090, 0x3e3e7c42, 0xb5b571c4, 0x6666ccaa,
0x484890d8, 0x03030605, 0xf6f6f701, 0x0e0e1c12,
0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0,
0x86861791, 0xc1c19958, 0x1d1d3a27, 0x9e9e27b9,
0xe1e1d938, 0xf8f8eb13, 0x98982bb3, 0x11112233,
0x6969d2bb, 0xd9d9a970, 0x8e8e0789, 0x949433a7,
0x9b9b2db6, 0x1e1e3c22, 0x87871592, 0xe9e9c920,
0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a,
0x8c8c038f, 0xa1a159f8, 0x89890980, 0x0d0d1a17,
0xbfbf65da, 0xe6e6d731, 0x424284c6, 0x6868d0b8,
0x414182c3, 0x999929b0, 0x2d2d5a77, 0x0f0f1e11,
0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a
);
static $T3 = array(
0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b,
0xf2ff0df2, 0x6bd6bd6b, 0x6fdeb16f, 0xc59154c5,
0x30605030, 0x01020301, 0x67cea967, 0x2b567d2b,
0xfee719fe, 0xd7b562d7, 0xab4de6ab, 0x76ec9a76,
0xca8f45ca, 0x821f9d82, 0xc98940c9, 0x7dfa877d,
0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0,
0xad41ecad, 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf,
0x9c23bf9c, 0xa453f7a4, 0x72e49672, 0xc09b5bc0,
0xb775c2b7, 0xfde11cfd, 0x933dae93, 0x264c6a26,
0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc,
0x34685c34, 0xa551f4a5, 0xe5d134e5, 0xf1f908f1,
0x71e29371, 0xd8ab73d8, 0x31625331, 0x152a3f15,
0x04080c04, 0xc79552c7, 0x23466523, 0xc39d5ec3,
0x18302818, 0x9637a196, 0x050a0f05, 0x9a2fb59a,
0x070e0907, 0x12243612, 0x801b9b80, 0xe2df3de2,
0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75,
0x09121b09, 0x831d9e83, 0x2c58742c, 0x1a342e1a,
0x1b362d1b, 0x6edcb26e, 0x5ab4ee5a, 0xa05bfba0,
0x52a4f652, 0x3b764d3b, 0xd6b761d6, 0xb37dceb3,
0x29527b29, 0xe3dd3ee3, 0x2f5e712f, 0x84139784,
0x53a6f553, 0xd1b968d1, 0x00000000, 0xedc12ced,
0x20406020, 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b,
0x6ad4be6a, 0xcb8d46cb, 0xbe67d9be, 0x39724b39,
0x4a94de4a, 0x4c98d44c, 0x58b0e858, 0xcf854acf,
0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb,
0x4386c543, 0x4d9ad74d, 0x33665533, 0x85119485,
0x458acf45, 0xf9e910f9, 0x02040602, 0x7ffe817f,
0x50a0f050, 0x3c78443c, 0x9f25ba9f, 0xa84be3a8,
0x51a2f351, 0xa35dfea3, 0x4080c040, 0x8f058a8f,
0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5,
0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321,
0x10203010, 0xffe51aff, 0xf3fd0ef3, 0xd2bf6dd2,
0xcd814ccd, 0x0c18140c, 0x13263513, 0xecc32fec,
0x5fbee15f, 0x9735a297, 0x4488cc44, 0x172e3917,
0xc49357c4, 0xa755f2a7, 0x7efc827e, 0x3d7a473d,
0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573,
0x60c0a060, 0x81199881, 0x4f9ed14f, 0xdca37fdc,
0x22446622, 0x2a547e2a, 0x903bab90, 0x880b8388,
0x468cca46, 0xeec729ee, 0xb86bd3b8, 0x14283c14,
0xdea779de, 0x5ebce25e, 0x0b161d0b, 0xdbad76db,
0xe0db3be0, 0x32645632, 0x3a744e3a, 0x0a141e0a,
0x4992db49, 0x060c0a06, 0x24486c24, 0x5cb8e45c,
0xc29f5dc2, 0xd3bd6ed3, 0xac43efac, 0x62c4a662,
0x9139a891, 0x9531a495, 0xe4d337e4, 0x79f28b79,
0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d,
0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9,
0x6cd8b46c, 0x56acfa56, 0xf4f307f4, 0xeacf25ea,
0x65caaf65, 0x7af48e7a, 0xae47e9ae, 0x08101808,
0xba6fd5ba, 0x78f08878, 0x254a6f25, 0x2e5c722e,
0x1c38241c, 0xa657f1a6, 0xb473c7b4, 0xc69751c6,
0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f,
0x4b96dd4b, 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a,
0x70e09070, 0x3e7c423e, 0xb571c4b5, 0x66ccaa66,
0x4890d848, 0x03060503, 0xf6f701f6, 0x0e1c120e,
0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9,
0x86179186, 0xc19958c1, 0x1d3a271d, 0x9e27b99e,
0xe1d938e1, 0xf8eb13f8, 0x982bb398, 0x11223311,
0x69d2bb69, 0xd9a970d9, 0x8e07898e, 0x9433a794,
0x9b2db69b, 0x1e3c221e, 0x87159287, 0xe9c920e9,
0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf,
0x8c038f8c, 0xa159f8a1, 0x89098089, 0x0d1a170d,
0xbf65dabf, 0xe6d731e6, 0x4284c642, 0x68d0b868,
0x4182c341, 0x9929b099, 0x2d5a772d, 0x0f1e110f,
0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16
);
static $T4 = array(
0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b,
0xff0df2f2, 0xd6bd6b6b, 0xdeb16f6f, 0x9154c5c5,
0x60503030, 0x02030101, 0xcea96767, 0x567d2b2b,
0xe719fefe, 0xb562d7d7, 0x4de6abab, 0xec9a7676,
0x8f45caca, 0x1f9d8282, 0x8940c9c9, 0xfa877d7d,
0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0,
0x41ecadad, 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf,
0x23bf9c9c, 0x53f7a4a4, 0xe4967272, 0x9b5bc0c0,
0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, 0x4c6a2626,
0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc,
0x685c3434, 0x51f4a5a5, 0xd134e5e5, 0xf908f1f1,
0xe2937171, 0xab73d8d8, 0x62533131, 0x2a3f1515,
0x080c0404, 0x9552c7c7, 0x46652323, 0x9d5ec3c3,
0x30281818, 0x37a19696, 0x0a0f0505, 0x2fb59a9a,
0x0e090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2,
0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575,
0x121b0909, 0x1d9e8383, 0x58742c2c, 0x342e1a1a,
0x362d1b1b, 0xdcb26e6e, 0xb4ee5a5a, 0x5bfba0a0,
0xa4f65252, 0x764d3b3b, 0xb761d6d6, 0x7dceb3b3,
0x527b2929, 0xdd3ee3e3, 0x5e712f2f, 0x13978484,
0xa6f55353, 0xb968d1d1, 0x00000000, 0xc12ceded,
0x40602020, 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b,
0xd4be6a6a, 0x8d46cbcb, 0x67d9bebe, 0x724b3939,
0x94de4a4a, 0x98d44c4c, 0xb0e85858, 0x854acfcf,
0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb,
0x86c54343, 0x9ad74d4d, 0x66553333, 0x11948585,
0x8acf4545, 0xe910f9f9, 0x04060202, 0xfe817f7f,
0xa0f05050, 0x78443c3c, 0x25ba9f9f, 0x4be3a8a8,
0xa2f35151, 0x5dfea3a3, 0x80c04040, 0x058a8f8f,
0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5,
0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121,
0x20301010, 0xe51affff, 0xfd0ef3f3, 0xbf6dd2d2,
0x814ccdcd, 0x18140c0c, 0x26351313, 0xc32fecec,
0xbee15f5f, 0x35a29797, 0x88cc4444, 0x2e391717,
0x9357c4c4, 0x55f2a7a7, 0xfc827e7e, 0x7a473d3d,
0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373,
0xc0a06060, 0x19988181, 0x9ed14f4f, 0xa37fdcdc,
0x44662222, 0x547e2a2a, 0x3bab9090, 0x0b838888,
0x8cca4646, 0xc729eeee, 0x6bd3b8b8, 0x283c1414,
0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb,
0xdb3be0e0, 0x64563232, 0x744e3a3a, 0x141e0a0a,
0x92db4949, 0x0c0a0606, 0x486c2424, 0xb8e45c5c,
0x9f5dc2c2, 0xbd6ed3d3, 0x43efacac, 0xc4a66262,
0x39a89191, 0x31a49595, 0xd337e4e4, 0xf28b7979,
0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d,
0x018c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9,
0xd8b46c6c, 0xacfa5656, 0xf307f4f4, 0xcf25eaea,
0xcaaf6565, 0xf48e7a7a, 0x47e9aeae, 0x10180808,
0x6fd5baba, 0xf0887878, 0x4a6f2525, 0x5c722e2e,
0x38241c1c, 0x57f1a6a6, 0x73c7b4b4, 0x9751c6c6,
0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f,
0x96dd4b4b, 0x61dcbdbd, 0x0d868b8b, 0x0f858a8a,
0xe0907070, 0x7c423e3e, 0x71c4b5b5, 0xccaa6666,
0x90d84848, 0x06050303, 0xf701f6f6, 0x1c120e0e,
0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9,
0x17918686, 0x9958c1c1, 0x3a271d1d, 0x27b99e9e,
0xd938e1e1, 0xeb13f8f8, 0x2bb39898, 0x22331111,
0xd2bb6969, 0xa970d9d9, 0x07898e8e, 0x33a79494,
0x2db69b9b, 0x3c221e1e, 0x15928787, 0xc920e9e9,
0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf,
0x038f8c8c, 0x59f8a1a1, 0x09808989, 0x1a170d0d,
0x65dabfbf, 0xd731e6e6, 0x84c64242, 0xd0b86868,
0x82c34141, 0x29b09999, 0x5a772d2d, 0x1e110f0f,
0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616
);
static function F1($x0, $x1, $x2, $x3)
{
$T1 = GPG_Cipher::$T1;
return
GPG_Utility::B1($T1[$x0 & 0xff]) | (GPG_Utility::B1($T1[($x1 >> 0x8) & 0xff]) << 0x8) |
(GPG_Utility::B1($T1[($x2 >> 0x10) & 0xff]) << 0x10) | (GPG_Utility::B1($T1[GPG_Utility::zshift($x3, 0x18)]) << 0x18);
}
}
?>

View file

@ -0,0 +1,105 @@
<?php
/** @package php-gpg::GPG */
/** require supporting files */
require_once("Cipher.php");
/**
* @package php-gpg::GPG
*/
class Expanded_Key {
var $rounds;
var $rk;
function Expanded_Key($key) {
$RCON = GPG_Cipher::$RCON;
$S = GPG_Cipher::$S;
$maxkc = GPG_Cipher::$maxkc;
$maxrk = GPG_Cipher::$maxrk;
$kc = 0;
$i = 0;
$j = 0;
$r = 0;
$t = 0;
$rounds = 0;
$keySched = array_fill(0, $maxrk + 1, 0);
$keylen = strlen($key);
$k = array_fill(0, $maxkc, 0);
$tk = array_fill(0, $maxkc, 0);
$rconpointer = 0;
if ($keylen == 16) {
$rounds = 10;
$kc = 4;
} else if ($keylen == 24) {
$rounds = 12;
$kc = 6;
} else if ($keylen == 32) {
$rounds = 14;
$kc = 8;
} else {
return;
}
for($i = 0; $i < $maxrk + 1; $i++) $keySched[$i] = array_fill(0, 4, 0);
for($i = 0, $j = 0; $j < $keylen; $j++, $i += 4) {
if ($i < $keylen) {
$k[$j] = ord($key[$i]) | (ord($key[$i + 1]) << 0x8) |
(ord($key[$i + 2]) << 0x10) | (ord($key[$i + 3]) << 0x18);
} else {
$k[$j] = 0;
}
}
for($j = $kc - 1; $j >= 0; $j--) $tk[$j] = $k[$j];
$r = 0;
$t = 0;
for($j = 0; ($j < $kc) && ($r < $rounds + 1); ) {
for(; ($j < $kc) && ($t < 4); $j++, $t++) {
$keySched[$r][$t] = $tk[$j];
}
if($t == 4) {
$r++;
$t = 0;
}
}
while($r < $rounds + 1) {
$temp = $tk[$kc - 1];
$tk[0] ^= $S[GPG_Utility::B1($temp)] | ($S[GPG_Utility::B2($temp)] << 0x8) |
($S[GPG_Utility::B3($temp)] << 0x10) | ($S[GPG_Utility::B0($temp)] << 0x18);
$tk[0] ^= $RCON[$rconpointer++];
if ($kc != 8) {
for($j = 1; $j < $kc; $j++) $tk[$j] ^= $tk[$j - 1];
} else {
for($j = 1; $j < $kc / 2; $j++) $tk[$j] ^= $tk[$j - 1];
$temp = $tk[$kc / 2 - 1];
$tk[$kc / 2] ^= $S[GPG_Utility::B0($temp)] | ($S[GPG_Utility::B1($temp)] << 0x8) |
($S[GPG_Utility::B2($temp)] << 0x10) | ($S[GPG_Utility::B3($temp)] << 0x18);
for($j = $kc / 2 + 1; $j < $kc; $j++) $tk[$j] ^= $tk[$j - 1];
}
for($j = 0; ($j < $kc) && ($r < $rounds + 1); ) {
for(; ($j < $kc) && ($t < 4); $j++, $t++) {
$keySched[$r][$t] = $tk[$j];
}
if($t == 4) {
$r++;
$t = 0;
}
}
}
$this->rounds = $rounds;
$this->rk = $keySched;
return $this;
}
}
?>

View file

@ -0,0 +1,217 @@
<?php
/** @package php-gpg::GPG */
/** require supporting files */
require_once("Expanded_Key.php");
define("PK_TYPE_ELGAMAL", 1);
define("PK_TYPE_RSA", 0);
define("PK_TYPE_UNKNOWN", -1);
/**
* Pure PHP implementation of PHP/GPG public key
*
* @package php-gpg::GPG
* @link http://www.verysimple.com/
* @copyright 1997-2011 VerySimple, Inc.
* @license http://www.gnu.org/licenses/lgpl.html LGPL
* @todo implement decryption
* @version 1.0
*/
class GPG_Public_Key {
var $version;
var $fp;
var $key_id;
var $user;
var $public_key;
var $type;
function IsValid()
{
return $this->version != -1 && $this->GetKeyType() != PK_TYPE_UNKNOWN;
}
function GetKeyType()
{
if (!strcmp($this->type, "ELGAMAL")) return PK_TYPE_ELGAMAL;
if (!strcmp($this->type, "RSA")) return PK_TYPE_RSA;
return PK_TYPE_UNKNOWN;
}
function GetFingerprint()
{
return strtoupper( trim(chunk_split($this->fp, 4, ' ')) );
}
function GetKeyId()
{
return (strlen($this->key_id) == 16) ? strtoupper($this->key_id) : '0000000000000000';
}
function GetPublicKey()
{
return str_replace("\n", "", $this->public_key);
}
function GPG_Public_Key($asc) {
$found = 0;
// normalize line breaks
$asc = str_replace("\r\n", "\n", $asc);
if (strpos($asc, "-----BEGIN PGP PUBLIC KEY BLOCK-----\n") === false)
throw new Exception("Missing header block in Public Key");
if (strpos($asc, "\n\n") === false)
throw new Exception("Missing body delimiter in Public Key");
if (strpos($asc, "\n-----END PGP PUBLIC KEY BLOCK-----") === false)
throw new Exception("Missing footer block in Public Key");
// get rid of everything except the base64 encoded key
$headerbody = explode("\n\n", str_replace("\n-----END PGP PUBLIC KEY BLOCK-----", "", $asc), 2);
$asc = trim($headerbody[1]);
$len = 0;
$s = base64_decode($asc);
$sa = str_split($s);
for($i = 0; $i < strlen($s);) {
$tag = ord($sa[$i++]);
// echo 'TAG=' . $tag . '/';
if(($tag & 128) == 0) break;
if($tag & 64) {
$tag &= 63;
$len = ord($sa[$i++]);
if ($len > 191 && $len < 224) $len = (($len - 192) << 8) + ord($sa[$i++]);
else if ($len == 255) $len = (ord($sa[$i++]) << 24) + (ord($sa[$i++]) << 16) + (ord($sa[$i++]) << 8) + ord($sa[$i++]);
else if ($len > 223 && len < 255) $len = (1 << ($len & 0x1f));
} else {
$len = $tag & 3;
$tag = ($tag >> 2) & 15;
if ($len == 0) $len = ord($sa[$i++]);
else if($len == 1) $len = (ord($sa[$i++]) << 8) + ord($sa[$i++]);
else if($len == 2) $len = (ord($sa[$i++]) << 24) + (ord($sa[$i++]) << 16) + (ord($sa[$i++]) << 8) + ord($sa[$i++]);
else $len = strlen($s) - 1;
}
// echo $tag . ' ';
if ($tag == 6 || $tag == 14) {
$k = $i;
$version = ord($sa[$i++]);
$found = 1;
$this->version = $version;
$time = (ord($sa[$i++]) << 24) + (ord($sa[$i++]) << 16) + (ord($sa[$i++]) << 8) + ord($sa[$i++]);
if($version == 2 || $version == 3) $valid = ord($sa[$i++]) << 8 + ord($sa[$i++]);
$algo = ord($sa[$i++]);
if($algo == 1 || $algo == 2) {
$m = $i;
$lm = floor((ord($sa[$i]) * 256 + ord($sa[$i + 1]) + 7) / 8);
$i += $lm + 2;
$mod = substr($s, $m, $lm + 2);
$le = floor((ord($sa[$i]) * 256 + ord($sa[$i+1]) + 7) / 8);
$i += $le + 2;
$this->public_key = base64_encode(substr($s, $m, $lm + $le + 4));
$this->type = "RSA";
if ($version == 3) {
$this->fp = '';
$this->key_id = bin2hex(substr($mod, strlen($mod) - 8, 8));
} else if($version == 4) {
// https://tools.ietf.org/html/rfc4880#section-12
$headerPos = strpos($s, chr(0x04)); // TODO: is this always the correct starting point for the pulic key packet 'version' field?
$delim = chr(0x01) . chr(0x00); // TODO: is this the correct delimiter for the end of the public key packet?
$delimPos = strpos($s, $delim) + (3-$headerPos);
// echo "POSITION: $delimPos\n";
$pkt = chr(0x99) . chr($delimPos >> 8) . chr($delimPos & 255) . substr($s, $headerPos, $delimPos);
// this is the original signing string which seems to have only worked for key lengths of 1024 or less
//$pkt = chr(0x99) . chr($len >> 8) . chr($len & 255) . substr($s, $k, $len);
$fp = sha1($pkt);
$this->fp = $fp;
$this->key_id = substr($fp, strlen($fp) - 16, 16);
// uncomment to debug the start point for the signing string
// for ($ii = 5; $ii > -1; $ii--) {
// $pkt = chr(0x99) . chr($ii >> 8) . chr($ii & 255) . substr($s, $headerPos, $ii);
// $fp = sha1($pkt);
// echo "LENGTH=" . $headerPos . '->' . $ii . " CHR(" . ord(substr($s,$ii, 1)) . ") = " . substr($fp, strlen($fp) - 16, 16) . "\n";
// }
// echo "\n";
// uncomment to debug the end point for the signing string
// for ($ii = strlen($s); $ii > 1; $ii--) {
// $pkt = chr(0x99) . chr($ii >> 8) . chr($ii & 255) . substr($s, $headerPos, $ii);
// $fp = sha1($pkt);
// echo "LENGTH=" . $headerPos . '->' . $ii . " CHR(" . ord(substr($s,$ii, 1)) . ") = " . substr($fp, strlen($fp) - 16, 16) . "\n";
// }
} else {
throw new Exception('GPG Key Version ' . $version . ' is not supported');
}
$found = 2;
} else if(($algo == 16 || $algo == 20) && $version == 4) {
$m = $i;
$lp = floor((ord($sa[$i]) * 256 + ord($sa[$i +1]) + 7) / 8);
$i += $lp + 2;
$lg = floor((ord($sa[$i]) * 256 + ord($sa[$i + 1]) + 7) / 8);
$i += $lg + 2;
$ly = floor((ord($sa[$i]) * 256 + ord($sa[$i + 1]) + 7)/8);
$i += $ly + 2;
$this->public_key = base64_encode(substr($s, $m, $lp + $lg + $ly + 6));
// TODO: should this be adjusted as it was for RSA (above)..?
$pkt = chr(0x99) . chr($len >> 8) . chr($len & 255) . substr($s, $k, $len);
$fp = sha1($pkt);
$this->fp = $fp;
$this->key_id = substr($fp, strlen($fp) - 16, 16);
$this->type = "ELGAMAL";
$found = 3;
} else {
$i = $k + $len;
}
} else if ($tag == 13) {
$this->user = substr($s, $i, $len);
$i += $len;
} else {
$i += $len;
}
}
if($found < 2) {
throw new Exception("Unable to parse Public Key");
// $this->version = "";
// $this->fp = "";
// $this->key_id = "";
// $this->user = "";
// $this->public_key = "";
}
}
function GetExpandedKey()
{
$ek = new Expanded_Key($this->public_key);
}
}
?>

View file

@ -0,0 +1,131 @@
<?php
/** @package php-gpg::GPG */
/** seed rand */
list($gpg_usec, $gpg_sec) = explode(' ', microtime());
srand((float) $gpg_sec + ((float) $gpg_usec * 100000));
/**
* @package php-gpg::GPG
*/
class GPG_Utility
{
static function starts_with($haystack, $needle)
{
return $needle === "" || strpos($haystack, $needle) === 0;
}
static function B0($x) {
return ($x & 0xff);
}
static function B1($x) {
return (($x >> 0x8) & 0xff);
}
static function B2($x) {
return (($x >> 0x10) & 0xff);
}
static function B3($x) {
return (($x >> 0x18) & 0xff);
}
static function zshift($x, $s) {
$res = $x >> $s;
$pad = 0;
for ($i = 0; $i < 32 - $s; $i++) $pad += (1 << $i);
return $res & $pad;
}
static function pack_octets($octets)
{
$i = 0;
$j = 0;
$len = count($octets);
$b = array_fill(0, $len / 4, 0);
if (!$octets || $len % 4) return;
for ($i = 0, $j = 0; $j < $len; $j += 4) {
$b[$i++] = $octets[$j] | ($octets[$j + 1] << 0x8) | ($octets[$j + 2] << 0x10) | ($octets[$j + 3] << 0x18);
}
return $b;
}
static function unpack_octets($packed)
{
$j = 0;
$i = 0;
$l = count($packed);
$r = array_fill(0, $l * 4, 0);
for ($j = 0; $j < $l; $j++) {
$r[$i++] = GPG_Utility::B0($packed[$j]);
$r[$i++] = GPG_Utility::B1($packed[$j]);
$r[$i++] = GPG_Utility::B2($packed[$j]);
$r[$i++] = GPG_Utility::B3($packed[$j]);
}
return $r;
}
static function hex2bin($h)
{
if(strlen($h) % 2) $h += "0";
$r = "";
for($i = 0; $i < strlen($h); $i += 2) {
$r .= chr(intval($h[$i], 16) * 16 + intval($h[$i + 1], 16));
}
return $r;
}
static function crc24($data)
{
$crc = 0xb704ce;
for($n = 0; $n < strlen($data); $n++) {
$crc ^= (ord($data[$n]) & 0xff) << 0x10;
for($i = 0; $i < 8; $i++) {
$crc <<= 1;
if($crc & 0x1000000) $crc ^= 0x1864cfb;
}
}
return
chr(($crc >> 0x10) & 0xff) .
chr(($crc >> 0x8) & 0xff) .
chr($crc & 0xff);
}
static function s_random($len, $textmode)
{
$r = "";
for($i = 0; $i < $len;)
{
$t = rand(0, 0xff);
if($t == 0 && $textmode) continue;
$i++;
$r .= chr($t);
}
return $r;
}
static function c_random() {
return round(rand(0, 0xff));
}
}
?>

View file

@ -0,0 +1,403 @@
<?php
/** @package php-gpg::GPG */
/** assign globals */
global $bs;
global $bx2;
global $bm;
global $bx;
global $bd;
global $bdm;
$bs = 28;
$bx2 = 1 << $bs;
$bm = $bx2 - 1;
$bx = $bx2 >> 1;
$bd = $bs >> 1;
$bdm = (1 << $bd) - 1;
/**
*/
function mpi2b($s)
{
global $bs;
global $bx2;
global $bm;
global $bx;
global $bd;
global $bdm;
$bn = 1;
$r = array(0);
$rn = 0;
$sb = 256;
$c = 0;
$sn = strlen($s);
if($sn < 2) {
echo("string too short, not a MPI");
return 0;
}
$len = ($sn - 2) * 8;
$bits = ord($s[0]) * 256 + ord($s[1]);
if ($bits > $len || $bits < $len - 8) {
echo("not a MPI, bits = $bits, len = $len");
return 0;
}
for ($n = 0; $n < $len; $n++) {
if (($sb <<= 1) > 255) {
$sb = 1; $c = ord($s[--$sn]);
}
if ($bn > $bm) {
$bn = 1;
$r[++$rn]=0;
}
if ($c & $sb) $r[$rn] |= $bn;
$bn <<= 1;
}
return $r;
}
/**
*/
function b2mpi($b)
{
global $bs;
global $bx2;
global $bm;
global $bx;
global $bd;
global $bdm;
$bn = 1;
$bc = 0;
$r = array(0);
$rb = 1;
$rn = 0;
$bits = count($b) * $bs;
$n = 0;
$rr = "";
for ($n = 0; $n < $bits; $n++) {
if ($b[$bc] & $bn) $r[$rn] |= $rb;
if(($rb <<= 1) > 255) {
$rb = 1; $r[++$rn]=0;
}
if (($bn <<= 1) > $bm) {
$bn=1; $bc++;
}
}
while ($rn && $r[$rn]==0) $rn--;
$bn=256;
for($bits = 8; $bits > 0; $bits--) if ($r[$rn] & ($bn >>= 1)) break;
$bits += $rn * 8;
$rr .= chr($bits / 256 ) . chr($bits % 256);
if ($bits) for($n = $rn; $n >= 0; $n--) $rr .= chr($r[$n]);
return $rr;
}
/**
*/
function bmodexp($xx, $y, $m) {
global $bs;
global $bx2;
global $bm;
global $bx;
global $bd;
global $bdm;
$r = array(1);
$an = 0;
$a = 0;
$x = array_merge((array)$xx);
$n = count($m) * 2;
$mu = array_fill(0, $n + 1, 0);
$mu[$n--] = 1;
for(; $n >= 0; $n--) $mu[$n] = 0;
$dd = new bdiv($mu, $m);
$mu = $dd->q;
for($n = 0; $n < count($y); $n++) {
for ($a = 1, $an = 0; $an < $bs; $an++, $a <<= 1) {
if ($y[$n] & $a) $r = bmod2(bmul($r, $x), $m, $mu);
$x = bmod2(bmul($x, $x), $m, $mu);
}
}
return $r;
}
/**
*/
function simplemod($i, $m) // returns the mod where m < 2^bd
{
$c = 0;
$v = 0;
for ($n = count($i) - 1; $n >= 0; $n--)
{
$v = $i[$n];
$c = (($v >> $bd) + ($c << $bd)) % $m;
$c = (($v & $bdm) + ($c << $bd)) % $m;
}
return $c;
}
/**
*/
function bmod($p, $m) // binary modulo
{
global $bdm;
if (count($m) == 1) {
if(count($p) == 1) return array($p[0] % $m[0]);
if($m[0] < $bdm) return array(simplemod($p, $m[0]));
}
$r = new bdiv($p, $m);
return $r->mod;
}
/**
*/
function bmod2($x, $m, $mu) {
$xl = count($x) - (count($m) << 1);
if ($xl > 0) return bmod2(array_concat(array_slice($x, 0, $xl), bmod2(array_slice($x, $xl), $m, $mu)), $m, $mu);
$ml1 = count($m) + 1;
$ml2 = count($m) - 1;
$rr = 0;
$q3 = array_slice(bmul(array_slice($x, $ml2), $mu), $ml1);
$r1 = array_slice($x, 0, $ml1);
$r2 = array_slice(bmul($q3, $m), 0, $ml1);
$r = bsub($r1, $r2);
if (count($r) == 0) {
$r1[$ml1] = 1;
$r = bsub($r1, $r2);
}
for ($n = 0;; $n++) {
$rr = bsub($r, $m);
if(count($rr) == 0) break;
$r = $rr;
if($n >= 3) return bmod2($r, $m, $mu);
}
return $r;
}
/**
*/
function toppart($x, $start, $len) {
global $bx2;
$n = 0;
while ($start >= 0 && $len-- > 0) $n = $n * $bx2 + $x[$start--];
return $n;
}
/**
*/
function zeros($n) {
$r = array_fill(0, $n, 0);
while ($n-- > 0) $r[$n] = 0;
return $r;
}
/**
* @package verysimple::Encryption
*/
class bdiv {
var $q;
var $mod;
function bdiv($x, $y)
{
global $bs;
global $bx2;
global $bm;
global $bx;
global $bd;
global $bdm;
$n = count($x) - 1;
$t = count($y) - 1;
$nmt = $n - $t;
if ($n < $t || $n == $t && ($x[$n] < $y[$n] || $n > 0 && $x[$n] == $y[$n] && $x[$n - 1] < $y[$n - 1])) {
$this->q = array(0);
$this->mod = array($x);
return;
}
if ($n == $t && toppart($x, $t, 2) / toppart($y, $t, 2) < 4) {
$qq = 0;
$xx = 0;
for(;;) {
$xx = bsub($x, $y);
if(count($xx) == 0) break;
$x = $xx; $qq++;
}
$this->q = array($qq);
$this->mod = $x;
return;
}
$shift2 = floor(log($y[$t]) / M_LN2) + 1;
$shift = $bs - $shift2;
if ($shift) {
$x = array_merge((array)$x); $y = array_merge((array)$y);
for($i = $t; $i > 0; $i--) $y[$i] = (($y[$i] << $shift) & $bm) | ($y[$i - 1] >> $shift2);
$y[0] = ($y[0] << $shift) & $bm;
if($x[$n] & (($bm << $shift2) & $bm)) {
$x[++$n] = 0; $nmt++;
}
for($i = $n; $i > 0; $i--) $x[$i] = (($x[$i] << $shift) & $bm) | ($x[$i - 1] >> $shift2);
$x[0] = ($x[0] << $shift) & $bm;
}
$i = 0;
$j = 0;
$x2 = 0;
$q = zeros($nmt + 1);
$y2 = array_merge(zeros($nmt), (array)$y);
for (;;) {
$x2 = bsub($x, $y2);
if(count($x2) == 0) break;
$q[$nmt]++;
$x = $x2;
}
$yt = $y[$t];
$top =toppart($y, $t, 2);
for ($i = $n; $i > $t; $i--) {
$m = $i - $t - 1;
if ($i >= count($x)) $q[$m] = 1;
else if($x[$i] == $yt) $q[$m] = $bm;
else $q[$m] = floor(toppart($x, $i, 2) / $yt);
$topx = toppart($x, $i, 3);
while ($q[$m] * $top > $topx) $q[$m]--;
$y2 = array_slice($y2, 1);
$x2 = bsub($x, bmul(array($q[$m]), $y2));
if (count($x2) == 0) {
$q[$m]--;
$x2 =bsub($x, bmul(array($q[m]), $y2));
}
$x = $x2;
}
if ($shift) {
for($i = 0; $i < count($x) - 1; $i++) $x[$i] = ($x[$i] >> $shift) | (($x[$i + 1] << $shift2) & $bm);
$x[count($x) - 1] >>= $shift;
}
$n = count($q);
while ($n > 1 && $q[$n - 1] == 0) $n--;
$this->q = array_slice($q, 0, $n);
$n = count($x);
while ($n > 1 && $x[$n - 1] == 0) $n--;
$this->mod = array_slice($x, 0, $n);
}
}
/**
*/
function bsub($a, $b) {
global $bs;
global $bx2;
global $bm;
global $bx;
global $bd;
global $bdm;
$al = count($a);
$bl = count($b);
if ($bl > $al) return array();
if ($bl == $al) {
if($b[$bl - 1] > $a[$bl - 1]) return array();
if($bl == 1) return array($a[0] - $b[0]);
}
$r = array_fill(0, $al, 0);
$c = 0;
for ($n = 0; $n < $bl; $n++) {
$c += $a[$n] - $b[$n];
$r[$n] = $c & $bm;
$c >>= $bs;
}
for (; $n < $al; $n++) {
$c += $a[$n];
$r[$n] = $c & $bm;
$c >>= $bs;
}
if ($c) return array();
if ($r[$n - 1]) return $r;
while ($n > 1 && $r[$n - 1] == 0) $n--;
return array_slice($r, 0, $n);
}
/**
*/
function bmul($a, $b) {
global $bs;
global $bx2;
global $bm;
global $bx;
global $bd;
global $bdm;
$b = array_merge((array)$b, array(0));
$al = count($a);
$bl = count($b);
$n = 0;
$nn = 0;
$aa = 0;
$c = 0;
$m = 0;
$g = 0;
$gg = 0;
$h = 0;
$hh = 0;
$ghh = 0;
$ghhb = 0;
$r = zeros($al + $bl + 1);
for ($n = 0; $n < $al; $n++) {
$aa = $a[$n];
if ($aa) {
$c = 0;
$hh = $aa >> $bd; $h = $aa & $bdm;
$m = $n;
for ($nn = 0; $nn < $bl; $nn++, $m++) {
$g = $b[$nn]; $gg = $g >> $bd; $g = $g & $bdm;
$ghh = $g * $hh + $h * $gg;
$ghhb = $ghh >> $bd; $ghh &= $bdm;
$c += $r[$m] + $h * $g + ($ghh << $bd);
$r[$m] = $c & $bm;
$c = ($c >> $bs) + $gg * $hh + $ghhb;
}
}
}
$n = count($r);
if ($r[$n - 1]) return $r;
while ($n > 1 && $r[$n - 1] == 0) $n--;
return array_slice($r, 0, $n);
}
?>

View file

@ -0,0 +1,135 @@
<?php
/**
* @package GPG::Tests
*/
/* ensure the framework libraries can be located */
set_include_path(
realpath("../libs") .
PATH_SEPARATOR . get_include_path()
);
require_once 'PHPUnit/Framework/TestCase.php';
require_once 'GPG.php';
/**
*
*/
class EncryptTest extends PHPUnit_Framework_TestCase
{
/**
* @see PHPUnit_Framework_TestCase::setUp()
*/
function setUp()
{
}
/**
* @see PHPUnit_Framework_TestCase::tearDown()
*/
function tearDown()
{
}
/**
* Return a public key used for encryption
* @return string PGP public key
*/
function getTestKey()
{
return "-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG/MacGPG2 v2.0.22 (Darwin)
Comment: GPGTools - https://gpgtools.org
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
0w==
=Opd1
-----END PGP PUBLIC KEY BLOCK-----";
}
/**
* Test that basic encryption returns a valid encrypted message
*/
function test_Encrypt()
{
// jason's public key
$public_key_ascii = $this->getTestKey();
// plain text message
$plain_text_string = "Whatever 90's tote bag, meggings put a bird on it cray bicycle rights vinyl semiotics Wes Anderson. Selvage Austin umami, letterpress Tumblr deep v kitsch polaroid. Trust fund messenger bag sartorial gluten-free, cred cray church-key pop-up Intelligentsia. Food truck Tumblr paleo mixtape XOXO banjo PBR&B Pinterest tofu banh mi. Portland messenger bag cornhole PBR Tonx High Life, DIY pork belly bespoke hoodie Terry Richardson dreamcatcher ethical forage. Put a bird on it slow-carb mixtape cardigan craft beer messenger bag. Aesthetic twee art party, Odd Future trust fund banjo ugh small batch semiotics.
Whatever asymmetrical keffiyeh literally narwhal. Keytar Odd Future blog, wayfarers literally gluten-free beard. Authentic Cosby sweater sustainable hashtag, VHS food truck kogi seitan put a bird on it YOLO. Selvage tousled mustache, flannel craft beer try-hard McSweeney's literally four loko YOLO keytar beard synth forage. Salvia Schlitz narwhal Terry Richardson typewriter, Wes Anderson butcher wolf. Slow-carb whatever bitters, letterpress trust fund pug before they sold out food truck artisan tousled. Church-key Vice craft beer Wes Anderson artisan flexitarian, kogi YOLO hella Tonx chia Neutra.
Farm-to-table actually Portland, artisan shabby chic vinyl organic seitan roof party distillery. Street art PBR&B banh mi, Tonx authentic you probably haven't heard of them fixie whatever tofu gluten-free. Gentrify locavore lo-fi umami, Thundercats salvia wolf four loko. Mixtape messenger bag gluten-free, squid American Apparel hella Shoreditch whatever selfies sriracha before they sold out. Pickled farm-to-table Intelligentsia occupy. Tumblr Etsy farm-to-table, mlkshk hella shabby chic meh jean shorts dreamcatcher fashion axe trust fund lomo Neutra. Freegan vegan narwhal tousled hoodie wolf flexitarian.
Flannel sriracha XOXO, slow-carb Godard ennui tousled American Apparel street art drinking vinegar lo-fi blog. Whatever Intelligentsia cardigan, Pinterest PBR&B pop-up semiotics. Jean shorts chillwave semiotics biodiesel. McSweeney's fap cardigan messenger bag fanny pack Cosby sweater Odd Future, Pitchfork four loko Marfa keytar mlkshk. 3 wolf moon McSweeney's gluten-free, umami freegan biodiesel fingerstache aesthetic sriracha swag Echo Park. Shabby chic selfies fixie, art party XOXO four loko chambray post-ironic letterpress messenger bag. Mustache beard lo-fi, flexitarian artisan tofu freegan occupy kale chips Carles twee chia bespoke.";
$gpg = new GPG();
$pub_key = new GPG_Public_Key($public_key_ascii);
$encrypted = $gpg->encrypt($pub_key,$plain_text_string);
$this->assertContains('-----BEGIN PGP MESSAGE-----', $encrypted, 'PGP Header Expected');
$this->assertContains('-----END PGP MESSAGE-----', $encrypted, 'PGP Footer Expected');
}
}
?>

View file

@ -0,0 +1,1474 @@
<?php
/**
* @package GPG::Tests
*/
/* ensure the framework libraries can be located */
set_include_path(
realpath("../libs") .
PATH_SEPARATOR . get_include_path()
);
require_once 'PHPUnit/Framework/TestCase.php';
require_once 'GPG.php';
/**
*
*/
class KeyTest extends PHPUnit_Framework_TestCase
{
/**
* @see PHPUnit_Framework_TestCase::setUp()
*/
function setUp()
{
}
/**
* @see PHPUnit_Framework_TestCase::tearDown()
*/
function tearDown()
{
}
function getGnuPGDSAKey()
{
return "-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG/MacGPG2 v2.0.22 (Darwin)
Comment: GPGTools - https://gpgtools.org
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
+ZVkIBkLx7SrbZW6Mogi3f2ViQIcBBMBAgAGBQJPUMRhAAoJEOD9KQZtDBSx0ckQ
ALAH7uPyQQ30HRM/Y55Ls38YRzGb8zn5vdmU8TNg3F3veHXKU+qa2MglcQLD0wm4
x7w3JaF8GPLN5YRaDtOoKcbRq5pMqw/bQLLlrX7ZjRzIDkOFOhC9jw3W15M/J8jI
v/xtf3O727eGvs/orXJF9+iCsBRPIG+0PssLdK8q+4CudRoC7quoxlpRwglW6yan
BPAElyxMNS3fM9B0sVWRfW+gtBa1VtAZZm+5h4mxybUln96cRBo2LGrJ28i9pc79
dIfUJMX6XOC7OFZJ5eHlwjPqQLplcE/yjlmHYBcoX62CIxyIV7CV98YOIZ3KrPFr
Qe+Ad+Ho/yuMVU9C29e8ahugvmSvOodL3R2FiiG3S174FRW9yXRm22WrB82A2LPV
LtHyRJ97A+LT7a8l3xTm0mCku+9+eiYE+vJY1Lbg7IznPP3junvOO/51Mebb/KdZ
j6lzx1h5bAzoyH4AOMwb0ZOFadaaw8Ks03AZSWBD71DdFjxtKpib3VeKJ0YQDWk/
gYdh+6RENzuyz97sOHPFwuriw19K5FHUgTSFvjHDSlg6e2kqLNHzVM5RX4grlZxc
AZTBlrbEppqoN69qEvnv9luK3IYviHtdaCpsMnT1HVG9HRiuAKg+JhxIdCYczmge
iUMRCJ3D8JdR6gQ6A4OgZqubAkz3SvXTgIElh4c2N9AviQIcBBMBAgAGBQJPoLUx
AAoJEG8wgEnVsL7DK/QQAMcgtYvGApHP2XGjAACfFFQLl19MC3M5dQJVoU4h5AM9
GYQaP4vMDmNWF/xNp4pzhi7J7DcU6UQ/J8a/PESuLHylBrMHzF1ao5Wvgmcv11mP
3byWKcDcyN/WuXQn7/UQai8MQfapmkaJmutqSmkEh6sPyIx98ftEv8fgaw+gH/Q/
XCqlMvyPiMKH3EdUx1eOwhS5y2GGzF1+MQQzDaRVDns4XCIUCNGigkJ0S9n2adyR
jpEhkf/YhLgrfdAXaVIIfvaqi46ItzqJYMhqy3qID62a5QxAiInbV/kL82dCjLTl
TvknCdN+3h8Pgba4jIr9X4CMqMxKxvRg4I3qisbsC3k9gdYgJEXZyroPlxunHx2r
wkrOqjPYt5+67O6EGHiNaH4dil/uDjbBk1B+s2yobmm5VPqATpivK5XnzDTm2NHp
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
GiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOE
hYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX
2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAfAQADAQEBAQEBAQEBAAAAAAAAAQID
BAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIy
gQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpT
VFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeo
qaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/
2gAMAwEAAhEDEQA/AP38ooooAKKKra1rNn4c0e71HxDdW9jYWEL3Fzc3Egjit4kU
s7u7EBVVQSSTgAE0AWa8Q+LX7fHgn4eeLH8L+ChqXj3xmp2nRPDkBvJoW44mdfki
xnnJyO4rxvUvi14w/wCCizy3Hw+1XVvht+z6rtCmtQKYNe+IABwxsgw3WlicECUj
fIORhTitvVPHvgX9jHwAmi/CbR7Dw3bOMR2tou68vWx96aU5eRj6kmgDobz4iftA
+Po/PTTvA3ws01xlf7Vu/t9+o7ZSMFM+xxXP3uleLyxPjD9owxzHkrp2iLEg9h+9
/pXmNpH8Xf2mbx5fCenS6Zprnie4JGF9TngVHf8A7J1vo8pT4ofGHwzpl5/HD9vQ
uh9CAc0Aep2OkeMgwPgv9otZpgchNS0VZFb2J8w/yret/ib+0D8O4/PvdE8F/FLT
EwWbRrz7HfsO5EbhV6dgGNeH6f8AslLrUgX4UfF3w1q93/DAt+gdj6BSc06bUPi1
+zHfq3jXTJ7/AE5DzNb5PHqMcGgD6a+Df7evgb4qeKB4a8QPf+CvGQIQ6H4ggNlc
yN6RF8LJnHAB3H0r2yvkiLxN8P8A9tzwCdM+LOj2fiCKIYxKPK1DTm/vQzDDow9j
9c1z2lfHXxl/wTiv7KL476xqHxD+AF3Mlrb+MJlMmr+B2Y7UTVQOZrTJA+0DlP4v
l+6AfbFFQ6fqFvq1hBd6VPDdWt1GssM0Th45UYZVlYcMCCCCOCDU1ABRRRQAUUUU
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
Bo827CdOXA==
=nadi
-----END PGP PUBLIC KEY BLOCK-----";
}
/**
* Return a public key used for encryption
* @return string PGP public key
*/
function getOpenPGPTestKey1()
{
return "-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: OpenPGP.js v.1.20140106
Comment: http://openpgpjs.org
xo0EUsvlVAEEAJN0OBFbVM21z3OzG9DDCohpaF9+rWUyCreRIDC+Cou9680f
t8v5m9B0+BTM2OVEB3uK7QbcWhsPkfpn7zW9YntStSXI5ESC+eAhNGbAKnvq
32MadP7DbwRUrtcldSEd2B6uI/embnmv1CBkmrTAh0MiKscHPh5xrxwcxLLJ
TQstABEBAAHNF1Rlc3QgPHRlc3RAZXhhbXBsZS5jb20+wpwEEAEIABAFAlLL
5VUJEI3OSY9gkd/WAAAgKwP/TUeVmXMS3YYvTLC0tRw/Ae1M4sNduvuKcza2
4l6iuiIhXHntL9u5pQERcyhzL171DsR1S3EUj/nIFpfqN8OWOuj0Wqt3H4F9
igkfsrJr68qHEQztSXRufP/jv7OX+0EF+ve0+IFa6r5LPRmibl0qta522gHd
2LVudfBDDi0Y6k4=
=JjPg
-----END PGP PUBLIC KEY BLOCK-----";
}
/**
* Return a public key used for encryption
* @return string PGP public key
*/
function getOpenPGPTestKey2()
{
return "-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: OpenPGP.js v.1.20140106
Comment: http://openpgpjs.org
xsBNBFLL5JEBCACFBaNfA4Iicm/MvO0sJcllB/iGc0qNgtqwpXGBydDt8Pj7
+mn0ZZ4Q1ol5wAYAxapGGaoEB1Wh5ALy2UvnrFx1/dyZEQhU3oUTRQevzhm1
/gp/0l9bNijBONir1spMuDc7okXWaR8GCW0mWwmeFgXZnjL4Dmr6dUJvZHpX
ZiekLPT3xHWQxrKdsafxmULVgd71ZdBq/6ikWQsK5XqBVykD2C/6jNDJ8Cga
wzCs8WOSQkpss7L28qQrEkL3+JaLGEe3+6UUnzs5KjwgTZvlAawDkm55corz
TistbvOotDVbs/nXyu6TnMhZXqJR2a0TEuRDXpS93qGr97flZKwVBp6vABEB
AAHNF1Rlc3QgPHRlc3RAZXhhbXBsZS5jb20+wsBcBBABCAAQBQJSy+SZCRDI
dThpeYYhmgAAVecH/R2IXW82smV41eDIwA9PzV6sKF7ywmlEl/zkZTEpTLaB
bXM3wScspVHGWV7hO+9ZQImtdcqb2AFpNpBgBtpFypM2nMGdFxTzv0m3uRUs
J8KT0lU0Uj4FEsr5YYCb1UWGgDrZP+vZFxfw8j+NWGIS5NlLHPeTTMJVRhKX
Xe0c8AaAF8qz10+JyapyDlUlFVr8+n/UjGwsUp15ODnDt0nsGTfw6jKelTU2
y/d0ckERWE0rWT2eooAxqxIoVayJkEZTzbfx/mHJXeGhOFwjg5danv7JnDI/
FHAUVqBD8zTkqmjdk9LZ6GnF6tuKRAWS59qU7y4+fchP58dhjep0mIFa6FQ=
=8aNP
-----END PGP PUBLIC KEY BLOCK-----";
}
/**
* Return a public key used for encryption
* @return string PGP public key
*/
function getGnuPGTestKey()
{
return "-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG/MacGPG2 v2.0.22 (Darwin)
Comment: GPGTools - https://gpgtools.org
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
0w==
=Opd1
-----END PGP PUBLIC KEY BLOCK-----";
}
/**
* Test key ID
*/
function test_VerifyGnuPGKey()
{
// jason's public key
$public_key_ascii = $this->getGnuPGTestKey();
$gpg = new GPG();
$pub_key = new GPG_Public_Key($public_key_ascii);
$this->assertEquals(PK_TYPE_RSA,$pub_key->GetKeyType(),'OpenPGP Incorrect Key Type');
$this->assertEquals('47009B66424E9476',$pub_key->GetKeyId(),'OpenPGP Incorrect Key ID');
$this->assertEquals('ED4F E89E 38A3 7833 3CD4 D6FA 4700 9B66 424E 9476',$pub_key->GetFingerprint(),'OpenPGP Incorrect Fingerprint');
}
/**
* Test key ID
*/
function test_VerifyOpenPGPKey1()
{
// OpenPGP Test Key
$public_key_ascii = $this->getOpenPGPTestKey1();
$gpg = new GPG();
$pub_key = new GPG_Public_Key($public_key_ascii);
$this->assertEquals(PK_TYPE_RSA,$pub_key->GetKeyType(),'OpenPGP Incorrect Key Type');
$this->assertEquals('8DCE498F6091DFD6',$pub_key->GetKeyId(),'OpenPGP Incorrect Key ID');
$this->assertEquals('C893 35AC EDF1 6046 7534 B25E 8DCE 498F 6091 DFD6',$pub_key->GetFingerprint(),'OpenPGP Incorrect Fingerprint');
}
/**
* Test key ID
*/
function test_VerifyOpenPGPKey2()
{
// OpenPGP Test Key
$public_key_ascii = $this->getOpenPGPTestKey2();
$gpg = new GPG();
$pub_key = new GPG_Public_Key($public_key_ascii);
$this->assertEquals(PK_TYPE_RSA,$pub_key->GetKeyType(),'OpenPGP Incorrect Key Type');
$this->assertEquals('C87538697986219A',$pub_key->GetKeyId(),'OpenPGP Incorrect Key ID');
$this->assertEquals('3C05 9D07 C624 84A4 EF2D 3651 C875 3869 7986 219A',$pub_key->GetFingerprint(),'OpenPGP Incorrect Fingerprint');
}
function test_VerifyGnuPGDSAKey()
{
// OpenPGP Test Key
$public_key_ascii = $this->getGnuPGDSAKey();
$gpg = new GPG();
$pub_key = new GPG_Public_Key($public_key_ascii);
$this->assertEquals(PK_TYPE_ELGAMAL,$pub_key->GetKeyType(),'OpenPGP Incorrect Key Type');
$this->assertEquals('76D78F0500D026C4',$pub_key->GetKeyId(),'OpenPGP Incorrect Key ID');
$this->assertEquals('85E3 8F69 046B 44C1 EC9F B07B 76D7 8F05 00D0 26C4',$pub_key->GetFingerprint(),'OpenPGP Incorrect Fingerprint');
}
}
?>

View file

@ -0,0 +1,4 @@
##
# Test runner for Phreeze
##
phpunit gpg/

93
securemail/securemail.php Normal file
View file

@ -0,0 +1,93 @@
<?php
/**
* Name: Secure Mail
* Description: Send notification mail encrypted with user-defined public GPG key
* Version: 1.0
* Author: Fabio Comuni <http://kirgroup.com/profile/fabrixxm>
*/
require_once 'php-gpg/libs/GPG.php';
function securemail_install() {
register_hook('plugin_settings', 'addon/securemail/securemail.php', 'securemail_settings');
register_hook('plugin_settings_post', 'addon/securemail/securemail.php', 'securemail_settings_post');
register_hook('emailer_send_prepare', 'addon/securemail/securemail.php', 'securemail_emailer_send_prepare');
logger("installed securemail");
}
function securemail_uninstall() {
unregister_hook('plugin_settings', 'addon/securemail/securemail.php', 'securemail_settings');
unregister_hook('plugin_settings_post', 'addon/securemail/securemail.php', 'securemail_settings_post');
unregister_hook('emailer_send_prepare', 'addon/securemail/securemail.php', 'securemail_emailer_send_prepare');
logger("removed securemail");
}
function securemail_settings(&$a,&$s){
if(! local_user())
return;
$enable_checked = (intval(get_pconfig(local_user(),'securemail','enable')) ? ' checked="checked"' : '');
$publickey = get_pconfig(local_user(),'securemail','pkey');
# all of this should be in a template...
$s .= '<span id="settings_securemail_inflated" class="settings-block fakelink" style="display: block;" onclick="openClose(\'settings_securemail_expanded\'); openClose(\'settings_securemail_inflated\');">';
$s .= '<h3>' . t('"Secure Mail" Settings').'</h3>';
$s .= '</span>';
$s .= '<div id="settings_securemail_expanded" class="settings-block" style="display: none;">';
$s .= '<span class="fakelink" onclick="openClose(\'settings_securemail_expanded\'); openClose(\'settings_securemail_inflated\');">';
$s .= '<h3>' . t('"Secure Mail" Settings').'</h3>';
$s .= '</span>';
$s .= '<div id="securemail-wrapper">';
$s .= '<input id="securemail-enable" type="checkbox" name="securemail-enable" value="1"'.$enable_checked.' />';
$s .= '<label id="securemail-enable-label" for="securemail-enable">'.t('Enable Secure Mail').'</label>';
$s .= '<div class="clear"></div>';
$s .= '<label id="securemail-label" for="securemail-pkey">'.t('Public key').' </label>';
$s .= '<textarea id="securemail-pkey" name="securemail-pkey">'.$publickey.'</textarea>';
$s .= '</div><div class="clear"></div>';
$s .= '<div class="settings-submit-wrapper" ><input type="submit" id="securemail-submit" name="securemail-submit" class="settings-submit" value="' . t('Save Settings') . '" /></div>';
$s .= '</div>';
return;
}
function securemail_settings_post(&$a, &$b){
if(! local_user())
return;
if($_POST['securemail-submit']) {
set_pconfig(local_user(),'securemail','pkey',trim($_POST['securemail-pkey']));
$enable = ((x($_POST,'securemail-enable')) ? 1 : 0);
set_pconfig(local_user(),'securemail','enable', $enable);
info( t('Secure Mail Settings saved.') . EOL);
}
}
function securemail_emailer_send_prepare(&$a, &$b) {
if (!x($b,'uid')) return;
$uid = $b['uid'];
$enable_checked = get_pconfig($uid,'securemail','enable');
if (!$enable_checked) return;
$public_key_ascii = get_pconfig($uid,'securemail','pkey');
$gpg = new GPG();
# create an instance of a GPG public key object based on ASCII key
$pub_key = new GPG_Public_Key($public_key_ascii);
# using the key, encrypt your plain text using the public key
$txt_encrypted = $gpg->encrypt($pub_key,$b['textVersion']);
$html_encrypted = $gpg->encrypt($pub_key,$b['htmlVersion']);
$b['textVersion'] = $txt_encrypted;
$b['htmlVersion'] = $html_encrypted;
#var_dump($b);
}