Compare commits
137 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
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 |
6
.travis.yml
Normal file
6
.travis.yml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
language: php
|
||||||
|
php:
|
||||||
|
- "5.4"
|
||||||
|
- "5.3"
|
||||||
|
before_script:
|
||||||
|
- composer install --prefer-source --dev
|
1
AUTHORS
1
AUTHORS
@@ -1 +1,2 @@
|
|||||||
* Arto Bendiken <arto.bendiken@gmail.com>
|
* Arto Bendiken <arto.bendiken@gmail.com>
|
||||||
|
* Stephen Paul Weber <singpolyma@singpolyma.net>
|
||||||
|
10
README.md
10
README.md
@@ -22,6 +22,15 @@ Features
|
|||||||
* Encodes and decodes ASCII-armored OpenPGP messages.
|
* Encodes and decodes ASCII-armored OpenPGP messages.
|
||||||
* Parses OpenPGP messages into their constituent packets.
|
* Parses OpenPGP messages into their constituent packets.
|
||||||
* Supports both old-format (PGP 2.6.x) and new-format (RFC 4880) packets.
|
* Supports both old-format (PGP 2.6.x) and new-format (RFC 4880) packets.
|
||||||
|
* Helper class for verifying, signing, encrypting, and decrypting messages using Crypt_RSA from <http://phpseclib.sourceforge.net>
|
||||||
|
* Helper class for encrypting and decrypting messages and keys using Crypt_AES and Crypt_TripleDES from <http://phpseclib.sourceforge.net>
|
||||||
|
|
||||||
|
Users
|
||||||
|
-----
|
||||||
|
|
||||||
|
OpenPGP.php is currently being used in the following projects:
|
||||||
|
|
||||||
|
* <http://drupal.org/project/openpgp>
|
||||||
|
|
||||||
Download
|
Download
|
||||||
--------
|
--------
|
||||||
@@ -39,6 +48,7 @@ Authors
|
|||||||
-------
|
-------
|
||||||
|
|
||||||
* [Arto Bendiken](mailto:arto.bendiken@gmail.com) - <http://ar.to/>
|
* [Arto Bendiken](mailto:arto.bendiken@gmail.com) - <http://ar.to/>
|
||||||
|
* [Stephen Paul Weber](mailto:singpolyma@singpolyma.net) - <http://singpolyma.net/>
|
||||||
|
|
||||||
License
|
License
|
||||||
-------
|
-------
|
||||||
|
24
composer.json
Normal file
24
composer.json
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"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": {
|
||||||
|
"phpseclib/phpseclib": "~0.3"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "~4.0"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"classmap": ["lib/"]
|
||||||
|
}
|
||||||
|
}
|
25
examples/clearsign.php
Normal file
25
examples/clearsign.php
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?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);
|
||||||
|
|
||||||
|
/* Generate clearsigned data */
|
||||||
|
$packets = $m->signatures()[0];
|
||||||
|
echo "-----BEGIN PGP SIGNED MESSAGE-----\nHash: SHA256\n\n";
|
||||||
|
echo preg_replace("/^-/", "- -", $packets[0]->data)."\n";
|
||||||
|
echo OpenPGP::enarmor($packets[1][0]->to_bytes(), "PGP SIGNATURE");
|
||||||
|
|
||||||
|
?>
|
27
examples/deASCIIdeCrypt.php
Normal file
27
examples/deASCIIdeCrypt.php
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?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
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
15
examples/encryptDecrypt.php
Normal file
15
examples/encryptDecrypt.php
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?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);
|
24
examples/keygen.php
Normal file
24
examples/keygen.php
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once dirname(__FILE__).'/../lib/openpgp.php';
|
||||||
|
require_once dirname(__FILE__).'/../lib/openpgp_crypt_rsa.php';
|
||||||
|
|
||||||
|
$rsa = new 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[1]->toBytes(),
|
||||||
|
'q' => $rsa->primes[2]->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));
|
||||||
|
|
||||||
|
print $m->to_bytes();
|
22
examples/sign.php
Normal file
22
examples/sign.php
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?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();
|
||||||
|
|
||||||
|
?>
|
18
examples/verify.php
Normal file
18
examples/verify.php
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?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));
|
||||||
|
|
||||||
|
?>
|
1375
lib/openpgp.php
1375
lib/openpgp.php
File diff suppressed because it is too large
Load Diff
261
lib/openpgp_crypt_rsa.php
Normal file
261
lib/openpgp_crypt_rsa.php
Normal file
@@ -0,0 +1,261 @@
|
|||||||
|
<?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/
|
||||||
|
require_once 'Crypt/RSA.php';
|
||||||
|
|
||||||
|
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);
|
||||||
|
$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) {
|
||||||
|
if($packet->key['p'] && $packet->key['q']) $rsa->primes = array($packet->key['p'], $packet->key['q']);
|
||||||
|
if($packet->key['u']) $rsa->coefficients = array($packet->key['u']);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
196
lib/openpgp_crypt_symmetric.php
Normal file
196
lib/openpgp_crypt_symmetric.php
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once dirname(__FILE__).'/openpgp.php';
|
||||||
|
@include_once dirname(__FILE__).'/openpgp_crypt_rsa.php';
|
||||||
|
@include_once dirname(__FILE__).'/openpgp_mcrypt_wrapper.php';
|
||||||
|
@include_once 'Crypt/AES.php';
|
||||||
|
@include_once 'Crypt/TripleDES.php';
|
||||||
|
require_once 'Crypt/Random.php'; // part of phpseclib is absolutely required
|
||||||
|
|
||||||
|
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 = crypt_random_string($key_block_bytes);
|
||||||
|
$prefix .= substr($prefix, -2);
|
||||||
|
|
||||||
|
$key = crypt_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(crypt_random_string(10));
|
||||||
|
$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 2:
|
||||||
|
if(class_exists('Crypt_TripleDES')) {
|
||||||
|
$cipher = new Crypt_TripleDES(CRYPT_DES_MODE_CFB);
|
||||||
|
$key_bytes = 24;
|
||||||
|
$key_block_bytes = 8;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if(defined('MCRYPT_CAST_128')) {
|
||||||
|
$cipher = new MCryptWrapper(MCRYPT_CAST_128);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
if(class_exists('Crypt_AES')) {
|
||||||
|
$cipher = new Crypt_AES(CRYPT_AES_MODE_CFB);
|
||||||
|
$cipher->setKeyLength(128);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
if(class_exists('Crypt_AES')) {
|
||||||
|
$cipher = new Crypt_AES(CRYPT_AES_MODE_CFB);
|
||||||
|
$cipher->setKeyLength(192);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
if(class_exists('Crypt_AES')) {
|
||||||
|
$cipher = new Crypt_AES(CRYPT_AES_MODE_CFB);
|
||||||
|
$cipher->setKeyLength(256);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(!$cipher) return array(NULL, NULL, NULL); // Unsupported cipher
|
||||||
|
if(!isset($key_bytes)) $key_bytes = $cipher->key_size;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
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.
BIN
tests/data/compressedsig-zlib.gpg
Normal file
BIN
tests/data/compressedsig-zlib.gpg
Normal file
Binary file not shown.
BIN
tests/data/compressedsig.gpg
Normal file
BIN
tests/data/compressedsig.gpg
Normal file
Binary file not shown.
BIN
tests/data/encryptedSecretKey.gpg
Normal file
BIN
tests/data/encryptedSecretKey.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