Skip to content

Commit

Permalink
Merge pull request #18 from bnogalm/Improvements
Browse files Browse the repository at this point in the history
SDK now works with MSVC 2017
Added Seed generator using QRandomGenerator
Fixed Memo hash serialization.
Timeout responses, default configured to 10 seconds.
  • Loading branch information
bnogalm authored Oct 13, 2018
2 parents 61a3400 + d6697f3 commit 7e3ddb0
Show file tree
Hide file tree
Showing 18 changed files with 228 additions and 76 deletions.
7 changes: 6 additions & 1 deletion StellarQtSDK.pri
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@


DEFINES += STELLAR_QT_REPLY_TIMEOUT=10000

DEFINES *= ED25519_NO_SEED

QT *= core network
CONFIG *= c++11

Expand Down Expand Up @@ -36,14 +41,14 @@ SOURCES += \
$$PWD/src/memo.cpp \
$$PWD/xdr/xdrhelper.cpp \
$$PWD/external/ed25519/src/add_scalar.c \
$$PWD/external/ed25519/src/ed25519_keypair.c \
$$PWD/external/ed25519/src/fe.c \
$$PWD/external/ed25519/src/ge.c \
$$PWD/external/ed25519/src/key_exchange.c \
$$PWD/external/ed25519/src/sc.c \
$$PWD/external/ed25519/src/seed.c \
$$PWD/external/ed25519/src/sha512.c \
$$PWD/external/ed25519/src/sign.c \
$$PWD/external/ed25519/src/_keypair.c \
$$PWD/external/ed25519/src/verify.c \
$$PWD/external/cyoencode/src/CyoDecode.cpp \
$$PWD/external/cyoencode/src/CyoEncode.cpp \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include "ge.h"


