Skip to content

Commit 7141cb6

Browse files
committed
last part: detect if a JWT is in a JWE on login
Signed-off-by: Julien Veyssier <julien-nc@posteo.net>
1 parent 4dd4ac7 commit 7141cb6

File tree

3 files changed

+19
-17
lines changed

3 files changed

+19
-17
lines changed

lib/Controller/LoginController.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -467,13 +467,15 @@ public function code(string $state = '', string $code = '', string $scope = '',
467467
$jwtHeader = json_decode(JWT::urlsafeB64Decode($jwtParts[0]), true);
468468
$this->logger->warning('JWT HEADER', ['jwt_header' => $jwtHeader]);
469469
if (isset($jwtHeader['typ']) && $jwtHeader['typ'] === 'JWT') {
470-
// we have a JWT
470+
// we have a JWT, do nothing
471471
} elseif (isset($jwtHeader['cty']) && $jwtHeader['cty'] === 'JWT') {
472-
// we have a JWE
472+
// we have a JWE that contains the JWT string (the ID token)
473+
$idTokenRaw = $this->jweService->decryptSerializedJwe($idTokenRaw);
474+
$this->logger->warning('raw decrypted JWE', ['decrypted_jwe' => $idTokenRaw]);
475+
$this->logger->warning('decrypted+decoded JWE', ['decrypted_jwe' => json_decode($idTokenRaw, true)]);
476+
} else {
477+
$this->logger->warning('Unsupported id_token when using "private key JWT"', ['id_token' => $idTokenRaw]);
473478
}
474-
475-
// $dec = $this->jweService->decryptSerializedJwe($idTokenRaw);
476-
// $this->logger->warning('decrypted JWE', ['decrypted_jwe' => json_decode($dec, true)]);
477479
}
478480
$jwks = $this->discoveryService->obtainJWK($provider, $idTokenRaw);
479481
JWT::$leeway = 60;

lib/Service/JweService.php

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,14 @@ public function __construct(
3535
}
3636

3737
/**
38-
* @param array $payloadArray the content of the JWE
38+
* @param string $payload the content of the JWE
3939
* @param array $encryptionJwk the public key in JWK format
4040
* @param string $keyEncryptionAlg the algorithm to use for the key encryption
4141
* @param string $contentEncryptionAlg the algorithm to use for the content encryption
4242
* @return string
4343
*/
4444
public function createSerializedJweWithKey(
45-
array $payloadArray, array $encryptionJwk,
45+
string $payload, array $encryptionJwk,
4646
string $keyEncryptionAlg = JwkService::PEM_ENC_KEY_ALGORITHM,
4747
string $contentEncryptionAlg = self::CONTENT_ENCRYPTION_ALGORITHM,
4848
): string {
@@ -66,11 +66,8 @@ public function createSerializedJweWithKey(
6666
// Our key.
6767
$jwk = new JWK($encryptionJwk);
6868

69-
// The payload we want to encrypt. It MUST be a string.
70-
$payload = json_encode($payloadArray);
71-
7269
$jwe = $jweBuilder
73-
->create() // We want to create a new JWE
70+
->create() // We want to create a new JWE
7471
->withPayload($payload) // We set the payload
7572
->withSharedProtectedHeader([
7673
// Key Encryption Algorithm
@@ -80,12 +77,14 @@ public function createSerializedJweWithKey(
8077
// 'enc' => 'A256CBC-HS512',
8178
'enc' => $contentEncryptionAlg,
8279
//'zip' => 'DEF' // Not recommended.
80+
'cty' => 'JWT',
8381
])
8482
->addRecipient($jwk) // We add a recipient (a shared key or public key).
8583
->build();
8684

87-
$serializer = new CompactSerializer(); // The serializer
88-
return $serializer->serialize($jwe, 0); // We serialize the recipient at index 0 (we only have one recipient).
85+
$serializer = new CompactSerializer();
86+
// We serialize the recipient at index 0 (we only have one recipient).
87+
return $serializer->serialize($jwe, 0);
8988
}
9089

9190
/**
@@ -171,13 +170,13 @@ public function decryptSerializedJwe(string $serializedJwe): string {
171170
return $this->decryptSerializedJweWithKey($serializedJwe, $encPrivJwk);
172171
}
173172

174-
public function createSerializedJwe(array $payloadArray): string {
173+
public function createSerializedJwe(string $payload): string {
175174
$myPemEncryptionKey = $this->jwkService->getMyEncryptionKey(true);
176175
$sslEncryptionKey = openssl_pkey_get_private($myPemEncryptionKey);
177176
$sslEncryptionKeyDetails = openssl_pkey_get_details($sslEncryptionKey);
178177
$encPublicJwk = $this->jwkService->getJwkFromSslKey($sslEncryptionKeyDetails, isEncryptionKey: true);
179178

180-
return $this->createSerializedJweWithKey($payloadArray, $encPublicJwk);
179+
return $this->createSerializedJweWithKey($payload, $encPublicJwk);
181180
}
182181

183182
public function debug(): array {
@@ -203,7 +202,7 @@ public function debug(): array {
203202
$serializedJweToken = $this->createSerializedJwe($payloadArray, $exampleJwkArray);
204203
$decryptedJweString = $this->decryptSerializedJwe($serializedJweToken, $exampleJwkArray);
205204
*/
206-
$serializedJweToken = $this->createSerializedJweWithKey($payloadArray, $encPublicJwk);
205+
$serializedJweToken = $this->createSerializedJweWithKey(json_encode($payloadArray), $encPublicJwk);
207206
$jwtParts = explode('.', $serializedJweToken, 3);
208207
$jwtHeader = json_decode(base64_decode($jwtParts[0]), true);
209208
$decryptedJweString = $this->decryptSerializedJweWithKey($serializedJweToken, $encPrivJwk);

tests/unit/Service/JweServiceTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,9 @@ public function testJweEncryptionDecryption() {
4444
'iss' => 'My service',
4545
'aud' => 'Your application',
4646
];
47+
$inputPayload = json_encode($inputPayloadArray);
4748

48-
$serializedJweToken = $this->jweService->createSerializedJweWithKey($inputPayloadArray, $encPublicJwk);
49+
$serializedJweToken = $this->jweService->createSerializedJweWithKey($inputPayload, $encPublicJwk);
4950
$decryptedJweString = $this->jweService->decryptSerializedJweWithKey($serializedJweToken, $encPrivJwk);
5051

5152
$outputPayloadArray = json_decode($decryptedJweString, true);

0 commit comments

Comments
 (0)