-
Notifications
You must be signed in to change notification settings - Fork 114
Kovri: new base32/64 impl / radix interface / unit-test #788
Conversation
Live tests and all new test-cases pass (only tested on Linux, awaiting buildbot). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, except for a couple minor things, the changes lgtm.
The new interface and code are really clean, and the exception handling is very nice.
std::string Base32::Encode(const std::uint8_t* in, const std::uint64_t len) | ||
{ | ||
// Prepare encoder | ||
CryptoPP::AlgorithmParameters static const params(CryptoPP::MakeParameters( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would you be open to adding a documentation line pointing to the CryptoPP Manual page for AlgorithmParameters (https://www.cryptopp.com/docs/ref/class_algorithm_parameters.html)?
Behavior for MakeParameters and AlgorithmParameters was hard to understand from reading the code, until I read the manual page, and it became very obvious.
Mainly the confusing bit was where AlgorithmParameters overrides the ()
operator to append a key-value pair, and return an AlgorithmParameters ref (allowing one to append an arbitrary number of key-value pairs).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would you be open to adding a documentation line pointing to the CryptoPP Manual page for AlgorithmParameters
This isn't necessary because this type of c++ / crypto++ question is outside the scope of kovri. Adding links to code is generally a bad idea too (links become outdated) and doing so would create a precedent for endless links. Crypto++'s manual merely produces doxygen output so you can read the same docs within the code (see deps/cryptopp
) or visit their website (as you did).
} | ||
|
||
//TODO(anonimal): let's try to avoid a memcpy | ||
std::memcpy(address.key, key.data(), sizeof(address.key)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not easily searchable for a secure alternative. from cppreference:
- If either dest or src is a null pointer, the behavior is undefined, even if count is zero.
- If the objects are not TriviallyCopyable, the behavior of memcpy is not specified and may be undefined
For the first case, checking that buffers are non-null seems like an easy fix.
Maybe for the TriviallyCopyable
case, could use:
try {
bool address_key_trivially_copyable = is_trivially_copyable<address.key>::value;
bool key_trivially_copyable ...
if !address_key_trivially_copyable || !key_trivially_copyable
throw
}
catch (...)
Know this doesn't fully address the "secure memcpy" problem, but would it help make the current situation more secure?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This TODO was a note for me to implement address.key
as a container and/or implement an overloaded operator for Tag
and/or rewrite/throw-out Tag
. See also #366 and #784 (note: a public address key in this context should not need #784).
The resolution of any of those aforementioned points should also resolve your concerns Edit: but is outside the scope of this PR.
FreeBSD's unit-test fails in test-case |
Here's a backtrace (note: the issue is reproducible with clang++39):
At least two immediate working solutions:
diff --git a/deps/cryptopp b/deps/cryptopp
--- a/deps/cryptopp
+++ b/deps/cryptopp
@@ -1 +1 @@
-Subproject commit f1a80e6a58e6cf72c969dda6825b9781eb300927
+Subproject commit f1a80e6a58e6cf72c969dda6825b9781eb300927-dirty
diff --git a/src/core/crypto/impl/cryptopp/radix.cc b/src/core/crypto/impl/cryptopp/radix.cc
index 4a37cdd..eac9f97 100644
--- a/src/core/crypto/impl/cryptopp/radix.cc
+++ b/src/core/crypto/impl/cryptopp/radix.cc
@@ -69,7 +69,11 @@ std::vector<std::uint8_t> Base32::Decode(
CryptoPP::AlgorithmParameters const params(CryptoPP::MakeParameters(
CryptoPP::Name::DecodingLookupArray(),
+#if defined(__FreeBSD__) // See #788
+ reinterpret_cast<const int*>(lookup), false));
+#else
reinterpret_cast<const int*>(lookup)));
+#endif
// Decode
return Radix::Decode<CryptoPP::Base32Decoder>(params, in, len);
diff --git a/src/core/router/identity.h b/src/core/router/identity.h
index e16f8975..c3716080 100644
--- a/src/core/router/identity.h
+++ b/src/core/router/identity.h
@@ -118,6 +118,9 @@ class Tag {
void FromBase32(const std::string& encoded)
{
+ if (encoded.empty())
+ throw std::length_error("Tag: null encoded length for b32");
+
std::vector<std::uint8_t> const decoded =
core::Base32::Decode(encoded.c_str(), encoded.length());
and then point 2 should be applied elsewhere. I'm personally vying for point 1. After reviewing cryptopp's smartptr and algparam, I don't see what patches could be applied (at least ones that wouldn't be unnecessary or intrusive). Maybe freebsd clang needs to work out another bug? Pinging @noloader. |
All tests now pass with the pre-processor patch applied. I'd like to wait for a resolution to weidai11/cryptopp#562 until merging. |
I'm crafting some self test for Crypto++ to test swapping an alphabet. Regarding this change, I think you may have been on the right track:
In fact, the library makes its parameters using
So the quickest way to side step the issue and get on with your real work is probably:
We added new self tests to the library. The are active when Unfortunately, they don't duplicate the problems. |
@noloader Ah, I see now. Thank you for clarifying! Though I see that |
Forgive my ignorance... In this:
What is If it is a |
Yes, |
On an unrelated note, I've added and rebased a few small changes:
On a related note, this PR should be safe to merge while @noloader and I continue debugging weidai11/cryptopp#562. |
- Removes i2pd's base32/64 impl, introduces new impl using crypto++ - Includes related rewrites, refactors, new documentation, and dead code removal Referencing monero-project#788
0750b84 Kovri: new base32/64 impl / radix interface / unit-test (anonimal)
This may have something to do with monero-project/kovri#788
ac06218 Fix compile error due to T = int [256] ...again. static_cast the array, switch back to 'static const' AlgorithmParameters. (Jeffrey Walton) 75f8ca1 Fix compile error due to T = int [256] (Jeffrey Walton) 32cfb4b Unroll DecodingLookupArray for Base32 and Base64 decoders This is a time/space tradeoff, but it also provides 1-time intialization while avoiding a race. It should also clear weidai11/cryptopp#562 and #788 once and for all (famous last words) (Jeffrey Walton)
Resolves #786. Works into #785.
By submitting this pull-request, I confirm the following: