diff --git a/tester/server/php/.env b/tester/server/php/.env deleted file mode 100644 index d21bb957a0b6e0a63f10aa1c885e57d09e263790..0000000000000000000000000000000000000000 --- a/tester/server/php/.env +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env bash -# All versions are set to more or less the latest at writting time -# it shall be safe to use latest instead but just in case, this -# configuration is known to work. - -# Nginx. Do not change the name or self signed certicate will fail -NGINX_HOST=localhost -NGINX_VERSION=1.13.12 - -# PHP -PHP_VERSION=7.2 - -#PHPMYADMIN -PHPMYADMIN_VERSION=4.8.0-3 - -# MySQL -MYSQL_VERSION=5.7.22 -# host name must match what is used in x3dh server setting -MYSQL_HOST=mysql -MYSQL_ROOT_USER=root -MYSQL_ROOT_PASSWORD=root diff --git a/tester/server/php/README.md b/tester/server/php/README.md deleted file mode 100644 index b603fe50f7d38a9d79d641e554a0158cbed3e518..0000000000000000000000000000000000000000 --- a/tester/server/php/README.md +++ /dev/null @@ -1,97 +0,0 @@ -README for the X3DH test server running on nginx/php/mysql docker images -======================================================================== - -Disclaimer ------------ -THIS SERVER IS NOT INTENDED FOR REAL USE BUT FOR TEST PURPOSE ONLY -DO NOT USE IN REAL LIFE IT IS NOT SECURE. - -Mostly, it is missing clients authentication. Providing a client -authentication layer before calling the x3dh_process_request function -SHOULD be enough to use it in a real situation. - -As usual, this code is distributed in the hope it will be usefull but -without any warranty or implied warranty. - - -Requirements ------------- -- docker-compose - -Install -------- -**Permissions:** -Check that the ./source/var/log directory is writable by anyone - -**Certificates:** -The X3DH servers use ./source/cn/x3dh-cert.pem and source/cn/x3dh-key.pem -By default it is the certificate available to test client in tester/data - -**Database:** -The database is accessible through phpmyadmin on localhost:8080 -User : root -Password : root - -To reset it, just delete the content of ./db/mysql directory. - -**Images version:** -All images points to version more or less matching the latest -at the time this is being written. - - -Content and Settings --------------------- - -./.env : docker-compose environment variables (https://docs.docker.com/compose/environment-variables/#the-env-file) - - images version - - mysql root password and host name - - nginx host name - -./customphp.ini : the php.ini configuration file - - make sure the error display is turned off - - set the path to error logs: /source/var/log/php-error.log - -./site.conf: the nginx sites configuration file spawning: - - http://localhost:8080 the phpmyadmin access - - https://localhost:25519 and https://localhost:25520 the X3DH test servers - -./docker-compose.yml : set images for - - nginx - - php - - phpmyadmin (used to help debugging if needed) - - mysql : acces on port 3306, user: root, password: root - -./db/mysql/ : directory used by mysql container to store all its data. - - When container is down, erase the content of this to force a DB reset at next up - -./db/initdb.d/ : contains SQL scripts executed at mysql container setup (first intanciation of the mysql container) - - x3dh25519.sql : set up the database for the x3dh-25519.php server - - x3dh448.sql : set up the database for the x3dh-448.php server - -./source/cn/: self signed certificate used by https server - -./source/x3dh/ : php sources of X3DH server. - - x3dh-25519.php : the settings file for the x3dh server running on curve 25519 - - x3dh-448.php : the settings file for the x3dh server running on curve 448 - - x3dh.php : the actual server source - - x3dh-createBase.php : a script to create the X3DH server database as needed. - It is not active by default and not used, just provided as example. - -./source/var/log : directory were the x3dh server and php logs are written, make sur it is writable - - php-error.log : the php logs - - X3DH25519.log : logs from X3DH 25519 server - - X3DH448.log : logs from X3DH 448 server - - -Usage ------ -start: -docker-compose up -d -(run without -d options to see full logs in the console, can be wise for the first runs) - -This command run 2 X3DH servers accessible at: -- https://localhost:25519 using curve25519 -- https://localhost:25520 using curve448 - -stop: -docker-compose down --volumes diff --git a/tester/server/php/customphp.ini b/tester/server/php/customphp.ini deleted file mode 100644 index d817c3d7b3cdd37b4e97d8466be51a1c953cacce..0000000000000000000000000000000000000000 --- a/tester/server/php/customphp.ini +++ /dev/null @@ -1,4 +0,0 @@ -log_errors = On -error_log = /source/var/log/php-error.log -display_errors = Off -date.timezone = UTC diff --git a/tester/server/php/db/initdb.d/x3dh25519.sql b/tester/server/php/db/initdb.d/x3dh25519.sql deleted file mode 100644 index 6906ec6ff51a2e6d23e7354ffafea3a8e1e68921..0000000000000000000000000000000000000000 --- a/tester/server/php/db/initdb.d/x3dh25519.sql +++ /dev/null @@ -1,41 +0,0 @@ -SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; -SET AUTOCOMMIT = 0; - -DROP DATABASE IF EXISTS `x3dh25519`; -CREATE DATABASE `x3dh25519` CHARACTER SET utf8 COLLATE utf8_bin; -USE `x3dh25519`; - -START TRANSACTION; - -DROP TABLE IF EXISTS `Users`; -CREATE TABLE `Users` ( - `Uid` INTEGER NOT NULL AUTO_INCREMENT, - `UserId` TEXT COLLATE utf8_bin NOT NULL, - `Ik` BLOB NOT NULL, - `SPk` BLOB DEFAULT NULL, - `SPk_sig` BLOB DEFAULT NULL, - `SPk_id` INTEGER UNSIGNED DEFAULT NULL, - PRIMARY KEY(`Uid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; - -DROP TABLE IF EXISTS `OPk`; -CREATE TABLE `OPk` ( - `id` INTEGER NOT NULL AUTO_INCREMENT, - `Uid` INTEGER NOT NULL, - `OPk` BLOB NOT NULL, - `OPk_id` INTEGER UNSIGNED NOT NULL, - PRIMARY KEY(`id`), - FOREIGN KEY(`Uid`) REFERENCES Users(`Uid`) ON UPDATE CASCADE ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; - -DROP TABLE IF EXISTS `Config`; -CREATE TABLE `Config` ( - `Name` VARCHAR(20) COLLATE utf8_bin DEFAULT NULL, - `Value` INTEGER NOT NULL -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; - -INSERT INTO `Config` (`Name`, `Value`) VALUES -('version', 1), -('curveId', 25519); - -COMMIT; diff --git a/tester/server/php/db/initdb.d/x3dh448.sql b/tester/server/php/db/initdb.d/x3dh448.sql deleted file mode 100644 index eadf2045b4fb68ea240255430a3ef968527f28cd..0000000000000000000000000000000000000000 --- a/tester/server/php/db/initdb.d/x3dh448.sql +++ /dev/null @@ -1,41 +0,0 @@ -SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; -SET AUTOCOMMIT = 0; - -DROP DATABASE IF EXISTS `x3dh448`; -CREATE DATABASE `x3dh448` CHARACTER SET utf8 COLLATE utf8_bin; -USE `x3dh448`; - -START TRANSACTION; - -DROP TABLE IF EXISTS `Users`; -CREATE TABLE `Users` ( - `Uid` INTEGER NOT NULL AUTO_INCREMENT, - `UserId` TEXT COLLATE utf8_bin NOT NULL, - `Ik` BLOB NOT NULL, - `SPk` BLOB DEFAULT NULL, - `SPk_sig` BLOB DEFAULT NULL, - `SPk_id` INTEGER UNSIGNED DEFAULT NULL, - PRIMARY KEY(`Uid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; - -DROP TABLE IF EXISTS `OPk`; -CREATE TABLE `OPk` ( - `id` INTEGER NOT NULL AUTO_INCREMENT, - `Uid` INTEGER NOT NULL, - `OPk` BLOB NOT NULL, - `OPk_id` INTEGER UNSIGNED NOT NULL, - PRIMARY KEY(`id`), - FOREIGN KEY(`Uid`) REFERENCES Users(`Uid`) ON UPDATE CASCADE ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; - -DROP TABLE IF EXISTS `Config`; -CREATE TABLE `Config` ( - `Name` VARCHAR(20) COLLATE utf8_bin DEFAULT NULL, - `Value` INTEGER NOT NULL -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; - -INSERT INTO `Config` (`Name`, `Value`) VALUES -('version', 1), -('curveId', 448); - -COMMIT; diff --git a/tester/server/php/db/mysql/.gitignore b/tester/server/php/db/mysql/.gitignore deleted file mode 100644 index 5e7d2734cfc60289debf74293817c0a8f572ff32..0000000000000000000000000000000000000000 --- a/tester/server/php/db/mysql/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# Ignore everything in this directory -* -# Except this file -!.gitignore diff --git a/tester/server/php/docker-compose.yml b/tester/server/php/docker-compose.yml deleted file mode 100644 index 557359ac56a090e2767b5369a3172a966bdc1a91..0000000000000000000000000000000000000000 --- a/tester/server/php/docker-compose.yml +++ /dev/null @@ -1,51 +0,0 @@ -version: '2' - -services: - web: - image: nginx:${NGINX_VERSION} - ports: - - "25519:25519" - - "25520:25520" - volumes: - - ./source:/source - - ./site.conf:/etc/nginx/conf.d/default.conf - restart: always - depends_on: - - php - - mysqldb - - php: - # use nanoninja php image to get mysqli - # https://hub.docker.com/r/nanoninja/php-fpm/tags/ - image: nanoninja/php-fpm:${PHP_VERSION} - volumes: - - ./source:/source - - ./customphp.ini:/usr/local/etc/php/conf.d/custom.ini - restart: always - - myadmin: - image: phpmyadmin/phpmyadmin:${PHPMYADMIN_VERSION} - container_name: phpmyadmin - ports: - - "8080:80" - environment: - - PMA_ARBITRARY=1 - - PMA_HOST=${MYSQL_HOST} - restart: always - depends_on: - - mysqldb - - mysqldb: - image: mysql:${MYSQL_VERSION} - container_name: ${MYSQL_HOST} - restart: always - env_file: - - ".env" - environment: - - MYSQL_DATABASE=${MYSQL_DATABASE} - - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} - ports: - - "8989:3306" - volumes: - - "./db/mysql:/var/lib/mysql" - - "./db/initdb.d:/docker-entrypoint-initdb.d" diff --git a/tester/server/php/site.conf b/tester/server/php/site.conf deleted file mode 100644 index 8b18a4268328a9b4bff4b8b6e178e79e42a3b07e..0000000000000000000000000000000000000000 --- a/tester/server/php/site.conf +++ /dev/null @@ -1,45 +0,0 @@ -server { - listen 25519 ssl default_server; - listen [::]:25519 ssl default_server; - ssl_certificate /source/cn/x3dh-cert.pem; - ssl_certificate_key /source/cn/x3dh-key.pem; - server_name localhost; - - index x3dh/x3dh-25519.php; - error_log /var/log/nginx/error.log; - access_log /var/log/nginx/access.log; - root /source; - - location ~ \.php$ { - try_files $uri =404; - fastcgi_split_path_info ^(.+\.php)(/.+)$; - fastcgi_pass php:9000; - fastcgi_index index.php; - include fastcgi_params; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - fastcgi_param PATH_INFO $fastcgi_path_info; - } -} - -server { - listen 25520 ssl default_server; - listen [::]:25520 ssl default_server; - ssl_certificate /source/cn/x3dh-cert.pem; - ssl_certificate_key /source/cn/x3dh-key.pem; - server_name localhost; - - index x3dh/x3dh-448.php; - error_log /var/log/nginx/error.log; - access_log /var/log/nginx/access.log; - root /source; - - location ~ \.php$ { - try_files $uri =404; - fastcgi_split_path_info ^(.+\.php)(/.+)$; - fastcgi_pass php:9000; - fastcgi_index index.php; - include fastcgi_params; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - fastcgi_param PATH_INFO $fastcgi_path_info; - } -} diff --git a/tester/server/php/source/cn/x3dh-cert.pem b/tester/server/php/source/cn/x3dh-cert.pem deleted file mode 100644 index 16a3de8c2179cb46574f3320879d85784c91e3d4..0000000000000000000000000000000000000000 --- a/tester/server/php/source/cn/x3dh-cert.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIEnjCCAwagAwIBAgIJAOIhBkBz+NzWMA0GCSqGSIb3DQEBCwUAMFkxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQxEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0xODA0MzAwMjQ2 -MzNaFw0yODA0MjcwMjQ2MzNaMFkxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21l -LVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEjAQBgNV -BAMMCWxvY2FsaG9zdDCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAK+Y -ZC3KPmB4XjGjDos6Tr1EFWCGkt3RAF1B/KNvXVvM2vve56yhjHM2PtHFBr9/JXCC -iZZq7fc/bN4JusZMWGDhs3EXAuP56/ydZ6X7eaYjRKXrClm1bKde1vSd3cTfiqDN -0YsrQfpW+6XK3stRAob0IKmQbcDjlrGjj8cUNd0YWfBLqkFvfpZALn4uwXXEGs+k -d9hijwXBwJhigzRVoazjZJWd57i+dKDxNzKRmlifMhFaBgh26Knx9F51JcMZbBJn -9bMQDjPc7l5yX0hmTyHouydA7ALCuIUVF/fhvJX+jwrGEMTraSl+ieLYWEtHkit8 -Vg5BEJXnitGFuGW3UelHz/sj/t9LDqBLAjrDVoebAFj0W0e1hSIQfmNNx2Q52j7U -TTH24wUqCOaWh4zqqcl4NlgJORqco1BjAGUNkkqhJnrzcSkoHBrcfWtvej+eoxo2 -IiCU8trxCyrTN5KMk0i/jXNVb2nChR3WZNvTQV60jKm8/zgX0kvkbLmgMxY8uQID -AQABo2kwZzAUBgNVHREEDTALgglsb2NhbGhvc3QwHQYDVR0OBBYEFGwQgyXv3x7h -lGhIRpgniBEr6Y6/MB8GA1UdIwQYMBaAFGwQgyXv3x7hlGhIRpgniBEr6Y6/MA8G -A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggGBACeOV0fk0gNlHcMJr5y3 -8ikVxElAbOjwa6WkOXDmCqp9ju33dvjC+F4kI4XWxVY/JeO5cPAYQNz6uIX0EGue -ynENSHKTnnJddCrcWkR50qAeo/vUHRzqiPyIQXxallp6qGxpDPJujVEfssnG6ZWm -JHrEbWa7YlXaDCzoy2L0CbXhRn4hFAC63+ReTec9y3cJo7zaZ07+xXi8oKO4pI/x -FXD4Xmmrs34JJNyWTaAw5a1na0Tuf8nxs+GkiuG8K1zthLjMZ1v+VjiMwzZw1MsQ -+8Z9fqkOjApmrtFpn2BD06AYobjopsSEzlsFyX4v49142bKmFCxzA3d88rL7hWH9 -6SC2hM4bgdQK1vP2vgNoGfdzew7R9Cszi1ApsXHbjCllldtMxySzivOJi7CuU6CF -PE5RjQ1uRKgazfFmBMuLHkE8aaPSiJOusrzmxHoE5QV5CmlE6H06PiQEPYA5v36C -Z9hMTT7bUxCA2r/2xcrqmF982HKrBbGZ2mt9O8HeF2SvIg== ------END CERTIFICATE----- diff --git a/tester/server/php/source/cn/x3dh-key.pem b/tester/server/php/source/cn/x3dh-key.pem deleted file mode 100644 index f2b7b067b6aacf675d7801f8c9c93f4b310e756c..0000000000000000000000000000000000000000 --- a/tester/server/php/source/cn/x3dh-key.pem +++ /dev/null @@ -1,39 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -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 ------END RSA PRIVATE KEY----- diff --git a/tester/server/php/source/var/log/.gitignore b/tester/server/php/source/var/log/.gitignore deleted file mode 100644 index 5e7d2734cfc60289debf74293817c0a8f572ff32..0000000000000000000000000000000000000000 --- a/tester/server/php/source/var/log/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# Ignore everything in this directory -* -# Except this file -!.gitignore diff --git a/tester/server/php/source/x3dh/x3dh-25519.php b/tester/server/php/source/x3dh/x3dh-25519.php deleted file mode 100644 index fdaaa3c0098a7449e68ff1de398e04269fa980c9..0000000000000000000000000000000000000000 --- a/tester/server/php/source/x3dh/x3dh-25519.php +++ /dev/null @@ -1,49 +0,0 @@ -<?php -/* - x3dh-25519.php - @author Johan Pascal - @copyright Copyright (C) 2018 Belledonne Communications SARL - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - - - -include "x3dh.php"; - -/*** X3DH server settings ***/ -// Curve to use, shall be either CurveId::CURVE25519 or CurveId::CURVE25519 -define ("curveId", CurveId::CURVE25519); - -// Database access -define("DB_HOST", "mysql"); -define("DB_USER", "root"); -define("DB_PASSWORD", "root"); -// this database must already exists with the requested tables -define ("DB_NAME", "x3dh25519"); - -// log level one of (LogLevel::DISABLED, ERROR, WARNING. MESSAGE, DEBUG) -// default to DISABLED (recommended value) -define ("x3dh_logLevel" , LogLevel::MESSAGE); -define ("x3dh_logFile", "/source/var/log/X3DH25519.log"); // make sure to have actual write permission to this file -define ("x3dh_logDomain", "X3DH"); // in case Logs are mixed with other applications ones, format is [time tag] -Domain- message - -/*** End of X3DH server settings ***/ - -// That one shall be set by the user authentication layer -$userId = $_SERVER['HTTP_FROM']; - -x3dh_process_request($userId); - -?> diff --git a/tester/server/php/source/x3dh/x3dh-448.php b/tester/server/php/source/x3dh/x3dh-448.php deleted file mode 100644 index 6458844d59b597a93d151fa1db1d4aa441fbd70c..0000000000000000000000000000000000000000 --- a/tester/server/php/source/x3dh/x3dh-448.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php -/* - x3dh-448.php - @author Johan Pascal - @copyright Copyright (C) 2018 Belledonne Communications SARL - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - - - - -include "x3dh.php"; - -/*** X3DH server settings ***/ -// Curve to use, shall be either CurveId::CURVE25519 or CurveId::CURVE25519 -define ("curveId", CurveId::CURVE448); - -// Database access -define("DB_HOST", "mysql"); -define("DB_USER", "root"); -define("DB_PASSWORD", "root"); -// this database must already exists with the requested tables -define ("DB_NAME", "x3dh448"); - -// log level one of (LogLevel::DISABLED, ERROR, WARNING. MESSAGE, DEBUG) -// default to DISABLED (recommended value) -define ("x3dh_logLevel" , LogLevel::MESSAGE); -define ("x3dh_logFile", "/source/var/log/X3DH448.log"); // make sure to have actual write permission to this file -define ("x3dh_logDomain", "X3DH"); // in case Logs are mixed with other applications ones, format is [time tag] -Domain- message - -/*** End of X3DH server settings ***/ - -// That one shall be set by the user authentication layer -$userId = $_SERVER['HTTP_FROM']; - -x3dh_process_request($userId); - -?> diff --git a/tester/server/php/source/x3dh/x3dh-createBase.php b/tester/server/php/source/x3dh/x3dh-createBase.php deleted file mode 100644 index c1cbc2e4b7558deaf656fafad5acd9fa2fd3b0f4..0000000000000000000000000000000000000000 --- a/tester/server/php/source/x3dh/x3dh-createBase.php +++ /dev/null @@ -1,98 +0,0 @@ -<?php -/* - x3dh-createBase.php - @author Johan Pascal - @copyright Copyright (C) 2018 Belledonne Communications SARL - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - - -// Database access -define("DB_HOST", "mysql"); -define("DB_USER", "root"); -define("DB_PASSWORD", "root"); - -$curve = $_GET['curve']; - -if ($curve != 448 ) { // Default is curve25519 - $curve=25519; -} - -function x3dh_create_db($dbname, $curve) { - $db = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD); - if (!$db) { - error_log ("Error: Unable to connect to MySQL.\nDebugging errno: " . mysqli_connect_errno() . "\nDebugging error: " . mysqli_connect_error() . "\n"); - exit; - } - - // get a clean base - $db->query("DROP DATABASE IF EXISTS $dbname"); - $db->query("CREATE DATABASE $dbname CHARACTER SET utf8 COLLATE utf8_bin"); - - // select DB - $db->select_db($dbname); - - /* Users table: - * - id as primary key (internal use) - * - a userId(shall be the GRUU) - * - Ik (Identity key - EDDSA public key) - * - SPk(the current signed pre-key - ECDH public key) - * - SPk_sig(current SPk public key signed with Identity key) - * - SPh_id (id for SPk provided and internally used by client) - 4 bytes unsigned integer - */ - - /* One Time PreKey table: - * - an id as primary key (internal use) - * - the Uid of user owning that key - * - the public key (ECDH public key) - * - OPk_id (id for OPk provided and internally used by client) - 4 bytes unsigned integer - */ - - /* Config table: holds version and curveId parameters: - * - Name: the parameter name (version or curveId) - * - Value: the parameter value (db version scheme or curveId mapped to an integer) - */ - - $db->query("CREATE TABLE Users ( - Uid INTEGER NOT NULL AUTO_INCREMENT, - UserId TEXT NOT NULL, - Ik BLOB NOT NULL, - SPk BLOB DEFAULT NULL, - SPk_sig BLOB DEFAULT NULL, - SPk_id INTEGER UNSIGNED DEFAULT NULL, - PRIMARY KEY(Uid));"); - - $db->query("CREATE TABLE OPk ( - id INTEGER NOT NULL AUTO_INCREMENT, - Uid INTEGER NOT NULL, - OPk BLOB NOT NULL, - OPk_id INTEGER UNSIGNED NOT NULL, - PRIMARY KEY(id), - FOREIGN KEY(Uid) REFERENCES Users(Uid) ON UPDATE CASCADE ON DELETE CASCADE);"); - - $db->query("CREATE TABLE Config( - Name VARCHAR(20), - Value INTEGER NOT NULL);"); - - $db->query("INSERT INTO Config(Name, Value) VALUES('version', 0x000001)"); // version of DB scheme MMmmpp - $db->query("INSERT INTO Config(Name, Value) VALUES('curveId', $curve)"); // what curveId we're using - - $db->close(); -} - -// Uncomment next line if you really want to use this script to create the requested tables -//x3dh_create_db('x3dh'.$curve, $curve); - -?> diff --git a/tester/server/php/source/x3dh/x3dh.php b/tester/server/php/source/x3dh/x3dh.php deleted file mode 100644 index 2686bb3d65471bf5d86f3b4423dacac3ec8e94f2..0000000000000000000000000000000000000000 --- a/tester/server/php/source/x3dh/x3dh.php +++ /dev/null @@ -1,546 +0,0 @@ -<?php -/* - x3dh.php - @author Johan Pascal - @copyright Copyright (C) 2018 Belledonne Communications SARL - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - - -function x3dh_get_db_conn() { - $db = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME); - if (!$db) { - error_log ("Error: Unable to connect to MySQL.\nDebugging errno: " . mysqli_connect_errno() . "\nDebugging error: " . mysqli_connect_error() . "\n"); - exit; - } - return $db; -} - - -// be sure we do not display any error or it may mess the returned message -ini_set('display_errors', 'Off'); - -// emulate simple enumeration -abstract class LogLevel { - const DISABLED = 0; - const ERROR = 1; - const WARNING = 2; - const MESSAGE = 3; - const DEBUG = 4; -}; - -function stringErrorLevel($level) { - switch($level) { - case LogLevel::DISABLED: return "DISABLED"; - case LogLevel::ERROR: return "ERROR"; - case LogLevel::WARNING: return "WARNING"; - case LogLevel::MESSAGE: return "MESSAGE"; - case LogLevel::DEBUG: return "DEBUG"; - default: return "UNKNOWN"; - } -} - -function x3dh_log($level, $message) { - if (x3dh_logLevel>=$level) { - if ($level === LogLevel::ERROR) { // in ERROR case, add a backtrace - file_put_contents(x3dh_logFile, date("Y-m-d h:m:s")." -".x3dh_logDomain."- ".stringErrorLevel($level)." : $message\n".print_r(debug_backtrace(),true), FILE_APPEND); - } else { - file_put_contents(x3dh_logFile, date("Y-m-d h:m:s")." -".x3dh_logDomain."- ".stringErrorLevel($level)." : $message\n", FILE_APPEND); - } - } -} - -/** - * Constants settings - */ -// define the curve Id used on this server, default is curve25519, it will be either load from DB or got from args if we are creation the DB. -// WARNING: value shall be in sync with defines in client code: Curve25519 = 1, Curve448 = 2 */ -// emulate simple enumeration with abstract class -abstract class CurveId { - const CURVE25519 = 1; - const CURVE448 = 2; -}; - -define ('X3DH_protocolVersion', 0x01); -define ('X3DH_headerSize', 3); - -// WARNING: value shall be in sync with defines in client code */ -// emulate simple enumeration with abstract class -abstract class MessageTypes { - const unset_type = 0x00; - const registerUser = 0x01; - const deleteUser = 0x02; - const postSPk = 0x03; - const postOPks = 0x04; - const getPeerBundle = 0x05; - const peerBundle = 0x06; - const getSelfOPks = 0x07; - const selfOPks = 0x08; - const error = 0xff; -}; - -// emulate simple enumeration with abstract class -abstract class ErrorCodes { - const bad_content_type = 0x00; - const bad_curve = 0x01; - const missing_senderId = 0x02; - const bad_x3dh_protocol_version = 0x03; - const bad_size = 0x04; - const user_already_in = 0x05; - const user_not_found = 0x06; - const db_error = 0x07; - const bad_request = 0x08; - const server_failure = 0x09; -}; - -// emulate simple enumeration with abstract class -abstract class KeyBundleFlag { - const noOPk = 0x00; - const OPk = 0x01; - const noBundle = 0x02; -} - - - -// define keys and signature size in bytes based on the curve used -const keySizes = array( - CurveId::CURVE25519 => array ('X_pub' => 32, 'X_priv' => 32, 'ED_pub' => 32, 'ED_priv' => 32, 'Sig' => 64), - CurveId::CURVE448 => array ('X_pub' => 56, 'X_priv' => 56, 'ED_pub' => 57, 'ED_priv' => 57, 'Sig' => 114) -); - -function returnError($code, $errorMessage) { - x3dh_log(LogLevel::WARNING, "return an error message code ".$code." : ".$errorMessage); - $header = pack("C4",X3DH_protocolVersion, MessageTypes::error, curveId, $code); // build the X3DH response header, append the error code - file_put_contents('php://output', $header.$errorMessage); - exit; -} - -function returnOk($message) { - x3dh_log(LogLevel::DEBUG, "Ok return a message ".bin2hex($message)); - file_put_contents('php://output', $message); - exit; -} - -// Check server setting: -function x3dh_checkSettings() { - // curveId must be 25519 or 448 - switch(curveId) { - // Authorized values - case CurveId::CURVE25519 : - case CurveId::CURVE448 : - break; - // Any other are invalid - default: - x3dh_log(LogLevel::ERROR, "Process X3DH request given incorrect curveId parameter (".curveId.")."); - returnError(ErrorCodes::server_failure, "X3DH server is not correctly configured"); - } - - // log Level, if not set or incorrect, disable log - switch(x3dh_logLevel) { - // Authorized values - case LogLevel::DISABLED : - case LogLevel::ERROR : - case LogLevel::WARNING : - case LogLevel::MESSAGE : - case LogLevel::DEBUG : - break; - // any other default to DISABLED - default: - error_log("X3DH log level setting is invalid ".x3dh_logLevel.". Disable X3DH logs"); - define ("x3dh_logLevel", LogLevel::DISABLED); - } -} - -function x3dh_process_request($userId) { - // Check setting - // that will end the script if settings are detected to be incorrect - // Could be commented out after server settings have been checked to be ok - x3dh_checkSettings(); - - $userId = filter_var($userId, FILTER_SANITIZE_URL); // userId is supposed to be a GRUU so it shall pass untouched the sanitize URL action - if ($userId == '') { - x3dh_log(LogLevel::ERROR, "X3DH server got a request without proper user Id"); - returnError(ErrorCodes::missing_senderId, "User not correctly identified"); - } - - // set response content type - header('Content-type: x3dh/octet-stream'); - - // retrieve response body from php://input - $request = file_get_contents('php://input'); - $requestSize = strlen($request); - x3dh_log(LogLevel::DEBUG, "Incoming request from ".$userId." is :".bin2hex($request)); - - // check available length before parsing, we must at least have a header - if ($requestSize < X3DH_headerSize) { - returnError(ErrorCodes.bad_size, "Packet is not even holding a header. Size ".$requestSize); - } - - // parse X3DH header - $X3DH_header=unpack("CprotocolVersion/CmessageType/CcurveId", $request); - - x3dh_log(LogLevel::DEBUG, "protocol version ".$X3DH_header['protocolVersion']." messageType ".$X3DH_header['messageType']." curveId ".$X3DH_header['curveId']); - - if ($X3DH_header['protocolVersion'] != X3DH_protocolVersion) { - returnError(ErrorCodes::bad_x3dh_protocol_version, "Server running X3DH procotol version ".X3DH_protocolVersion.". Can't process packet with version ".$X3DH_header['protocolVersion']); - } - - if ($X3DH_header['curveId'] != curveId) { - returnError(ErrorCodes::bad_curve, "Server running X3DH procotol using curve ".((curveId==CurveId.CURVE25519)?"25519":"448")+"(id ".curveId."). Can't process serve client using curveId ".$X3DH_header['curveId']); - } - - // acknowledge message by sending an empty message with same header (modified in case of getPeerBundle and get selfOPks request) - $returnHeader = substr($request, 0, X3DH_headerSize); - - // open the db connexion - $db = x3dh_get_db_conn(); - - switch ($X3DH_header['messageType']) { - /* Register User Identity Key : Identity Key <EDDSA Public key size >*/ - case MessageTypes::registerUser: - x3dh_log(LogLevel::MESSAGE, "Got a registerUser Message from ".$userId); - $x3dh_expectedSize = keySizes[curveId]['ED_pub']; - if ($requestSize < X3DH_headerSize + $x3dh_expectedSize) { - returnError(ErrorCodes::bad_size, "Register Identity packet is expexted to be ".(X3DH_headerSize+$x3dh_expectedSize)." bytes, but we got $requestSize bytes"); - return; - } - $Ik = substr($request, X3DH_headerSize, $x3dh_expectedSize); - - // Acquire lock on the user table to avoid 2 users being written at the same time with the same name - $db->query("LOCK TABLES Users WRITE"); - // Check that this usedId is not already in base - if (($stmt = $db->prepare("SELECT Uid FROM Users WHERE UserId = ? LIMIT 1")) === FALSE) { - x3dh_log(LogLevel::ERROR, "Database appears to be not what we expect"); - returnError(ErrorCodes::db_error, "Server database not ready"); - } - $stmt->bind_param('s', $userId); - $stmt->execute(); - $result = $stmt->get_result(); - $stmt->close(); - if ($result->num_rows !== 0) { - $db->query("UNLOCK TABLES"); - returnError(ErrorCodes::user_already_in, "Can't insert user ".$userId." - is already present in base"); - } - // Insert User in DB - x3dh_log(LogLevel::DEBUG, "Insert user $userId with Ik :".bin2hex($Ik)); - if (($stmt = $db->prepare("INSERT INTO Users(UserId,Ik) VALUES(?,?)")) === FALSE) { - x3dh_log(LogLevel::ERROR, "Database appears to be not what we expect"); - returnError(ErrorCodes::db_error, "Server database not ready"); - } - $null = NULL; - $stmt->bind_param('sb', $userId, $null); - $stmt->send_long_data(1,$Ik); - $status = $stmt->execute(); - $stmt->close(); - $db->query("UNLOCK TABLES"); - - if (!$status) { - x3dh_log(LogLevel::ERROR, "User $userId INSERT failed error is ".$db->error); - returnError(ErrorCodes::db_error, "Error while trying to insert user ".userId); - } - - // we're done - returnOk($returnHeader); - break; - - /* Delete user: message is empty(or at least shall be, anyway, just ignore anything present in the messange and just delete the user given in From header */ - case MessageTypes::deleteUser: - x3dh_log(LogLevel::MESSAGE, "Got a deleteUser Message from ".$userId); - if (($stmt = $db->prepare("DELETE FROM Users WHERE UserId = ?")) === FALSE) { - x3dh_log(LogLevel::ERROR, "Database appears to be not what we expect"); - returnError(ErrorCodes::db_error, "Server database not ready"); - } - $stmt->bind_param('s', $userId); - $status = $stmt->execute(); - $stmt->close(); - - if ($status) { - returnOk($returnHeader); - } else { - x3dh_log(LogLevel::ERROR, "User $userId DELETE failed err is ".$db->error); - returnError(ErrorCodes::db_error, "Error while trying to delete user ".$userId); - } - break; - - /* Post Signed Pre Key: Signed Pre Key <ECDH public key size> | SPk Signature <Signature length> | SPk id <uint32_t big endian: 4 bytes> */ - case MessageTypes::postSPk: - x3dh_log(LogLevel::MESSAGE, "Got a postSPk Message from ".$userId); - - $x3dh_expectedSize = keySizes[curveId]['X_pub'] + keySizes[curveId]['Sig'] + 4; - // check message length - if ($requestSize < X3DH_headerSize + $x3dh_expectedSize) { - returnError(ErrorCodes::bad_size, "post SPK packet is expexted to be ".(X3DH_headerSize+$x3dh_expectedSize)." bytes, but we got $requestSize bytes"); - } - - // parse message - $bufferIndex = X3DH_headerSize; - $SPk = substr($request, $bufferIndex, keySizes[curveId]['X_pub']); - $bufferIndex += keySizes[curveId]['X_pub']; - $Sig = substr($request, $bufferIndex, keySizes[curveId]['Sig']); - $bufferIndex += keySizes[curveId]['Sig']; - $SPk_id = unpack('N', substr($request, $bufferIndex))[1]; // SPk id is a 32 bits unsigned integer in Big endian - - // check we have a matching user in DB - if (($stmt = $db->prepare("SELECT Uid FROM Users WHERE UserId = ? LIMIT 1")) === FALSE) { - x3dh_log(LogLevel::ERROR, "Database appears to be not what we expect"); - returnError(ErrorCodes::db_error, "Server database not ready"); - } - $stmt->bind_param('s', $userId); - $stmt->execute(); - $result = $stmt->get_result(); - if ($result->num_rows === 0) { // user not found - $stmt->close(); - returnError(ErrorCodes::user_not_found, "Post SPk but ".$userId." not found in db"); // that will exit the script execution - } - - // get the Uid from previous query - $row = $result->fetch_assoc(); - $Uid = $row['Uid']; - $stmt->close(); - - // write the SPk - if (($stmt = $db->prepare("UPDATE Users SET SPk = ?, SPk_sig = ?, SPk_id = ? WHERE Uid = ?")) === FALSE) { - x3dh_log(LogLevel::ERROR, "Database appears to be not what we expect"); - returnError(ErrorCodes::db_error, "Server database not ready"); - } - $null = NULL; - $stmt->bind_param('bbii', $null, $null, $SPk_id, $Uid); - $stmt->send_long_data(0,$SPk); - $stmt->send_long_data(1,$Sig); - - $status = $stmt->execute(); - $stmt->close(); - - if ($status) { - returnOk($returnHeader); - } else { - x3dh_log(LogLevel::ERROR, "User's $userId SPk INSERT failed err is ".$db->error); - returnError(ErrorCodes::db_error, "Error while trying to insert SPK for user $userId. Backend says :".$db->error); - } - break; - - /* Post OPks : OPk number < uint16_t big endian: 2 bytes> | (OPk <ECDH public key size> | OPk id <uint32_t big endian: 4 bytes> ){OPk number} */ - case MessageTypes::postOPks: - x3dh_log(LogLevel::MESSAGE,"Got a postOPks Message from ".$userId); - // get the OPks number in the first message bytes(unsigned int 16 in big endian) - $bufferIndex = X3DH_headerSize; - $OPk_number = unpack('n', substr($request, $bufferIndex))[1]; - $x3dh_expectedSize = 2 + $OPk_number*(keySizes[curveId]['X_pub'] + 4); // expect: OPk count<2bytes> + number of OPks*(public key size + OPk_Id<4 bytes>) - if ($requestSize < X3DH_headerSize + $x3dh_expectedSize) { - returnError(ErrorCodes::bad_size, "post OPKs packet is expected to be ".(X3DH_headerSize+$x3dh_expectedSize)." bytes, but we got $requestSize bytes"); - } - $bufferIndex+=2; // point to the beginning of first key - - x3dh_log(LogLevel::DEBUG, "It contains ".$OPk_number." keys"); - - // check we have a matching user in DB - if (($stmt = $db->prepare("SELECT Uid FROM Users WHERE UserId = ? LIMIT 1")) === FALSE) { - x3dh_log(LogLevel::ERROR, "Database appears to be not what we expect"); - returnError(ErrorCodes::db_error, "Server database not ready"); - } - $stmt->bind_param('s', $userId); - $stmt->execute(); - $result = $stmt->get_result(); - if ($result->num_rows === 0) { - $stmt->close(); - returnError(ErrorCodes::user_not_found, "Post SPk but ".$userId." not found in db"); // that will exit the script execution - } - - // get the Uid from previous query - $row = $result->fetch_assoc(); - $Uid = $row['Uid']; - $stmt->close(); - - if (($stmt = $db->prepare("INSERT INTO OPk(Uid, OPk, OPk_id) VALUES(?,?,?)")) === FALSE) { - x3dh_log(LogLevel::ERROR, "Database appears to be not what we expect"); - returnError(ErrorCodes::db_error, "Server database not ready"); - } - $null = NULL; - $stmt ->bind_param("ibi", $Uid, $null, $OPk_id); - - // before version 5.6.5, begin_transaction doesn't support READ_WRITE flag - if ($db->server_version < 50605) { - $db->begin_transaction(); - } else { - $db->begin_transaction(MYSQLI_TRANS_START_READ_WRITE); - } - for ($i = 0; $i<$OPk_number; $i++) { - $OPk = substr($request, $bufferIndex, keySizes[curveId]['X_pub']); - $bufferIndex += keySizes[curveId]['X_pub']; - $stmt->send_long_data(1,$OPk); - $OPk_id = unpack('N', substr($request, $bufferIndex))[1]; // OPk id is a 32 bits unsigned integer in Big endian - $bufferIndex += 4; - - if (!$stmt->execute()) { - $stmt->close(); - $db->rollback(); - returnError(ErrorCodes::db_error, "Error while trying to insert OPk for user ".$userId.". Backend says :".$db->error); - } - } - - $stmt->close(); - $db->commit(); - - returnOk($returnHeader); - break; - - /* peerBundle : bundle Count < 2 bytes unsigned Big Endian> | - * ( deviceId Size < 2 bytes unsigned Big Endian > | deviceId - * Flag<1 byte: 0 if no OPK in bundle, 1 if OPk is present, 2 when no bundle was found for this device> | - * Ik <EDDSA Public Key Length> | - * SPk <ECDH Public Key Length> | SPK id <4 bytes> - * SPk_sig <Signature Length> | - * (OPk <ECDH Public Key Length> | OPk id <4 bytes>){0,1 in accordance to flag} - * ) { bundle Count} - */ - case MessageTypes::getPeerBundle: - x3dh_log(LogLevel::MESSAGE, "Got a getPeerBundle Message from ".$userId); - - // first parse the message - if ($requestSize < X3DH_headerSize + 2) { // we must have at least 2 bytes to parse peers counts - returnError(ErrorCodes::bad_size, "post SPKs packet is expected to be at least ".(X3DH_headerSize+2)." bytes, but we got $requestSize bytes"); - } - // get the peers number in the first message bytes(unsigned int 16 in big endian) - $bufferIndex = X3DH_headerSize; - $peersCount = unpack('n', substr($request, $bufferIndex))[1]; - if ($peersCount === 0) { - returnError(ErrorCodes::bad_request, "Ask for peer Bundles but no device id given"); - } - $bufferIndex+=2; // point to the beginning of first key - - // build an array of arrays like [[deviceId], [deviceId], ...] - $peersBundle = array(); - for ($i=0; $i<$peersCount; $i++) { - // check we have enought bytes to parse before calling unpack - if ($requestSize - $bufferIndex<2) { - returnError(ErrorCodes::bad_request, "Malformed getPeerBundle request: peers count doesn't match the device id list length"); - } - $idLength = unpack('n', substr($request, $bufferIndex))[1]; - $bufferIndex+=2; - if ($requestSize - $bufferIndex<$idLength) { - returnError(ErrorCodes::bad_request, "Malformed getPeerBundle request: device id given size doesn't match the string length"); - } - $peersBundle[] = array(substr($request, $bufferIndex, $idLength)); - $bufferIndex+=$idLength; - } - - x3dh_log(LogLevel::DEBUG, "Found request for ".$peersCount." keys bundles"); - x3dh_log(LogLevel::DEBUG, print_r($peersBundle, true)); - - $db->query("LOCK TABLES Users,OPk WRITE"); // lock the OPk table so we won't give twice a one-time pre-key - - // before version 5.6.5, begin_transaction doesn't support READ_WRITE flag - if ($db->server_version < 50605) { - $db->begin_transaction(); - } else { - $db->begin_transaction(MYSQLI_TRANS_START_READ_WRITE); - } - - if (($stmt = $db->prepare("SELECT u.Ik as Ik, u.SPk as SPk, u.SPk_id as SPk_id, u.SPk_sig as SPk_sig, o.OPk as OPk, o.OPk_id as OPk_id, o.id as id FROM Users as u LEFT JOIN OPk as o ON u.Uid=o.Uid WHERE UserId = ? AND u.SPk IS NOT NULL LIMIT 1")) === FALSE) { - x3dh_log(LogLevel::ERROR, "Database appears to be not what we expect"); - returnError(ErrorCodes::db_error, "Server database not ready"); - } - - $keyBundleErrors = ''; // an empty string to store error message if any - for ($i=0; $i<$peersCount; $i++) { - $stmt->bind_param('s', $peersBundle[$i][0]); - $stmt->execute(); - $row = $stmt->get_result()->fetch_assoc(); - if (!$row) { - x3dh_log(LogLevel::DEBUG, "User ".$peersBundle[$i][0]." not found"); - } else { - array_push($peersBundle[$i], $row['Ik'], $row['SPk'], $row['SPk_id'], $row['SPk_sig']); - if ($row['OPk']) { // there is an OPk - array_push($peersBundle[$i], $row['OPk'], $row['OPk_id']); - // now that we used that one, we MUST delete it - if (($del_stmt = $db->prepare("DELETE FROM OPk WHERE id = ?")) === FALSE) { - x3dh_log(LogLevel::ERROR, "Database appears to be not what we expect"); - returnError(ErrorCodes::db_error, "Server database not ready"); - } - $del_stmt->bind_param('i', $row['id']); - if (!$del_stmt->execute()) { - $keyBundleErrors .=' ## could not delete OPk key retrieved user '.$peersBundle[$i][0]." err : ".$db->error; - } - $del_stmt->close(); - } - } - } - $stmt->close(); - - // No errors: commit transition, release lock and build the message out of the key bundles extracted - if($keyBundleErrors === '') { - $db->commit(); - $db->query("UNLOCK TABLES"); - $peersBundleMessage = pack("C3n",X3DH_protocolVersion, MessageTypes::peerBundle, curveId, $peersCount); // build the X3DH response header - foreach ($peersBundle as $bundle) { - // elements in bundle array are : deviceId, [Ik, SPk, SPk_id, SPk_sig, [OPk, OPk_id]] - $peersBundleMessage .= pack("n", strlen($bundle[0])); // size of peer Device Id, 2 bytes in big endian - $peersBundleMessage .= $bundle[0]; // peer Device Id - if (count($bundle)==1) { // we have no keys for this device - $peersBundleMessage .= pack("C", KeyBundleFlag::noBundle); // 1 byte : the key bundle flag - } else { - $flagOPk = (count($bundle)>5)?(KeyBundleFlag::OPk):(KeyBundleFlag::noOPk); // does the bundle hold an OPk? - $peersBundleMessage .= pack("C", $flagOPk); // 1 byte : the key bundle flag - $peersBundleMessage .= $bundle[1]; // Ik - $peersBundleMessage .= $bundle[2]; // SPk - $peersBundleMessage .= pack("N", $bundle[3]); // SPk Id : 4 bytes in big endian - $peersBundleMessage .= $bundle[4]; // SPk Signature - if ($flagOPk == KeyBundleFlag::OPk) { - $peersBundleMessage .= $bundle[5]; // OPk - $peersBundleMessage .= pack("N", $bundle[6]); // OPk Id : 4 bytes in big endian - } - } - } - returnOk($peersBundleMessage); - } else { // something went wrong - $db->rollback(); - $db->query("UNLOCK TABLES"); - returnError(ErrorCodes::db_error, "Error while trying to get peers bundles :".$keyBundleErrors); - } - break; - - /* selfOPks : OPKs Id Count < 2 bytes unsigned Big Endian> | - * (OPk id <4 bytes>){ OPks Id Count} - */ - case MessageTypes::getSelfOPks: - x3dh_log(LogLevel::MESSAGE, "Process a getSelfOPks Message from ".$userId); - if (($stmt = $db->prepare("SELECT o.OPk_id as OPk_id FROM Users as u INNER JOIN OPk as o ON u.Uid=o.Uid WHERE UserId = ?")) === FALSE) { - x3dh_log(LogLevel::ERROR, "Database appears to be not what we expect"); - returnError(ErrorCodes::db_error, "Server database not ready"); - } - $stmt->bind_param('s', $userId); - if (!$stmt->execute()) { - returnError(ErrorCodes::db_error, " Database error in getSelfOPks by ".$userId." : ".$db->error); - } - $result = $stmt->get_result(); - - // build the X3DH response header, include OPks number (unsigned int on 2 bytes in big endian) - $selfOPksMessage = pack("C3n",X3DH_protocolVersion, MessageTypes::selfOPks, curveId, $result->num_rows); - - while ($row = $result->fetch_assoc()) { - $selfOPksMessage .= pack("N", $row['OPk_id']); // OPk Id : 4 bytes in big endian - } - - returnOk($selfOPksMessage); - break; - - default: - returnError(ErrorCodes.bad_message_type, "Unknown message type ".$X3DH_header['messageType']); - break; - } - - $db->close(); -} -?>