Skip to content

Commit 4dd4ac7

Browse files
committed
tests
Signed-off-by: Julien Veyssier <julien-nc@posteo.net>
1 parent 90888b3 commit 4dd4ac7

File tree

3 files changed

+50
-7
lines changed

3 files changed

+50
-7
lines changed

lib/Controller/LoginController.php

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use OCA\UserOIDC\Event\TokenObtainedEvent;
2222
use OCA\UserOIDC\Helper\HttpClientHelper;
2323
use OCA\UserOIDC\Service\DiscoveryService;
24+
use OCA\UserOIDC\Service\JweService;
2425
use OCA\UserOIDC\Service\JwkService;
2526
use OCA\UserOIDC\Service\LdapService;
2627
use OCA\UserOIDC\Service\OIDCService;
@@ -93,6 +94,7 @@ public function __construct(
9394
private TokenService $tokenService,
9495
private OidcService $oidcService,
9596
private JwkService $jwkService,
97+
private JweService $jweService,
9698
) {
9799
parent::__construct($request, $config, $l10n);
98100
}
@@ -181,6 +183,8 @@ public function login(int $providerId, ?string $redirectUrl = null) {
181183
$this->session->set(self::NONCE, $nonce);
182184

183185
$oidcSystemConfig = $this->config->getSystemValue('user_oidc', []);
186+
// TODO add config param to force PKCE even if not supported in discovery
187+
// condition becomes: ($isPkceSupported || $force) && ($oidcSystemConfig['use_pkce'] ?? true)
184188
$isPkceSupported = in_array('S256', $discovery['code_challenge_methods_supported'] ?? [], true);
185189
$isPkceEnabled = $isPkceSupported && ($oidcSystemConfig['use_pkce'] ?? true);
186190

@@ -450,11 +454,27 @@ public function code(string $state = '', string $code = '', string $scope = '',
450454
}
451455

452456
$data = json_decode($body, true);
453-
$this->logger->debug('Received code response: ' . json_encode($data, JSON_THROW_ON_ERROR));
457+
$this->logger->warning('Received code response: ' . json_encode($data, JSON_THROW_ON_ERROR));
454458
$this->eventDispatcher->dispatchTyped(new TokenObtainedEvent($data, $provider, $discovery));
455459

456460
// TODO: proper error handling
457461
$idTokenRaw = $data['id_token'];
462+
if ($usePrivateKeyJwt) {
463+
// we could check the header there
464+
// if kid is our private JWK, we have a JWE to decrypt
465+
// if typ=JWT, we have a classic JWT to decode
466+
$jwtParts = explode('.', $idTokenRaw, 3);
467+
$jwtHeader = json_decode(JWT::urlsafeB64Decode($jwtParts[0]), true);
468+
$this->logger->warning('JWT HEADER', ['jwt_header' => $jwtHeader]);
469+
if (isset($jwtHeader['typ']) && $jwtHeader['typ'] === 'JWT') {
470+
// we have a JWT
471+
} elseif (isset($jwtHeader['cty']) && $jwtHeader['cty'] === 'JWT') {
472+
// we have a JWE
473+
}
474+
475+
// $dec = $this->jweService->decryptSerializedJwe($idTokenRaw);
476+
// $this->logger->warning('decrypted JWE', ['decrypted_jwe' => json_decode($dec, true)]);
477+
}
458478
$jwks = $this->discoveryService->obtainJWK($provider, $idTokenRaw);
459479
JWT::$leeway = 60;
460480
try {

lib/Service/JweService.php

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public function __construct(
4141
* @param string $contentEncryptionAlg the algorithm to use for the content encryption
4242
* @return string
4343
*/
44-
public function createSerializedJwe(
44+
public function createSerializedJweWithKey(
4545
array $payloadArray, array $encryptionJwk,
4646
string $keyEncryptionAlg = JwkService::PEM_ENC_KEY_ALGORITHM,
4747
string $contentEncryptionAlg = self::CONTENT_ENCRYPTION_ALGORITHM,
@@ -94,7 +94,7 @@ public function createSerializedJwe(
9494
* @return string
9595
* @throws \Exception
9696
*/
97-
public function decryptSerializedJwe(string $serializedJwe, array $jwkArray): string {
97+
public function decryptSerializedJweWithKey(string $serializedJwe, array $jwkArray): string {
9898
$algorithmManager = new AlgorithmManager([
9999
new A256KW(),
100100
new A256CBCHS512(),
@@ -162,6 +162,24 @@ public function decryptSerializedJwe(string $serializedJwe, array $jwkArray): st
162162
return $payload;
163163
}
164164

165+
public function decryptSerializedJwe(string $serializedJwe): string {
166+
$myPemEncryptionKey = $this->jwkService->getMyEncryptionKey(true);
167+
$sslEncryptionKey = openssl_pkey_get_private($myPemEncryptionKey);
168+
$sslEncryptionKeyDetails = openssl_pkey_get_details($sslEncryptionKey);
169+
$encPrivJwk = $this->jwkService->getJwkFromSslKey($sslEncryptionKeyDetails, isEncryptionKey: true, includePrivateKey: true);
170+
171+
return $this->decryptSerializedJweWithKey($serializedJwe, $encPrivJwk);
172+
}
173+
174+
public function createSerializedJwe(array $payloadArray): string {
175+
$myPemEncryptionKey = $this->jwkService->getMyEncryptionKey(true);
176+
$sslEncryptionKey = openssl_pkey_get_private($myPemEncryptionKey);
177+
$sslEncryptionKeyDetails = openssl_pkey_get_details($sslEncryptionKey);
178+
$encPublicJwk = $this->jwkService->getJwkFromSslKey($sslEncryptionKeyDetails, isEncryptionKey: true);
179+
180+
return $this->createSerializedJweWithKey($payloadArray, $encPublicJwk);
181+
}
182+
165183
public function debug(): array {
166184
$myPemEncryptionKey = $this->jwkService->getMyEncryptionKey(true);
167185
$sslEncryptionKey = openssl_pkey_get_private($myPemEncryptionKey);
@@ -185,12 +203,17 @@ public function debug(): array {
185203
$serializedJweToken = $this->createSerializedJwe($payloadArray, $exampleJwkArray);
186204
$decryptedJweString = $this->decryptSerializedJwe($serializedJweToken, $exampleJwkArray);
187205
*/
188-
$serializedJweToken = $this->createSerializedJwe($payloadArray, $encPublicJwk);
189-
$decryptedJweString = $this->decryptSerializedJwe($serializedJweToken, $encPrivJwk);
206+
$serializedJweToken = $this->createSerializedJweWithKey($payloadArray, $encPublicJwk);
207+
$jwtParts = explode('.', $serializedJweToken, 3);
208+
$jwtHeader = json_decode(base64_decode($jwtParts[0]), true);
209+
$decryptedJweString = $this->decryptSerializedJweWithKey($serializedJweToken, $encPrivJwk);
190210

191211
return [
212+
'public_key' => $encPublicJwk,
213+
'private_key' => $encPrivJwk,
192214
'input_payloadArray' => $payloadArray,
193215
'input_serializedJweToken' => $serializedJweToken,
216+
'jwe_header' => $jwtHeader,
194217
'output_payloadArray' => json_decode($decryptedJweString, true),
195218
];
196219
}

tests/unit/Service/JweServiceTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ public function testJweEncryptionDecryption() {
4545
'aud' => 'Your application',
4646
];
4747

48-
$serializedJweToken = $this->jweService->createSerializedJwe($inputPayloadArray, $encPublicJwk);
49-
$decryptedJweString = $this->jweService->decryptSerializedJwe($serializedJweToken, $encPrivJwk);
48+
$serializedJweToken = $this->jweService->createSerializedJweWithKey($inputPayloadArray, $encPublicJwk);
49+
$decryptedJweString = $this->jweService->decryptSerializedJweWithKey($serializedJweToken, $encPrivJwk);
5050

5151
$outputPayloadArray = json_decode($decryptedJweString, true);
5252
$this->assertEquals($inputPayloadArray, $outputPayloadArray);

0 commit comments

Comments
 (0)