3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
6 * Contains a class representing GPG sub-keys and constants for GPG algorithms
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.
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.
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
26 * @category Encryption
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
36 // {{{ class Crypt_GPG_SubKey
39 * A class for GPG sub-key information
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.
44 * @category Encryption
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()
54 class Crypt_GPG_SubKey
56 // {{{ class constants
59 * RSA encryption algorithm.
61 const ALGORITHM_RSA = 1;
64 * Elgamal encryption algorithm (encryption only).
66 const ALGORITHM_ELGAMAL_ENC = 16;
69 * DSA encryption algorithm (sometimes called DH, sign only).
71 const ALGORITHM_DSA = 17;
74 * Elgamal encryption algorithm (signage and encryption - should not be
77 const ALGORITHM_ELGAMAL_ENC_SGN = 20;
80 // {{{ class properties
83 * The id of this sub-key
90 * The algorithm used to create this sub-key
92 * The value is one of the Crypt_GPG_SubKey::ALGORITHM_* constants.
96 private $_algorithm = 0;
99 * The fingerprint of this sub-key
103 private $_fingerprint = '';
106 * Length of this sub-key in bits
110 private $_length = 0;
113 * Date this sub-key was created
115 * This is a Unix timestamp.
119 private $_creationDate = 0;
122 * Date this sub-key expires
124 * This is a Unix timestamp. If this sub-key does not expire, this will be
129 private $_expirationDate = 0;
132 * Whether or not this sub-key can sign data
136 private $_canSign = false;
139 * Whether or not this sub-key can encrypt data
143 private $_canEncrypt = false;
146 * Whether or not the private key for this sub-key exists in the keyring
150 private $_hasPrivate = false;
153 * Whether or not this sub-key is revoked
157 private $_isRevoked = false;
163 * Creates a new sub-key object
165 * Sub-keys can be initialized from an array of named values. Available
168 * - <kbd>string id</kbd> - the key id of the sub-key.
169 * - <kbd>integer algorithm</kbd> - the encryption algorithm of the
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
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
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.
193 public function __construct($key = null)
196 if (is_string($key)) {
197 $key = self::parse($key);
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;
214 // initialize from array
215 if (is_array($key)) {
216 if (array_key_exists('id', $key)) {
217 $this->setId($key['id']);
220 if (array_key_exists('algorithm', $key)) {
221 $this->setAlgorithm($key['algorithm']);
224 if (array_key_exists('fingerprint', $key)) {
225 $this->setFingerprint($key['fingerprint']);
228 if (array_key_exists('length', $key)) {
229 $this->setLength($key['length']);
232 if (array_key_exists('creation', $key)) {
233 $this->setCreationDate($key['creation']);
236 if (array_key_exists('expiration', $key)) {
237 $this->setExpirationDate($key['expiration']);
240 if (array_key_exists('canSign', $key)) {
241 $this->setCanSign($key['canSign']);
244 if (array_key_exists('canEncrypt', $key)) {
245 $this->setCanEncrypt($key['canEncrypt']);
248 if (array_key_exists('hasPrivate', $key)) {
249 $this->setHasPrivate($key['hasPrivate']);
252 if (array_key_exists('isRevoked', $key)) {
253 $this->setRevoked($key['isRevoked']);
262 * Gets the id of this sub-key
264 * @return string the id of this sub-key.
266 public function getId()
272 // {{{ getAlgorithm()
275 * Gets the algorithm used by this sub-key
277 * The algorithm should be one of the Crypt_GPG_SubKey::ALGORITHM_*
280 * @return integer the algorithm used by this sub-key.
282 public function getAlgorithm()
284 return $this->_algorithm;
288 // {{{ getCreationDate()
291 * Gets the creation date of this sub-key
293 * This is a Unix timestamp.
295 * @return integer the creation date of this sub-key.
297 public function getCreationDate()
299 return $this->_creationDate;
303 // {{{ getExpirationDate()
306 * Gets the date this sub-key expires
308 * This is a Unix timestamp. If this sub-key does not expire, this will be
311 * @return integer the date this sub-key expires.
313 public function getExpirationDate()
315 return $this->_expirationDate;
319 // {{{ getFingerprint()
322 * Gets the fingerprint of this sub-key
324 * @return string the fingerprint of this sub-key.
326 public function getFingerprint()
328 return $this->_fingerprint;
335 * Gets the length of this sub-key in bits
337 * @return integer the length of this sub-key in bits.
339 public function getLength()
341 return $this->_length;
348 * Gets whether or not this sub-key can sign data
350 * @return boolean true if this sub-key can sign data and false if this
351 * sub-key can not sign data.
353 public function canSign()
355 return $this->_canSign;
362 * Gets whether or not this sub-key can encrypt data
364 * @return boolean true if this sub-key can encrypt data and false if this
365 * sub-key can not encrypt data.
367 public function canEncrypt()
369 return $this->_canEncrypt;
376 * Gets whether or not the private key for this sub-key exists in the
379 * @return boolean true the private key for this sub-key exists in the
380 * keyring and false if it does not.
382 public function hasPrivate()
384 return $this->_hasPrivate;
391 * Gets whether or not this sub-key is revoked
393 * @return boolean true if this sub-key is revoked and false if it is not.
395 public function isRevoked()
397 return $this->_isRevoked;
401 // {{{ setCreationDate()
404 * Sets the creation date of this sub-key
406 * The creation date is a Unix timestamp.
408 * @param integer $creationDate the creation date of this sub-key.
410 * @return Crypt_GPG_SubKey the current object, for fluent interface.
412 public function setCreationDate($creationDate)
414 $this->_creationDate = intval($creationDate);
419 // {{{ setExpirationDate()
422 * Sets the expiration date of this sub-key
424 * The expiration date is a Unix timestamp. Specify zero if this sub-key
427 * @param integer $expirationDate the expiration date of this sub-key.
429 * @return Crypt_GPG_SubKey the current object, for fluent interface.
431 public function setExpirationDate($expirationDate)
433 $this->_expirationDate = intval($expirationDate);
441 * Sets the id of this sub-key
443 * @param string $id the id of this sub-key.
445 * @return Crypt_GPG_SubKey the current object, for fluent interface.
447 public function setId($id)
449 $this->_id = strval($id);
454 // {{{ setAlgorithm()
457 * Sets the algorithm used by this sub-key
459 * @param integer $algorithm the algorithm used by this sub-key.
461 * @return Crypt_GPG_SubKey the current object, for fluent interface.
463 public function setAlgorithm($algorithm)
465 $this->_algorithm = intval($algorithm);
470 // {{{ setFingerprint()
473 * Sets the fingerprint of this sub-key
475 * @param string $fingerprint the fingerprint of this sub-key.
477 * @return Crypt_GPG_SubKey the current object, for fluent interface.
479 public function setFingerprint($fingerprint)
481 $this->_fingerprint = strval($fingerprint);
489 * Sets the length of this sub-key in bits
491 * @param integer $length the length of this sub-key in bits.
493 * @return Crypt_GPG_SubKey the current object, for fluent interface.
495 public function setLength($length)
497 $this->_length = intval($length);
505 * Sets whether of not this sub-key can sign data
507 * @param boolean $canSign true if this sub-key can sign data and false if
510 * @return Crypt_GPG_SubKey the current object, for fluent interface.
512 public function setCanSign($canSign)
514 $this->_canSign = ($canSign) ? true : false;
519 // {{{ setCanEncrypt()
522 * Sets whether of not this sub-key can encrypt data
524 * @param boolean $canEncrypt true if this sub-key can encrypt data and
525 * false if it can not.
527 * @return Crypt_GPG_SubKey the current object, for fluent interface.
529 public function setCanEncrypt($canEncrypt)
531 $this->_canEncrypt = ($canEncrypt) ? true : false;
536 // {{{ setHasPrivate()
539 * Sets whether of not the private key for this sub-key exists in the
542 * @param boolean $hasPrivate true if the private key for this sub-key
543 * exists in the keyring and false if it does
546 * @return Crypt_GPG_SubKey the current object, for fluent interface.
548 public function setHasPrivate($hasPrivate)
550 $this->_hasPrivate = ($hasPrivate) ? true : false;
558 * Sets whether or not this sub-key is revoked
560 * @param boolean $isRevoked whether or not this sub-key is revoked.
562 * @return Crypt_GPG_SubKey the current object, for fluent interface.
564 public function setRevoked($isRevoked)
566 $this->_isRevoked = ($isRevoked) ? true : false;
574 * Parses a sub-key object from a sub-key string
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.
580 * @param string $string the string containing the sub-key.
582 * @return Crypt_GPG_SubKey the sub-key object parsed from the string.
584 public static function parse($string)
586 $tokens = explode(':', $string);
588 $subKey = new Crypt_GPG_SubKey();
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]));
596 if ($tokens[1] == 'r') {
597 $subKey->setRevoked(true);
600 if (strpos($tokens[11], 's') !== false) {
601 $subKey->setCanSign(true);
604 if (strpos($tokens[11], 'e') !== false) {
605 $subKey->setCanEncrypt(true);
615 * Parses a date string as provided by GPG into a UNIX timestamp
617 * @param string $string the date string.
619 * @return integer the UNIX timestamp corresponding to the provided date
622 private static function _parseDate($string)
627 // all times are in UTC according to GPG documentation
628 $timeZone = new DateTimeZone('UTC');
630 if (strpos($string, 'T') === false) {
631 // interpret as UNIX timestamp
632 $string = '@' . $string;
635 $date = new DateTime($string, $timeZone);
637 // convert to UNIX timestamp
638 $timestamp = intval($date->format('U'));