= 28 ) { $plain = openssl_decrypt( substr( $raw, 28 ), 'aes-256-gcm', $key, OPENSSL_RAW_DATA, substr( $raw, 0, 12 ), substr( $raw, 12, 16 ) ); return false === $plain ? null : $plain; } if ( 0 === strpos( $blob, 's1:' ) && strlen( $raw ) > SODIUM_CRYPTO_SECRETBOX_NONCEBYTES ) { try { $plain = sodium_crypto_secretbox_open( substr( $raw, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES ), substr( $raw, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES ), $key ); } catch ( \Throwable $e ) { return null; } return false === $plain ? null : $plain; } return null; } /** * Whether openssl AES-256-GCM is available. */ public static function has_gcm() { return function_exists( 'openssl_encrypt' ) && in_array( 'aes-256-gcm', openssl_get_cipher_methods(), true ); } /** * Reads an encrypted array option. Returns the default when missing or undecryptable. * * @param string $name Option name. * @param array $default Default. * @return array */ public static function get_option( $name, $default = array() ) { $blob = get_option( $name, '' ); if ( '' === $blob || ! is_string( $blob ) ) { return $default; } $plain = self::decrypt( $blob ); if ( null === $plain ) { return $default; } $data = json_decode( $plain, true ); return is_array( $data ) ? $data : $default; } /** * Whether an encrypted option exists but cannot be decrypted (salts changed). * * @param string $name Option name. */ public static function is_unreadable( $name ) { $blob = get_option( $name, '' ); return is_string( $blob ) && '' !== $blob && null === self::decrypt( $blob ); } /** * Saves an array option encrypted, never autoloaded. * * @param string $name Option name. * @param array $value Value. */ public static function update_option( $name, array $value ) { update_option( $name, self::encrypt( (string) wp_json_encode( $value ) ), false ); } /** * URL-safe base64 helpers. * * @param string $bytes Bytes. */ public static function b64url_encode( $bytes ) { return rtrim( strtr( base64_encode( $bytes ), '+/', '-_' ), '=' ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode } /** * Decodes URL-safe base64. Returns false when invalid. * * @param string $text Text. * @return string|false */ public static function b64url_decode( $text ) { $text = strtr( (string) $text, '-_', '+/' ); $pad = strlen( $text ) % 4; if ( $pad ) { $text .= str_repeat( '=', 4 - $pad ); } return base64_decode( $text, true ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode } }