[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 <?php 2 3 declare(strict_types=1); 4 5 /* 6 * The MIT License (MIT) 7 * 8 * Copyright (c) 2014-2020 Spomky-Labs 9 * 10 * This software may be modified and distributed under the terms 11 * of the MIT license. See the LICENSE file for details. 12 */ 13 14 namespace Jose\Component\Signature\Serializer; 15 16 use function array_key_exists; 17 use Base64Url\Base64Url; 18 use function count; 19 use InvalidArgumentException; 20 use function is_array; 21 use function is_string; 22 use Jose\Component\Core\Util\JsonConverter; 23 use Jose\Component\Signature\JWS; 24 use LogicException; 25 26 final class JSONGeneralSerializer extends Serializer 27 { 28 public const NAME = 'jws_json_general'; 29 30 public function displayName(): string 31 { 32 return 'JWS JSON General'; 33 } 34 35 public function name(): string 36 { 37 return self::NAME; 38 } 39 40 /** 41 * @throws LogicException if no signature is attached 42 */ 43 public function serialize(JWS $jws, ?int $signatureIndex = null): string 44 { 45 if (0 === $jws->countSignatures()) { 46 throw new LogicException('No signature.'); 47 } 48 49 $data = []; 50 $this->checkPayloadEncoding($jws); 51 52 if (false === $jws->isPayloadDetached()) { 53 $data['payload'] = $jws->getEncodedPayload(); 54 } 55 56 $data['signatures'] = []; 57 foreach ($jws->getSignatures() as $signature) { 58 $tmp = ['signature' => Base64Url::encode($signature->getSignature())]; 59 $values = [ 60 'protected' => $signature->getEncodedProtectedHeader(), 61 'header' => $signature->getHeader(), 62 ]; 63 64 foreach ($values as $key => $value) { 65 if ((is_string($value) && '' !== $value) || (is_array($value) && 0 !== count($value))) { 66 $tmp[$key] = $value; 67 } 68 } 69 $data['signatures'][] = $tmp; 70 } 71 72 return JsonConverter::encode($data); 73 } 74 75 /** 76 * @throws InvalidArgumentException if the input is not supported 77 */ 78 public function unserialize(string $input): JWS 79 { 80 $data = JsonConverter::decode($input); 81 if (!isset($data['signatures'])) { 82 throw new InvalidArgumentException('Unsupported input.'); 83 } 84 85 $isPayloadEncoded = null; 86 $rawPayload = $data['payload'] ?? null; 87 $signatures = []; 88 foreach ($data['signatures'] as $signature) { 89 if (!isset($signature['signature'])) { 90 throw new InvalidArgumentException('Unsupported input.'); 91 } 92 [$encodedProtectedHeader, $protectedHeader, $header] = $this->processHeaders($signature); 93 $signatures[] = [ 94 'signature' => Base64Url::decode($signature['signature']), 95 'protected' => $protectedHeader, 96 'encoded_protected' => $encodedProtectedHeader, 97 'header' => $header, 98 ]; 99 $isPayloadEncoded = $this->processIsPayloadEncoded($isPayloadEncoded, $protectedHeader); 100 } 101 102 $payload = $this->processPayload($rawPayload, $isPayloadEncoded); 103 $jws = new JWS($payload, $rawPayload); 104 foreach ($signatures as $signature) { 105 $jws = $jws->addSignature( 106 $signature['signature'], 107 $signature['protected'], 108 $signature['encoded_protected'], 109 $signature['header'] 110 ); 111 } 112 113 return $jws; 114 } 115 116 /** 117 * @throws InvalidArgumentException if the payload encoding is invalid 118 */ 119 private function processIsPayloadEncoded(?bool $isPayloadEncoded, array $protectedHeader): bool 120 { 121 if (null === $isPayloadEncoded) { 122 return $this->isPayloadEncoded($protectedHeader); 123 } 124 if ($this->isPayloadEncoded($protectedHeader) !== $isPayloadEncoded) { 125 throw new InvalidArgumentException('Foreign payload encoding detected.'); 126 } 127 128 return $isPayloadEncoded; 129 } 130 131 private function processHeaders(array $signature): array 132 { 133 $encodedProtectedHeader = $signature['protected'] ?? null; 134 $protectedHeader = null === $encodedProtectedHeader ? [] : JsonConverter::decode(Base64Url::decode($encodedProtectedHeader)); 135 $header = array_key_exists('header', $signature) ? $signature['header'] : []; 136 137 return [$encodedProtectedHeader, $protectedHeader, $header]; 138 } 139 140 private function processPayload(?string $rawPayload, ?bool $isPayloadEncoded): ?string 141 { 142 if (null === $rawPayload) { 143 return null; 144 } 145 146 return false === $isPayloadEncoded ? $rawPayload : Base64Url::decode($rawPayload); 147 } 148 149 // @throws LogicException if the payload encoding is invalid 150 private function checkPayloadEncoding(JWS $jws): void 151 { 152 if ($jws->isPayloadDetached()) { 153 return; 154 } 155 $is_encoded = null; 156 foreach ($jws->getSignatures() as $signature) { 157 if (null === $is_encoded) { 158 $is_encoded = $this->isPayloadEncoded($signature->getProtectedHeader()); 159 } 160 if (false === $jws->isPayloadDetached()) { 161 if ($is_encoded !== $this->isPayloadEncoded($signature->getProtectedHeader())) { 162 throw new LogicException('Foreign payload encoding detected.'); 163 } 164 } 165 } 166 } 167 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |