Mercurial > hg > rc1
comparison vendor/pear/crypt_gpg/Crypt/GPG/SubKey.php @ 0:1e000243b222
vanilla 1.3.3 distro, I hope
author | Charlie Root |
---|---|
date | Thu, 04 Jan 2018 15:50:29 -0500 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:1e000243b222 |
---|---|
1 <?php | |
2 | |
3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ | |
4 | |
5 /** | |
6 * Contains a class representing GPG sub-keys and constants for GPG algorithms | |
7 * | |
8 * PHP version 5 | |
9 * | |
10 * LICENSE: | |
11 * | |
12 * This library is free software; you can redistribute it and/or modify | |
13 * it under the terms of the GNU Lesser General Public License as | |
14 * published by the Free Software Foundation; either version 2.1 of the | |
15 * License, or (at your option) any later version. | |
16 * | |
17 * This library is distributed in the hope that it will be useful, | |
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
20 * Lesser General Public License for more details. | |
21 * | |
22 * You should have received a copy of the GNU Lesser General Public | |
23 * License along with this library; if not, see | |
24 * <http://www.gnu.org/licenses/> | |
25 * | |
26 * @category Encryption | |
27 * @package Crypt_GPG | |
28 * @author Michael Gauthier <mike@silverorange.com> | |
29 * @author Nathan Fredrickson <nathan@silverorange.com> | |
30 * @copyright 2005-2010 silverorange | |
31 * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 | |
32 * @link http://pear.php.net/package/Crypt_GPG | |
33 */ | |
34 | |
35 // {{{ class Crypt_GPG_SubKey | |
36 | |
37 /** | |
38 * A class for GPG sub-key information | |
39 * | |
40 * This class is used to store the results of the {@link Crypt_GPG::getKeys()} | |
41 * method. Sub-key objects are members of a {@link Crypt_GPG_Key} object. | |
42 * | |
43 * @category Encryption | |
44 * @package Crypt_GPG | |
45 * @author Michael Gauthier <mike@silverorange.com> | |
46 * @author Nathan Fredrickson <nathan@silverorange.com> | |
47 * @copyright 2005-2010 silverorange | |
48 * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 | |
49 * @link http://pear.php.net/package/Crypt_GPG | |
50 * @see Crypt_GPG::getKeys() | |
51 * @see Crypt_GPG_Key::getSubKeys() | |
52 */ | |
53 class Crypt_GPG_SubKey | |
54 { | |
55 // {{{ algorithm class constants | |
56 | |
57 /** | |
58 * RSA encryption algorithm. | |
59 */ | |
60 const ALGORITHM_RSA = 1; | |
61 | |
62 /** | |
63 * Elgamal encryption algorithm (encryption only). | |
64 */ | |
65 const ALGORITHM_ELGAMAL_ENC = 16; | |
66 | |
67 /** | |
68 * DSA encryption algorithm (sometimes called DH, sign only). | |
69 */ | |
70 const ALGORITHM_DSA = 17; | |
71 | |
72 /** | |
73 * Elgamal encryption algorithm (signage and encryption - should not be | |
74 * used). | |
75 */ | |
76 const ALGORITHM_ELGAMAL_ENC_SGN = 20; | |
77 | |
78 // }}} | |
79 // {{{ usage class constants | |
80 | |
81 /** | |
82 * Key can be used to encrypt | |
83 */ | |
84 const USAGE_ENCRYPT = 1; | |
85 | |
86 /** | |
87 * Key can be used to sign | |
88 */ | |
89 const USAGE_SIGN = 2; | |
90 | |
91 /** | |
92 * Key can be used to certify other keys | |
93 */ | |
94 const USAGE_CERTIFY = 4; | |
95 | |
96 /** | |
97 * Key can be used for authentication | |
98 */ | |
99 const USAGE_AUTHENTICATION = 8; | |
100 | |
101 // }}} | |
102 // {{{ class properties | |
103 | |
104 /** | |
105 * The id of this sub-key | |
106 * | |
107 * @var string | |
108 */ | |
109 private $_id = ''; | |
110 | |
111 /** | |
112 * The algorithm used to create this sub-key | |
113 * | |
114 * The value is one of the Crypt_GPG_SubKey::ALGORITHM_* constants. | |
115 * | |
116 * @var integer | |
117 */ | |
118 private $_algorithm = 0; | |
119 | |
120 /** | |
121 * The fingerprint of this sub-key | |
122 * | |
123 * @var string | |
124 */ | |
125 private $_fingerprint = ''; | |
126 | |
127 /** | |
128 * Length of this sub-key in bits | |
129 * | |
130 * @var integer | |
131 */ | |
132 private $_length = 0; | |
133 | |
134 /** | |
135 * Date this sub-key was created | |
136 * | |
137 * This is a Unix timestamp. | |
138 * | |
139 * @var integer | |
140 */ | |
141 private $_creationDate = 0; | |
142 | |
143 /** | |
144 * Date this sub-key expires | |
145 * | |
146 * This is a Unix timestamp. If this sub-key does not expire, this will be | |
147 * zero. | |
148 * | |
149 * @var integer | |
150 */ | |
151 private $_expirationDate = 0; | |
152 | |
153 /** | |
154 * Contains usage flags of this sub-key | |
155 * | |
156 * @var int | |
157 */ | |
158 private $_usage = 0; | |
159 | |
160 /** | |
161 * Whether or not the private key for this sub-key exists in the keyring | |
162 * | |
163 * @var boolean | |
164 */ | |
165 private $_hasPrivate = false; | |
166 | |
167 /** | |
168 * Whether or not this sub-key is revoked | |
169 * | |
170 * @var boolean | |
171 */ | |
172 private $_isRevoked = false; | |
173 | |
174 // }}} | |
175 // {{{ __construct() | |
176 | |
177 /** | |
178 * Creates a new sub-key object | |
179 * | |
180 * Sub-keys can be initialized from an array of named values. Available | |
181 * names are: | |
182 * | |
183 * - <kbd>string id</kbd> - the key id of the sub-key. | |
184 * - <kbd>integer algorithm</kbd> - the encryption algorithm of the | |
185 * sub-key. | |
186 * - <kbd>string fingerprint</kbd> - the fingerprint of the sub-key. The | |
187 * fingerprint should not contain | |
188 * formatting characters. | |
189 * - <kbd>integer length</kbd> - the length of the sub-key in bits. | |
190 * - <kbd>integer creation</kbd> - the date the sub-key was created. | |
191 * This is a UNIX timestamp. | |
192 * - <kbd>integer expiration</kbd> - the date the sub-key expires. This | |
193 * is a UNIX timestamp. If the sub-key | |
194 * does not expire, use 0. | |
195 * - <kbd>boolean canSign</kbd> - whether or not the sub-key can be | |
196 * used to sign data. | |
197 * - <kbd>boolean canEncrypt</kbd> - whether or not the sub-key can be | |
198 * used to encrypt data. | |
199 * - <kbd>integer usage</kbd> - the sub-key usage flags | |
200 * - <kbd>boolean hasPrivate</kbd> - whether or not the private key for | |
201 * the sub-key exists in the keyring. | |
202 * - <kbd>boolean isRevoked</kbd> - whether or not this sub-key is | |
203 * revoked. | |
204 * | |
205 * @param Crypt_GPG_SubKey|string|array $key optional. Either an existing | |
206 * sub-key object, which is copied; a sub-key string, which is | |
207 * parsed; or an array of initial values. | |
208 */ | |
209 public function __construct($key = null) | |
210 { | |
211 // parse from string | |
212 if (is_string($key)) { | |
213 $key = self::parse($key); | |
214 } | |
215 | |
216 // copy from object | |
217 if ($key instanceof Crypt_GPG_SubKey) { | |
218 $this->_id = $key->_id; | |
219 $this->_algorithm = $key->_algorithm; | |
220 $this->_fingerprint = $key->_fingerprint; | |
221 $this->_length = $key->_length; | |
222 $this->_creationDate = $key->_creationDate; | |
223 $this->_expirationDate = $key->_expirationDate; | |
224 $this->_usage = $key->_usage; | |
225 $this->_hasPrivate = $key->_hasPrivate; | |
226 $this->_isRevoked = $key->_isRevoked; | |
227 } | |
228 | |
229 // initialize from array | |
230 if (is_array($key)) { | |
231 if (array_key_exists('id', $key)) { | |
232 $this->setId($key['id']); | |
233 } | |
234 | |
235 if (array_key_exists('algorithm', $key)) { | |
236 $this->setAlgorithm($key['algorithm']); | |
237 } | |
238 | |
239 if (array_key_exists('fingerprint', $key)) { | |
240 $this->setFingerprint($key['fingerprint']); | |
241 } | |
242 | |
243 if (array_key_exists('length', $key)) { | |
244 $this->setLength($key['length']); | |
245 } | |
246 | |
247 if (array_key_exists('creation', $key)) { | |
248 $this->setCreationDate($key['creation']); | |
249 } | |
250 | |
251 if (array_key_exists('expiration', $key)) { | |
252 $this->setExpirationDate($key['expiration']); | |
253 } | |
254 | |
255 if (array_key_exists('usage', $key)) { | |
256 $this->setUsage($key['usage']); | |
257 } | |
258 | |
259 if (array_key_exists('canSign', $key)) { | |
260 $this->setCanSign($key['canSign']); | |
261 } | |
262 | |
263 if (array_key_exists('canEncrypt', $key)) { | |
264 $this->setCanEncrypt($key['canEncrypt']); | |
265 } | |
266 | |
267 if (array_key_exists('hasPrivate', $key)) { | |
268 $this->setHasPrivate($key['hasPrivate']); | |
269 } | |
270 | |
271 if (array_key_exists('isRevoked', $key)) { | |
272 $this->setRevoked($key['isRevoked']); | |
273 } | |
274 } | |
275 } | |
276 | |
277 // }}} | |
278 // {{{ getId() | |
279 | |
280 /** | |
281 * Gets the id of this sub-key | |
282 * | |
283 * @return string the id of this sub-key. | |
284 */ | |
285 public function getId() | |
286 { | |
287 return $this->_id; | |
288 } | |
289 | |
290 // }}} | |
291 // {{{ getAlgorithm() | |
292 | |
293 /** | |
294 * Gets the algorithm used by this sub-key | |
295 * | |
296 * The algorithm should be one of the Crypt_GPG_SubKey::ALGORITHM_* | |
297 * constants. | |
298 * | |
299 * @return integer the algorithm used by this sub-key. | |
300 */ | |
301 public function getAlgorithm() | |
302 { | |
303 return $this->_algorithm; | |
304 } | |
305 | |
306 // }}} | |
307 // {{{ getCreationDate() | |
308 | |
309 /** | |
310 * Gets the creation date of this sub-key | |
311 * | |
312 * This is a Unix timestamp. | |
313 * | |
314 * @return integer the creation date of this sub-key. | |
315 */ | |
316 public function getCreationDate() | |
317 { | |
318 return $this->_creationDate; | |
319 } | |
320 | |
321 // }}} | |
322 // {{{ getExpirationDate() | |
323 | |
324 /** | |
325 * Gets the date this sub-key expires | |
326 * | |
327 * This is a Unix timestamp. If this sub-key does not expire, this will be | |
328 * zero. | |
329 * | |
330 * @return integer the date this sub-key expires. | |
331 */ | |
332 public function getExpirationDate() | |
333 { | |
334 return $this->_expirationDate; | |
335 } | |
336 | |
337 // }}} | |
338 // {{{ getFingerprint() | |
339 | |
340 /** | |
341 * Gets the fingerprint of this sub-key | |
342 * | |
343 * @return string the fingerprint of this sub-key. | |
344 */ | |
345 public function getFingerprint() | |
346 { | |
347 return $this->_fingerprint; | |
348 } | |
349 | |
350 // }}} | |
351 // {{{ getLength() | |
352 | |
353 /** | |
354 * Gets the length of this sub-key in bits | |
355 * | |
356 * @return integer the length of this sub-key in bits. | |
357 */ | |
358 public function getLength() | |
359 { | |
360 return $this->_length; | |
361 } | |
362 | |
363 // }}} | |
364 // {{{ canSign() | |
365 | |
366 /** | |
367 * Gets whether or not this sub-key can sign data | |
368 * | |
369 * @return boolean true if this sub-key can sign data and false if this | |
370 * sub-key can not sign data. | |
371 */ | |
372 public function canSign() | |
373 { | |
374 return ($this->_usage & self::USAGE_SIGN) != 0; | |
375 } | |
376 | |
377 // }}} | |
378 // {{{ canEncrypt() | |
379 | |
380 /** | |
381 * Gets whether or not this sub-key can encrypt data | |
382 * | |
383 * @return boolean true if this sub-key can encrypt data and false if this | |
384 * sub-key can not encrypt data. | |
385 */ | |
386 public function canEncrypt() | |
387 { | |
388 return ($this->_usage & self::USAGE_ENCRYPT) != 0; | |
389 } | |
390 | |
391 // }}} | |
392 // {{{ usage() | |
393 | |
394 /** | |
395 * Gets usage flags of this sub-key | |
396 * | |
397 * @return int Sum of usage flags | |
398 */ | |
399 public function usage() | |
400 { | |
401 return $this->_usage; | |
402 } | |
403 | |
404 // }}} | |
405 // {{{ hasPrivate() | |
406 | |
407 /** | |
408 * Gets whether or not the private key for this sub-key exists in the | |
409 * keyring | |
410 * | |
411 * @return boolean true the private key for this sub-key exists in the | |
412 * keyring and false if it does not. | |
413 */ | |
414 public function hasPrivate() | |
415 { | |
416 return $this->_hasPrivate; | |
417 } | |
418 | |
419 // }}} | |
420 // {{{ isRevoked() | |
421 | |
422 /** | |
423 * Gets whether or not this sub-key is revoked | |
424 * | |
425 * @return boolean true if this sub-key is revoked and false if it is not. | |
426 */ | |
427 public function isRevoked() | |
428 { | |
429 return $this->_isRevoked; | |
430 } | |
431 | |
432 // }}} | |
433 // {{{ setCreationDate() | |
434 | |
435 /** | |
436 * Sets the creation date of this sub-key | |
437 * | |
438 * The creation date is a Unix timestamp. | |
439 * | |
440 * @param integer $creationDate the creation date of this sub-key. | |
441 * | |
442 * @return Crypt_GPG_SubKey the current object, for fluent interface. | |
443 */ | |
444 public function setCreationDate($creationDate) | |
445 { | |
446 $this->_creationDate = intval($creationDate); | |
447 return $this; | |
448 } | |
449 | |
450 // }}} | |
451 // {{{ setExpirationDate() | |
452 | |
453 /** | |
454 * Sets the expiration date of this sub-key | |
455 * | |
456 * The expiration date is a Unix timestamp. Specify zero if this sub-key | |
457 * does not expire. | |
458 * | |
459 * @param integer $expirationDate the expiration date of this sub-key. | |
460 * | |
461 * @return Crypt_GPG_SubKey the current object, for fluent interface. | |
462 */ | |
463 public function setExpirationDate($expirationDate) | |
464 { | |
465 $this->_expirationDate = intval($expirationDate); | |
466 return $this; | |
467 } | |
468 | |
469 // }}} | |
470 // {{{ setId() | |
471 | |
472 /** | |
473 * Sets the id of this sub-key | |
474 * | |
475 * @param string $id the id of this sub-key. | |
476 * | |
477 * @return Crypt_GPG_SubKey the current object, for fluent interface. | |
478 */ | |
479 public function setId($id) | |
480 { | |
481 $this->_id = strval($id); | |
482 return $this; | |
483 } | |
484 | |
485 // }}} | |
486 // {{{ setAlgorithm() | |
487 | |
488 /** | |
489 * Sets the algorithm used by this sub-key | |
490 * | |
491 * @param integer $algorithm the algorithm used by this sub-key. | |
492 * | |
493 * @return Crypt_GPG_SubKey the current object, for fluent interface. | |
494 */ | |
495 public function setAlgorithm($algorithm) | |
496 { | |
497 $this->_algorithm = intval($algorithm); | |
498 return $this; | |
499 } | |
500 | |
501 // }}} | |
502 // {{{ setFingerprint() | |
503 | |
504 /** | |
505 * Sets the fingerprint of this sub-key | |
506 * | |
507 * @param string $fingerprint the fingerprint of this sub-key. | |
508 * | |
509 * @return Crypt_GPG_SubKey the current object, for fluent interface. | |
510 */ | |
511 public function setFingerprint($fingerprint) | |
512 { | |
513 $this->_fingerprint = strval($fingerprint); | |
514 return $this; | |
515 } | |
516 | |
517 // }}} | |
518 // {{{ setLength() | |
519 | |
520 /** | |
521 * Sets the length of this sub-key in bits | |
522 * | |
523 * @param integer $length the length of this sub-key in bits. | |
524 * | |
525 * @return Crypt_GPG_SubKey the current object, for fluent interface. | |
526 */ | |
527 public function setLength($length) | |
528 { | |
529 $this->_length = intval($length); | |
530 return $this; | |
531 } | |
532 | |
533 // }}} | |
534 // {{{ setCanSign() | |
535 | |
536 /** | |
537 * Sets whether or not this sub-key can sign data | |
538 * | |
539 * @param boolean $canSign true if this sub-key can sign data and false if | |
540 * it can not. | |
541 * | |
542 * @return Crypt_GPG_SubKey the current object, for fluent interface. | |
543 */ | |
544 public function setCanSign($canSign) | |
545 { | |
546 if ($canSign) { | |
547 $this->_usage |= self::USAGE_SIGN; | |
548 } else { | |
549 $this->_usage &= ~self::USAGE_SIGN; | |
550 } | |
551 | |
552 return $this; | |
553 } | |
554 | |
555 // }}} | |
556 // {{{ setCanEncrypt() | |
557 | |
558 /** | |
559 * Sets whether or not this sub-key can encrypt data | |
560 * | |
561 * @param boolean $canEncrypt true if this sub-key can encrypt data and | |
562 * false if it can not. | |
563 * | |
564 * @return Crypt_GPG_SubKey the current object, for fluent interface. | |
565 */ | |
566 public function setCanEncrypt($canEncrypt) | |
567 { | |
568 if ($canEncrypt) { | |
569 $this->_usage |= self::USAGE_ENCRYPT; | |
570 } else { | |
571 $this->_usage &= ~self::USAGE_ENCRYPT; | |
572 } | |
573 | |
574 return $this; | |
575 } | |
576 | |
577 // }}} | |
578 // {{{ setUsage() | |
579 | |
580 /** | |
581 * Sets usage flags of the sub-key | |
582 * | |
583 * @param integer $usage Usage flags | |
584 * | |
585 * @return Crypt_GPG_SubKey the current object, for fluent interface. | |
586 */ | |
587 public function setUsage($usage) | |
588 { | |
589 $this->_usage = (int) $usage; | |
590 return $this; | |
591 } | |
592 | |
593 // }}} | |
594 // {{{ setHasPrivate() | |
595 | |
596 /** | |
597 * Sets whether of not the private key for this sub-key exists in the | |
598 * keyring | |
599 * | |
600 * @param boolean $hasPrivate true if the private key for this sub-key | |
601 * exists in the keyring and false if it does | |
602 * not. | |
603 * | |
604 * @return Crypt_GPG_SubKey the current object, for fluent interface. | |
605 */ | |
606 public function setHasPrivate($hasPrivate) | |
607 { | |
608 $this->_hasPrivate = ($hasPrivate) ? true : false; | |
609 return $this; | |
610 } | |
611 | |
612 // }}} | |
613 // {{{ setRevoked() | |
614 | |
615 /** | |
616 * Sets whether or not this sub-key is revoked | |
617 * | |
618 * @param boolean $isRevoked whether or not this sub-key is revoked. | |
619 * | |
620 * @return Crypt_GPG_SubKey the current object, for fluent interface. | |
621 */ | |
622 public function setRevoked($isRevoked) | |
623 { | |
624 $this->_isRevoked = ($isRevoked) ? true : false; | |
625 return $this; | |
626 } | |
627 | |
628 // }}} | |
629 // {{{ parse() | |
630 | |
631 /** | |
632 * Parses a sub-key object from a sub-key string | |
633 * | |
634 * See <b>doc/DETAILS</b> in the | |
635 * {@link http://www.gnupg.org/download/ GPG distribution} for information | |
636 * on how the sub-key string is parsed. | |
637 * | |
638 * @param string $string the string containing the sub-key. | |
639 * | |
640 * @return Crypt_GPG_SubKey the sub-key object parsed from the string. | |
641 */ | |
642 public static function parse($string) | |
643 { | |
644 $tokens = explode(':', $string); | |
645 | |
646 $subKey = new Crypt_GPG_SubKey(); | |
647 | |
648 $subKey->setId($tokens[4]); | |
649 $subKey->setLength($tokens[2]); | |
650 $subKey->setAlgorithm($tokens[3]); | |
651 $subKey->setCreationDate(self::_parseDate($tokens[5])); | |
652 $subKey->setExpirationDate(self::_parseDate($tokens[6])); | |
653 | |
654 if ($tokens[1] == 'r') { | |
655 $subKey->setRevoked(true); | |
656 } | |
657 | |
658 $usage = 0; | |
659 $usage_map = array( | |
660 'a' => self::USAGE_AUTHENTICATION, | |
661 'c' => self::USAGE_CERTIFY, | |
662 'e' => self::USAGE_ENCRYPT, | |
663 's' => self::USAGE_SIGN, | |
664 ); | |
665 | |
666 foreach ($usage_map as $key => $flag) { | |
667 if (strpos($tokens[11], $key) !== false) { | |
668 $usage |= $flag; | |
669 } | |
670 } | |
671 | |
672 $subKey->setUsage($usage); | |
673 | |
674 return $subKey; | |
675 } | |
676 | |
677 // }}} | |
678 // {{{ _parseDate() | |
679 | |
680 /** | |
681 * Parses a date string as provided by GPG into a UNIX timestamp | |
682 * | |
683 * @param string $string the date string. | |
684 * | |
685 * @return integer the UNIX timestamp corresponding to the provided date | |
686 * string. | |
687 */ | |
688 private static function _parseDate($string) | |
689 { | |
690 if ($string == '') { | |
691 $timestamp = 0; | |
692 } else { | |
693 // all times are in UTC according to GPG documentation | |
694 $timeZone = new DateTimeZone('UTC'); | |
695 | |
696 if (strpos($string, 'T') === false) { | |
697 // interpret as UNIX timestamp | |
698 $string = '@' . $string; | |
699 } | |
700 | |
701 $date = new DateTime($string, $timeZone); | |
702 | |
703 // convert to UNIX timestamp | |
704 $timestamp = intval($date->format('U')); | |
705 } | |
706 | |
707 return $timestamp; | |
708 } | |
709 | |
710 // }}} | |
711 } | |
712 | |
713 // }}} | |
714 | |
715 ?> |