# partcp-php Library for leveraging the ParTCP protocol in PHP projects ## Requirements - PHP 8+ - php-sodium extension - YAML library (tested with [Symfony YAML component](https://github.com/symfony/yaml)) ## Usage You have to make sure that a YAML library is loaded and the yaml_emit() and yaml_parse() functions are available. The following code shows how this can be achieved when using the [Symfony YAML component](https://github.com/symfony/yaml) (without the Symfony framework): ```php if ( ! function_exists('yaml_parse') ){ require_once 'yaml/Exception/ExceptionInterface.php'; require_once 'yaml/Exception/RuntimeException.php'; require_once 'yaml/Exception/ParseException.php'; require_once 'yaml/Dumper.php'; require_once 'yaml/Escaper.php'; require_once 'yaml/Inline.php'; require_once 'yaml/Parser.php'; require_once 'yaml/Unescaper.php'; require_once 'yaml/Yaml.php'; function yaml_parse( $string ){ return Symfony\Component\Yaml\Yaml::parse( $string ); } function yaml_emit( $string ){ $option = Symfony\Component\Yaml\Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK | Symfony\Component\Yaml\Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE; return Symfony\Component\Yaml\Yaml::dump( $string, 3, 2, $option ); } } ``` Load the ParTCP PHP class files: ```php require_once 'crypto.class.php'; require_once 'key_storage.class.php'; require_once 'identity.class.php'; require_once 'incoming_message.class.php'; require_once 'outgoing_message.class.php'; ``` Set the base directory for storing identities: ```php ParTCP_Key_Storage::$storageDir = '/path/to/writable/directory'; ``` Or, if you have your own class for storing keys, register it with the ParTCP_Identity class: ```php ParTCP_Identity::$storage = 'My_Own_Key_Storage'; ``` Create a private (local) identity and submit the public key to a remote server: ```php $localId = new ParTCP_Private_Identity( 'name@server.tld', TRUE, TRUE ); $remoteId = new ParTCP_Public_Identity( 'server.tld', TRUE ); $msg = new ParTCP_Outgoing_Message( $remoteId, $localId, [ 'Message-Type' => 'key-submission', 'Credential~~' => $credential, 'Public-Key' => $localId->pubKey, ]); $msg->set_date(); $response = $msg->send(); ``` Check the response: ```php if ( $response['status'] != 200 ){ die('Could not connect to server'); } $msg = new ParTCP_Incoming_Message( $response['body'] ); if ( $msg->get('Message-Type') == 'Rejection-Notice' ){ die( 'Key submission rejected: ' . $msg->get('Rejection-Reason') ); } $result = $msg->get_signature_status(); if ( ! $result ){ die( 'Signature error: ' . $msg->signatureStatusMessage ); } ``` Use low-level crypto functions: ```php ParTCP_Crypto::set_remote_pubkey( $pubKey ); ParTCP_Crypto::set_local_privkey( $privKey ); $signature = ParTCP_Crypto::generate_signature( $data ); $verified = ParTCP_Crypto::verify_signature( $signature ); $encrypted = ParTCP_Crypto::encrypt( $data ); $decrypted = ParTCP_Crypto::decrypt( $encrypted ); ```