diff --git a/.travis.yml b/.travis.yml index 124d8d9b..15ea818a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,16 +3,16 @@ language: php sudo: true matrix: + allow_failures: + - php: nightly fast_finish: true include: - php: 5.6 env: deps=low - php: 5.6 - env: WITH_CRYPTO=true - php: 7.0 - env: deps=low - php: 7.0 - env: WITH_CRYPTO=true + env: deps=low - php: 7.1 - php: hhvm - php: hhvm diff --git a/composer.json b/composer.json index fc74bbc0..99656c27 100644 --- a/composer.json +++ b/composer.json @@ -29,7 +29,7 @@ "lib-openssl": "*", "spomky-labs/base64url": "^1.0", "spomky-labs/aes-key-wrap": "^3.0", - "spomky-labs/php-aes-gcm": "^1.0", + "spomky-labs/php-aes-gcm": "^1.2", "beberlei/assert": "^2.4", "symfony/polyfill-mbstring": "^1.1", "symfony/polyfill-php70": "^1.1", diff --git a/src/Algorithm/ContentEncryption/AESGCM.php b/src/Algorithm/ContentEncryption/AESGCM.php index 2a2334f8..522a995b 100644 --- a/src/Algorithm/ContentEncryption/AESGCM.php +++ b/src/Algorithm/ContentEncryption/AESGCM.php @@ -27,22 +27,6 @@ public function encryptContent($data, $cek, $iv, $aad, $encoded_protected_header $calculated_aad .= '.'.$aad; } - if (version_compare(PHP_VERSION, '7.1.0') >= 0) { - return openssl_encrypt($data, $this->getMode($cek), $cek, OPENSSL_RAW_DATA, $iv, $tag, $calculated_aad, 16); - } elseif (class_exists('\Crypto\Cipher')) { - $cipher = Cipher::aes(Cipher::MODE_GCM, $this->getKeySize()); - $calculated_aad = $encoded_protected_header; - if (null !== $aad) { - $calculated_aad .= '.'.$aad; - } - - $cipher->setAAD($calculated_aad); - $cyphertext = $cipher->encrypt($data, $cek, $iv); - $tag = $cipher->getTag(); - - return $cyphertext; - } - list($cyphertext, $tag) = GCM::encrypt($cek, $iv, $data, $calculated_aad); return $cyphertext; diff --git a/src/Algorithm/KeyEncryption/AESGCMKW.php b/src/Algorithm/KeyEncryption/AESGCMKW.php index 672ba0d4..623efbc3 100644 --- a/src/Algorithm/KeyEncryption/AESGCMKW.php +++ b/src/Algorithm/KeyEncryption/AESGCMKW.php @@ -32,20 +32,8 @@ public function wrapKey(JWKInterface $key, $cek, array $complete_headers, array $iv = random_bytes(96 / 8); $additional_headers['iv'] = Base64Url::encode($iv); - if (version_compare(PHP_VERSION, '7.1.0') >= 0) { - $tag = null; - $encrypted_cek = openssl_encrypt($cek, $this->getMode($kek), $kek, OPENSSL_RAW_DATA, $iv, $tag, null, 16); - $additional_headers['tag'] = Base64Url::encode($tag); - } elseif (class_exists('\Crypto\Cipher')) { - $cipher = Cipher::aes(Cipher::MODE_GCM, $this->getKeySize()); - $cipher->setAAD(null); - $encrypted_cek = $cipher->encrypt($cek, $kek, $iv); - - $additional_headers['tag'] = Base64Url::encode($cipher->getTag()); - } else { - list($encrypted_cek, $tag) = AESGCM::encrypt($kek, $iv, $cek, null); - $additional_headers['tag'] = Base64Url::encode($tag); - } + list($encrypted_cek, $tag) = AESGCM::encrypt($kek, $iv, $cek, null); + $additional_headers['tag'] = Base64Url::encode($tag); return $encrypted_cek; } diff --git a/src/Factory/JWKFactory.php b/src/Factory/JWKFactory.php index 3b4800c9..55be1186 100644 --- a/src/Factory/JWKFactory.php +++ b/src/Factory/JWKFactory.php @@ -13,6 +13,7 @@ use Assert\Assertion; use Base64Url\Base64Url; +use Jose\KeyConverter\ECKey; use Jose\KeyConverter\KeyConverter; use Jose\KeyConverter\RSAKey; use Jose\Object\JKUJWKSet; @@ -119,20 +120,38 @@ public static function createECKey(array $values) { Assertion::keyExists($values, 'crv', 'The curve is not set.'); $curve = $values['crv']; - $curve_name = self::getNistName($curve); - $generator = CurveFactory::getGeneratorByName($curve_name); - $private_key = $generator->createPrivateKey(); - - $values = array_merge( - $values, - [ - 'kty' => 'EC', - 'crv' => $curve, - 'x' => self::encodeValue($private_key->getPublicKey()->getPoint()->getX()), - 'y' => self::encodeValue($private_key->getPublicKey()->getPoint()->getY()), - 'd' => self::encodeValue($private_key->getSecret()), - ] - ); + if (function_exists('openssl_get_curve_names')) { + $args = [ + 'curve_name' => self::getOpensslName($curve), + 'private_key_type' => OPENSSL_KEYTYPE_EC, + ]; + $key = openssl_pkey_new($args); + $res = openssl_pkey_export($key, $out); + Assertion::true($res, 'Unable to create the key'); + + $rsa = new ECKey($out); + $values = array_merge( + $values, + $rsa->toArray() + ); + + return new JWK($values); + } else { + $curve_name = self::getNistName($curve); + $generator = CurveFactory::getGeneratorByName($curve_name); + $private_key = $generator->createPrivateKey(); + + $values = array_merge( + $values, + [ + 'kty' => 'EC', + 'crv' => $curve, + 'x' => self::encodeValue($private_key->getPublicKey()->getPoint()->getX()), + 'y' => self::encodeValue($private_key->getPublicKey()->getPoint()->getY()), + 'd' => self::encodeValue($private_key->getSecret()), + ] + ); + } return new JWK($values); } @@ -233,6 +252,27 @@ private static function convertDecToBin($value) return hex2bin($adapter->decHex($value)); } + /** + * @param string $curve + * + * @throws \InvalidArgumentException + * + * @return string + */ + private static function getOpensslName($curve) + { + switch ($curve) { + case 'P-256': + return 'prime256v1'; + case 'P-384': + return 'secp384r1'; + case 'P-521': + return 'secp521r1'; + default: + throw new \InvalidArgumentException(sprintf('The curve "%s" is not supported.', $curve)); + } + } + /** * @param string $curve *