Skip to content

Commit 1582c1f

Browse files
authored
Signature: Don't use param as component (#1892)
1 parent bbb6357 commit 1582c1f

File tree

1 file changed

+24
-20
lines changed

1 file changed

+24
-20
lines changed

includes/signature/class-http-message-signature.php

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ public function sign( $args, $url ) {
3636
'"@method"' => \strtoupper( $args['method'] ),
3737
'"@target-uri"' => $url,
3838
'"@authority"' => \wp_parse_url( $url, PHP_URL_HOST ),
39-
'"created"' => \strtotime( $args['headers']['Date'] ), // Required by Mastodon. See https://github.com/mastodon/mastodon/pull/34814.
4039
);
4140
$identifiers = \array_keys( $components );
4241

@@ -49,7 +48,7 @@ public function sign( $args, $url ) {
4948
}
5049

5150
$params = array(
52-
'created' => $components['"created"'],
51+
'created' => \strtotime( $args['headers']['Date'] ),
5352
'keyid' => $args['key_id'],
5453
'alg' => 'rsa-v1_5-sha256',
5554
);
@@ -61,7 +60,7 @@ public function sign( $args, $url ) {
6160
\openssl_sign( $signature_base, $signature, $args['private_key'], \OPENSSL_ALGO_SHA256 );
6261
$signature = \base64_encode( $signature );
6362

64-
$args['headers']['Signature-Input'] = 'wp=(' . \implode( ' ', $identifiers ) . ');created=' . $components['"created"'] . ';keyid="' . $args['key_id'] . '";alg="rsa-v1_5-sha256"';
63+
$args['headers']['Signature-Input'] = 'wp=(' . \implode( ' ', $identifiers ) . ')' . $this->get_params_string( $params );
6564
$args['headers']['Signature'] = 'wp=:' . $signature . ':';
6665

6766
return $args;
@@ -188,7 +187,8 @@ private function verify_signature_label( $data, $headers, $body ) {
188187
return $result;
189188
}
190189

191-
$signature_base = $this->get_signature_base_string( $data['components'], $params, $headers );
190+
$components = $this->get_component_values( $data['components'], $headers );
191+
$signature_base = $this->get_signature_base_string( $components, $params );
192192

193193
$verified = \openssl_verify( $signature_base, $data['signature'], $public_key, $algorithm ) > 0;
194194
if ( ! $verified ) {
@@ -313,34 +313,43 @@ private function verify_algorithm( $alg_string, $public_key ) {
313313
*
314314
* @param array $components Signature components.
315315
* @param array $params Signature params.
316-
* @param array $headers Optional. The HTTP headers. Default: empty array.
317316
*
318317
* @return string Base string to compare signature with.
319318
*/
320-
private function get_signature_base_string( $components, $params, $headers = array() ) {
319+
private function get_signature_base_string( $components, $params ) {
321320
$signature_base = '';
322321

323-
// We only get component names when we verify a signature and have to get their values.
324-
if ( \array_is_list( $components ) ) {
325-
$components = $this->get_component_values( $components, \array_merge( $params, $headers ) );
326-
}
327-
328322
foreach ( $components as $component => $value ) {
329323
$signature_base .= $component . ': ' . $value . "\n";
330324
}
331325

332326
$signature_base .= '"@signature-params": (' . \implode( ' ', \array_keys( $components ) ) . ')';
327+
$signature_base .= $this->get_params_string( $params );
328+
329+
return $signature_base;
330+
}
331+
332+
/**
333+
* Returns the signature params in a string format.
334+
*
335+
* @param array $params Signature params.
336+
*
337+
* @return string Signature params.
338+
*/
339+
private function get_params_string( $params ) {
340+
$signature_params = '';
341+
333342
foreach ( $params as $key => $value ) {
334343
if ( \is_numeric( $value ) ) {
335-
$signature_base .= ';' . $key . '=' . $value; // No quotes.
344+
$signature_params .= ';' . $key . '=' . $value; // No quotes.
336345
} else {
337346
// Escape backslashes and double quotes per RFC-9421.
338-
$value = \str_replace( array( '\\', '"' ), array( '\\\\', '\\"' ), $value );
339-
$signature_base .= ';' . $key . '="' . $value . '"'; // Double quotes.
347+
$value = \str_replace( array( '\\', '"' ), array( '\\\\', '\\"' ), $value );
348+
$signature_params .= ';' . $key . '="' . $value . '"'; // Double quotes.
340349
}
341350
}
342351

343-
return $signature_base;
352+
return $signature_params;
344353
}
345354

346355
/**
@@ -359,11 +368,6 @@ private function get_component_values( $components, $headers ) {
359368
$key = \strtolower( \trim( $key, '"' ) );
360369

361370
switch ( $key ) {
362-
case 'created':
363-
case 'expires':
364-
$value = (int) $headers[ $key ] ?? 0;
365-
break;
366-
367371
case '@method':
368372
$value = $_SERVER['REQUEST_METHOD'] ?? 'GET';
369373
break;

0 commit comments

Comments
 (0)