Пример #1
0
 /**
  * Creates a symmetric key.
  *
  * The supported formats are:
  *
  * - `php` - JSON web key formatted as a PHP associative array
  * - `json` - JSON web key
  * - `jwe` - Encrypted JSON web key
  * - `base64url` - the symmetric key encoded in Base64url format
  * - `base64` - the symmetric key encoded in Base64 format
  * - `bin` - the symmetric key encoded in binary format
  *
  * @param string|array $data the key data
  * @param string $format the format
  * @param string $password the password, if the key is password protected
  * @param string $alg the algorithm, if the key is password protected
  */
 public function __construct($data, $format, $password = null, $alg = 'PBES2-HS256+A128KW')
 {
     switch ($format) {
         case 'php':
         case 'json':
         case 'jwe':
             parent::__construct($data, $format, $password, $alg);
             break;
         case 'base64url':
             $jwk = array('kty' => self::KTY, 'k' => $data);
             parent::__construct($jwk);
             break;
         case 'base64':
             $jwk = array('kty' => self::KTY, 'k' => Util::base64url_encode(base64_decode($data)));
             parent::__construct($jwk);
             break;
         case 'bin':
             $jwk = array('kty' => self::KTY, 'k' => Util::base64url_encode($data));
             parent::__construct($jwk);
             break;
         default:
             throw new KeyException('Incorrect format');
     }
     if (!isset($this->data['kty'])) {
         $this->data['kty'] = self::KTY;
     }
 }
Пример #2
0
 /**
  * Removes a key from the key set
  *
  * @param Key $key the key to remove
  */
 function remove($key)
 {
     for ($i = 0; $i < count($this->keys); $i++) {
         if ($this->keys[$i]->getSignature() == $key->getSignature()) {
             unset($this->keys[$i]);
             return;
         }
     }
 }
Пример #3
0
 /**
  * Creates an RSA key.
  *
  * The supported formats are:
  *
  * - `php` - JSON web key formatted as a PHP associative array
  * - `json` - JSON web key
  * - `jwe` - Encrypted JSON web key
  * - `pem` - the public or private key encoded in PEM (base64 encoded DER) format
  *
  * @param string|array $data the key data
  * @param string $format the format
  * @param string $password the password, if the key is password protected
  * @param string $alg the algorithm, if the key is password protected
  */
 public function __construct($data, $format, $password = null, $alg = 'PBES2-HS256+A128KW')
 {
     switch ($format) {
         case 'php':
         case 'json':
         case 'jwe':
             parent::__construct($data, $format, $password, $alg);
             break;
         case 'pem':
             $offset = 0;
             $jwk = array();
             if (preg_match(Key::PEM_PUBLIC, $data, $matches)) {
                 $der = base64_decode($matches[1]);
                 if ($der === FALSE) {
                     throw new KeyException('Cannot read PEM key');
                 }
                 $offset += ASN1::readDER($der, $offset, $value);
                 // SEQUENCE
                 $offset += ASN1::readDER($der, $offset, $value);
                 // SEQUENCE
                 $offset += ASN1::readDER($der, $offset, $algorithm);
                 // OBJECT IDENTIFIER - AlgorithmIdentifier
                 $algorithm = ASN1::decodeOID($algorithm);
                 if ($algorithm != self::OID) {
                     throw new KeyException('Not RSA key');
                 }
                 $offset += ASN1::readDER($der, $offset, $value);
                 // NULL - parameters
                 $offset += ASN1::readDER($der, $offset, $value, true);
                 // BIT STRING
                 $offset += ASN1::readDER($der, $offset, $value);
                 // SEQUENCE
                 $offset += ASN1::readDER($der, $offset, $n);
                 // INTEGER [n]
                 $offset += ASN1::readDER($der, $offset, $e);
                 // INTEGER [e]
                 $jwk['kty'] = self::KTY;
                 $jwk['n'] = Util::base64url_encode($n);
                 $jwk['e'] = Util::base64url_encode($e);
             } elseif (preg_match(self::PEM_PRIVATE, $data, $matches)) {
                 $der = base64_decode($matches[1]);
                 if ($der === FALSE) {
                     throw new KeyException('Cannot read PEM key');
                 }
                 $offset += ASN1::readDER($der, $offset, $data);
                 // SEQUENCE
                 $offset += ASN1::readDER($der, $offset, $version);
                 // INTEGER
                 if (ord($version) != 0) {
                     throw new KeyException('Unsupported RSA private key version');
                 }
                 $offset += ASN1::readDER($der, $offset, $n);
                 // INTEGER [n]
                 $offset += ASN1::readDER($der, $offset, $e);
                 // INTEGER [e]
                 $offset += ASN1::readDER($der, $offset, $d);
                 // INTEGER [d]
                 $offset += ASN1::readDER($der, $offset, $p);
                 // INTEGER [p]
                 $offset += ASN1::readDER($der, $offset, $q);
                 // INTEGER [q]
                 $offset += ASN1::readDER($der, $offset, $dp);
                 // INTEGER [dp]
                 $offset += ASN1::readDER($der, $offset, $dq);
                 // INTEGER [dq]
                 $offset += ASN1::readDER($der, $offset, $qi);
                 // INTEGER [qi]
                 if (strlen($der) > $offset) {
                     ASN1::readDER($der, $offset, $oth);
                 }
                 // INTEGER [other]
                 $jwk['kty'] = self::KTY;
                 $jwk['n'] = Util::base64url_encode($n);
                 $jwk['e'] = Util::base64url_encode($e);
                 $jwk['d'] = Util::base64url_encode($d);
                 $jwk['p'] = Util::base64url_encode($p);
                 $jwk['q'] = Util::base64url_encode($q);
                 $jwk['dp'] = Util::base64url_encode($dp);
                 $jwk['dq'] = Util::base64url_encode($dq);
                 $jwk['qi'] = Util::base64url_encode($qi);
             }
             parent::__construct($jwk);
             break;
         default:
             throw new KeyException('Incorrect format');
     }
     if (!isset($this->data['kty'])) {
         $this->data['kty'] = self::KTY;
     }
 }
