From a1377cadb4e9bee33f010df1803ebcde2af5fc81 Mon Sep 17 00:00:00 2001 From: Florent Morselli Date: Tue, 22 Nov 2016 22:44:05 +0100 Subject: [PATCH 1/5] AES GCM algs updated and ECKey Generator modified --- .travis.yml | 9 +-- composer.json | 2 +- src/Algorithm/ContentEncryption/AESGCM.php | 16 ----- src/Algorithm/KeyEncryption/AESGCMKW.php | 16 +---- src/Factory/JWKFactory.php | 79 ++++++++++++++++++---- 5 files changed, 73 insertions(+), 49 deletions(-) diff --git a/.travis.yml b/.travis.yml index 124d8d9b..24c6ef6a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,16 +3,17 @@ language: php sudo: true matrix: + allow_failures: + - php: nightly fast_finish: true include: - - php: 5.6 + - php: 5.5 + - php: 5.5 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 c5a43d12..03855b9f 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..14e68732 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,24 +120,53 @@ 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')) { + $curve_name = self::getOpensslName($curve); + $args = [ + 'ec_group_name' => $curve_name, + '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() + ); + var_dump('OpenSSL youpiiii!'); + + 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); } + /** + * @param array $values + * + * @return array + */ + private static function createECKeyFromNativeFunctions(array $values) + { + } + /** * {@inheritdoc} */ @@ -233,6 +263,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 'secp256k1'; + 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 * From 473a4b02f2e18934e4c56dcc3104baa5cdfc8b8f Mon Sep 17 00:00:00 2001 From: Florent Morselli Date: Tue, 22 Nov 2016 22:45:14 +0100 Subject: [PATCH 2/5] Bug fixed --- src/Factory/JWKFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Factory/JWKFactory.php b/src/Factory/JWKFactory.php index 14e68732..d8a785bc 100644 --- a/src/Factory/JWKFactory.php +++ b/src/Factory/JWKFactory.php @@ -123,7 +123,7 @@ public static function createECKey(array $values) if (function_exists('openssl_get_curve_names')) { $curve_name = self::getOpensslName($curve); $args = [ - 'ec_group_name' => $curve_name, + 'curve_name' => $curve_name, 'private_key_type' => OPENSSL_KEYTYPE_EC, ]; $key = openssl_pkey_new($args); From efe1224d6c5716080cb7d82dca624bf72e93315e Mon Sep 17 00:00:00 2001 From: Florent Morselli Date: Tue, 22 Nov 2016 22:58:23 +0100 Subject: [PATCH 3/5] Fix --- .travis.yml | 3 +-- src/Factory/JWKFactory.php | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 24c6ef6a..15ea818a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,8 +7,7 @@ matrix: - php: nightly fast_finish: true include: - - php: 5.5 - - php: 5.5 + - php: 5.6 env: deps=low - php: 5.6 - php: 7.0 diff --git a/src/Factory/JWKFactory.php b/src/Factory/JWKFactory.php index d8a785bc..e8212277 100644 --- a/src/Factory/JWKFactory.php +++ b/src/Factory/JWKFactory.php @@ -274,7 +274,7 @@ private static function getOpensslName($curve) { switch ($curve) { case 'P-256': - return 'secp256k1'; + return 'prime256v1'; case 'P-384': return 'secp384r1'; case 'P-521': From 062d2122ff57bec4205958da2a7b33556b4890cc Mon Sep 17 00:00:00 2001 From: Florent Morselli Date: Tue, 22 Nov 2016 23:10:37 +0100 Subject: [PATCH 4/5] Minor changes --- src/Factory/JWKFactory.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Factory/JWKFactory.php b/src/Factory/JWKFactory.php index e8212277..7342968a 100644 --- a/src/Factory/JWKFactory.php +++ b/src/Factory/JWKFactory.php @@ -121,9 +121,8 @@ public static function createECKey(array $values) Assertion::keyExists($values, 'crv', 'The curve is not set.'); $curve = $values['crv']; if (function_exists('openssl_get_curve_names')) { - $curve_name = self::getOpensslName($curve); $args = [ - 'curve_name' => $curve_name, + 'curve_name' => self::getOpensslName($curve), 'private_key_type' => OPENSSL_KEYTYPE_EC, ]; $key = openssl_pkey_new($args); @@ -135,7 +134,6 @@ public static function createECKey(array $values) $values, $rsa->toArray() ); - var_dump('OpenSSL youpiiii!'); return new JWK($values); } else { From 045f7032b442cab458f686c9f3a08e41d5334216 Mon Sep 17 00:00:00 2001 From: Florent Morselli Date: Tue, 22 Nov 2016 23:30:32 +0100 Subject: [PATCH 5/5] Unused code removed --- src/Factory/JWKFactory.php | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/Factory/JWKFactory.php b/src/Factory/JWKFactory.php index 7342968a..55be1186 100644 --- a/src/Factory/JWKFactory.php +++ b/src/Factory/JWKFactory.php @@ -156,15 +156,6 @@ public static function createECKey(array $values) return new JWK($values); } - /** - * @param array $values - * - * @return array - */ - private static function createECKeyFromNativeFunctions(array $values) - { - } - /** * {@inheritdoc} */