/** * @param \Jose\Object\JWEInterface $jwe * @param \Jose\Object\JWKSetInterface $jwk_set * @param int $i * * @return int|null */ private function decryptRecipientKey(Object\JWEInterface &$jwe, Object\JWKSetInterface $jwk_set, $i) { $recipient = $jwe->getRecipient($i); $complete_headers = array_merge($jwe->getSharedProtectedHeaders(), $jwe->getSharedHeaders(), $recipient->getHeaders()); $this->checkCompleteHeader($complete_headers); $key_encryption_algorithm = $this->getKeyEncryptionAlgorithm($complete_headers); $content_encryption_algorithm = $this->getContentEncryptionAlgorithm($complete_headers); foreach ($jwk_set as $jwk) { try { $this->checkKeyUsage($jwk, 'decryption'); if ('dir' !== $key_encryption_algorithm->getAlgorithmName()) { $this->checkKeyAlgorithm($jwk, $key_encryption_algorithm->getAlgorithmName()); } else { $this->checkKeyAlgorithm($jwk, $content_encryption_algorithm->getAlgorithmName()); } $cek = $this->decryptCEK($key_encryption_algorithm, $content_encryption_algorithm, $jwk, $recipient, $complete_headers); if (null !== $cek) { if (true === $this->decryptPayload($jwe, $cek, $content_encryption_algorithm, $complete_headers)) { return $i; } } } catch (\Exception $e) { //We do nothing, we continue with other keys continue; } } }
/** * @param \Jose\Object\JWEInterface $jwe * @param \Jose\Object\RecipientInterface $recipient * @param string $cek * @param \Jose\Algorithm\ContentEncryptionAlgorithmInterface $content_encryption_algorithm * @param array $additional_headers */ private function processRecipient(Object\JWEInterface $jwe, Object\RecipientInterface &$recipient, $cek, Algorithm\ContentEncryptionAlgorithmInterface $content_encryption_algorithm, array &$additional_headers) { if (null === $recipient->getRecipientKey()) { return; } $complete_headers = array_merge($jwe->getSharedProtectedHeaders(), $jwe->getSharedHeaders(), $recipient->getHeaders()); $key_encryption_algorithm = $this->findKeyEncryptionAlgorithm($complete_headers); $this->checkKeys($key_encryption_algorithm, $content_encryption_algorithm, $recipient->getRecipientKey()); $encrypted_content_encryption_key = $this->getEncryptedKey($complete_headers, $cek, $key_encryption_algorithm, $content_encryption_algorithm, $additional_headers, $recipient->getRecipientKey()); $recipient_headers = $recipient->getHeaders(); if (!empty($additional_headers) && 1 !== $jwe->countRecipients()) { $recipient_headers = array_merge($recipient_headers, $additional_headers); $additional_headers = []; } $recipient = Object\Recipient::createRecipientFromLoadedJWE($recipient_headers, $encrypted_content_encryption_key); }
/** * @param \Jose\Object\JWEInterface $jwe * * @return \Jose\Algorithm\ContentEncryptionAlgorithmInterface */ private function getContentEncryptionAlgorithm(Object\JWEInterface $jwe) { $algorithm = null; foreach ($jwe->getRecipients() as $recipient) { $complete_headers = array_merge($jwe->getSharedProtectedHeaders(), $jwe->getSharedHeaders(), $recipient->getHeaders()); Assertion::keyExists($complete_headers, 'enc', 'Parameter "enc" is missing.'); if (null === $algorithm) { $algorithm = $complete_headers['enc']; } else { Assertion::eq($algorithm, $complete_headers['enc'], 'Foreign content encryption algorithms are not allowed.'); } } $content_encryption_algorithm = $this->getJWAManager()->getAlgorithm($algorithm); Assertion::isInstanceOf($content_encryption_algorithm, Algorithm\ContentEncryptionAlgorithmInterface::class, sprintf('The content encryption algorithm "%s" is not supported or not a content encryption algorithm instance.', $algorithm)); return $content_encryption_algorithm; }