Initial commit

This commit is contained in:
concise7113
2025-07-21 14:23:21 +00:00
commit 558cae10c6
15 changed files with 658 additions and 0 deletions

28
client/Makefile Normal file
View File

@ -0,0 +1,28 @@
# pq-ftp/client/Makefile
CXX=g++
CXXFLAGS=-std=c++17 -Wall
# You must have liboqs installed locally for this to work
# sudo ninja install from the liboqs build directory
LDFLAGS=-loqs -lz -lcrypto
SRC_DIR=src
BUILD_DIR=build
BIN_DIR=bin
TARGET=$(BIN_DIR)/client
SRCS=$(wildcard $(SRC_DIR)/*.cpp)
OBJS=$(patsubst $(SRC_DIR)/%.cpp, $(BUILD_DIR)/%.o, $(SRCS))
all: $(TARGET)
$(TARGET): $(OBJS)
@mkdir -p $(BIN_DIR)
$(CXX) $(OBJS) -o $(TARGET) $(LDFLAGS)
@echo "Client compiled successfully!"
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp
@mkdir -p $(BUILD_DIR)
$(CXX) $(CXXFLAGS) -c $< -o $@
clean:
rm -rf $(BUILD_DIR) $(BIN_DIR)

BIN
client/bin/client Executable file

Binary file not shown.

BIN
client/build/client.o Normal file

Binary file not shown.

1
client/liboqs Submodule

Submodule client/liboqs added at 94b421ebb8

170
client/src/client.cpp Normal file
View File

@ -0,0 +1,170 @@
// pq-ftp/client/src/client.cpp
#include <iostream>
#include <string>
#include <vector>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fstream>
#include <sstream>
#include <oqs/oqs.h>
#include <zlib.h>
#define SERVER_IP "127.0.0.1"
#define PORT 2121
#define BUFFER_SIZE 4096
#define PQC_ALGORITHM "Kyber768"
// Data compression function
std::vector<uint8_t> compress_data(const std::vector<uint8_t>& data) {
if (data.empty()) return {};
uLongf compressed_size = compressBound(data.size());
std::vector<uint8_t> compressed_data(compressed_size);
if (compress(compressed_data.data(), &compressed_size, data.data(), data.size()) != Z_OK) {
std::cerr << "Compression failed!" << std::endl;
return {};
}
compressed_data.resize(compressed_size);
return compressed_data;
}
int main() {
int sock = 0;
struct sockaddr_in serv_addr;
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
std::cerr << "Socket creation error" << std::endl;
return -1;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
if (inet_pton(AF_INET, SERVER_IP, &serv_addr.sin_addr) <= 0) {
std::cerr << "Invalid address/ Address not supported" << std::endl;
return -1;
}
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
std::cerr << "Connection Failed" << std::endl;
return -1;
}
std::cout << "Connected to server. Performing PQC key exchange..." << std::endl;
// 1. PQC Key Exchange
OQS_KEM *kem = NULL;
uint8_t *public_key = NULL;
uint8_t *ciphertext = NULL;
uint8_t *shared_secret_client = NULL;
kem = OQS_KEM_new(PQC_ALGORITHM);
if (kem == NULL) {
std::cerr << "Error: OQS_KEM_new failed." << std::endl;
return -1;
}
public_key = new uint8_t[kem->length_public_key];
ciphertext = new uint8_t[kem->length_ciphertext];
shared_secret_client = new uint8_t[kem->length_shared_secret];
// Receive public key from server
recv(sock, public_key, kem->length_public_key, 0);
// Encapsulate to generate ciphertext and our shared secret
if (OQS_KEM_encaps(kem, ciphertext, shared_secret_client, public_key) != OQS_SUCCESS) {
std::cerr << "Error: OQS_KEM_encaps failed." << std::endl;
return -1;
}
// Send ciphertext to server
send(sock, ciphertext, kem->length_ciphertext, 0);
std::cout << "PQC key exchange successful." << std::endl;
// NOTE: The shared_secret_client should be identical to the server's.
// 2. Authentication
std::cout << "Authenticating..." << std::endl;
std::string user = "user";
std::string pass = "pass";
send(sock, user.c_str(), user.length() + 1, 0);
send(sock, pass.c_str(), pass.length() + 1, 0);
char auth_status[10] = {0};
recv(sock, auth_status, sizeof(auth_status), 0);
if (std::string(auth_status) != "OK") {
std::cerr << "Authentication failed. Server responded: " << auth_status << std::endl;
return -1;
}
std::cout << "Authentication successful!" << std::endl;
std::cout << "Commands: put <filepath>, get <filename>, exit" << std::endl;
// 3. Command Loop
for (std::string line; std::cout << "> " && std::getline(std::cin, line);) {
if (line.empty()) continue;
if (line == "exit") break;
std::stringstream ss(line);
std::string command, filepath;
ss >> command >> filepath;
if (command == "put") {
std::ifstream file(filepath, std::ios::binary | std::ios::ate);
if (!file.is_open()) {
std::cerr << "Error: Could not open file " << filepath << std::endl;
continue;
}
// Get file size
std::streamsize size = file.tellg();
file.seekg(0, std::ios::beg);
// Read file into a vector
std::vector<char> buffer(size);
if (!file.read(buffer.data(), size)) {
std::cerr << "Error reading file." << std::endl;
continue;
}
file.close();
// Convert char vector to uint8_t vector for compression
std::vector<uint8_t> data(buffer.begin(), buffer.end());
// Compress the data
std::vector<uint8_t> compressed_data = compress_data(data);
std::cout << "Original size: " << data.size() << " bytes, Compressed size: " << compressed_data.size() << " bytes." << std::endl;
// Send command and filename
std::string put_command = "put " + filepath.substr(filepath.find_last_of("/\\") + 1);
send(sock, put_command.c_str(), put_command.length() + 1, 0);
// Send file size
uint64_t compressed_size = compressed_data.size();
send(sock, &compressed_size, sizeof(compressed_size), 0);
// Send file data
send(sock, compressed_data.data(), compressed_data.size(), 0);
std::cout << "File uploaded successfully." << std::endl;
} else if (command == "get") {
std::cout << "GET command is not implemented in this example." << std::endl;
} else {
std::cout << "Unknown command: " << command << std::endl;
}
}
// Cleanup
OQS_KEM_free(kem);
delete[] public_key;
delete[] ciphertext;
delete[] shared_secret_client;
close(sock);
return 0;
}

1
client/testfile.txt Normal file
View File

@ -0,0 +1 @@
This is a post-quantum test file. This is a post-quantum test file.