diff --git a/apps/enclave/LICENSE b/apps/enclave/LICENSE new file mode 100644 index 000000000..ed1daacf6 --- /dev/null +++ b/apps/enclave/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2004, Matthew P. Cashdollar +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + * Neither the name of the author nor the names of any contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/apps/enclave/Makefile b/apps/enclave/Makefile new file mode 100644 index 000000000..60075e7ce --- /dev/null +++ b/apps/enclave/Makefile @@ -0,0 +1,76 @@ +# +# This Makefile is compatible with GNU Make and should work on Linux +# (Tested on Debian 3.0) +# + +# +# Directories +# + +BINDIR = bin +LOGDIR = log +OBJDIR = obj +SRCDIR = src + +SAMINCDIR = ../libsam/inc +SAMLIBDIR = ../libsam/lib +TOMCRYPTDIR = ../libtomcrypt-0.96 + +# +# Programs +# + +CC = g++ + +# +# Flags +# + +CFLAGS = -g -march=i486 -pipe -Wall + +# +# Libraries +# + +CFLAGS += -I$(SAMINCDIR) -I$(TOMCRYPTDIR) +LDFLAGS = -L$(SAMLIBDIR) -L$(TOMCRYPTDIR) +LIBS = -lsam -ltomcrypt + +# +# Object files +# + +OBJS = $(OBJDIR)/bigint.o \ + $(OBJDIR)/logger.o \ + $(OBJDIR)/main.o \ + $(OBJDIR)/peers.o \ + $(OBJDIR)/rpc.o \ + $(OBJDIR)/sam.o \ + $(OBJDIR)/sha1.o + +# +# Build rules +# + +all: depend enclave + +depend: + $(CC) $(CFLAGS) -MM $(SRCDIR)/*.cpp > .depend + +$(OBJDIR)/%.o: $(SRCDIR)/%.cpp + $(CC) $(CFLAGS) -o $@ -c $< + +enclave: $(OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) -o $(BINDIR)/enclave $(OBJS) $(LIBS) + +# +# Cleanup rules +# + +clean: + -rm -f $(BINDIR)/* $(OBJDIR)/* .depend + +clean-logs: + -rm -f $(LOGDIR)/* + +tidy: clean clean-logs diff --git a/apps/enclave/cfg/peers.ref b/apps/enclave/cfg/peers.ref new file mode 100644 index 000000000..2d72a5f73 --- /dev/null +++ b/apps/enclave/cfg/peers.ref @@ -0,0 +1,2 @@ +4KpEG0uUvTM~IZKuWZZifdmh5UU6evIPG0tE3ppoqy37AY2NJrsM8BU0EkT1SG-g18qSW9UHDp7qs7m~WzeWTXyYggEb6k6-e0GYC2Cj8ED8JV58-2~cFZumVNJ2d1hns-MGX7RZv2lz3Cz2ZVhfZxSIw9UnpV-kwVn7sQ7PBCvJYE4INbp5OlRQH1-3lXiUheoJfeZpegGTUSHUwIRWglX7w87YF~LCbJMYXDgMyA3SaxsZaun7Wc8ku4bqtbmG9u15XlmqimLUUmDG0cw77HJzqxnR1C1hx0wf-9zgH6u4jwTWk92w5tZJZSv1SHKejlPkIbRNAhZv5wroyZsn6T0koV~kTVCvbUEwILho-rHn4A6C2jLQifwE9aucziBTVq3YLK2urf1wI1jLh98iFNav40S~B2w-4xZFAQ49bOdWzY4KmVIjocVhfGi~RLl5bHD1TEJS7nOaDhI8qCSe7mR0XzZgQ~iROR~XowlwKXBzNPjKED7yN8GgV2pWRGNYAAAA +WiotuvEjGpSz7q14eZGYFpD0xNt3V~nxZdDDgKc~whkW-pardZyz~wZipHXLIOvniThDL2rxJ~OW7RxgUycCph4x--NL51kEJhMWZ~bgxPioxw-T4JGQ9LSNndt9xNOf6yhEqyokqyEOEeJjw6m2e7RX7mTRffmTlCdu6uH6rVEk22o4Uu5S26p6-LS2k9lRyMWitFd~t9cnOgLTZTE~h4d-UlAd1BGxpCTlGWcaynOQzKKtljZknZMF9Qv19MxT83t18~3IURb6aOLlC4oih9pMt1pHouZuOaStKA7cGLsXUAhSB31BvK8l4R7VhgcudwJ9EQZkZQee51hcng7K1Yqmd4lnjHHuf1mDk0YXBAWDZOM0-oEwkJWumGuYl0NUtLhNlFrBjenbjACx88qhfy6mkXfo8c-c2QqEXuD2xt4OVqrWxBTIrr1pR-E1NdIxzIvOlCbrRXaqxqu-wnrrG2vCO-1zu9NHacCVjXD7AR7p3T628wPdCUzj2~rZRcCkAAAA diff --git a/apps/enclave/src/bigint.cpp b/apps/enclave/src/bigint.cpp new file mode 100644 index 000000000..ec6675357 --- /dev/null +++ b/apps/enclave/src/bigint.cpp @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2004, Matthew P. Cashdollar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the author nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "platform.hpp" +#include "bigint.hpp" + +/******************************************************************************/ +// Note: All the const_casts below are necessary because libtomcrypt doesn't // +// have its arguments as const, even when they are not changed // +/******************************************************************************/ + +Bigint::Bigint(const Bigint& bigint) +{ + init(); + copyover_mp_int(bigint.mpi); +} + +Bigint::Bigint(const uchar_t* data, size_t size) +{ + init(); + import_uraw(data, size); +} + +Bigint::Bigint(uint16_t i) +{ + init(); + i = htons(i); + import_uraw(reinterpret_cast(&i), 2); +} + +Bigint::Bigint(uint32_t i) +{ + init(); + i = htonl(i); + import_uraw(reinterpret_cast(&i), 4); +} + +/* + * Replaces our current mp_int with another one + * (just a wrapper for mp_copy) + */ +void Bigint::copyover_mp_int(const mp_int& i) +{ + int rc = mp_copy(const_cast(&i), &mpi); + assert(rc == MP_OKAY); +} + +/* + * Saves a Bigint to a raw unsigned big-endian integer + * Note that the result must be freed with delete[] + * + * size - filled with the size of the output + * + * Returns: binary data + */ +uchar_t* Bigint::export_uraw(size_t& size) const +{ + uchar_t* out; + size = mp_unsigned_bin_size(const_cast(&mpi)); + if (size != 0) { + out = new uchar_t[size]; + int rc = mp_to_unsigned_bin(const_cast(&mpi), out); + assert(rc == MP_OKAY); + } else { // size == 0 + size = 1; + out = new uchar_t[1]; + out[0] = 0; + } + return out; +} + +/* + * Loads a raw unsigned big-endian integer into Bigint + * + * data - binary data + * size - size of data + */ +void Bigint::import_uraw(const uchar_t* data, size_t size) +{ + uchar_t tmp[size]; // mp_read_unsigned_bin() arg 2 is not const + memcpy(tmp, data, sizeof tmp); // I'm not taking any chances + int rc = mp_read_unsigned_bin(&mpi, tmp, sizeof tmp); + assert(rc == MP_OKAY); +} + +/* + * Initialises the object + */ +void Bigint::init(void) +{ + int rc = mp_init(&mpi); + assert(rc == MP_OKAY); +} + +bool Bigint::operator<(const Bigint& rhs) const +{ + int rc = mp_cmp(const_cast(&mpi), const_cast(&rhs.mpi)); + if (rc == MP_LT) + return true; + else + return false; +} + +Bigint& Bigint::operator=(const Bigint& rhs) +{ + if (this != &rhs) // check for self-assignment: a = a + copyover_mp_int(rhs.mpi); + return *this; +} + +bool Bigint::operator==(const Bigint& rhs) const +{ + int rc = mp_cmp(const_cast(&mpi), const_cast(&rhs.mpi)); + if (rc == MP_EQ) + return true; + else + return false; +} + +bool Bigint::operator>(const Bigint& rhs) const +{ + int rc = mp_cmp(const_cast(&mpi), const_cast(&rhs.mpi)); + if (rc == MP_GT) + return true; + else + return false; +} + +/* + * Xors another Bigint with this Bigint and puts the result in Bigint `result' + * + * rhs - the bigint to xor with + * result - will be filled with the result of the xor + */ +void Bigint::xor(const Bigint& rhs, Bigint& result) const +{ + int rc = mp_xor(const_cast(&mpi), const_cast(&rhs.mpi), + &result.mpi); + assert(rc == MP_OKAY); +} diff --git a/apps/enclave/src/bigint.hpp b/apps/enclave/src/bigint.hpp new file mode 100644 index 000000000..9142bb6a4 --- /dev/null +++ b/apps/enclave/src/bigint.hpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2004, Matthew P. Cashdollar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the author nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef BIGINT_HPP +#define BIGINT_HPP + +class Bigint { + public: + Bigint(void) { init(); } + Bigint(const Bigint& bigint); + Bigint(const uchar_t* data, size_t size); + Bigint(uint16_t i); + Bigint(uint32_t i); + ~Bigint(void) { mp_clear(&mpi); } + uchar_t* export_uraw(size_t& size) const; + const mp_int& get_mp_int(void) const { return mpi; } + void import_uraw(const uchar_t* data, size_t size); + bool operator<(const Bigint& rhs) const; + Bigint& operator=(const Bigint& rhs); + bool operator==(const Bigint& rhs) const; + bool operator>(const Bigint& rhs) const; + void xor(const Bigint& rhs, Bigint& result) const; + + protected: + mp_int mpi; + + private: + void copyover_mp_int(const mp_int& i); + void init(void); +}; + +#endif // BIGINT_HPP \ No newline at end of file diff --git a/apps/enclave/src/logger.cpp b/apps/enclave/src/logger.cpp new file mode 100644 index 000000000..ba0a10c3d --- /dev/null +++ b/apps/enclave/src/logger.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2004, Matthew P. Cashdollar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the author nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "platform.hpp" +#include "logger.hpp" + +Logger::Logger(const string& file) +{ + this->file = file; + loglevel = priority = debug; + logf.open(file.c_str(), ios::app); + if (!logf) { + cerr << "Error opening log file (" << file.c_str() << ")\n"; + throw runtime_error("Error opening log file"); + } +} diff --git a/apps/enclave/src/logger.hpp b/apps/enclave/src/logger.hpp new file mode 100644 index 000000000..e5c528d88 --- /dev/null +++ b/apps/enclave/src/logger.hpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2004, Matthew P. Cashdollar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the author nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LOGGER_HPP +#define LOGGER_HPP + +/* + * LDEBUG - debugging messages + * LMINOR - unimportant messages + * LINFO - informational messages + * LWARN - errors we automatically recover from + * LERROR - major, important errors + */ +#if VERBOSE_LOGS + #define LDEBUG logger.set_pri(Logger::debug); logger << "(D)" << __FILE__ << ':' << __LINE__ << ':' << __func__ << "(): " + #define LMINOR logger.set_pri(Logger::minor); logger << "(M)" << __FILE__ << ':' << __LINE__ << ':' << __func__ << "(): " + #define LINFO logger.set_pri(Logger::info); logger << "(I)" << __FILE__ << ':' << __LINE__ << ':' << __func__ << "(): " + #define LWARN logger.set_pri(Logger::warn); logger << "(W)" << __FILE__ << ':' << __LINE__ << ':' << __func__ << "(): " + #define LERROR logger.set_pri(Logger::error); logger << "(E)" << __FILE__ << ':' << __LINE__ << ':' << __func__ << "(): " +#else + #define LDEBUG logger.set_pri(Logger::debug); logger + #define LMINOR logger.set_pri(Logger::minor); logger + #define LINFO logger.set_pri(Logger::info); logger + #define LWARN logger.set_pri(Logger::warn); logger + #define LERROR logger.set_pri(Logger::error); logger +#endif + +class Logger { + public: + typedef enum {debug = 0, minor = 1, info = 2, warn = 3, error = 4} + priority_t; + + Logger(const string& file); + + void flush(void) { logf.flush(); } + priority_t get_loglevel(void) const { return loglevel; } + void set_loglevel(priority_t priority) { loglevel = priority; } + Logger& operator<<(char c) + { if (priority >= loglevel) { logf << c; flush(); } return *this; } + Logger& operator<<(const char* c) + { if (priority >= loglevel) { logf << c; flush(); } return *this; } + Logger& operator<<(int i) + { if (priority >= loglevel) { logf << i; flush(); } return *this; } + Logger& operator<<(const string& s) + { if (priority >= loglevel) { logf << s; flush(); } return *this; } + Logger& operator<<(unsigned int i) + { if (priority >= loglevel) { logf << i; flush(); } return *this; } + void set_pri(priority_t priority) { this->priority = priority; } + + private: + priority_t priority; // importance of the following log message(s) + string file; + priority_t loglevel; // write log messsages at or above this priority + ofstream logf; +}; + +#endif // LOGGER_HPP diff --git a/apps/enclave/src/main.cpp b/apps/enclave/src/main.cpp new file mode 100644 index 000000000..807766295 --- /dev/null +++ b/apps/enclave/src/main.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2004, Matthew P. Cashdollar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the author nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "platform.hpp" +#include "main.hpp" + +Logger logger(LOG_FILE); +Sam *sam; + +int main(int argc, char* argv[]) +{ + logger.set_loglevel(Logger::debug); + + if (argc != 2) { // put some getopts stuff in here later + LERROR << "Please specify your destination name. e.g. 'bin/enclave " \ + "enclave'\n"; + return -1; + } + + LINFO << "Enclave DHT - Built on " << __DATE__ << ' ' << __TIME__ << '\n'; + try { + sam = new Sam("eldritch", 7656, argv[1], 0); + } catch (const Sam_error& x) { + LERROR << "SAM error: " << x.what() << '\n'; + if (x.code() == SAM_SOCKET_ERROR) + LERROR << "Check whether you have specified the correct SAM host " \ + "and port number\n"; + return 1; + } + sam->naming_lookup(); + while (sam->get_my_dest() == "") + sam->read_buffer(); // wait until we get our own dest back from lookup + + sam->peers->advertise_self(); + + while (true) + sam->read_buffer(); + + delete sam; + return 0; +} diff --git a/apps/enclave/src/main.hpp b/apps/enclave/src/main.hpp new file mode 100644 index 000000000..48c9244e1 --- /dev/null +++ b/apps/enclave/src/main.hpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2004, Matthew P. Cashdollar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the author nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef MAIN_HPP +#define MAIN_HPP + +// intentionally left blank + +#endif // MAIN_HPP diff --git a/apps/enclave/src/near_peer.hpp b/apps/enclave/src/near_peer.hpp new file mode 100644 index 000000000..bd433803b --- /dev/null +++ b/apps/enclave/src/near_peer.hpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2004, Matthew P. Cashdollar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the author nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NEAR_PEER_HPP +#define NEAR_PEER_HPP + +// +// Used for finding the closest peers to a sha1 +// + +class Near_peer { + public: + Near_peer(const Bigint& distance, Peer* peer) + : distance(distance), peer(peer) {} + + Peer* get_peer(void) const { return peer; } + bool operator<(const Near_peer& rhs) const + { if (distance < rhs.distance) return true; else return false; } + + protected: + const Bigint distance; + + private: + Peer* peer; +}; + +#endif // NEAR_PEER_HPP \ No newline at end of file diff --git a/apps/enclave/src/peer.hpp b/apps/enclave/src/peer.hpp new file mode 100644 index 000000000..939f7d7b8 --- /dev/null +++ b/apps/enclave/src/peer.hpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2004, Matthew P. Cashdollar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the author nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PEER_HPP +#define PEER_HPP + +class Peer { + public: + Peer(const string& dest, const Sha1& kaddr) + : dest(dest), kaddr(kaddr), lag(-1) {} + + const string& get_b64kaddr(void) const { return kaddr.b64hash(); } + const uchar_t* get_binkaddr(void) const { return kaddr.binhash(); } + const string& get_dest(void) const { return dest; } + int get_lag(void) const { return lag; } + const string get_sdest(void) const { return dest.substr(0, 8); } + void set_lag(int lag) { this->lag = lag; } + + private: + const string dest; + const Sha1 kaddr; + int lag; // if -1, then it is unknown +}; + +#endif // PEER_HPP diff --git a/apps/enclave/src/peers.cpp b/apps/enclave/src/peers.cpp new file mode 100644 index 000000000..707bd437d --- /dev/null +++ b/apps/enclave/src/peers.cpp @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2004, Matthew P. Cashdollar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the author nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "platform.hpp" +#include "near_peer.hpp" +#include "rpc.hpp" +#include "sha1.hpp" +#include "peers.hpp" + +/* + * Inform other peers of our existence and collect the destination addresses of + * nearby peers + */ +void Peers::advertise_self(void) +{ + list near_peers; + get_nearest(sam->get_my_sha1(), PAR_RPCS, near_peers); + for (near_peers_ci i = near_peers.begin(); i != near_peers.end(); i++) { + Rpc rpc(i->get_peer()); + rpc.find_peers(sam->get_my_sha1()); + } +} + +/* + * Find the `n' nearest peers by xoring a sha1 with a kaddr + * + * sha1 - sha1 to find nearness to + * n - number of peers to find + * near_peers - a list to put the found peers in + */ +void Peers::get_nearest(const Sha1& sha1, size_t n, list& near_peers) +{ + near_peers.clear(); // prevents duplicate peers in the list + for (peersmap_i i = peersmap.begin(); i != peersmap.end(); i++) { + const Sha1& kaddr = i->first; + Bigint distance; + sha1.xor(kaddr, distance); + Near_peer np(distance, &(i->second)); + near_peers.insert(near_peers.end(), np); + } + near_peers.sort(); + while (near_peers.size() > n) + near_peers.pop_back(); +} + +Peer* Peers::get_peer_by_dest(const sam_pubkey_t dest) +{ + const string s = dest; + return get_peer_by_dest(s); +} + +/* + * Gets a peer by its base 64 destination address + * + * dest - destination + * + * Returns: pointer to peer, or 0 if the peer wasn't found + */ +Peer* Peers::get_peer_by_dest(const string& dest) +{ + for (peersmap_i i = peersmap.begin(); i != peersmap.end(); i++) { + Peer& tmp = i->second; + if (tmp.get_dest() == dest) + return &(i->second); + } + return 0; +} + +/* + * Gets a peer by its Kademlia address + * + * kaddr - Kademlia adddress + * + * Returns: pointer to peer, or 0 if the peer wasn't found + */ +Peer* Peers::get_peer_by_kaddr(const Sha1& kaddr) +{ + peersmap_i i = peersmap.find(kaddr); + if (i != peersmap.end()) + return &(i->second); + else + return 0; +} + +/* + * Loads peer addresses from a file + */ +void Peers::load(void) +{ + string dest; + + ifstream peersf(file.c_str()); + if (!peersf) { + LERROR << "Couldn't load peers reference file (" << file.c_str() + << ")\n"; + if (peersmap.size() > 0) + return; + else + throw runtime_error("No peer references in memory"); + } + + for (getline(peersf, dest); peersf; getline(peersf, dest)) + new_peer(dest); + + if (peersmap.size() > 0) { + LMINOR << peersmap.size() << " peer references in memory\n"; + } else + throw runtime_error("No peer references in memory"); +} + +Peer* Peers::new_peer(const sam_pubkey_t dest) +{ + const string s = dest; + return new_peer(s); +} + +/* + * Adds a newly discovered peer to the peers map + * + * dest - destination address of the peer + * + * Returns: pointer to the peer + */ +Peer* Peers::new_peer(const string& dest) +{ + // Check the destination address + if (!sam->valid_dest(dest)) { + LWARN << "Bad format in peer reference: " << dest.substr(0, 8) << '\n'; + return 0; + } + // Never add our own peer to the peers we can connect to + if (dest == sam->get_my_dest()) { + LDEBUG << "Not adding my own peer reference: " << dest.substr(0, 8) + << '\n'; + return 0; + } + // Be sure that the peer is not already known to us + Peer *peer = get_peer_by_dest(dest); + if (peer != 0) { + LDEBUG << "Redundant peer reference: " << dest.substr(0, 8) << '\n'; + return peer; + } + + // Tests passed, add it + Sha1 sha1(dest); + pair p = peersmap.insert( + make_pair(sha1, Peer(dest, sha1))); + assert(p.second); + LMINOR << "New peer reference: " << dest.substr(0, 8) + << " (Kaddr: " << sha1.b64hash() << ")\n"; + peer = &(p.first->second); + return peer; +} + +/* + * Saves peer destinations to a file + * + * file - the file to save to + */ +void Peers::save(void) +{ + ofstream peersf(file.c_str()); + if (!peersf) { + LERROR << "Error opening peers reference file (" << file.c_str() + << ")\n"; + return; + } + + LDEBUG << "Saving " << peersmap.size() + 1 << " peer references\n"; + peersf << sam->get_my_dest() << '\n'; + for (peersmap_ci i = peersmap.begin(); i != peersmap.end(); i++) { + const Peer& tmp = i->second; + peersf << tmp.get_dest() << '\n'; + } +} + +/* + * Stores data on some peers + * + * sha1 - the sha1 value for the data + * data - the data + */ +void Peers::store(const Sha1& sha1) +{ + list near_peers; + get_nearest(sam->get_my_sha1(), PAR_RPCS, near_peers); + for (near_peers_ci i = near_peers.begin(); i != near_peers.end(); i++) { + Rpc rpc(i->get_peer()); + rpc.store(sha1); + } +} diff --git a/apps/enclave/src/peers.hpp b/apps/enclave/src/peers.hpp new file mode 100644 index 000000000..c948a1968 --- /dev/null +++ b/apps/enclave/src/peers.hpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2004, Matthew P. Cashdollar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the author nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PEERS_HPP +#define PEERS_HPP + +class Peers { + public: + static const int PAR_RPCS = 3; // The number of parallel RPCs to send + static const int RET_REFS = 20; // The number of peer refs to return on + // failed requests + Peers(const string& file) + : file(file) + { load(); } + ~Peers(void) { save(); } + + void advertise_self(void); + void get_nearest(const Sha1& sha1, size_t n, + list& near_peers); + Peer* get_peer_by_dest(const sam_pubkey_t dest); + Peer* get_peer_by_dest(const string& dest); + Peer* get_peer_by_kaddr(const Sha1& kaddr); + Peer* new_peer(const sam_pubkey_t dest); + Peer* new_peer(const string& dest); + void store(const Sha1& sha1); + + private: + typedef map::const_iterator peersmap_ci; + typedef map::iterator peersmap_i; + typedef list::const_iterator near_peers_ci; + typedef list::iterator near_peers_i; + + void load(void); + void save(void); + + const string file; + map peersmap; +}; + +#endif // PEERS_HPP diff --git a/apps/enclave/src/platform.hpp b/apps/enclave/src/platform.hpp new file mode 100644 index 000000000..3a0a843d5 --- /dev/null +++ b/apps/enclave/src/platform.hpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2004, Matthew P. Cashdollar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the author nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PLATFORM_HPP +#define PLATFORM_HPP + +/* + * Operating system + */ +#define FREEBSD 0 // FreeBSD (untested) +#define MINGW 1 // Windows native (Mingw) +#define LINUX 2 // Linux +#define CYGWIN 3 // Cygwin + +/* + * System includes + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +/* + * Define this to '1' to cause the printing of source code file and line number + * information with each log message. Set it to '0' for simple logging. + */ +#define VERBOSE_LOGS 0 + +/* + * The default locations for some files + */ +#define LOG_FILE "log/main.log" +#define PEERS_REF_FILE "cfg/peers.ref" + +/* + * Library includes + */ +#include "mycrypt.h" // LibTomCrypt +#include "sam.h" // LibSAM + +/* + * Local includes + */ +#include "logger.hpp" +#include "sam_error.hpp" // for sam.hpp +#include "bigint.hpp" // for sha1.hpp +#include "sha1.hpp" // for peers.hpp +#include "peer.hpp" // for peers.hpp +#include "near_peer.hpp" // for peers.hpp +#include "peers.hpp" // for sam.hpp +#include "sam.hpp" // SAM + +/* + * Global variables + */ +extern Logger logger; +extern Sam *sam; + +#endif // PLATFORM_HPP diff --git a/apps/enclave/src/rpc.cpp b/apps/enclave/src/rpc.cpp new file mode 100644 index 000000000..0cd2f502f --- /dev/null +++ b/apps/enclave/src/rpc.cpp @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2004, Matthew P. Cashdollar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the author nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "platform.hpp" +#include "rpc.hpp" + +// These can't be 'const' because I have to make them big-endian first +uint16_t Rpc::VERSION = htons(1); +uint16_t Rpc::OLDEST_GOOD_VERSION = htons(1); + +/* + * Requests a peer to find the addresses of the closest peers to the specified + * sha1 and return them + * + * sha1 - closeness to this sha1 + */ +void Rpc::find_peers(const Sha1& sha1) +{ + LDEBUG << "To: " << peer->get_sdest() << " [" << peer->get_b64kaddr() + << "] Msg: FIND_PEERS\n"; + + // VERSION + command + bin sha1 + const size_t len = sizeof VERSION + 1 + Sha1::SHA1BIN_LEN; + uchar_t buf[len]; + uchar_t* p = static_cast(memcpy(buf, &VERSION, sizeof VERSION)); + p += sizeof VERSION; + *p = FIND_PEERS; + p++; + memcpy(p, sha1.binhash(), Sha1::SHA1BIN_LEN); + sam->send_dgram(peer->get_dest(), buf, len); +} + +/* + * Returns the closest peer references to a Sha1 + * + * sha1 - sha1 to test nearness to + */ +void Rpc::found_peers(const Sha1& sha1) +{ + list near_peers; + sam->peers->get_nearest(sha1, Peers::RET_REFS, near_peers); + LDEBUG << "To: " << peer->get_sdest() << " [" << peer->get_b64kaddr() + << "] Msg: FOUND_PEERS (" << near_peers.size() << " peers)\n"; + + // VERSION + command + number of sha1s (0-255) + bin sha1s + const size_t len = sizeof VERSION + 1 + 1 + + (near_peers.size() * (SAM_PUBKEY_LEN - 1)); + assert(near_peers.size() <= 255); + uchar_t buf[len]; + uchar_t* p = static_cast(memcpy(buf, &VERSION, sizeof VERSION)); + p += sizeof VERSION; + *p = FOUND_PEERS; + p++; + *p = near_peers.size(); + p++; + for (Peers::near_peers_ci i = near_peers.begin(); i != near_peers.end(); + i++) { + const Peer* peer = i->get_peer(); + memcpy(p, peer->get_dest().c_str(), (SAM_PUBKEY_LEN - 1)); + p += SAM_PUBKEY_LEN - 1; + } + sam->send_dgram(peer->get_dest(), buf, len); +} + +/* + * Parse incoming data and invoke the appropriate RPC + * + * data - the data + * size - the size of `data' + */ +void Rpc::parse(const void* data, size_t size) +{ + uint16_t his_ver; + + memcpy(&his_ver, data, sizeof VERSION); + if (ntohs(his_ver) < ntohs(VERSION)) { + LMINOR << "Ignored RPC from " << peer->get_sdest() << " [" + << peer->get_b64kaddr() << "] using obsolete protocol version " + << ntohs(his_ver) << '\n'; + return; + } else if (size <= 4) { + LWARN << "RPC too small from " << peer->get_sdest() << " [" + << peer->get_b64kaddr() << "]\n"; + return; + } + const uchar_t* p = static_cast(data); + + if (p[2] == PING) { //----------------------------------------------------- + LDEBUG << "From: " << peer->get_sdest() << " [" << peer->get_b64kaddr() + << "] Msg: PING\n"; + uint32_t ptime; + if (size != sizeof VERSION + 1 + sizeof ptime) { + LWARN << "Malformed PING RPC from " << peer->get_sdest() + << " [" << peer->get_b64kaddr() << "]\n"; + return; + } + p += sizeof VERSION + 1; + memcpy(&ptime, p, sizeof ptime); + pong(ptime); // no need to ntohl() it here because we're just copying it + return; + + } else if (p[2] == PONG) { //---------------------------------------------- + LDEBUG << "From: " << peer->get_sdest() << " [" << peer->get_b64kaddr() + << "] Msg: PONG\n"; + uint32_t ptime; + if (size != sizeof VERSION + 1 + sizeof ptime) { + LWARN << "Malformed PONG RPC from " << peer->get_sdest() + << " [" << peer->get_b64kaddr() << "]\n"; + return; + } + p += sizeof VERSION + 1; + memcpy(&ptime, p, sizeof ptime); + ptime = ntohl(ptime); + uint32_t now = time(NULL); + peer->set_lag(now - ptime); + LDEBUG << "Lag is " << peer->get_lag() << " seconds\n"; + return; + + } else if (p[2] == FIND_PEERS) { //---------------------------------------- + if (size != sizeof VERSION + 1 + Sha1::SHA1BIN_LEN) { + LWARN << "Malformed FIND_PEERS RPC from " << peer->get_sdest() + << " [" << peer->get_b64kaddr() << "]\n"; + return; + } + LDEBUG << "From: " << peer->get_sdest() << " [" << peer->get_b64kaddr() + << "] Msg: FIND_PEERS\n"; + found_peers(Sha1(p + 4)); + return; + + } else if (p[2] == FOUND_PEERS) { //--------------------------------------- + const size_t refs = p[3]; + if (size != sizeof VERSION + 1 + 1 + (refs * (SAM_PUBKEY_LEN - 1))) { + LWARN << "Malformed FOUND_PEERS RPC from " << peer->get_sdest() + << " [" << peer->get_b64kaddr() << "]\n"; + return; + } + LDEBUG << "From: " << peer->get_sdest() << " [" << peer->get_b64kaddr() + << "] Msg: FOUND_PEERS (" << refs << " peers)\n"; + p += sizeof VERSION + 1 + 1; + for (size_t i = 1; i <= refs; i++) { + sam_pubkey_t dest; + memcpy(dest, p, SAM_PUBKEY_LEN - 1); // - 1 == no NUL in RPC + dest[SAM_PUBKEY_LEN - 1] = '\0'; + //LDEBUG << "Message had: " << dest << '\n'; + sam->peers->new_peer(dest); + p += SAM_PUBKEY_LEN - 1; + } + return; + + } else //------------------------------------------------------------------ + LWARN << "Unknown RPC #" << static_cast(p[2]) << " from " + << peer->get_sdest() << " [" << peer->get_b64kaddr() << "]\n"; +} + +/* + * Sends a ping to someone + */ +void Rpc::ping(void) +{ + LDEBUG << "To: " << peer->get_sdest() << " [" << peer->get_b64kaddr() + << "] Msg: PING\n"; + + uint32_t now = htonl(time(NULL)); + // VERSION + command + seconds since 1970 + const size_t len = sizeof VERSION + 1 + sizeof now; + uchar_t buf[len]; + uchar_t* p = static_cast(memcpy(buf, &VERSION, sizeof VERSION)); + p += sizeof VERSION; + *p = PING; + p++; + memcpy(p, &now, sizeof now); + sam->send_dgram(peer->get_dest(), buf, len); +} + +/* + * Sends a ping reply to someone + * + * ptime - the time the peer sent us (we echo the same time back) + */ +void Rpc::pong(uint32_t ptime) +{ + LDEBUG << "To: " << peer->get_sdest() << " [" << peer->get_b64kaddr() + << "] Msg: PONG\n"; + + // VERSION + command + pinger's seconds since 1970 echoed back + const size_t len = sizeof VERSION + 1 + sizeof ptime; + uchar_t buf[len]; + uchar_t* p = static_cast(memcpy(buf, &VERSION, sizeof VERSION)); + p += sizeof VERSION; + *p = PONG; + p++; + memcpy(p, &ptime, sizeof ptime); + sam->send_dgram(peer->get_dest(), buf, len); +} + +/* + * Tells a peer to store some data + * + * sha1 - sha1 value for the data + * data - the data + */ +void Rpc::store(const Sha1& sha1) +{ + LDEBUG << "To: " << peer->get_sdest() << " [" << peer->get_b64kaddr() + << "] Msg: STORE\n"; +} diff --git a/apps/enclave/src/rpc.hpp b/apps/enclave/src/rpc.hpp new file mode 100644 index 000000000..6ed019a9b --- /dev/null +++ b/apps/enclave/src/rpc.hpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2004, Matthew P. Cashdollar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the author nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef RPC_HPP +#define RPC_HPP + +class Rpc { + public: + // The PROTOCOL version we are using + static uint16_t VERSION; + // The oldest version we will talk to + static uint16_t OLDEST_GOOD_VERSION; + // RPC identifiers (0-255) + typedef enum { + PING = 0, + PONG = 1, + FIND_PEERS = 2, + FOUND_PEERS = 3, + STORE = 4 + } rpc_t; + + Rpc(Peer* peer) + : peer(peer) {}; + void find_peers(const Sha1& sha1); + void parse(const void* data, size_t size); + void ping(void); + void store(const Sha1& sha1); + + private: + void found_peers(const Sha1& sha1); + void pong(uint32_t ptime); + + Peer* peer; + basic_string data; +}; + +#endif // RPC_HPP diff --git a/apps/enclave/src/sam.cpp b/apps/enclave/src/sam.cpp new file mode 100644 index 000000000..25bc99de5 --- /dev/null +++ b/apps/enclave/src/sam.cpp @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2004, Matthew P. Cashdollar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the author nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "platform.hpp" +#include "rpc.hpp" +#include "sam.hpp" + +extern "C" { + /* + * Assorted callbacks required by LibSAM - ugly, but it works + */ + static void dgramback(sam_pubkey_t dest, void* data, size_t size); + static void diedback(void); + static void logback(char* str); + static void namingback(char* name, sam_pubkey_t pubkey, samerr_t result); +} + +/* + * Prevents more than one Sam object from existing in the program at a time + * (LibSAM limitation) + */ +bool Sam::exists = false; + +Sam::Sam(const char* samhost, uint16_t samport, const char* destname, + uint_t tunneldepth) +{ + // Only allow one Sam object to exist at a time + assert(!exists); + exists = true; + + // hook up callbacks + sam_dgramback = &dgramback; + sam_diedback = &diedback; + sam_logback = &logback; + sam_namingback = &namingback; + + // we haven't connected to SAM yet + set_connected(false); + + // now try to connect to SAM + connect(samhost, samport, destname, tunneldepth); +} + +Sam::~Sam(void) +{ + delete peers; // this must be before set_connected(false)! + if (get_connected()) { + sam_close(); + set_connected(false); + } + exists = false; +} + +/* + * Connects to the SAM host + * + * samhost - host that SAM is running on (hostname or IP address) + * samport - port number that SAM is running own + * destname - the destination name of this program + * tunneldepth - how long the tunnels should be + */ +void Sam::connect(const char* samhost, uint16_t samport, const char* destname, + uint_t tunneldepth) +{ + assert(!get_connected()); + samerr_t rc = sam_connect(samhost, samport, destname, SAM_DGRAM, tunneldepth); + if (rc == SAM_OK) + set_connected(true); + else + throw Sam_error(rc); +} + +/* + * Loads peer references from disk + * Note: this can only be called after my_dest has been set + */ +void Sam::load_peers(void) +{ + peers = new Peers(PEERS_REF_FILE); +} + +/* + * Converts `name' to a base 64 destination + * + * name - name to lookup + */ +void Sam::naming_lookup(const string& name) const +{ + assert(get_connected()); + sam_naming_lookup(name.c_str()); +} + +/* + * Parses an incoming datagram + * + * dest - source destination address + * data - datagram payload + * size - size of `data' + */ +void Sam::parse_dgram(const string& dest, void* data, size_t size) +{ + assert(get_connected()); + Peer* peer = peers->new_peer(dest); + Rpc rpc(peer); + rpc.parse(data, size); + rpc.ping(); + free(data); +} + +/* + * Checks the SAM connection for incoming commands and invokes callbacks + */ +void Sam::read_buffer(void) +{ + assert(get_connected()); + sam_read_buffer(); +} + +/* + * Sends a datagram to a destination + * + * dest - destination to send to + * data - data to send + * size - size of `data' + */ +void Sam::send_dgram(const string& dest, uchar_t *data, size_t size) +{ + samerr_t rc = sam_dgram_send(dest.c_str(), data, size); + assert(rc == SAM_OK); // i.e. not SAM_TOO_BIG +} + +/* + * Sets the connection status + * + * connected - true for connected, false for disconnected + */ +void Sam::set_connected(bool connected) +{ + if (!connected) + my_dest = ""; + this->connected = connected; +} + +/* + * Sets my destination address + * + * pubkey - the base 64 destination + */ +void Sam::set_my_dest(const sam_pubkey_t pubkey) +{ + my_dest = pubkey; + my_sha1 = Sha1(my_dest); +} + +/* + * Checks whether the destination specified is of a valid base 64 syntax + * + * Returns: true if it is valid, false if it isn't + */ +bool Sam::valid_dest(const string& dest) +{ + if (dest.size() != 516) + return false; + if (dest.substr(512, 4) == "AAAA") // note this AAAA signifies a null + return true; // certificate - may not be true in the + else // future + return false; +} + +/* + * * * * Callbacks * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Unfortunately these aren't part of the "Sam" object because they are function + * pointers to _C_ functions. As a hack, we just have them call the global Sam + * object. + */ + +/* + * Callback: A datagram was received + */ +static void dgramback(sam_pubkey_t dest, void* data, size_t size) +{ + sam->parse_dgram(dest, data, size); +} + +/* + * Callback: The connection to SAM has failed + */ +static void diedback(void) +{ + LERROR << "Connection to SAM lost!\n"; + sam->set_connected(false); + throw Sam_error(SAM_SOCKET_ERROR); +} + +/* + * Callback: A log message has been sent from LibSAM + */ +static void logback(char* str) +{ + LINFO << "LibSAM: " << str << '\n'; +} + +/* + * Callback: A naming lookup has completed + */ +static void namingback(char* name, sam_pubkey_t pubkey, samerr_t result) +{ + Sam_error res(result); + if (res.code() == SAM_OK) { + if (strcmp(name, "ME") == 0) { + sam->set_my_dest(pubkey); + sam->load_peers(); + } else { + assert(false); + } + } else { + LERROR << "Naming look failed for '" << name << "': " << res.what() + << '\n'; + } +} diff --git a/apps/enclave/src/sam.hpp b/apps/enclave/src/sam.hpp new file mode 100644 index 000000000..57eb8d6fa --- /dev/null +++ b/apps/enclave/src/sam.hpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2004, Matthew P. Cashdollar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the author nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SAM_HPP +#define SAM_HPP + +class Sam { + public: + Sam(const char* samhost, uint16_t samport, const char* destname, + uint_t tunneldepth); + ~Sam(void); + const string& get_my_dest(void) const { return my_dest; } + const Sha1& get_my_sha1(void) const { return my_sha1; } + void naming_lookup(const string& name = "ME") const; + void read_buffer(void); + void send_dgram(const string& dest, uchar_t *data, size_t size); + bool valid_dest(const string& dest); + + Peers* peers; + + //callback-private: + void load_peers(void); + void parse_dgram(const string& dest, void* data, size_t size); + void set_connected(bool connected); + void set_my_dest(const sam_pubkey_t pubkey); + + private: + void connect(const char* samhost, uint16_t samport, + const char* destname, uint_t tunneldepth); + bool get_connected(void) const { return connected; } + + bool connected; + static bool exists; + string my_dest; + Sha1 my_sha1; +}; + +#endif // SAM_HPP diff --git a/apps/enclave/src/sam_error.hpp b/apps/enclave/src/sam_error.hpp new file mode 100644 index 000000000..a37bfea40 --- /dev/null +++ b/apps/enclave/src/sam_error.hpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2004, Matthew P. Cashdollar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the author nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SAM_ERROR_HPP +#define SAM_ERROR_HPP + +class Sam_error { + public: + Sam_error(samerr_t error) + : errcode(error) {} + samerr_t code(void) const { return errcode; } + const char* what(void) const { return sam_strerror(errcode); } + + private: + const samerr_t errcode; +}; + +#endif // SAM_ERROR_HPP \ No newline at end of file diff --git a/apps/enclave/src/sha1.cpp b/apps/enclave/src/sha1.cpp new file mode 100644 index 000000000..48bbd8c93 --- /dev/null +++ b/apps/enclave/src/sha1.cpp @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2004, Matthew P. Cashdollar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the author nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "platform.hpp" +#include "sha1.hpp" + +Sha1::Sha1(void) +{ + b64hashed = "No value!"; + memset(binhashed, 0, sizeof binhashed); +} + +Sha1::Sha1(const string& data) +{ + /* Hash it */ + hash_state md; + sha1_init(&md); + int rc = sha1_process(&md, reinterpret_cast(data.c_str()), + data.size()); + assert(rc == CRYPT_OK); + rc = sha1_done(&md, binhashed); + assert(rc == CRYPT_OK); + b64(); +} + +/* + * Initialises the Sha1 object from a binary hash + */ +Sha1::Sha1(const uchar_t binary[SHA1BIN_LEN]) +{ + memcpy(binhashed, binary, sizeof binhashed); + b64(); +} + +/* + * Base 64 the binary hash + */ +void Sha1::b64(void) +{ + ulong_t outlen = 29; + char tmp[outlen]; + // b64 FIXME: replace + with ~, and / with - to be like freenet + int rc = base64_encode(binhashed, sizeof binhashed, reinterpret_cast(tmp), &outlen); + assert(rc == CRYPT_OK); + b64hashed = tmp; +} + +/* + * Compares two Sha1s, returning true if the this one is less than the right one + */ +bool Sha1::operator<(const Sha1& rhs) const +{ + Bigint lhsnum(binhashed, SHA1BIN_LEN); + Bigint rhsnum(rhs.binhash(), SHA1BIN_LEN); + if (lhsnum < rhsnum) + return true; + else + return false; +} + +/* + * Assigns a value from another Sha1 to this one + */ +Sha1& Sha1::operator=(const Sha1& rhs) +{ + if (this != &rhs) { // check for self-assignment: a = a + b64hashed = rhs.b64hash(); + memcpy(binhashed, rhs.binhash(), sizeof binhashed); + } + return *this; +} + +/* + * Compares Sha1s for equality + */ +bool Sha1::operator==(const Sha1& rhs) const +{ + if (memcmp(binhashed, rhs.binhash(), sizeof binhashed) == 0) + return true; + else + return false; +} + +/* + * Xors this Sha1 with another, and stores the result in a Bigint + * + * rhs - sha1 to xor this one with + * result - will be filled with the result + */ +void Sha1::xor(const Sha1& rhs, Bigint& result) const +{ + Bigint lhsnum(binhashed, SHA1BIN_LEN); + Bigint rhsnum(rhs.binhash(), SHA1BIN_LEN); + lhsnum.xor(rhsnum, result); +} diff --git a/apps/enclave/src/sha1.hpp b/apps/enclave/src/sha1.hpp new file mode 100644 index 000000000..abef143b6 --- /dev/null +++ b/apps/enclave/src/sha1.hpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2004, Matthew P. Cashdollar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the author nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SHA1_HPP +#define SHA1_HPP + +class Sha1 { + public: + static const size_t SHA1BIN_LEN = 20; + + Sha1(void); + Sha1(const string& data); + Sha1(const uchar_t binary[SHA1BIN_LEN]); + const string& b64hash(void) const { return b64hashed; } + const uchar_t* binhash(void) const { return binhashed; } + bool operator<(const Sha1& rhs) const; + Sha1& operator=(const Sha1& rhs); + bool operator==(const Sha1& rhs) const; + void xor(const Sha1& rhs, Bigint& result) const; + + private: + void b64(void); + + string b64hashed; // base 64 of the hash + uchar_t binhashed[SHA1BIN_LEN]; // non-NUL terminated binary hash +}; + +#endif // SHA1_HPP \ No newline at end of file