Skip to content

Commit

Permalink
Merge pull request blueprint-freespeech#44 from pospeselr/v3onion-review
Browse files Browse the repository at this point in the history
V3onion review
  • Loading branch information
chrisculnane authored Aug 23, 2020
2 parents 642b4c9 + 55d29d7 commit 0ff42f6
Show file tree
Hide file tree
Showing 236 changed files with 2,277 additions and 1,542 deletions.
10 changes: 5 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ src/tests/*/tst_*
*.pb.cc
packaging/installer/Qt
packaging/installer/Output
translation/*.qm
src/tego-ui/translation/*.qm
src/tego_ui/translation/*.qm
config
config.ricochet
config.log
Expand All @@ -40,9 +39,10 @@ buildscripts/output
buildscripts/lib
target_wrapper\.sh
moc_predefs.h
moc_*.cpp
qrc_*.cpp
ricochet-refresh
*.gch
\.vscode/c_cpp_properties\.json

\.vscode/
notes/*

ricochet-refresh
6 changes: 6 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,9 @@
[submodule "buildscripts/src/libevent"]
path = buildscripts/src/libevent
url = https://github.com/libevent/libevent
[submodule "src/extern/fmt"]
path = src/extern/fmt
url = https://github.com/fmtlib/fmt.git
[submodule "src/extern/tor"]
path = src/extern/tor
url = https://git.torproject.org/tor.git
File renamed without changes.
1 change: 1 addition & 0 deletions src/extern/fmt
Submodule fmt added at 0b6e7c
1 change: 1 addition & 0 deletions src/extern/tor
Submodule tor added at 18d2c7
72 changes: 72 additions & 0 deletions src/libtego/include/tego/logger.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#pragma once

#ifdef ENABLE_TEGO_LOGGER

// std
#include <memory>
#include <cstddef>
#include <iostream>
#include <fstream>
#include <mutex>
#include <typeinfo>
#include <experimental/source_location>
using std::experimental::source_location;
#include <thread>

// fmt
#include <fmt/format.h>
#include <fmt/ostream.h>

// wrapper around fmt::print that writes to singleton log file libtego.log
class logger
{
public:
template<size_t N, typename... ARGS>
static void println(const char (&format)[N], ARGS&&... args)
{
std::lock_guard<std::mutex> guard(get_mutex());

auto& fs = get_stream();

fmt::print(fs, "[{:f}][{}] ", get_timestamp(), std::this_thread::get_id());
fmt::print(fs, format, std::forward<ARGS>(args)...);
fs << std::endl;
}

template<size_t N>
static void println(const char (&msg)[N])
{
std::lock_guard<std::mutex> guard(get_mutex());

auto& fs = get_stream();

fmt::print(fs, "[{:f}][{}] ", get_timestamp(), std::this_thread::get_id());
fs << msg << std::endl;
}

static void trace(const source_location& loc = source_location::current());
private:
static std::ofstream& get_stream();
static std::mutex& get_mutex();
static double get_timestamp();
};

std::ostream& operator<<(std::ostream& out, const class QString& str);
std::ostream& operator<<(std::ostream& out, const class QByteArray& blob);
std::ostream& operator<<(std::ostream& out, const std::type_info& ti);
#else // ENABLE_TEGO_LOGGER

// mock no-op logger
class logger
{
public:
template<size_t N, typename... ARGS>
static void println(const char (&)[N], ARGS&&...) {}
template<size_t N>
static void println(const char (&)[N]) {}
static void trace() {}
};



#endif // ENABLE_TEGO_LOGGER
236 changes: 236 additions & 0 deletions src/libtego/include/tego/tego.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
#ifndef TEGO_H
#define TEGO_H

#include <stddef.h>
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

#define TEGO_TRUE 1
#define TEGO_FALSE 0

// number of bytes in an ed25519 signature
#define TEGO_ED25519_SIGNATURE_SIZE 64
// length of a valid v3 service id string not including null terminator
#define TEGO_V3_ONION_SERVICE_ID_LENGTH 56
// length of a v3 service id string including null terminator
#define TEGO_V3_ONION_SERVICE_ID_SIZE (TEGO_V3_ONION_SERVICE_ID_LENGTH + 1)
// length of the ed25519 KeyBlob string not including null terminator
#define TEGO_ED25519_KEYBLOB_LENGTH 99
// length of an ed25519 keyblob string including null terminator
#define TEGO_ED25519_KEYBLOB_SIZE (TEGO_ED25519_KEYBLOB_LENGTH + 1)

typedef struct tego_error tego_error_t;

/*
* Get error message form tego_error
*
* @param error : the error object to get the message from
* @return : null terminated string with error message whose
* lifetime is tied to the source tego_error_t
*/
const char* tego_error_get_message(const tego_error_t* error);

