diff --git a/src/Cryptography/AES.h b/src/Cryptography/AES.h index c245e9d..2a00d06 100644 --- a/src/Cryptography/AES.h +++ b/src/Cryptography/AES.h @@ -11,7 +11,7 @@ namespace RNS { namespace Cryptography { class AES_128_CBC { public: - static inline Bytes encrypt(const Bytes &plaintext, const Bytes &key, const Bytes &iv) { + static inline const Bytes encrypt(const Bytes &plaintext, const Bytes &key, const Bytes &iv) { CBC cbc; cbc.setKey(key.data(), key.size()); cbc.setIV(iv.data(), iv.size()); @@ -20,7 +20,7 @@ namespace RNS { namespace Cryptography { return ciphertext; } - static inline Bytes decrypt(const Bytes &ciphertext, const Bytes &key, const Bytes &iv) { + static inline const Bytes decrypt(const Bytes &ciphertext, const Bytes &key, const Bytes &iv) { CBC cbc; cbc.setKey(key.data(), key.size()); cbc.setIV(iv.data(), iv.size()); diff --git a/src/Cryptography/Ed25519.h b/src/Cryptography/Ed25519.h index 0c46665..aca68f2 100644 --- a/src/Cryptography/Ed25519.h +++ b/src/Cryptography/Ed25519.h @@ -30,7 +30,7 @@ namespace RNS { namespace Cryptography { return Ptr(new Ed25519PublicKey(publicKey)); } - inline Bytes public_bytes() { + inline const Bytes &public_bytes() { return _publicKey; } @@ -75,7 +75,7 @@ namespace RNS { namespace Cryptography { return Ptr(new Ed25519PrivateKey(privateKey)); } - inline Bytes private_bytes() { + inline const Bytes &private_bytes() { return _privateKey; } @@ -84,7 +84,7 @@ namespace RNS { namespace Cryptography { return Ed25519PublicKey::from_public_bytes(_publicKey); } - inline Bytes sign(const Bytes &message) { + inline const Bytes sign(const Bytes &message) { //zreturn _sk.sign(message); Bytes signature; Ed25519::sign(signature.writable(64), _privateKey.data(), _publicKey.data(), message.data(), message.size()); diff --git a/src/Cryptography/Fernet.cpp b/src/Cryptography/Fernet.cpp index 13e755c..306d381 100644 --- a/src/Cryptography/Fernet.cpp +++ b/src/Cryptography/Fernet.cpp @@ -49,7 +49,7 @@ bool Fernet::verify_hmac(const Bytes &token) { return (received_hmac == expected_hmac); } -Bytes Fernet::encrypt(const Bytes &data) { +const Bytes Fernet::encrypt(const Bytes &data) { debug("Fernet::encrypt: plaintext length: " + std::to_string(data.size())); Bytes iv = random(16); @@ -76,7 +76,7 @@ Bytes Fernet::encrypt(const Bytes &data) { } -Bytes Fernet::decrypt(const Bytes &token) { +const Bytes Fernet::decrypt(const Bytes &token) { debug("Fernet::decrypt: token length: " + std::to_string(token.size())); if (token.size() < 48) { diff --git a/src/Cryptography/Fernet.h b/src/Cryptography/Fernet.h index a8a8a1d..5869c25 100644 --- a/src/Cryptography/Fernet.h +++ b/src/Cryptography/Fernet.h @@ -22,7 +22,7 @@ namespace RNS { namespace Cryptography { static const uint8_t FERNET_OVERHEAD = 48; // Bytes public: - static inline Bytes generate_key() { return random(32); } + static inline const Bytes generate_key() { return random(32); } public: Fernet(const Bytes &key); @@ -30,8 +30,8 @@ namespace RNS { namespace Cryptography { public: bool verify_hmac(const Bytes &token); - Bytes encrypt(const Bytes &data); - Bytes decrypt(const Bytes &token); + const Bytes encrypt(const Bytes &data); + const Bytes decrypt(const Bytes &token); private: Bytes _signing_key; diff --git a/src/Cryptography/HKDF.cpp b/src/Cryptography/HKDF.cpp index f614131..2299749 100644 --- a/src/Cryptography/HKDF.cpp +++ b/src/Cryptography/HKDF.cpp @@ -5,7 +5,7 @@ using namespace RNS; -Bytes RNS::Cryptography::hkdf(size_t length, const Bytes &derive_from, const Bytes &salt /*= {Bytes::NONE}*/, const Bytes &context /*= {Bytes::NONE}*/) { +const Bytes RNS::Cryptography::hkdf(size_t length, const Bytes &derive_from, const Bytes &salt /*= {Bytes::NONE}*/, const Bytes &context /*= {Bytes::NONE}*/) { if (length <= 0) { throw std::invalid_argument("Invalid output key length"); diff --git a/src/Cryptography/HKDF.h b/src/Cryptography/HKDF.h index f3f9039..e8a7ca5 100644 --- a/src/Cryptography/HKDF.h +++ b/src/Cryptography/HKDF.h @@ -4,6 +4,6 @@ namespace RNS { namespace Cryptography { - Bytes hkdf(size_t length, const Bytes &derive_from, const Bytes &salt = {Bytes::NONE}, const Bytes &context = {Bytes::NONE}); + const Bytes hkdf(size_t length, const Bytes &derive_from, const Bytes &salt = {Bytes::NONE}, const Bytes &context = {Bytes::NONE}); } } diff --git a/src/Cryptography/HMAC.h b/src/Cryptography/HMAC.h index 980fc11..cc09811 100644 --- a/src/Cryptography/HMAC.h +++ b/src/Cryptography/HMAC.h @@ -99,7 +99,7 @@ namespace RNS { namespace Cryptography { msg: bytes or buffer, Input message. digest: The underlying hash algorithm to use. */ - inline Bytes digest(const Bytes &key, const Bytes &msg, HMAC::Digest digest = HMAC::DIGEST_SHA256) { + inline const Bytes digest(const Bytes &key, const Bytes &msg, HMAC::Digest digest = HMAC::DIGEST_SHA256) { HMAC hmac(key, msg, digest); hmac.update(msg); return hmac.digest(); diff --git a/src/Cryptography/Hashes.cpp b/src/Cryptography/Hashes.cpp index e656fb6..7f9521e 100644 --- a/src/Cryptography/Hashes.cpp +++ b/src/Cryptography/Hashes.cpp @@ -14,7 +14,7 @@ uses Python's internal SHA-256 implementation. All SHA-256 calls in RNS end up here. */ -Bytes RNS::Cryptography::sha256(const Bytes &data) { +const Bytes RNS::Cryptography::sha256(const Bytes &data) { //extreme("Cryptography::sha256: data: " + data.toHex() ); SHA256 digest; digest.reset(); @@ -25,7 +25,7 @@ Bytes RNS::Cryptography::sha256(const Bytes &data) { return hash; } -Bytes RNS::Cryptography::sha512(const Bytes &data) { +const Bytes RNS::Cryptography::sha512(const Bytes &data) { SHA512 digest; digest.reset(); digest.update(data.data(), data.size()); diff --git a/src/Cryptography/Hashes.h b/src/Cryptography/Hashes.h index 8c0b913..e12d1c6 100644 --- a/src/Cryptography/Hashes.h +++ b/src/Cryptography/Hashes.h @@ -6,7 +6,7 @@ namespace RNS { namespace Cryptography { - Bytes sha256(const Bytes &data); - Bytes sha512(const Bytes &data); + const Bytes sha256(const Bytes &data); + const Bytes sha512(const Bytes &data); } } diff --git a/src/Cryptography/PKCS7.h b/src/Cryptography/PKCS7.h index c508406..aad906d 100644 --- a/src/Cryptography/PKCS7.h +++ b/src/Cryptography/PKCS7.h @@ -13,13 +13,13 @@ namespace RNS { namespace Cryptography { static const size_t BLOCKSIZE = 16; - static inline Bytes pad(const Bytes &data, size_t bs = BLOCKSIZE) { + static inline const Bytes pad(const Bytes &data, size_t bs = BLOCKSIZE) { Bytes padded(data); inplace_pad(padded, bs); return padded; } - static inline Bytes unpad(const Bytes &data, size_t bs = BLOCKSIZE) { + static inline const Bytes unpad(const Bytes &data, size_t bs = BLOCKSIZE) { Bytes unpadded(data); inplace_unpad(unpadded, bs); return unpadded; diff --git a/src/Cryptography/Random.h b/src/Cryptography/Random.h index 3a4b955..5454fc7 100644 --- a/src/Cryptography/Random.h +++ b/src/Cryptography/Random.h @@ -8,7 +8,7 @@ namespace RNS { namespace Cryptography { // return vector specified length of random bytes - inline Bytes random(size_t length) { + inline const Bytes random(size_t length) { Bytes rand; RNG.rand(rand.writable(length), length); return rand; diff --git a/src/Cryptography/X25519.h b/src/Cryptography/X25519.h index bf1832d..27cb745 100644 --- a/src/Cryptography/X25519.h +++ b/src/Cryptography/X25519.h @@ -111,11 +111,11 @@ namespace RNS { namespace Cryptography { } /* - inline Bytes private_bytes() { + inline const Bytes private_bytes() { return _pack_number(_a); } */ - inline Bytes private_bytes() { + inline const Bytes &private_bytes() { return _privateKey; } @@ -130,7 +130,7 @@ namespace RNS { namespace Cryptography { } /* - inline Bytes exchange(const Bytes &peer_public_key) { + inline const Bytes exchange(const Bytes &peer_public_key) { if isinstance(peer_public_key, bytes): peer_public_key = X25519PublicKey.from_public_bytes(peer_public_key) @@ -168,7 +168,7 @@ namespace RNS { namespace Cryptography { return shared } */ - inline Bytes exchange(const Bytes &peer_public_key) { + inline const Bytes exchange(const Bytes &peer_public_key) { debug("X25519PublicKey::exchange: public key: " + _publicKey.toHex()); debug("X25519PublicKey::exchange: peer public key: " + peer_public_key.toHex()); debug("X25519PublicKey::exchange: pre private key: " + _privateKey.toHex()); diff --git a/src/Destination.cpp b/src/Destination.cpp index f755e28..25ba5df 100644 --- a/src/Destination.cpp +++ b/src/Destination.cpp @@ -314,7 +314,7 @@ Encrypts information for ``RNS.Destination.SINGLE`` or ``RNS.Destination.GROUP`` :param plaintext: A *bytes-like* containing the plaintext to be encrypted. :raises: ``ValueError`` if destination does not hold a necessary key for encryption. */ -Bytes Destination::encrypt(const Bytes &data) { +const Bytes Destination::encrypt(const Bytes &data) { assert(_object); debug("Destination::encrypt: encrypting data..."); @@ -348,7 +348,7 @@ Decrypts information for ``RNS.Destination.SINGLE`` or ``RNS.Destination.GROUP`` :param ciphertext: *Bytes* containing the ciphertext to be decrypted. :raises: ``ValueError`` if destination does not hold a necessary key for decryption. */ -Bytes Destination::decrypt(const Bytes &data) { +const Bytes Destination::decrypt(const Bytes &data) { assert(_object); debug("Destination::decrypt: decrypting data..."); @@ -382,7 +382,7 @@ Signs information for ``RNS.Destination.SINGLE`` type destination. :param message: *Bytes* containing the message to be signed. :returns: A *bytes-like* containing the message signature, or *None* if the destination could not sign the message. */ -Bytes Destination::sign(const Bytes &message) { +const Bytes Destination::sign(const Bytes &message) { assert(_object); if (_object->_type == SINGLE && _object->_identity) { return _object->_identity.sign(message); diff --git a/src/Destination.h b/src/Destination.h index 12635bc..5aee89f 100644 --- a/src/Destination.h +++ b/src/Destination.h @@ -144,16 +144,16 @@ namespace RNS { void receive(const Packet &packet); void incoming_link_request(const Bytes &data, const Packet &packet); - Bytes encrypt(const Bytes &data); - Bytes decrypt(const Bytes &data); - Bytes sign(const Bytes &message); + const Bytes encrypt(const Bytes &data); + const Bytes decrypt(const Bytes &data); + const Bytes sign(const Bytes &message); // getters/setters inline Type::Destination::types type() const { assert(_object); return _object->_type; } inline Type::Destination::directions direction() const { assert(_object); return _object->_direction; } inline Type::Destination::proof_strategies proof_strategy() const { assert(_object); return _object->_proof_strategy; } - inline Bytes hash() const { assert(_object); return _object->_hash; } - inline Bytes link_id() const { assert(_object); return _object->_link_id; } + inline const Bytes &hash() const { assert(_object); return _object->_hash; } + inline const Bytes &link_id() const { assert(_object); return _object->_link_id; } inline uint16_t mtu() const { assert(_object); return _object->_mtu; } inline void mtu(uint16_t mtu) { assert(_object); _object->_mtu = mtu; } inline Type::Link::status status() const { assert(_object); return _object->_status; } diff --git a/src/Identity.cpp b/src/Identity.cpp index c80ba3e..6414bd2 100644 --- a/src/Identity.cpp +++ b/src/Identity.cpp @@ -132,7 +132,7 @@ Encrypts information for the identity. :returns: Ciphertext token as *bytes*. :raises: *KeyError* if the instance does not hold a public key. */ -Bytes Identity::encrypt(const Bytes &plaintext) { +const Bytes Identity::encrypt(const Bytes &plaintext) { assert(_object); debug("Identity::encrypt: encrypting data..."); if (!_object->_pub) { @@ -172,7 +172,7 @@ Decrypts information for the identity. :returns: Plaintext as *bytes*, or *None* if decryption fails. :raises: *KeyError* if the instance does not hold a private key. */ -Bytes Identity::decrypt(const Bytes &ciphertext_token) { +const Bytes Identity::decrypt(const Bytes &ciphertext_token) { assert(_object); debug("Identity::decrypt: decrypting data..."); if (!_object->_prv) { @@ -226,7 +226,7 @@ Signs information by the identity. :returns: Signature as *bytes*. :raises: *KeyError* if the instance does not hold a private key. */ -Bytes Identity::sign(const Bytes &message) { +const Bytes Identity::sign(const Bytes &message) { assert(_object); if (!_object->_sig_prv) { throw std::runtime_error("Signing failed because identity does not hold a private key"); diff --git a/src/Identity.h b/src/Identity.h index 87c7bd4..d7867ca 100644 --- a/src/Identity.h +++ b/src/Identity.h @@ -48,7 +48,7 @@ namespace RNS { /* :returns: The public key as *bytes* */ - inline Bytes get_public_key() { + inline const Bytes get_public_key() { assert(_object); return _object->_pub_bytes + _object->_sig_pub_bytes; } @@ -65,7 +65,7 @@ namespace RNS { :param data: Data to be hashed as *bytes*. :returns: SHA-256 hash as *bytes* */ - static inline Bytes full_hash(const Bytes &data) { + static inline const Bytes full_hash(const Bytes &data) { return Cryptography::sha256(data); } /* @@ -74,7 +74,7 @@ namespace RNS { :param data: Data to be hashed as *bytes*. :returns: Truncated SHA-256 hash as *bytes* */ - static inline Bytes truncated_hash(const Bytes &data) { + static inline const Bytes truncated_hash(const Bytes &data) { //return Identity.full_hash(data)[:(Identity.TRUNCATED_HASHLENGTH//8)] return full_hash(data).left(Type::Identity::TRUNCATED_HASHLENGTH/8); } @@ -84,18 +84,18 @@ namespace RNS { :param data: Data to be hashed as *bytes*. :returns: Truncated SHA-256 hash of random data as *bytes* */ - static inline Bytes get_random_hash() { + static inline const Bytes get_random_hash() { return truncated_hash(Cryptography::random(Type::Identity::TRUNCATED_HASHLENGTH/8)); } static bool validate_announce(const Packet &packet); - inline Bytes get_salt() { assert(_object); return _object->_hash; } - inline Bytes get_context() { return {Bytes::NONE}; } + inline const Bytes get_salt() { assert(_object); return _object->_hash; } + inline const Bytes get_context() { return {Bytes::NONE}; } - Bytes encrypt(const Bytes &plaintext); - Bytes decrypt(const Bytes &ciphertext_token); - Bytes sign(const Bytes &message); + const Bytes encrypt(const Bytes &plaintext); + const Bytes decrypt(const Bytes &ciphertext_token); + const Bytes sign(const Bytes &message); bool validate(const Bytes &signature, const Bytes &message); // CBA following default for reference value requires inclusiion of header //void prove(const Packet &packet, const Destination &destination = {Type::NONE}); @@ -103,11 +103,11 @@ namespace RNS { void prove(const Packet &packet); // getters/setters - inline Bytes encryptionPrivateKey() const { assert(_object); return _object->_prv_bytes; } - inline Bytes signingPrivateKey() const { assert(_object); return _object->_sig_prv_bytes; } - inline Bytes encryptionPublicKey() const { assert(_object); return _object->_prv_bytes; } - inline Bytes signingPublicKey() const { assert(_object); return _object->_sig_prv_bytes; } - inline Bytes hash() const { assert(_object); return _object->_hash; } + inline const Bytes &encryptionPrivateKey() const { assert(_object); return _object->_prv_bytes; } + inline const Bytes &signingPrivateKey() const { assert(_object); return _object->_sig_prv_bytes; } + inline const Bytes &encryptionPublicKey() const { assert(_object); return _object->_prv_bytes; } + inline const Bytes &signingPublicKey() const { assert(_object); return _object->_sig_prv_bytes; } + inline const Bytes &hash() const { assert(_object); return _object->_hash; } inline std::string hexhash() const { assert(_object); return _object->_hexhash; } inline std::string toString() const { assert(_object); return "{Identity:" + _object->_hash.toHex() + "}"; } diff --git a/src/Interface.cpp b/src/Interface.cpp index f1e85b7..a0f34b5 100644 --- a/src/Interface.cpp +++ b/src/Interface.cpp @@ -1,5 +1,6 @@ #include "Interface.h" +#include "Identity.h" #include "Transport.h" using namespace RNS; @@ -20,6 +21,10 @@ using namespace RNS::Type::Interface; _object->_txb += data.size(); } +const Bytes Interface::get_hash() const { + return Identity::full_hash({toString()}); +} + void Interface::process_announce_queue() { /* if not hasattr(self, "announce_cap"): diff --git a/src/Interface.h b/src/Interface.h index 4355a0f..621f858 100644 --- a/src/Interface.h +++ b/src/Interface.h @@ -65,7 +65,7 @@ namespace RNS { } public: - inline Bytes get_hash() const { /*return Identity::full_hash();*/ return {}; } + const Bytes get_hash() const; void process_announce_queue(); inline void detach() {} @@ -87,13 +87,13 @@ namespace RNS { inline bool FWD() const { assert(_object); return _object->_FWD; } inline bool RPT() const { assert(_object); return _object->_RPT; } inline std::string name() const { assert(_object); return _object->_name; } - inline Bytes ifac_identity() const { assert(_object); return _object->_ifac_identity; } + inline const Bytes &ifac_identity() const { assert(_object); return _object->_ifac_identity; } inline Type::Interface::modes mode() const { assert(_object); return _object->_mode; } inline uint32_t bitrate() const { assert(_object); return _object->_bitrate; } inline uint64_t announce_allowed_at() const { assert(_object); return _object->_announce_allowed_at; } inline void announce_allowed_at(uint64_t announce_allowed_at) { assert(_object); _object->_announce_allowed_at = announce_allowed_at; } inline float announce_cap() const { assert(_object); return _object->_announce_cap; } - inline std::list announce_queue() const { assert(_object); return _object->_announce_queue; } + inline std::list &announce_queue() const { assert(_object); return _object->_announce_queue; } virtual inline std::string toString() const { assert(_object); return "Interface[" + _object->_name + "]"; } diff --git a/src/Packet.cpp b/src/Packet.cpp index 9f2d1b8..8b9aeb7 100644 --- a/src/Packet.cpp +++ b/src/Packet.cpp @@ -15,10 +15,10 @@ Packet::Packet(const Destination &destination, const Interface &attached_interfa if (_object->_destination) { extreme("Creating packet with destination..."); - // CBA TODO handle NONE - if (transport_type == -1) { - transport_type = Type::Transport::BROADCAST; - } + // CBA Should never see empty transport_type + //if (transport_type == NONE) { + // transport_type = Type::Transport::BROADCAST; + //} // following moved to object constructor to avoid extra NONE object //_destination = destination; _object->_header_type = header_type; diff --git a/src/Packet.h b/src/Packet.h index e55b10e..ca87730 100644 --- a/src/Packet.h +++ b/src/Packet.h @@ -190,9 +190,9 @@ namespace RNS { inline uint8_t flags() const { assert(_object); return _object->_flags; } inline uint8_t hops() const { assert(_object); return _object->_hops; } inline void hops(uint8_t hops) { assert(_object); _object->_hops = hops; } - inline Bytes packet_hash() const { assert(_object); return _object->_packet_hash; } - inline Bytes destination_hash() const { assert(_object); return _object->_destination_hash; } - inline Bytes transport_id() const { assert(_object); return _object->_transport_id; } + inline const Bytes &packet_hash() const { assert(_object); return _object->_packet_hash; } + inline const Bytes &destination_hash() const { assert(_object); return _object->_destination_hash; } + inline const Bytes &transport_id() const { assert(_object); return _object->_transport_id; } inline void transport_id(const Bytes &transport_id) { assert(_object); _object->_transport_id = transport_id; } inline const Bytes &raw() const { assert(_object); return _object->_raw; } inline const Bytes &data() const { assert(_object); return _object->_data; } diff --git a/src/Test/TestBytes.cpp b/src/Test/TestBytes.cpp index 693f552..2f26108 100644 --- a/src/Test/TestBytes.cpp +++ b/src/Test/TestBytes.cpp @@ -6,6 +6,21 @@ #include #include +//void testBytesDefault(const RNS::Bytes &bytes = {RNS::Bytes::NONE}) { +void testBytesDefault(const RNS::Bytes &bytes = {}) { + assert(!bytes); + assert(bytes.size() == 0); + assert(bytes.data() == nullptr); +} + +RNS::Bytes ref("Test"); +const RNS::Bytes &testBytesReference() { + // NOTE: Can NOT return local instance as reference!!! + //RNS::Bytes ref("Test"); + RNS::extreme("returning..."); + return ref; +} + void testBytes() { RNS::Bytes bytes; @@ -50,14 +65,23 @@ void testBytes() { RNS::extreme("assign prebuf: " + prebuf.toString()); RNS::extreme("assign postbuf: " + postbuf.toString()); + // test string assignment bytes = "Foo"; assert(bytes.size() == 3); assert(memcmp(bytes.data(), "Foo", bytes.size()) == 0); + // test string addition bytes = prebuf + postbuf; assert(bytes.size() == 11); assert(memcmp(bytes.data(), "Hello World", bytes.size()) == 0); + // test string constructor + { + RNS::Bytes str("Foo"); + assert(str.size() == 3); + assert(memcmp(str.data(), "Foo", str.size()) == 0); + } + // test left in range { RNS::Bytes left(bytes.left(5)); @@ -205,6 +229,20 @@ void testBytes() { assert(bytes.data() == nullptr); } + // function default argument + RNS::head("TestBytes: function default argument", RNS::LOG_EXTREME); + testBytesDefault(); + + // function reference return + RNS::head("TestBytes: function reference return", RNS::LOG_EXTREME); + { + RNS::Bytes test = testBytesReference(); + RNS::extreme("returned"); + assert(test); + assert(test.size() == 4); + assert(memcmp(test.data(), "Test", test.size()) == 0); + } + // TODO test comparison } diff --git a/src/Transport.h b/src/Transport.h index 4c1b0bf..d7697d3 100644 --- a/src/Transport.h +++ b/src/Transport.h @@ -224,6 +224,7 @@ namespace RNS { static void exit_handler(); private: + // CBA MUST use references to interfaces here in order for virtul overrides for send/receive to work //static std::set, std::less> _interfaces; // All active interfaces static std::list> _interfaces; // All active interfaces static std::set _destinations; // All active destinations diff --git a/src/main.cpp b/src/main.cpp index 72d60ff..d8bbc71 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -144,6 +144,7 @@ void setup() { //testReference(); //testCrypto(); RNS::extreme("Finished running tests"); + //return; #endif //std::stringstream test;