\ * --version=7.23.1 \ * --package-url=https://.../argus-wordpress-defence-7.23.1.zip \ * --sha256= \ * [--min-php=7.4] [--min-wp=6.0] [--critical] \ * [--out=manifest.json] * * The signed payload's field set and order (version, released_at, * package_url, sha256, min_php, min_wp, critical) MUST exactly match * Argus_Update_Client::canonical_payload() -- any drift and every * signature this produces fails verification client-side. */ $args = array(); foreach ( $argv as $arg ) { if ( 0 === strpos( $arg, '--' ) ) { $parts = explode( '=', substr( $arg, 2 ), 2 ); $args[ $parts[0] ] = $parts[1] ?? true; } } function required( $args, $key ) { if ( empty( $args[ $key ] ) ) { fwrite( STDERR, "Missing required --{$key}\n" ); exit( 1 ); } return $args[ $key ]; } $private_key_b64 = required( $args, 'private-key' ); $version = required( $args, 'version' ); $package_url = required( $args, 'package-url' ); $sha256 = required( $args, 'sha256' ); $min_php = $args['min-php'] ?? '7.4'; $min_wp = $args['min-wp'] ?? '6.0'; $critical = ! empty( $args['critical'] ); $released_at = gmdate( 'c' ); $out = $args['out'] ?? ( dirname( __DIR__ ) . '/manifest.json' ); if ( 64 !== strlen( $sha256 ) || ! ctype_xdigit( $sha256 ) ) { fwrite( STDERR, "--sha256 must be a 64-character hex string (run: sha256sum )\n" ); exit( 1 ); } $private_key = base64_decode( $private_key_b64, true ); if ( false === $private_key || SODIUM_CRYPTO_SIGN_SECRETKEYBYTES !== strlen( $private_key ) ) { fwrite( STDERR, "--private-key is not a valid base64-encoded Ed25519 secret key\n" ); exit( 1 ); } // Must match Argus_Update_Client::canonical_payload() exactly -- same key // set, same order, same JSON_UNESCAPED_SLASHES flag. $ordered = array( 'version' => $version, 'released_at' => $released_at, 'package_url' => $package_url, 'sha256' => $sha256, 'min_php' => $min_php, 'min_wp' => $min_wp, 'critical' => $critical, ); $canonical = json_encode( $ordered, JSON_UNESCAPED_SLASHES ); $signature = sodium_crypto_sign_detached( $canonical, $private_key ); $manifest = $ordered; $manifest['signature'] = base64_encode( $signature ); file_put_contents( $out, json_encode( $manifest, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES ) . "\n" ); echo "Wrote {$out}\n"; echo " version: {$version}\n"; echo " package_url: {$package_url}\n"; echo " sha256: {$sha256}\n"; echo " critical: " . ( $critical ? 'true' : 'false' ) . "\n";