Пример #4
0
 /**
  * Creates an EC key.
  *
  * The supported formats are:
  *
  * - `php` - JSON web key formatted as a PHP associative array
  * - `json` - JSON web key
  * - `jwe` - Encrypted JSON web key
  * - `pem` - the public or private key encoded in PEM (base64 encoded DER) format
  *
  * @param string|array $data the key data
  * @param string $format the format
  * @param string $password the password, if the key is password protected
  * @param string $alg the algorithm, if the key is password protected
  */
 public function __construct($data, $format, $password = null, $alg = 'PBES2-HS256+A128KW')
 {
     switch ($format) {
         case 'php':
         case 'json':
         case 'jwe':
             parent::__construct($data, $format, $password, $alg);
             break;
         case 'pem':
             $offset = 0;
             $jwk = array();
             if (preg_match(Key::PEM_PUBLIC, $data, $matches)) {
                 $der = base64_decode($matches[1]);
                 if ($der === FALSE) {
                     throw new KeyException('Cannot read PEM key');
                 }
                 $offset += ASN1::readDER($der, $offset, $value);
                 // SEQUENCE
                 $offset += ASN1::readDER($der, $offset, $value);
                 // SEQUENCE
                 $offset += ASN1::readDER($der, $offset, $algorithm);
                 // OBJECT IDENTIFIER - AlgorithmIdentifier
                 $algorithm = ASN1::decodeOID($algorithm);
                 if ($algorithm != self::EC_OID) {
                     throw new KeyException('Not EC key');
                 }
                 $offset += ASN1::readDER($der, $offset, $curve);
                 // OBJECT IDENTIFIER - parameters
                 $curve = ASN1::decodeOID($curve);
                 if (!isset(self::$curves, $curve)) {
                     throw new KeyException('Unrecognised EC parameter: ' . $curve);
                 }
                 $len = self::$curves[$curve]['len'];
                 $offset += ASN1::readDER($der, $offset, $point);
                 // BIT STRING - ECPoint
                 if (strlen($point) != $len + 1) {
                     throw new KeyException('Incorrect public key length: ' . strlen($point));
                 }
                 if (ord($point[0]) != 0x4) {
                     throw new KeyException('Invalid public key');
                 }
                 // W
                 $x = substr($point, 1, $len / 2);
                 $y = substr($point, 1 + $len / 2);
                 $jwk['kty'] = self::KTY;
                 $jwk['crv'] = self::$curves[$curve]['crv'];
                 $jwk['x'] = Util::base64url_encode($x);
                 $jwk['y'] = Util::base64url_encode($y);
             } elseif (preg_match(self::PEM_PRIVATE, $data, $matches)) {
                 $der = base64_decode($matches[1]);
                 if ($der === FALSE) {
                     throw new KeyException('Cannot read PEM key');
                 }
                 $offset += ASN1::readDER($der, $offset, $data);
                 // SEQUENCE
                 $offset += ASN1::readDER($der, $offset, $version);
                 // INTEGER
                 if (ord($version) != 1) {
                     throw new KeyException('Invalid private key version');
                 }
                 $offset += ASN1::readDER($der, $offset, $d);
                 // OCTET STRING [d]
                 $offset += ASN1::readDER($der, $offset, $data);
                 // SEQUENCE[0]
                 $offset += ASN1::readDER($der, $offset, $curve);
                 // OBJECT IDENTIFIER - parameters
                 $curve = ASN1::decodeOID($curve);
                 if (!isset(self::$curves, $curve)) {
                     throw new KeyException('Unrecognised EC parameter: ' . $curve);
                 }
                 $len = self::$curves[$curve]['len'];
                 $offset += ASN1::readDER($der, $offset, $data);
                 // SEQUENCE[1]
                 $offset += ASN1::readDER($der, $offset, $point);
                 // BIT STRING - ECPoint
                 if (strlen($point) != $len + 1) {
                     throw new KeyException('Incorrect private key length: ' . strlen($point));
                 }
                 if (ord($point[0]) != 0x4) {
                     throw new KeyException('Invalid private key');
                 }
                 // W
                 $x = substr($point, 1, ($len - 1) / 2);
                 $y = substr($point, 1 + ($len - 1) / 2);
                 $jwk['kty'] = self::KTY;
                 $jwk['crv'] = self::$curves[$curve]['crv'];
                 $jwk['d'] = Util::base64url_encode($d);
                 $jwk['x'] = Util::base64url_encode($x);
                 $jwk['y'] = Util::base64url_encode($y);
             }
             parent::__construct($jwk);
             break;
         default:
             throw new KeyException('Incorrect format');
     }
     if (!isset($this->data['kty'])) {
         $this->data['kty'] = self::KTY;
     }
 }