\n\n\n\n\n" ) ) * * Directions: "site-to-cp" (this plugin to the backend) and "cp-to-site" * (backend to this plugin). The path is the logical path, not the site URL. * * @package OrderPing */ defined( 'ABSPATH' ) || exit; const ORDERPING_MAX_SKEW_SECONDS = 300; const ORDERPING_NONCE_TTL = 600; /** * Computes the request signature. * * @param string $secret Per-store secret. * @param string $direction "site-to-cp" or "cp-to-site". * @param string $method HTTP method. * @param string $path Logical request path. * @param int $timestamp Unix seconds. * @param string $nonce Unique per request. * @param string $body Raw request body. * @return string Lowercase hex HMAC. */ function orderping_sign( $secret, $direction, $method, $path, $timestamp, $nonce, $body ) { $canonical = implode( "\n", array( 'v1', $direction, strtoupper( $method ), $path, (string) $timestamp, $nonce, hash( 'sha256', $body ), ) ); return hash_hmac( 'sha256', $canonical, $secret ); } /** * Verifies a request from the backend. Returns true, or a short failure code. * * @param string $secret Per-store secret. * @param string $direction Direction the request must have been signed for. * @param string $method HTTP method. * @param string $path Logical request path. * @param string $timestamp Timestamp header value. * @param string $nonce Nonce header value. * @param string $signature Signature header value. * @param string $body Raw request body. * @param int $now Current Unix time. * @return true|string */ function orderping_verify( $secret, $direction, $method, $path, $timestamp, $nonce, $signature, $body, $now ) { if ( ! preg_match( '/^\d{1,12}$/', $timestamp ) || ! preg_match( '/^[A-Za-z0-9_-]{16,64}$/', $nonce ) || ! preg_match( '/^[0-9a-fA-F]{64}$/', $signature ) ) { return 'malformed'; } if ( abs( $now - (int) $timestamp ) > ORDERPING_MAX_SKEW_SECONDS ) { return 'stale_timestamp'; } $expected = orderping_sign( $secret, $direction, $method, $path, (int) $timestamp, $nonce, $body ); if ( ! hash_equals( $expected, strtolower( $signature ) ) ) { return 'bad_signature'; } return true; }