2626
2727/**
2828 * Works with JWS.
29+ *
30+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
2931 */
3032class JwsManager
3133{
@@ -77,20 +79,11 @@ public function __construct(
7779 */
7880 public function build (JwsInterface $ jws , EncryptionSettingsInterface $ encryptionSettings ): string
7981 {
80- if (!$ encryptionSettings instanceof JwsSignatureJwks) {
81- throw new JwtException ('Can only work with JWK encryption settings for JWS tokens ' );
82- }
83- $ signaturesCount = count ($ encryptionSettings ->getJwkSet ()->getKeys ());
84- if ($ jws ->getProtectedHeaders () && count ($ jws ->getProtectedHeaders ()) !== $ signaturesCount ) {
85- throw new MalformedTokenException ('Number of headers must equal to number of JWKs ' );
86- }
87- if ($ jws ->getUnprotectedHeaders ()
88- && count ($ jws ->getUnprotectedHeaders ()) !== $ signaturesCount
89- ) {
90- throw new MalformedTokenException ('There must be an equal number of protected and unprotected headers. ' );
91- }
82+ $ this ->validate ($ jws , $ encryptionSettings );
9283 $ builder = $ this ->jwsBuilder ->create ();
9384 $ builder = $ builder ->withPayload ($ jws ->getPayload ()->getContent ());
85+ $ signaturesCount = count ($ encryptionSettings ->getJwkSet ()->getKeys ());
86+
9487 for ($ i = 0 ; $ i < $ signaturesCount ; $ i ++) {
9588 $ jwk = $ encryptionSettings ->getJwkSet ()->getKeys ()[$ i ];
9689 $ protected = [];
@@ -101,6 +94,7 @@ public function build(JwsInterface $jws, EncryptionSettingsInterface $encryption
10194 $ protected ['kid ' ] = $ jwk ->getKeyId ();
10295 }
10396 if ($ jws ->getProtectedHeaders ()) {
97+ // phpcs:ignore Magento2.Performance.ForeachArrayMerge
10498 $ protected = array_merge ($ protected , $ this ->extractHeaderData ($ jws ->getProtectedHeaders ()[$ i ]));
10599 }
106100 $ protected ['alg ' ] = $ protected ['alg ' ] ?? $ jwk ->getAlgorithm ();
@@ -124,6 +118,28 @@ public function build(JwsInterface $jws, EncryptionSettingsInterface $encryption
124118 return $ this ->jwsSerializer ->serialize ('jws_compact ' , $ jwsCreated );
125119 }
126120
121+ /**
122+ * Validate jws and encryption settings.
123+ *
124+ * @param JwsInterface $jws
125+ * @param EncryptionSettingsInterface $encryptionSettings
126+ */
127+ private function validate (JwsInterface $ jws , EncryptionSettingsInterface $ encryptionSettings ): void
128+ {
129+ if (!$ encryptionSettings instanceof JwsSignatureJwks) {
130+ throw new JwtException ('Can only work with JWK encryption settings for JWS tokens ' );
131+ }
132+ $ signaturesCount = count ($ encryptionSettings ->getJwkSet ()->getKeys ());
133+ if ($ jws ->getProtectedHeaders () && count ($ jws ->getProtectedHeaders ()) !== $ signaturesCount ) {
134+ throw new MalformedTokenException ('Number of headers must equal to number of JWKs ' );
135+ }
136+ if ($ jws ->getUnprotectedHeaders ()
137+ && count ($ jws ->getUnprotectedHeaders ()) !== $ signaturesCount
138+ ) {
139+ throw new MalformedTokenException ('There must be an equal number of protected and unprotected headers. ' );
140+ }
141+ }
142+
127143 /**
128144 * Read and verify JWS token.
129145 *
0 commit comments