dont serialize ephemeral members of service identity (#1370)

* prepare for keytool script

* dont serialize ephemeral members in service key file
* regnerate ephemeral members in service identity on load

* add keygen script

* use nacl for generating keys

* format
pull/1367/head
Jeff 4 years ago committed by GitHub
parent 15229ea7ff
commit 53598ec0e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1 @@
*.private

@ -0,0 +1,35 @@
#!/usr/bin/env python3
"""
keygen tool for lokinet
"""
from argparse import ArgumentParser as AP
from base64 import b32encode
from nacl.signing import SigningKey
def base32z(data):
""" base32 z encode """
return b32encode(data).translate(
bytes.maketrans(
b'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567',
b'ybndrfg8ejkmcpqxot1uwisza345h769')).decode().rstrip('=')
def main():
"""
main function for keygen
"""
argparser = AP()
argparser.add_argument('--keyfile', type=str, required=True, help='place to put generated keys')
args = argparser.parse_args()
secret = SigningKey.generate()
with open(args.keyfile, 'wb') as wfile:
wfile.write(b'd1:s64:')
wfile.write(secret.encode())
wfile.write(secret.verify_key.encode())
wfile.write(b'e')
print("{}.loki".format(base32z(secret.verify_key.encode())))
if __name__ == '__main__':
main()

@ -0,0 +1,14 @@
# lokinet key generator
requires:
* python3.7 or higher
* pynacl
usage:
```bash
./keygen.py --keyfile somekeyfile.private
```
this will overwrite the keyfile with new keys

@ -90,7 +90,7 @@ namespace llarp
return BEncodeSignedSection(buf);
else if (version == 1)
{
//TODO: heapless serialization for this in lokimq's bt serialization.
// TODO: heapless serialization for this in lokimq's bt serialization.
if (not buf->writef("li1e%lu:", signature.size()))
return false;
if (not buf->write(signature.begin(), signature.end()))
@ -224,16 +224,15 @@ namespace llarp
{
Clear();
if (*buf->cur == 'd') // old format
if (*buf->cur == 'd') // old format
{
return DecodeVersion_0(buf);
}
else if (*buf->cur != 'l') // if not dict, should be new format and start with list
else if (*buf->cur != 'l') // if not dict, should be new format and start with list
{
return false;
}
try
{
std::string_view buf_view(reinterpret_cast<char*>(buf->cur), buf->sz);
@ -267,7 +266,7 @@ namespace llarp
bool
RouterContact::DecodeVersion_0(llarp_buffer_t* buf)
{
signed_bt_dict = std::string(reinterpret_cast<char *>(buf->cur), buf->sz);
signed_bt_dict = std::string(reinterpret_cast<char*>(buf->cur), buf->sz);
return bencode_decode_dict(*this, buf);
}
@ -424,7 +423,7 @@ namespace llarp
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
signed_bt_dict = std::string(reinterpret_cast<char *>(buf.base), buf.sz);
signed_bt_dict = std::string(reinterpret_cast<char*>(buf.base), buf.sz);
if (version == 0 or version == 1)
{

@ -20,7 +20,7 @@
namespace lokimq
{
struct bt_list_consumer;
} // namespace lokimq (forward declarations)
} // namespace lokimq
namespace llarp
{
@ -222,9 +222,7 @@ namespace llarp
bool
VerifySignature() const;
private:
private:
bool
DecodeVersion_0(llarp_buffer_t* buf);

@ -13,16 +13,10 @@ namespace llarp
{
if (!bencode_start_dict(buf))
return false;
if (!BEncodeWriteDictEntry("e", enckey, buf))
return false;
if (!BEncodeWriteDictEntry("q", pq, buf))
return false;
if (!BEncodeWriteDictEntry("s", signkey, buf))
return false;
if (!BEncodeWriteDictInt("v", version, buf))
return false;
if (!BEncodeWriteDictEntry("x", vanity, buf))
return false;
return bencode_end(buf);
}
@ -30,30 +24,23 @@ namespace llarp
Identity::DecodeKey(const llarp_buffer_t& key, llarp_buffer_t* buf)
{
bool read = false;
if (!BEncodeMaybeReadDictEntry("e", enckey, read, key, buf))
return false;
if (key == "q")
{
llarp_buffer_t str;
if (!bencode_read_string(buf, &str))
return false;
if (str.sz == 3200 || str.sz == 2818)
{
pq = str.base;
return true;
}
return false;
}
if (!BEncodeMaybeReadDictEntry("s", signkey, read, key, buf))
return false;
if (!BEncodeMaybeReadDictInt("v", version, read, key, buf))
return false;
if (!BEncodeMaybeReadDictEntry("x", vanity, read, key, buf))
return false;
return read;
}
void
Identity::Clear()
{
signkey.Zero();
enckey.Zero();
pq.Zero();
derivedSignKey.Zero();
vanity.Zero();
}
void
Identity::RegenerateKeys()
{
@ -64,7 +51,7 @@ namespace llarp
crypto->pqe_keygen(pq);
if (not crypto->derive_subkey_private(derivedSignKey, signkey, 1))
{
LogError("failed to generate derived key");
throw std::runtime_error("failed to derive subkey");
}
}
@ -87,6 +74,9 @@ namespace llarp
void
Identity::EnsureKeys(fs::path fname, bool needBackup)
{
// make sure we are empty
Clear();
std::array<byte_t, 4096> tmp;
llarp_buffer_t buf(tmp);
@ -137,12 +127,21 @@ namespace llarp
if (!bencode_decode_dict(*this, &buf))
throw std::length_error("could not decode service identity");
auto crypto = CryptoManager::instance();
// ensure that the encryption key is set
if (enckey.IsZero())
crypto->encryption_keygen(enckey);
// also ensure the ntru key is set
if (pq.IsZero())
crypto->pqe_keygen(pq);
std::optional<VanityNonce> van;
if (!vanity.IsZero())
van = vanity;
// update pubkeys
pub.Update(seckey_topublic(signkey), seckey_topublic(enckey), van);
auto crypto = CryptoManager::instance();
if (not crypto->derive_subkey_private(derivedSignKey, signkey, 1))
{
throw std::runtime_error("failed to derive subkey");

@ -55,6 +55,10 @@ namespace llarp
bool
Sign(Signature& sig, const llarp_buffer_t& buf) const;
/// zero out all secret key members
void
Clear();
};
inline bool

Loading…
Cancel
Save