inline void ed25519_create_keypair(unsigned char *public_key, unsigned char *private_key, const unsigned char *seed) {
void ed25519_create_keypair(unsigned char *public_key, unsigned char *private_key, const unsigned char *seed) {
ge_p3 A;

sha512(seed, 32, private_key);
Expand Down
6 changes: 6 additions & 0 deletions src/account.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ Account::Account(KeyPair *keypair, qint64 sequenceNumber) {
m_sequenceNumber = sequenceNumber;
}

Account::~Account()
{
if(m_keyPair)
delete m_keyPair;
}

KeyPair *Account::getKeypair() {
return m_keyPair;
}
Expand Down
2 changes: 1 addition & 1 deletion src/account.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class Account : public TransactionBuilderAccount
* @param sequenceNumber Current sequence number of the account (can be obtained using java-stellar-sdk or horizon server)
*/
Account(KeyPair* keypair, qint64 sequenceNumber);

~Account();

KeyPair* getKeypair();

Expand Down
14 changes: 7 additions & 7 deletions src/federation/federationserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@

#include <QCoreApplication>

QNetworkAccessManager* FederationServer::s_httpClient = 0;
QHash<QString,FederationServer*>* FederationServer::s_cachedFederationServers = 0;
QNetworkAccessManager* FederationServer::s_httpClient = nullptr;
QHash<QString,FederationServer*>* FederationServer::s_cachedFederationServers = nullptr;
FederationServer::FederationServer()
{

}

QNetworkReply *FederationServer::buildReply(QString address)
QNetworkReply *FederationServer::buildReply(const QString& address)
{
QStringList tokens = address.split("*");
if (tokens.size() != 2) {
Expand Down Expand Up @@ -108,10 +108,10 @@ bool FederationServer::valid() const
return this->m_serverUri.isValid();
}

FederationResponse *FederationServer::resolveAddress(QString address) {
FederationResponse *FederationServer::resolveAddress(const QString &address) {
if(!this->valid()){
//delay request
auto response = new FederationResponse(0);
auto response = new FederationResponse(nullptr);

connect(this,&FederationServer::ready,[this,address,response](){
auto reply = buildReply(address);
Expand Down Expand Up @@ -193,11 +193,11 @@ void FederationServer::initialize()
#else
//workaround until i find a working alternative in android.. or android decide to fix their sdk problems once
QList<QByteArray> lines = data.split('\n');
for(QByteArray line : lines){
for(const QByteArray& line : lines){

if(line.contains("FEDERATION_SERVER=")){
QString textLine = QString::fromLatin1(line);
textLine.trimmed();
textLine=textLine.trimmed();
textLine.replace("FEDERATION_SERVER=","");
int from = textLine.indexOf('"')+1;
int to = textLine.lastIndexOf('"');
Expand Down
4 changes: 2 additions & 2 deletions src/federation/federationserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class FederationServer : public QObject
QString m_domain;
static QNetworkAccessManager* s_httpClient;
static QHash<QString,FederationServer*>* s_cachedFederationServers;
QNetworkReply * buildReply(QString address);
QNetworkReply * buildReply(const QString &address);
static QNetworkAccessManager &httpClient();


Expand Down Expand Up @@ -69,7 +69,7 @@ class FederationServer : public QObject
* @param address Stellar address, like <code>bob*stellar.org</code>
* @return FederationResponse
*/
FederationResponse* resolveAddress(QString address);
FederationResponse* resolveAddress(const QString& address);

/**
* Returns a federation server URI.
Expand Down
29 changes: 14 additions & 15 deletions src/keypair.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <QDebug>
#include <cstring>
#include <QDateTime>
#include <QRandomGenerator>

void memset_s(char * data,int value, int size)
{
Expand All @@ -21,7 +22,7 @@ KeyPair* checkNotNull(KeyPair* keypair, const char *error)
return keypair;
}

KeyPair::KeyPair():m_publicKey(0),m_privateKey(0)
KeyPair::KeyPair():m_publicKey(nullptr),m_privateKey(nullptr)
{

}
Expand Down Expand Up @@ -50,13 +51,13 @@ KeyPair::KeyPair(quint8 *publicKey, quint8 *privateKey)
memcpy(m_privateKey,privateKey,keyLength*2);
}
else{
m_privateKey=0;
m_privateKey=nullptr;
}
}

bool KeyPair::canSign() {

return m_privateKey != 0;
return m_privateKey != nullptr;
}

KeyPair *KeyPair::fromSecretSeed(QString seed) {
Expand Down Expand Up @@ -94,19 +95,14 @@ KeyPair *KeyPair::fromPublicKey(QByteArray publicKey) {
return new KeyPair((quint8*)publicKey.data());
}

std::random_device randomDevice;//random device is not really random in some devices...

KeyPair *KeyPair::random() {
#ifndef STELLAR_ALLOW_UNSECURE_RANDOM
throw std::runtime_error("Don't use KeyPair::random(); it uses std::random_device. it is not guaranteed to generate real random numbers.");
#endif
QByteArray seed;
seed.reserve(keyLength);
seed.resize(keyLength);
//you MUST mix random generated keypair with some other source of random as random_device is not random in many platforms
//and even if they are randoms you shouldnt trust anybody... so mix them, if they are random, they will stay random.
for(int i=0;i<keyLength;i++){
seed.append(randomDevice());
}
QRandomGenerator randomDevice = QRandomGenerator::securelySeeded();
randomDevice.fillRange((quint32*)seed.data(),keyLength/sizeof(quint32));
return fromSecretSeed(seed);
}

Expand All @@ -115,9 +111,11 @@ KeyPair *KeyPair::random(QByteArray rand)
if(rand.size()!=32)
throw std::runtime_error("rand should be 32 random bytes");
QByteArray seed;
seed.reserve(keyLength);
seed.resize(keyLength);
QRandomGenerator randomDevice = QRandomGenerator::securelySeeded();
randomDevice.fillRange((quint32*)seed.data(),keyLength/sizeof(quint32));
for(int i=0;i<keyLength;i++){
seed[i] = rand[i] ^ randomDevice();
seed[i] = rand[i] ^ seed[i];
}
return fromSecretSeed(seed);
}
Expand Down Expand Up @@ -199,8 +197,9 @@ stellar::DecoratedSignature KeyPair::signDecorated(QByteArray data) {
}

bool KeyPair::verify(QByteArray data, QByteArray signature) {
int res = ed25519_verify((uchar*)signature.data(),(uchar*)data.data(),data.length(),this->m_publicKey);
return res;
if(signature.size()>=64)
return ed25519_verify((uchar*)signature.data(),(uchar*)data.data(),data.length(),this->m_publicKey);
return false;
}

bool KeyPair::equals(KeyPair *obj) {
Expand Down
2 changes: 1 addition & 1 deletion src/keypair.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class KeyPair
* @param publicKey
* @param privateKey
*/
KeyPair(quint8* publicKey,quint8* privateKey=0);
KeyPair(quint8* publicKey,quint8* privateKey=nullptr);
/**
* Returns true if this Keypair is capable of signing
*/
Expand Down
33 changes: 24 additions & 9 deletions src/memo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ Memo *Memo::fromXdr(stellar::Memo& memo)
}
case stellar::MemoType::MEMO_HASH:
{
QByteArray data = QByteArray::fromRawData((const char*)memo.hash,sizeof(memo.hash));
QByteArray data((const char*)memo.hash,sizeof(memo.hash));
return Memo::hash(data);
}
case stellar::MemoType::MEMO_RETURN:
{
QByteArray data = QByteArray::fromRawData((const char*)memo.retHash,sizeof(memo.retHash));
QByteArray data((const char*)memo.retHash,sizeof(memo.retHash));
return Memo::returnHash(data);
}
};
Expand All @@ -51,7 +51,7 @@ Memo *Memo::parse(QString type, QString memo)
else
return Memo::text("");//null!=empty
} else if (type=="id") {
return Memo::id(memo.toLongLong());
return Memo::id(memo.toULongLong());
} else if (type=="hash") {
return Memo::hash(memo);
} else if (type=="return") {
Expand Down Expand Up @@ -100,6 +100,10 @@ MemoId* Memo::id(qint64 id) {
return new MemoId(id);
}

MemoId* Memo::id(quint64 id) {
return new MemoId(id);
}

MemoHash* Memo::hash(QByteArray bytes) {
return new MemoHash(bytes);
}
Expand Down Expand Up @@ -159,7 +163,8 @@ MemoNone::~MemoNone(){
MemoReturnHash::MemoReturnHash(QByteArray bytes):MemoHashAbstract(bytes) {
}

MemoReturnHash::MemoReturnHash(QString hexString):MemoHashAbstract(hexString){// throws DecoderException {

MemoReturnHash::MemoReturnHash(QString hexString):MemoHashAbstract(CheckHex(hexString)){// throws DecoderException {
}

MemoReturnHash::~MemoReturnHash(){
Expand Down Expand Up @@ -187,6 +192,7 @@ MemoText::~MemoText(){

}


QString MemoText::getText() const{
return m_text;
}
Expand All @@ -207,20 +213,24 @@ MemoHashAbstract::MemoHashAbstract(QByteArray bytes) {
throw std::runtime_error("MEMO_HASH can contain 32 bytes at max.");
}
else{

this->m_bytes = bytes;
}
}


MemoHashAbstract::MemoHashAbstract(QString hexString): MemoHashAbstract(QByteArray::fromHex(hexString.toLatin1())){
}

MemoHashAbstract::~MemoHashAbstract(){

}

QByteArray MemoHashAbstract::getBytes() const{

QByteArray MemoHashAbstract::getBytes() const {
return m_bytes;
}

QString MemoHashAbstract::getHexValue() const{
QString MemoHashAbstract::getHexValue() const {
return QString(m_bytes.toHex());
}

Expand Down Expand Up @@ -257,16 +267,21 @@ stellar::Memo MemoHash::toXdr() {

MemoId::MemoId(qint64 id) {
if (id < 0) {
//throw new IllegalArgumentException("id must be a positive number");
throw std::runtime_error("id must be a positive number");
}
this->m_id = static_cast<quint64>(id);
}

MemoId::MemoId(quint64 id) {
this->m_id = id;
}

MemoId::~MemoId(){

}

qint64 MemoId::getId() const{

quint64 MemoId::getId() const {
return m_id;
}

Expand Down
Loading

0 comments on commit 7e3ddb0

Please sign in to comment.