// library init/uninit
void tego_initialize(tego_error_t** error);
void tego_uninitialize(tego_error_t** error);

/*
* v3 onion/ed25519 functionality
*/

typedef struct tego_ed25519_private_key tego_ed25519_private_key_t;
typedef struct tego_ed25519_public_key tego_ed25519_public_key_t;
typedef struct tego_ed25519_signature tego_ed25519_signature_t;
typedef struct tego_v3_onion_service_id tego_v3_onion_service_id_t;

/*
* Conversion method for converting the KeyBlob string returned by
* ADD_ONION command into an ed25519_private_key_t
*
* @param out_privateKey : returned ed25519 private key
* @param keyBlob : an ED25519 KeyBlob string in the form
* "ED25519-V3:abcd1234..."
* @param keyBlobLength : number of characters in keyBlob not
* counting the null terminator
* @param error : filled with a tego_error_t on error
*/
void tego_ed25519_private_key_from_ed25519_keyblob(
tego_ed25519_private_key_t** out_privateKey,
const char* keyBlob,
size_t keyBlobLength,
tego_error_t** error);

/*
* Conversion method for converting an ed25519 private key
* to a null-terminated KeyBlob string for use with ADD_ONION
* command
*
* @param out_keyBlob : buffer to be filled with ed25519 KeyBlob in
* the form "ED25519-V3:abcd1234...\0"
* @param keyBlobSize : size of out_keyBlob buffer in bytes, must be at
* least 100 characters (99 for string + 1 for null terminator)
* @param privateKey : the private key to encode
* @param error : filled with a tego_error_t on error
* @return : the number of characters written (including null terminator)
* to out_keyBlob
*/
size_t tego_ed25519_keyblob_from_ed25519_private_key(
char *out_keyBlob,
size_t keyBlobSize,
const tego_ed25519_private_key_t* privateKey,
tego_error_t** error);

/*
* Calculate ed25519 public key from ed25519 private key
*
* @param out_publicKey : returned ed25519 public key
* @param privateKey : input ed25519 private key
* @param error : filled with a tego_error_t on error
*/
void tego_ed25519_public_key_from_ed25519_private_key(
tego_ed25519_public_key_t** out_publicKey,
const tego_ed25519_private_key_t* privateKey,
tego_error_t** error);

/*
* Construct a service id object from string. Validates
* the checksum and version byte per spec:
* https://gitweb.torproject.org/torspec.git/tree/rend-spec-v3.txt
*
* @param out_serviceId : returned v3 onion service id
* @param serviceIdString : a string beginning with a v3 service id
* @param serviceIdStringLength : length of the service id string not
* counting the null terminator
* @param error : filled with a tego_error_t on error
*/
void tego_v3_onion_service_id_from_string(
tego_v3_onion_service_id_t** out_serviceId,
const char* serviceIdString,
size_t serviceIdStringLength,
tego_error_t** error);

