1<?php
2
3require_once __DIR__ . "/vars.inc";
4
5class gnupgt {
6    /**
7     * Import all keys
8     */
9    static public function import_key()
10    {
11        global $testkey;
12
13        self::reset_key();
14
15        $gpg = new gnupg();
16        $gpg->import($testkey);
17    }
18
19    /**
20     * Delete all keys.
21     * @param null|string $homeDir
22     */
23    static public function delete_key($homeDir = null)
24    {
25        if (is_null($homeDir)) {
26            $homeDir = self::get_home_dir();
27        }
28        if (!is_dir($homeDir)) {
29            return;
30        }
31        foreach (glob($homeDir . '/*') as $filename) {
32            if (!is_dir($filename)) {
33                unlink($filename);
34            }
35        }
36        $privKeyDir = self::get_priv_key_dir($homeDir);
37        if (is_dir($privKeyDir)) {
38            foreach (glob($privKeyDir . '/*') as $key) {
39                unlink($key);
40            }
41            rmdir($privKeyDir);
42        }
43        rmdir($homeDir);
44    }
45
46    /**
47     * Initialize key directory.
48     */
49    static public function init_key_dir()
50    {
51        mkdir(self::get_home_dir());
52        mkdir(self::get_priv_key_dir(), 0700);
53    }
54
55    /**
56     * Reset all keys.
57     */
58    static public function reset_key()
59    {
60        self::delete_key();
61        self::init_key_dir();
62    }
63
64    /**
65     * Get home directory.
66     *
67     * @return string
68     */
69    static private function get_home_dir()
70    {
71        return __DIR__ . '/home';
72    }
73
74    /**
75     * Get private key directory (for GPG2).
76     * @param null|string $homeDir
77     * @return string
78     */
79    static private function get_priv_key_dir($homeDir = null)
80    {
81        if (is_null($homeDir)) {
82            $homeDir = self::get_home_dir();
83        }
84        return $homeDir . '/private-keys-v1.d';
85    }
86
87    /**
88     * Print error message and return false.
89     *
90     * @param string $msg
91     * @return bool
92     */
93    static private function error($msg)
94    {
95        echo "ERROR: " . $msg;
96        return false;
97    }
98
99    /**
100     * Check single array value.
101     *
102     * @param mixed $expected
103     * @param array $a
104     * @param string $key1
105     * @return bool
106     */
107    static public function check_array($expected, $a, $key1)
108    {
109        $args = func_get_args();
110        $keys = array_splice($args, 2);
111        $value = $a;
112        foreach ($keys as $key) {
113            if (!isset($value[$key])) {
114                return self::error("key $key not found in the array");
115            }
116            $value = $value[$key];
117        }
118        if ($value !== $expected) {
119
120            return self::error(
121                sprintf(
122                    "key %s value %s does not match expected %s\n",
123                    $key,
124                    var_export($value, true),
125                    var_export($expected, true)
126                )
127            );
128        }
129
130        return true;
131    }
132
133    /**
134     * Check single array value but only for GpgME version higher than supplied.
135     *
136     * @param mixed $expected
137     * @param array $a
138     * @param string $key1
139     * @return bool
140     */
141    static public function check_array_from_version($version, $expected, $a, $key1)
142    {
143        if (version_compare(GNUPG_GPGME_VERSION,  $version) < 0) {
144            return true;
145        }
146
147        $args = func_get_args();
148        return call_user_func_array('gnupgt::check_array', array_splice($args, 1));
149    }
150
151    /**
152     * Check keyinfo for var key
153     *
154     * @param $ret
155     * @param $secret_only
156     */
157    static public function check_keyinfo($ret, $secret_only) {
158        self::check_array(false, $ret, 0, 'disabled');
159        self::check_array(false, $ret, 0, 'expired');
160        self::check_array(false, $ret, 0, 'revoked');
161        self::check_array($secret_only, $ret, 0, 'is_secret');
162        self::check_array(true, $ret, 0, 'can_sign');
163        self::check_array(true, $ret, 0, 'can_encrypt');
164        // uid
165        self::check_array('PHP GnuPG', $ret, 0, 'uids', 0, 'name');
166        self::check_array('', $ret, 0, 'uids', 0, 'comment');
167        self::check_array('gnupg@php.net', $ret, 0, 'uids', 0, 'email');
168        self::check_array('PHP GnuPG <gnupg@php.net>', $ret, 0, 'uids', 0, 'uid');
169        self::check_array(false, $ret, 0, 'uids', 0, 'revoked');
170        self::check_array(false, $ret, 0, 'uids', 0, 'invalid');
171        self::check_array(false, $ret, 0, 'uids', 0, 'invalid');
172        // subkey 1
173        self::check_array("2DF0DD02DC9B70B7F64F572E669E775E0A6284B3", $ret, 0, 'subkeys', 0, 'fingerprint');
174        self::check_array("669E775E0A6284B3", $ret, 0, 'subkeys', 0, 'keyid');
175        self::check_array(1567958444, $ret, 0, 'subkeys', 0, 'timestamp');
176        self::check_array(0, $ret, 0, 'subkeys', 0, 'expires');
177        self::check_array($secret_only, $ret, 0, 'subkeys', 0, 'is_secret');
178        self::check_array(false, $ret, 0, 'subkeys', 0, 'can_encrypt');
179        self::check_array(true, $ret, 0, 'subkeys', 0, 'can_sign');
180        self::check_array(false, $ret, 0, 'subkeys', 0, 'disabled');
181        self::check_array(false, $ret, 0, 'subkeys', 0, 'expired');
182        self::check_array(false, $ret, 0, 'subkeys', 0, 'revoked');
183        self::check_array(true, $ret, 0, 'subkeys', 0, 'can_certify');
184        self::check_array(false, $ret, 0, 'subkeys', 0, 'can_authenticate');
185        self::check_array(false, $ret, 0, 'subkeys', 0, 'is_qualified');
186        // TODO: The is_de_vs seems to differ between gpg2 (true) and gpg1 (false) - differenatiate the test
187        //self::check_array_from_version('1.9.0', true, $ret, 0, 'subkeys', 0, 'is_de_vs');
188        self::check_array(GNUPG_PK_RSA, $ret, 0, 'subkeys', 0, 'pubkey_algo');
189        self::check_array(2048, $ret, 0, 'subkeys', 0, 'length');
190        self::check_array_from_version('1.7.0', false, $ret, 0, 'subkeys', 0, 'is_cardkey');
191        // subkey 2
192        self::check_array("9E84AE800874DFF647B6062B46DCA9B3662C7DFC", $ret, 0, 'subkeys', 1, 'fingerprint');
193        self::check_array("46DCA9B3662C7DFC", $ret, 0, 'subkeys', 1, 'keyid');
194        self::check_array(1567958444, $ret, 0, 'subkeys', 1, 'timestamp');
195        self::check_array(0, $ret, 0, 'subkeys', 1, 'expires');
196        self::check_array($secret_only, $ret, 0, 'subkeys', 1, 'is_secret');
197        self::check_array(true, $ret, 0, 'subkeys', 1, 'can_encrypt');
198        self::check_array(false, $ret, 0, 'subkeys', 1, 'can_sign');
199        self::check_array(false, $ret, 0, 'subkeys', 1, 'disabled');
200        self::check_array(false, $ret, 0, 'subkeys', 1, 'expired');
201        self::check_array(false, $ret, 0, 'subkeys', 1, 'revoked');
202        self::check_array(false, $ret, 0, 'subkeys', 1, 'can_certify');
203        self::check_array(false, $ret, 0, 'subkeys', 1, 'can_authenticate');
204        self::check_array(false, $ret, 0, 'subkeys', 1, 'is_qualified');
205        // TODO: The is_de_vs seems to differ between gpg2 (true) and gpg1 (false) - differenatiate the test
206        // self::check_array_from_version('1.9.0', true, $ret, 0, 'subkeys', 1, 'is_de_vs');
207        self::check_array(GNUPG_PK_RSA, $ret, 0, 'subkeys', 1, 'pubkey_algo');
208        self::check_array(2048, $ret, 0, 'subkeys', 1, 'length');
209        self::check_array_from_version('1.7.0', false, $ret, 0, 'subkeys', 1, 'is_cardkey');
210    }
211}
212