-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2 from pdsinterop/feature/jwks
Add JWKs request response.
- Loading branch information
Showing
9 changed files
with
220 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<?php | ||
|
||
namespace Pdsinterop\Solid\Auth\Enum\Jwk; | ||
|
||
class Parameter | ||
{ | ||
public const ALGORITHM = 'alg'; | ||
|
||
public const KEY_ID = 'kid'; | ||
|
||
public const KEY_OPERATIONS = 'key_ops'; | ||
|
||
public const KEY_TYPE = 'kty'; | ||
|
||
public const PUBLIC_KEY_USE = 'use'; | ||
|
||
public const X_509_CERTIFICATE_CHAIN = 'x5c'; | ||
|
||
public const X_509_CERTIFICATE_SHA_1_THUMBPRINT = 'x5t'; | ||
|
||
public const X_509_CERTIFICATE_SHA_256_THUMBPRINT = 'x5t#S256'; | ||
|
||
public const X_509_URL = 'x5u'; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
<?php | ||
|
||
namespace Pdsinterop\Solid\Auth\Enum\Rsa; | ||
|
||
/** | ||
* Parameters for RSA Public Keys | ||
* | ||
* These members MUST be present for RSA public keys. | ||
* | ||
* The RSA Key blinding operation [Kocher], which is a defense against some | ||
* timing attacks, requires all of the RSA key values "n", "e", and "d". | ||
* | ||
* However, some RSA private key representations do not include the public | ||
* exponent "e", but only include the modulus "n" and the private exponent | ||
* "d". This is true, for instance, of the Java RSAPrivateKeySpec API, which | ||
* does not include the public exponent "e" as a parameter. So as to enable | ||
* RSA key blinding, such representations should be avoided. For Java, the | ||
* RSAPrivateCrtKeySpec API can be used instead. Section 8.2.2(i) of the | ||
* "Handbook of Applied Cryptography" [HAC] discusses how to compute the | ||
* remaining RSA private key parameters, if needed, using only "n", "e", | ||
* and "d".} | ||
* | ||
* @see https://tools.ietf.org/html/rfc7518#section-6.3 | ||
*/ | ||
class Parameter | ||
{ | ||
/** | ||
* The "e" (exponent) parameter contains the exponent value for the RSA | ||
* public key. It is represented as a Base64urlUInt-encoded value. For | ||
* instance, when representing the value 65537, the octet sequence to be | ||
* base64url-encoded MUST consist of the three octets [1, 0, 1]; the | ||
* resulting representation for this value is "AQAB". | ||
*/ | ||
public const PUBLIC_EXPONENT = 'e'; | ||
|
||
/** | ||
* The "n" (modulus) parameter contains the modulus value for the RSA public | ||
* key. It is represented as a Base64urlUInt-encoded value. | ||
*/ | ||
public const PUBLIC_MODULUS = 'n'; | ||
|
||
/** | ||
* The "d" (private exponent) parameter contains the private exponent value | ||
* for the RSA private key. It is represented as a Base64urlUInt-encoded | ||
* value.} | ||
*/ | ||
public const PRIVATE_EXPONENT = 'd'; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<?php | ||
|
||
namespace Pdsinterop\Solid\Auth\Utils; | ||
|
||
/** | ||
* URL-safe Base64 encode and decode | ||
* | ||
* ...as PHP does not natively offer this functionality | ||
*/ | ||
class Base64Url | ||
{ | ||
private const URL_UNSAFE = '+/'; | ||
private const URL_SAFE = '-_'; | ||
|
||
public static function encode($subject) : string | ||
{ | ||
return strtr(rtrim(base64_encode($subject), '='), self::URL_UNSAFE, self::URL_SAFE); | ||
} | ||
|
||
public static function decode($subject) : string | ||
{ | ||
return base64_decode(strtr($subject, self::URL_SAFE, self::URL_UNSAFE)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
<?php | ||
|
||
namespace Pdsinterop\Solid\Auth\Utils; | ||
|
||
use JsonSerializable; | ||
use Lcobucci\JWT\Signer\Key; | ||
use Pdsinterop\Solid\Auth\Enum\Jwk\Parameter as JwkParameter; | ||
use Pdsinterop\Solid\Auth\Enum\Rsa\Parameter as RsaParameter; | ||
|
||
class Jwks implements JsonSerializable | ||
{ | ||
////////////////////////////// CLASS PROPERTIES \\\\\\\\\\\\\\\\\\\\\\\\\\\\ | ||
|
||
/** @var Key */ | ||
private $publicKey; | ||
|
||
//////////////////////////////// PUBLIC API \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ | ||
|
||
final public function __construct(Key $publicKey) | ||
{ | ||
$this->publicKey = $publicKey; | ||
} | ||
|
||
final public function __toString() : string | ||
{ | ||
return (string) json_encode($this); | ||
} | ||
|
||
final public function jsonSerialize() | ||
{ | ||
return $this->create(); | ||
} | ||
|
||
////////////////////////////// UTILITY METHODS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\ | ||
|
||
/** | ||
* @param string $certificate | ||
* @param $subject | ||
* | ||
* @return array | ||
*/ | ||
private function createKey(string $certificate, $subject) : array | ||
{ | ||
return [ | ||
JwkParameter::ALGORITHM => 'RS256', | ||
JwkParameter::KEY_ID => md5($certificate), | ||
JwkParameter::KEY_TYPE => 'RSA', | ||
RsaParameter::PUBLIC_EXPONENT => 'AQAB', // Hard-coded as `Base64Url::encode($keyInfo['rsa']['e'])` tends to be empty... | ||
RsaParameter::PUBLIC_MODULUS => Base64Url::encode($subject), | ||
]; | ||
} | ||
|
||
/** | ||
* As the JWT library does not (yet?) have support for JWK, a custom solution is used for now. | ||
* | ||
* @return array | ||
* | ||
* @see https://github.com/lcobucci/jwt/issues/32 | ||
*/ | ||
private function create() : array | ||
{ | ||
$jwks = ['keys' => []]; | ||
|
||
$publicKeys = [$this->publicKey]; | ||
|
||
array_walk($publicKeys, function (Key $publicKey) use (&$jwks) { | ||
$certificate = $publicKey->getContent(); | ||
|
||
$key = openssl_pkey_get_public($certificate); | ||
$keyInfo = openssl_pkey_get_details($key); | ||
|
||
$jwks['keys'][] = $this->createKey($certificate, $keyInfo['rsa']['n']); | ||
}); | ||
|
||
return $jwks; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters