24576){throw new InvalidArgumentException('core_record_capacity');} $record=json_decode($raw,true,16,JSON_THROW_ON_ERROR); if(!is_array($record)){throw new InvalidArgumentException('core_record_format');} return $record; } private static function binding(array $request,string $generation): array { OG_Native_Remote_Binding::encode($request); if(!preg_match('/^[a-f0-9]{32}$/D',$generation)){throw new InvalidArgumentException('generation');} return array('install'=>$request['install'],'namespace'=>$request['namespace'], 'request_id'=>$request['request_id'],'generation'=>$generation, 'operation_id'=>$request['operation_id'],'request_digest'=>OG_Native_Remote_Binding::digest($request)); } private static function mac(array $body,#[SensitiveParameter] string $secret): string { if(!preg_match('/^[a-f0-9]{64}$/D',$secret)){throw new InvalidArgumentException('secret');} return hash_hmac('sha256',"og-native-core-observation-v1\n".OG_Native_Remote_Binding::canonical($body),hex2bin($secret)); } public static function seal(array $request,string $generation,string $store,string $nonce,string $proof,#[SensitiveParameter] string $secret,array $active,array $history=array(),array $revoked=array(),string $environment='production'): ?string { try { $binding=self::binding($request,$generation); $verified=OG_Native_Core_Proof::verify($request,$store,$nonce,$proof,$active,$history,$revoked,$environment); if($verified['status']!=='authenticated_remote_core'){return null;} $body=array('version'=>'og-native-core-observation-v1','binding'=>$binding, 'store_domain'=>$store,'nonce'=>$nonce,'proof'=>$proof); return OG_Native_Remote_Binding::canonical(array('body'=>$body,'hmac'=>self::mac($body,$secret))); }catch(Throwable $e){return null;} } public static function read(array $request,string $generation,string $store,string $raw,#[SensitiveParameter] string $secret,array $active,array $history=array(),array $revoked=array(),string $environment='production'): array { $unknown=array('status'=>'remote_unknown','erasure_complete'=>false,'local_cleanup_authorized'=>false); try { $record=self::decode($raw); if(!is_array($record)||array_keys($record)!==array('body','hmac')||OG_Native_Remote_Binding::canonical($record)!==$raw|| !is_array($record['body'])||!is_string($record['hmac'])){return $unknown;} $body=$record['body']; if(array_keys($body)!==array('version','binding','store_domain','nonce','proof')|| $body['version']!=='og-native-core-observation-v1'||$body['binding']!==self::binding($request,$generation)|| $body['store_domain']!==$store||!hash_equals(self::mac($body,$secret),$record['hmac'])){return $unknown;} // A saved wrapper may now have a historical signer. Both registries // are independently configured; conflicting material always refuses. $active=OG_Native_Remote_Binding::validateRegistry($active); $history=OG_Native_Remote_Binding::validateRegistry($history); foreach($history as $id=>$key){if(isset($active[$id])&&$active[$id]!==$key){return $unknown;}} $verified=OG_Native_Core_Proof::verify($request,$store,$body['nonce'],$body['proof'],$active+$history,array(),$revoked,$environment); if($verified['status']!=='authenticated_remote_core'){return $unknown;} return array_merge($verified,array('status'=>'server_committed_core','erasure_complete'=>false, 'local_cleanup_authorized'=>false,'next_action'=>'guarded_recovery_required')); }catch(Throwable $e){return $unknown;} } }