/*
* Serializes out a service id object as a null terminated string
* string to provided character buffer.
*
* @param serviceId : v3 onion service id object to serialize
* @param out_serviceIdString : destination buffer for string
* @param serviceIdStringSize : size of out_serviceIdString buffer in
* bytes, must be at least 57 bytes (56 bytes for string + null
* terminator)
* @param error : filled with a tego_error_t on error
*/
size_t tego_v3_onion_service_id_to_string(
const tego_v3_onion_service_id_t* serviceId,
char* out_serviceIdString,
size_t serviceIdStringSize,
tego_error_t** error);

/*
* Extract public key from v3 service id per
* https://gitweb.torproject.org/torspec.git/tree/rend-spec-v3.txt
*
* @param out_publicKey : returned ed25519 public key
* @param serviceId : input service id
* @param error : filled with a tego_error_t on error
*/
void tego_ed25519_public_key_from_v3_onion_service_id(
tego_ed25519_public_key_t** out_publicKey,
const tego_v3_onion_service_id_t* serviceId,
tego_error_t** error);

/*
* Derive an onion's service id from its ed25519 public key per
* https://gitweb.torproject.org/torspec.git/tree/rend-spec-v3.txt
*
* @param out_serviceId : returned service id
* @param publicKey : the public key input
* @param error : filled with a tego_error_t on error
*/
void tego_v3_onion_service_id_from_ed25519_public_key(
tego_v3_onion_service_id_t** out_serviceId,
const tego_ed25519_public_key_t* publicKey,
tego_error_t** error);

/*
* Read in signature from length 64 byte buffer
*
* @param out_signature : returned ed25519 signature
* @param buffer : source memory buffer holding signature
* @param bufferSize : size of data in bytes, must be at least 64 bytes
* @param error : filled with a tego_error_t on error
*/
void tego_ed25519_signature_from_bytes(
tego_ed25519_signature_t** out_signature,
const uint8_t* buffer,
size_t bufferSize,
tego_error_t** error);

/*
* Get the signature and place it in length 64 byte buffer
*
* @param signature : a calculated message signature
* @param out_buffer : output buffer to write signature to
* @param bufferSize : size of buffer in bytes, must be at least 64 bytes
* @param error : filled with a tego_error_t on error
* @return : number of bytes written to out_buffer
*/
size_t tego_ed25519_signature_to_bytes(
const tego_ed25519_signature_t* signature,
uint8_t* out_buffer,
size_t bufferSize,
tego_error_t** error);

/*
* Sign a message with an ed25519 key-pair
*
* @param message : message binary to sign
* @param messageSize : size of message in bytes
* @param privateKey : the ed25519 private key
* @param publicKey : the ed25519 public key
* @param out_signature : the output signature
* @param error : filled with a tego_error_t on error
*/
void tego_message_ed25519_sign(
const uint8_t* message,
size_t messageSize,
const tego_ed25519_private_key_t* privateKey,
const tego_ed25519_public_key_t* publicKey,
tego_ed25519_signature_t** out_signature,
tego_error_t** error);

/*
* Verify a message's signature given a public key
*
* @param signature : the signature to verify
* @param message : the message that was signed
* @param messageSize : size of the message in bytes
* @param publicKey : the public key to very the the signature against
* @param error : filled with a tego_error_t on error
* @return : TEGO_TRUE if signature is verified, TEGO_FALSE if it is not
* verified or if an error occurs
*/
int tego_ed25519_signature_verify(
const tego_ed25519_signature_t* signature,
const uint8_t* message,
size_t messageLength,
const tego_ed25519_public_key_t* publicKey,
tego_error_t** error);

/*
Destructors for various tego types
*/

void tego_ed25519_private_key_delete(tego_ed25519_private_key_t*);
void tego_ed25519_public_key_delete(tego_ed25519_public_key_t*);
void tego_ed25519_signature_delete(tego_ed25519_signature_t*);
void tego_v3_onion_service_id_delete(tego_v3_onion_service_id_t*);
void tego_error_delete(tego_error_t*);

#ifdef __cplusplus
}
#endif // __cplusplus
#endif // TEGO_H
Loading

0 comments on commit 0ff42f6

Please sign in to comment.