<?php class ParTCP_Incoming_Message { public $signatureStatus; public $signatureStatusMessage; public $data; public $rawMessage; public $senderPubKey; public $encryptedElements = []; private $crypto; // an object providing crypto functions private $keyRetrievalFunction; // callback for retrieving public key of an identity public function __construct( $rawMessage, $cryptoObject, $keyRetrievalFunction = NULL ){ $this->crypto = $cryptoObject; $this->keyRetrievalFunction = $keyRetrievalFunction; $this->rawMessage = str_replace( ["\r\n", "\r"], "\n", trim( $rawMessage ) ); $this->data = yaml_parse( $this->rawMessage ); var_dump( $this->data ); if ( ! $this->data ){ return; } $senderKey = $this->get_sender_key( TRUE ); if ( ! $senderKey ){ return; } foreach ( $this->data as $key => $value ){ if ( substr( $key, -1 ) == '~' ){ $key = substr( $key, 0, -1 ); $this->encryptedElements[] = $key; $decrypted = $this->crypto->decrypt( $value, $senderKey ); if ( $decrypted !== FALSE ){ $this->data[ $key ] = $decrypted; } } } } public function get( $name ){ return $this->data[ $name ] ?? NULL; } public function is_encrypted( $key ){ return in_array( $key, $this->encryptedElements ); } private function get_sender_key( $forCrypto = FALSE ){ if ( is_null( $this->senderPubKey ) ){ if ( $forCrypto && $pubKey = $this->get('Public-Key') ){ $this->senderPubKey = $pubKey; } else { $sender = $this->get('From'); if ( $sender && is_callable( $this->keyRetrievalFunction ) ){ $this->senderPubKey = call_user_func( $this->keyRetrievalFunction, $sender, $this ); } } } if ( empty( $this->senderPubKey ) ){ return FALSE; } return $this->senderPubKey; } public function get_signature_status( $useEmbeddedKey = FALSE ){ if ( ! $signature = $this->get('Signature') ){ $this->signatureStatus = -1; $this->signatureStatusMessage = 'Missing signature'; return FALSE; } if ( $useEmbeddedKey ){ if ( ! $key = $this->get('Public-Key') ){ $this->signatureStatus = -3; $this->signatureStatusMessage = 'Missing public key'; return FALSE; } } else { if ( ! $this->get('From') ){ $this->signatureStatus = -5; $this->signatureStatusMessage = 'Missing sender'; return FALSE; } $key = $this->get_sender_key(); if ( ! $key ){ $this->signatureStatus = -6; $this->signatureStatusMessage = 'Unknown sender'; return FALSE; } } $unsignedMessage = substr( $this->rawMessage, strpos( $this->rawMessage, "\n" ) + 1 ); $success = $this->crypto->verify_signature( $signature, $unsignedMessage, $key ); if ( ! $success ){ $this->signatureStatus = -9; $this->signatureStatusMessage = 'Verification failed (' . $this->crypto->lastError . ')'; return FALSE; } $this->signatureStatus = 1; $this->signatureStatusMessage = 'Signature verified successfully'; return TRUE; } } // end of file incoming_message.class.php