mirror of https://github.com/qTox/qTox.git
Browse Source
qtox-updater-sign takes data from stdin or as argument, signs it with the updater's private key, and output the signature + the data qtox-updater-genflist generates a flist, a serialized list of AutoUpdater::UpdateFileMeta for the qTox updaterpull/689/head
6 changed files with 456 additions and 0 deletions
@ -0,0 +1,97 @@ |
|||||||
|
#include <iostream> |
||||||
|
#include <QFile> |
||||||
|
#include <QByteArray> |
||||||
|
#include <QDir> |
||||||
|
#include <QCryptographicHash> |
||||||
|
#include <sodium.h> |
||||||
|
#include "serialize.h" |
||||||
|
|
||||||
|
using namespace std; |
||||||
|
|
||||||
|
/// Pass the target folder as first argument, no spaces allowed. We'll call that dir $TARGET
|
||||||
|
/// Update the content of $TARGET/files/ before calling this tool
|
||||||
|
/// We'll generate $TARGET/flist and exit
|
||||||
|
/// We need qtox-updater-skey in our working directory to sign the flist
|
||||||
|
///
|
||||||
|
/// The generated flist is very simple and just installs everything in the working directory ...
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) |
||||||
|
{ |
||||||
|
cout << "qTox updater flist generator" << endl; |
||||||
|
|
||||||
|
/// First some basic error handling, prepare our handles, ...
|
||||||
|
if (argc != 2) |
||||||
|
{ |
||||||
|
cout << "ERROR: qtox-updater-genflist takes the target path in argument" << endl; |
||||||
|
return 1; |
||||||
|
} |
||||||
|
|
||||||
|
QFile skeyFile("qtox-updater-skey"); |
||||||
|
if (!skeyFile.open(QIODevice::ReadOnly)) |
||||||
|
{ |
||||||
|
cout << "ERROR: qtox-updater-genflist can't open the secret (private) key file" << endl; |
||||||
|
return 1; |
||||||
|
} |
||||||
|
QByteArray skeyData = skeyFile.readAll(); |
||||||
|
skeyData = QByteArray::fromHex(skeyData); |
||||||
|
skeyFile.close(); |
||||||
|
|
||||||
|
QString target(argv[1]); |
||||||
|
|
||||||
|
QFile flistFile(target+"/flist"); |
||||||
|
if (!flistFile.open(QIODevice::Truncate | QIODevice::WriteOnly)) |
||||||
|
{ |
||||||
|
cout << "ERROR: qtox-updater-genflist can't open the target flist" << endl; |
||||||
|
return 1; |
||||||
|
} |
||||||
|
|
||||||
|
QDir fdir(target+"/files/"); |
||||||
|
if (!fdir.isReadable()) |
||||||
|
{ |
||||||
|
cout << "ERROR: qtox-updater-genflist can't open the target files directory" << endl; |
||||||
|
return 1; |
||||||
|
} |
||||||
|
|
||||||
|
QStringList filesListStr = fdir.entryList(QDir::Files); |
||||||
|
|
||||||
|
/// Serialize the flist data
|
||||||
|
QByteArray flistData; |
||||||
|
for (QString fileStr : filesListStr) |
||||||
|
{ |
||||||
|
cout << "Adding "<<fileStr.toStdString()<<"..."<<endl; |
||||||
|
|
||||||
|
QFile file(target+"/files/"+fileStr); |
||||||
|
if (!file.open(QIODevice::ReadOnly)) |
||||||
|
{ |
||||||
|
cout << "ERROR: qtox-updater-genflist couldn't open a target file to sign it" << endl; |
||||||
|
return 1; |
||||||
|
} |
||||||
|
|
||||||
|
QByteArray fileData = file.readAll(); |
||||||
|
|
||||||
|
unsigned char sig[crypto_sign_BYTES]; |
||||||
|
crypto_sign_detached(sig, nullptr, (unsigned char*)fileData.data(), fileData.size(), (unsigned char*)skeyData.data()); |
||||||
|
|
||||||
|
flistData += QByteArray::fromRawData((char*)sig, crypto_sign_BYTES); |
||||||
|
flistData += stringToData(QCryptographicHash::hash(fileStr.toUtf8(), QCryptographicHash::Sha3_224).toHex()); |
||||||
|
flistData += stringToData("./"+fileStr); ///< Always install in the working directory for now
|
||||||
|
flistData += uint64ToData(fileData.size()); |
||||||
|
|
||||||
|
file.close(); |
||||||
|
} |
||||||
|
|
||||||
|
cout << "Signing and writing the flist..."<<endl; |
||||||
|
|
||||||
|
/// Sign our flist
|
||||||
|
unsigned char sig[crypto_sign_BYTES]; |
||||||
|
crypto_sign_detached(sig, nullptr, (unsigned char*)flistData.data(), flistData.size(), (unsigned char*)skeyData.data()); |
||||||
|
|
||||||
|
/// Write the flist
|
||||||
|
flistFile.write("1"); |
||||||
|
flistFile.write((char*)sig, crypto_sign_BYTES); |
||||||
|
flistFile.write(flistData); |
||||||
|
|
||||||
|
flistFile.close(); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
@ -0,0 +1,10 @@ |
|||||||
|
TEMPLATE = app |
||||||
|
CONFIG += console c++11 |
||||||
|
QT += core |
||||||
|
LIBS += -lsodium |
||||||
|
|
||||||
|
SOURCES += main.cpp \ |
||||||
|
serialize.cpp |
||||||
|
|
||||||
|
HEADERS += \ |
||||||
|
serialize.h |
@ -0,0 +1,254 @@ |
|||||||
|
/*
|
||||||
|
Copyright (C) 2014 by Project Tox <https://tox.im>
|
||||||
|
|
||||||
|
This file is part of qTox, a Qt-based graphical interface for Tox. |
||||||
|
|
||||||
|
This program is libre 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 COPYING file for more details. |
||||||
|
*/ |
||||||
|
|
||||||
|
|
||||||
|
#include "serialize.h" |
||||||
|
|
||||||
|
QByteArray doubleToData(double num) |
||||||
|
{ |
||||||
|
union |
||||||
|
{ |
||||||
|
char tab[8]; |
||||||
|
double n; |
||||||
|
} castUnion; |
||||||
|
//char n[8];
|
||||||
|
//*((double*) n) = num;
|
||||||
|
|
||||||
|
castUnion.n=num; |
||||||
|
return QByteArray(castUnion.tab,8); |
||||||
|
} |
||||||
|
|
||||||
|
QByteArray floatToData(float num) |
||||||
|
{ |
||||||
|
union |
||||||
|
{ |
||||||
|
char tab[4]; |
||||||
|
float n; |
||||||
|
} castUnion; |
||||||
|
|
||||||
|
castUnion.n=num; |
||||||
|
return QByteArray(castUnion.tab,4); |
||||||
|
} |
||||||
|
|
||||||
|
float dataToFloat(QByteArray data) |
||||||
|
{ |
||||||
|
union |
||||||
|
{ |
||||||
|
char tab[4]; |
||||||
|
float n; |
||||||
|
} castUnion; |
||||||
|
|
||||||
|
castUnion.tab[0]=data.data()[0]; |
||||||
|
castUnion.tab[1]=data.data()[1]; |
||||||
|
castUnion.tab[2]=data.data()[2]; |
||||||
|
castUnion.tab[3]=data.data()[3]; |
||||||
|
return castUnion.n; |
||||||
|
} |
||||||
|
|
||||||
|
// Converts a string into PNet string data
|
||||||
|
QByteArray stringToData(QString str) |
||||||
|
{ |
||||||
|
QByteArray data(4,0); |
||||||
|
// Write the size in a Uint of variable lenght (8-32 bits)
|
||||||
|
int i=0; |
||||||
|
uint num1 = (uint)str.toUtf8().size(); |
||||||
|
while (num1 >= 0x80) |
||||||
|
{ |
||||||
|
data[i] = (unsigned char)(num1 | 0x80); i++; |
||||||
|
num1 = num1 >> 7; |
||||||
|
} |
||||||
|
data[i]=num1; |
||||||
|
data.resize(i+1); |
||||||
|
data+=str.toUtf8(); |
||||||
|
return data; |
||||||
|
} |
||||||
|
|
||||||
|
QString dataToString(QByteArray data) |
||||||
|
{ |
||||||
|
// Variable UInt32
|
||||||
|
unsigned char num3; |
||||||
|
int num = 0; |
||||||
|
int num2 = 0; |
||||||
|
int i=0; |
||||||
|
do |
||||||
|
{ |
||||||
|
num3 = data[i]; i++; |
||||||
|
num |= (num3 & 0x7f) << num2; |
||||||
|
num2 += 7; |
||||||
|
} while ((num3 & 0x80) != 0); |
||||||
|
unsigned int strlen = (uint) num; |
||||||
|
|
||||||
|
if (!strlen) |
||||||
|
return QString(); |
||||||
|
|
||||||
|
data = data.right(data.size()-i); // Remove the strlen
|
||||||
|
data.truncate(strlen); |
||||||
|
return QString(data); |
||||||
|
} |
||||||
|
|
||||||
|
float dataToRangedSingle(float min, float max, int numberOfBits, QByteArray data) |
||||||
|
{ |
||||||
|
uint endvalue=0; |
||||||
|
uint value=0; |
||||||
|
if (numberOfBits <= 8) |
||||||
|
{ |
||||||
|
endvalue = (uchar)data[0]; |
||||||
|
goto done; |
||||||
|
} |
||||||
|
value = (uchar)data[0]; |
||||||
|
numberOfBits -= 8; |
||||||
|
if (numberOfBits <= 8) |
||||||
|
{ |
||||||
|
endvalue = (value | ((uint) ((uchar)data[1]) << 8)); |
||||||
|
goto done; |
||||||
|
} |
||||||
|
value |= (uint) (((uchar)data[1]) << 8); |
||||||
|
numberOfBits -= 8; |
||||||
|
if (numberOfBits <= 8) |
||||||
|
{ |
||||||
|
uint num2 = (uint) (((uchar)data[2]) << 0x10); |
||||||
|
endvalue = (value | num2); |
||||||
|
goto done; |
||||||
|
} |
||||||
|
value |= (uint) (((uchar)data[2]) << 0x10); |
||||||
|
numberOfBits -= 8; |
||||||
|
endvalue = (value | ((uint) (((uchar)data[3]) << 0x18))); |
||||||
|
goto done; |
||||||
|
|
||||||
|
done: |
||||||
|
|
||||||
|
float num = max - min; |
||||||
|
int num2 = (((int) 1) << numberOfBits) - 1; |
||||||
|
float num3 = endvalue; |
||||||
|
float num4 = num3 / ((float) num2); |
||||||
|
return (min + (num4 * num)); |
||||||
|
} |
||||||
|
|
||||||
|
QByteArray rangedSingleToData(float value, float min, float max, int numberOfBits) |
||||||
|
{ |
||||||
|
QByteArray data; |
||||||
|
float num = max - min; |
||||||
|
float num2 = (value - min) / num; |
||||||
|
int num3 = (((int) 1) << numberOfBits) - 1; |
||||||
|
uint source = num3 * num2; |
||||||
|
|
||||||
|
if (numberOfBits <= 8) |
||||||
|
{ |
||||||
|
data += (unsigned char)source; |
||||||
|
return data; |
||||||
|
} |
||||||
|
data += (unsigned char)source; |
||||||
|
numberOfBits -= 8; |
||||||
|
if (numberOfBits <= 8) |
||||||
|
{ |
||||||
|
data += (unsigned char)source>>8; |
||||||
|
return data; |
||||||
|
} |
||||||
|
data += (unsigned char)source>>8; |
||||||
|
numberOfBits -= 8; |
||||||
|
if (numberOfBits <= 8) |
||||||
|
{ |
||||||
|
data += (unsigned char)source>>16; |
||||||
|
return data; |
||||||
|
} |
||||||
|
data += (unsigned char)source>>16; |
||||||
|
data += (unsigned char)source>>24; |
||||||
|
|
||||||
|
return data; |
||||||
|
} |
||||||
|
|
||||||
|
uint8_t dataToUint8(QByteArray data) |
||||||
|
{ |
||||||
|
return (uint8_t)data[0]; |
||||||
|
} |
||||||
|
|
||||||
|
uint16_t dataToUint16(QByteArray data) |
||||||
|
{ |
||||||
|
return ((uint16_t)(uint8_t)data[0]) |
||||||
|
+(((uint16_t)(uint8_t)data[1])<<8); |
||||||
|
} |
||||||
|
|
||||||
|
uint32_t dataToUint32(QByteArray data) |
||||||
|
{ |
||||||
|
return ((uint32_t)(uint8_t)data[0]) |
||||||
|
+(((uint32_t)(uint8_t)data[1])<<8) |
||||||
|
+(((uint32_t)(uint8_t)data[2])<<16) |
||||||
|
+(((uint32_t)(uint8_t)data[3])<<24); |
||||||
|
} |
||||||
|
|
||||||
|
uint64_t dataToUint64(QByteArray data) |
||||||
|
{ |
||||||
|
return ((uint64_t)(uint8_t)data[0]) |
||||||
|
+(((uint64_t)(uint8_t)data[1])<<8) |
||||||
|
+(((uint64_t)(uint8_t)data[2])<<16) |
||||||
|
+(((uint64_t)(uint8_t)data[3])<<24) |
||||||
|
+(((uint64_t)(uint8_t)data[4])<<32) |
||||||
|
+(((uint64_t)(uint8_t)data[5])<<40) |
||||||
|
+(((uint64_t)(uint8_t)data[6])<<48) |
||||||
|
+(((uint64_t)(uint8_t)data[7])<<56); |
||||||
|
} |
||||||
|
|
||||||
|
unsigned getVUint32Size(QByteArray data) |
||||||
|
{ |
||||||
|
unsigned lensize=0; |
||||||
|
{ |
||||||
|
unsigned char num3; |
||||||
|
do { |
||||||
|
num3 = data[lensize]; |
||||||
|
lensize++; |
||||||
|
} while ((num3 & 0x80) != 0); |
||||||
|
} |
||||||
|
return lensize; |
||||||
|
} |
||||||
|
|
||||||
|
QByteArray uint8ToData(uint8_t num) |
||||||
|
{ |
||||||
|
QByteArray data(1,0); |
||||||
|
data[0] = (uint8_t)num; |
||||||
|
return data; |
||||||
|
} |
||||||
|
|
||||||
|
QByteArray uint16ToData(uint16_t num) |
||||||
|
{ |
||||||
|
QByteArray data(2,0); |
||||||
|
data[0] = (uint8_t)(num & 0xFF); |
||||||
|
data[1] = (uint8_t)((num>>8) & 0xFF); |
||||||
|
return data; |
||||||
|
} |
||||||
|
|
||||||
|
QByteArray uint32ToData(uint32_t num) |
||||||
|
{ |
||||||
|
QByteArray data(4,0); |
||||||
|
data[0] = (uint8_t)(num & 0xFF); |
||||||
|
data[1] = (uint8_t)((num>>8) & 0xFF); |
||||||
|
data[2] = (uint8_t)((num>>16) & 0xFF); |
||||||
|
data[3] = (uint8_t)((num>>24) & 0xFF); |
||||||
|
return data; |
||||||
|
} |
||||||
|
|
||||||
|
QByteArray uint64ToData(uint64_t num) |
||||||
|
{ |
||||||
|
QByteArray data(8,0); |
||||||
|
data[0] = (uint8_t)(num & 0xFF); |
||||||
|
data[1] = (uint8_t)((num>>8) & 0xFF); |
||||||
|
data[2] = (uint8_t)((num>>16) & 0xFF); |
||||||
|
data[3] = (uint8_t)((num>>24) & 0xFF); |
||||||
|
data[4] = (uint8_t)((num>>32) & 0xFF); |
||||||
|
data[5] = (uint8_t)((num>>40) & 0xFF); |
||||||
|
data[6] = (uint8_t)((num>>48) & 0xFF); |
||||||
|
data[7] = (uint8_t)((num>>56) & 0xFF); |
||||||
|
return data; |
||||||
|
} |
@ -0,0 +1,45 @@ |
|||||||
|
/*
|
||||||
|
Copyright (C) 2014 by Project Tox <https://tox.im>
|
||||||
|
|
||||||
|
This file is part of qTox, a Qt-based graphical interface for Tox. |
||||||
|
|
||||||
|
This program is libre 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 COPYING file for more details. |
||||||
|
*/ |
||||||
|
|
||||||
|
|
||||||
|
#ifndef SERIALIZE_H |
||||||
|
#define SERIALIZE_H |
||||||
|
|
||||||
|
#include <cstdint> |
||||||
|
#include <QByteArray> |
||||||
|
#include <QString> |
||||||
|
|
||||||
|
/// Most of those functions are unsafe unless otherwise specified
|
||||||
|
/// Do not use them on untrusted data (e.g. check a signature first)
|
||||||
|
|
||||||
|
QByteArray doubleToData(double num); |
||||||
|
QByteArray floatToData(float num); |
||||||
|
float dataToFloat(QByteArray data); |
||||||
|
QByteArray stringToData(QString str); |
||||||
|
QString dataToString(QByteArray data); |
||||||
|
float dataToRangedSingle(float min, float max, int numberOfBits, QByteArray data); |
||||||
|
QByteArray rangedSingleToData(float value, float min, float max, int numberOfBits); |
||||||
|
uint8_t dataToUint8(QByteArray data); |
||||||
|
uint16_t dataToUint16(QByteArray data); |
||||||
|
uint32_t dataToUint32(QByteArray data); |
||||||
|
uint64_t dataToUint64(QByteArray data); |
||||||
|
unsigned getVUint32Size(QByteArray data); |
||||||
|
QByteArray uint8ToData(uint8_t num); |
||||||
|
QByteArray uint16ToData(uint16_t num); |
||||||
|
QByteArray uint32ToData(uint32_t num); |
||||||
|
QByteArray uint64ToData(uint64_t num); |
||||||
|
|
||||||
|
#endif // SERIALIZE_H
|
@ -0,0 +1,43 @@ |
|||||||
|
#include <sodium.h> |
||||||
|
#include <QByteArray> |
||||||
|
#include <QFile> |
||||||
|
|
||||||
|
using namespace std; |
||||||
|
|
||||||
|
int main(int argc, char* argv[]) |
||||||
|
{ |
||||||
|
QFile io; |
||||||
|
QByteArray msg; |
||||||
|
if (argc > 1) |
||||||
|
{ |
||||||
|
msg = QByteArray(argv[1]); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
io.open(stdin, QIODevice::ReadOnly); |
||||||
|
msg = io.readAll(); |
||||||
|
io.close(); |
||||||
|
} |
||||||
|
io.open(stdout, QIODevice::WriteOnly); |
||||||
|
|
||||||
|
QFile skeyFile("qtox-updater-skey"); |
||||||
|
if (!skeyFile.open(QIODevice::ReadOnly)) |
||||||
|
{ |
||||||
|
io.write("ERROR: qtox-updater-sign can't open the secret (private) key file\n"); |
||||||
|
io.close(); |
||||||
|
return 1; |
||||||
|
} |
||||||
|
QByteArray skeyData = skeyFile.readAll(); |
||||||
|
skeyData = QByteArray::fromHex(skeyData); |
||||||
|
skeyFile.close(); |
||||||
|
|
||||||
|
unsigned char sig[crypto_sign_BYTES]; |
||||||
|
crypto_sign_detached(sig, nullptr, (unsigned char*)msg.data(), msg.size(), (unsigned char*)skeyData.data()); |
||||||
|
|
||||||
|
io.write((char*)sig, crypto_sign_BYTES); |
||||||
|
io.write(msg); |
||||||
|
io.close(); |
||||||
|
|
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
Loading…
Reference in new issue