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