♻️ refactor: switch to Bytes typedef

main
_ 2021-01-19 19:31:41 -06:00
parent 199aacadd3
commit 02346c3285
10 changed files with 69 additions and 61 deletions

View File

@ -36,7 +36,7 @@ int file (const string & file_path) {
const auto len = f.tellg (); const auto len = f.tellg ();
f.seekg (0, ifstream::beg); f.seekg (0, ifstream::beg);
vector <uint8_t> bytes; Bytes bytes;
bytes.resize (len); bytes.resize (len);
f.read ((char *)bytes.data (), bytes.size ()); f.read ((char *)bytes.data (), bytes.size ());
@ -63,7 +63,7 @@ int file (const string & file_path) {
<< " (" << now.x - key.time_created.x << " seconds ago)" << " (" << now.x - key.time_created.x << " seconds ago)"
<< endl; << endl;
cout << "Generated on machine ID " << key.machine_id << endl; cout << "Generated on machine ID " << key.machine_id << endl;
cout << "Claims to have Base64 pubkey " << base64_encode (key.pubkey) << endl; cout << "Claims to have Base64 pubkey `" << base64_encode (key.pubkey) << "`" << endl;
// Print warnings // Print warnings
if (now.x < key.time_created.x) { if (now.x < key.time_created.x) {
@ -90,7 +90,7 @@ int file (const string & file_path) {
<< " (" << now.x - key.time_created.x << " seconds ago)" << " (" << now.x - key.time_created.x << " seconds ago)"
<< endl; << endl;
cout << "Generated on machine ID " << key.machine_id << endl; cout << "Generated on machine ID " << key.machine_id << endl;
cout << "Claims to have Base64 pubkey " << base64_encode (key.pubkey ()) << endl; cout << "Claims to have Base64 pubkey `" << base64_encode (key.pubkey ()) << "`" << endl;
// Print warnings // Print warnings
if (now.x < key.time_created.x) { if (now.x < key.time_created.x) {
@ -166,6 +166,8 @@ int main (int argc, char ** argv) {
options.add_options () options.add_options ()
("generate-human-key", "Generate a passphrase-protected key for human use", cxxopts::value <string> ()) ("generate-human-key", "Generate a passphrase-protected key for human use", cxxopts::value <string> ())
("generate-machine-key", "Generate a key for machine use, with no passphrase", cxxopts::value <string> ()) ("generate-machine-key", "Generate a key for machine use, with no passphrase", cxxopts::value <string> ())
("generate-key-cert", "Certify a key for 1 month and save the cert here", cxxopts::value <string> ())
("using-key", "Key to load for other operations", cxxopts::value <string> ())
("file", "Print info about any file generated by BMC", cxxopts::value <string> ()) ("file", "Print info about any file generated by BMC", cxxopts::value <string> ())
("test", "Run self-test") ("test", "Run self-test")
("help", "Print usage") ("help", "Print usage")

View File

@ -9,10 +9,12 @@
namespace BareMinimumCrypto { namespace BareMinimumCrypto {
using namespace std; using namespace std;
typedef vector <uint8_t> Bytes;
struct ExpiringSignature { struct ExpiringSignature {
// Payload is contained in here // Payload is contained in here
vector <uint8_t> cert; Bytes cert;
vector <uint8_t> sig; Bytes sig;
bool operator == (const ExpiringSignature & o) const; bool operator == (const ExpiringSignature & o) const;
bool operator != (const ExpiringSignature & o) const; bool operator != (const ExpiringSignature & o) const;

View File

@ -12,12 +12,12 @@
namespace BareMinimumCrypto::Receiver { namespace BareMinimumCrypto::Receiver {
using nlohmann::json; using nlohmann::json;
bool is_pubkey_length (const vector <uint8_t> & v) { bool is_pubkey_length (const Bytes & v) {
return v.size () == crypto_sign_PUBLICKEYBYTES; return v.size () == crypto_sign_PUBLICKEYBYTES;
} }
optional <vector <uint8_t>> try_verify_signed_data ( optional <Bytes> try_verify_signed_data (
const vector <uint8_t> & pubkey, const Bytes & pubkey,
const ExpiringSignature & sig, const ExpiringSignature & sig,
Instant now Instant now
) { ) {
@ -52,8 +52,8 @@ namespace BareMinimumCrypto::Receiver {
return payload; return payload;
} }
optional <vector <uint8_t>> verify_signed_data ( optional <Bytes> verify_signed_data (
const vector <uint8_t> & pubkey, const Bytes & pubkey,
const ExpiringSignature & sig, const ExpiringSignature & sig,
Instant now Instant now
) { ) {
@ -65,9 +65,9 @@ namespace BareMinimumCrypto::Receiver {
} }
} }
optional <vector <uint8_t>> try_verify_cert_and_data ( optional <Bytes> try_verify_cert_and_data (
const vector <uint8_t> & root_pubkey, const Bytes & root_pubkey,
const vector <uint8_t> & msgpack, const Bytes & msgpack,
Instant now Instant now
) { ) {
const auto j = json::from_msgpack (msgpack); const auto j = json::from_msgpack (msgpack);
@ -90,9 +90,9 @@ namespace BareMinimumCrypto::Receiver {
return verify_signed_data (subkey, data, now); return verify_signed_data (subkey, data, now);
} }
optional <vector <uint8_t>> verify_cert_and_data ( optional <Bytes> verify_cert_and_data (
const vector <uint8_t> & root_pubkey, const Bytes & root_pubkey,
const vector <uint8_t> & msgpack const Bytes & msgpack
) { ) {
try { try {
return try_verify_cert_and_data (root_pubkey, msgpack, Instant::now ()); return try_verify_cert_and_data (root_pubkey, msgpack, Instant::now ());

View File

@ -24,14 +24,16 @@ data are disposable and not exposed to callers.
namespace BareMinimumCrypto::Receiver { namespace BareMinimumCrypto::Receiver {
using namespace std; using namespace std;
optional <vector <uint8_t>> verify_cert_and_data ( typedef vector <uint8_t> Bytes;
const vector <uint8_t> & root_pubkey,
optional <Bytes> verify_cert_and_data (
const Bytes & root_pubkey,
const ExpiringSignature & signed_cert, const ExpiringSignature & signed_cert,
const ExpiringSignature & signed_data const ExpiringSignature & signed_data
); );
optional <vector <uint8_t>> verify_cert_and_data ( optional <Bytes> verify_cert_and_data (
const vector <uint8_t> & root_pubkey, const Bytes & root_pubkey,
const vector <uint8_t> & msgpack const Bytes & msgpack
); );
} }

View File

@ -18,7 +18,7 @@ namespace BareMinimumCrypto {
return s; return s;
} }
vector <uint8_t> Sender::try_sign (const vector <uint8_t> & data, Instant now) const { Bytes Sender::try_sign (const Bytes & data, Instant now) const {
const auto signed_data = std::move (*sender_key.sign_data (data, now)); const auto signed_data = std::move (*sender_key.sign_data (data, now));
const json j { const json j {
@ -35,7 +35,7 @@ namespace BareMinimumCrypto {
return json::to_msgpack (j); return json::to_msgpack (j);
} }
optional <vector <uint8_t>> Sender::sign (const vector <uint8_t> & data, Instant now) const { optional <Bytes> Sender::sign (const Bytes & data, Instant now) const {
try { try {
return try_sign (data, now); return try_sign (data, now);
} }
@ -44,7 +44,7 @@ namespace BareMinimumCrypto {
} }
} }
optional <vector <uint8_t>> Sender::sign (const vector <uint8_t> & data) const { optional <Bytes> Sender::sign (const Bytes & data) const {
return sign (data, Instant::now ()); return sign (data, Instant::now ());
} }
} }

View File

@ -15,13 +15,13 @@ namespace BareMinimumCrypto {
static optional <Sender> create (SigningKey k, ExpiringSignature c); static optional <Sender> create (SigningKey k, ExpiringSignature c);
// Signs data and attaches our cert from the CA // Signs data and attaches our cert from the CA
optional <vector <uint8_t>> sign (const vector <uint8_t> & data) const; optional <Bytes> sign (const Bytes & data) const;
private: private:
SigningKey sender_key; SigningKey sender_key;
ExpiringSignature cert; ExpiringSignature cert;
vector <uint8_t> try_sign (const vector <uint8_t> & data, Instant now) const; Bytes try_sign (const Bytes & data, Instant now) const;
optional <vector <uint8_t>> sign (const vector <uint8_t> & data, Instant now) const; optional <Bytes> sign (const Bytes & data, Instant now) const;
}; };
} }

View File

@ -23,7 +23,7 @@ namespace BareMinimumCrypto {
return machine_id; return machine_id;
} }
vector <uint8_t> HumanKeyFile::to_msgpack () const { Bytes HumanKeyFile::to_msgpack () const {
const auto j = json { const auto j = json {
// Breaking changes should generate a new Base32 schema. // Breaking changes should generate a new Base32 schema.
{"schema", "3T6XF5DZ"}, {"schema", "3T6XF5DZ"},
@ -49,7 +49,7 @@ namespace BareMinimumCrypto {
}; };
} }
vector <uint8_t> MachineKeyFile::to_msgpack () const { Bytes MachineKeyFile::to_msgpack () const {
const auto j = json { const auto j = json {
// Breaking changes should generate a new Base32 schema. // Breaking changes should generate a new Base32 schema.
{"schema", "2PVHIKMA"}, {"schema", "2PVHIKMA"},
@ -73,14 +73,14 @@ namespace BareMinimumCrypto {
}; };
} }
vector <uint8_t> MachineKeyFile::pubkey () const { Bytes MachineKeyFile::pubkey () const {
vector <uint8_t> pk; Bytes pk;
pk.resize (crypto_sign_PUBLICKEYBYTES); pk.resize (crypto_sign_PUBLICKEYBYTES);
crypto_sign_ed25519_sk_to_pk (pk.data (), secretkey.data ()); crypto_sign_ed25519_sk_to_pk (pk.data (), secretkey.data ());
return pk; return pk;
} }
bool save_key_file (const string & file_path, const vector <uint8_t> msg) bool save_key_file (const string & file_path, const Bytes msg)
{ {
ofstream f; ofstream f;
f.open (file_path, ofstream::binary); f.open (file_path, ofstream::binary);
@ -114,10 +114,10 @@ namespace BareMinimumCrypto {
return nullopt; return nullopt;
} }
vector <uint8_t> seed; Bytes seed;
seed.resize (crypto_sign_SEEDBYTES); seed.resize (crypto_sign_SEEDBYTES);
vector <uint8_t> salt; Bytes salt;
salt.resize (crypto_pwhash_SALTBYTES); salt.resize (crypto_pwhash_SALTBYTES);
randombytes_buf (salt.data (), salt.size ()); randombytes_buf (salt.data (), salt.size ());
@ -136,7 +136,7 @@ namespace BareMinimumCrypto {
//key.pk.resize (crypto_sign_PUBLICKEYBYTES); //key.pk.resize (crypto_sign_PUBLICKEYBYTES);
key.sk.resize (crypto_sign_SECRETKEYBYTES); key.sk.resize (crypto_sign_SECRETKEYBYTES);
vector <uint8_t> pk; Bytes pk;
pk.resize (crypto_sign_PUBLICKEYBYTES); pk.resize (crypto_sign_PUBLICKEYBYTES);
if (crypto_sign_seed_keypair (pk.data (), key.sk.data (), seed.data ()) != 0) { if (crypto_sign_seed_keypair (pk.data (), key.sk.data (), seed.data ()) != 0) {
return nullopt; return nullopt;
@ -182,21 +182,21 @@ namespace BareMinimumCrypto {
SigningKey::SigningKey () { SigningKey::SigningKey () {
try_sodium_init (); try_sodium_init ();
vector <uint8_t> pk; Bytes pk;
pk.resize (crypto_sign_PUBLICKEYBYTES); pk.resize (crypto_sign_PUBLICKEYBYTES);
sk.resize (crypto_sign_SECRETKEYBYTES); sk.resize (crypto_sign_SECRETKEYBYTES);
crypto_sign_keypair (pk.data (), sk.data ()); crypto_sign_keypair (pk.data (), sk.data ());
} }
vector <uint8_t> SigningKey::pubkey () const { Bytes SigningKey::pubkey () const {
vector <uint8_t> pk; Bytes pk;
pk.resize (crypto_sign_PUBLICKEYBYTES); pk.resize (crypto_sign_PUBLICKEYBYTES);
crypto_sign_ed25519_sk_to_pk (pk.data (), sk.data ()); crypto_sign_ed25519_sk_to_pk (pk.data (), sk.data ());
return pk; return pk;
} }
vector <uint8_t> SigningKey::pub_to_msgpack () const { Bytes SigningKey::pub_to_msgpack () const {
const json j = { const json j = {
{"key", json::binary (pubkey ())}, {"key", json::binary (pubkey ())},
}; };
@ -204,7 +204,7 @@ namespace BareMinimumCrypto {
} }
optional <ExpiringSignature> SigningKey::sign ( optional <ExpiringSignature> SigningKey::sign (
const vector <uint8_t> & payload, const Bytes & payload,
TimeRange tr TimeRange tr
) const { ) const {
try_sodium_init (); try_sodium_init ();
@ -221,7 +221,7 @@ namespace BareMinimumCrypto {
const auto cert = json::to_msgpack (j); const auto cert = json::to_msgpack (j);
vector <uint8_t> sig; Bytes sig;
sig.resize (crypto_sign_BYTES); sig.resize (crypto_sign_BYTES);
crypto_sign_detached (sig.data (), nullptr, cert.data (), cert.size (), sk.data ()); crypto_sign_detached (sig.data (), nullptr, cert.data (), cert.size (), sk.data ());
@ -237,7 +237,7 @@ namespace BareMinimumCrypto {
return sign (k.pub_to_msgpack (), TimeRange::from_start_and_dur (now, about_3_months)); return sign (k.pub_to_msgpack (), TimeRange::from_start_and_dur (now, about_3_months));
} }
optional <ExpiringSignature> SigningKey::sign_data (const vector <uint8_t> & v, Instant now) const optional <ExpiringSignature> SigningKey::sign_data (const Bytes & v, Instant now) const
{ {
return sign (v, TimeRange::from_start_and_dur (now, about_1_week)); return sign (v, TimeRange::from_start_and_dur (now, about_1_week));
} }

View File

@ -17,28 +17,28 @@ namespace BareMinimumCrypto {
string get_machine_id (); string get_machine_id ();
struct SigningKey { struct SigningKey {
vector <uint8_t> sk; Bytes sk;
SigningKey (); SigningKey ();
static optional <SigningKey> load_human_key_file (const string & file_path, const string & passphrase); static optional <SigningKey> load_human_key_file (const string & file_path, const string & passphrase);
vector <uint8_t> pubkey () const; Bytes pubkey () const;
vector <uint8_t> pub_to_msgpack () const; Bytes pub_to_msgpack () const;
optional <ExpiringSignature> sign ( optional <ExpiringSignature> sign (
const vector <uint8_t> & payload, const Bytes & payload,
TimeRange tr TimeRange tr
) const; ) const;
optional <ExpiringSignature> sign_key (const SigningKey & k, Instant now) const; optional <ExpiringSignature> sign_key (const SigningKey & k, Instant now) const;
optional <ExpiringSignature> sign_data (const vector <uint8_t> & v, Instant now) const; optional <ExpiringSignature> sign_data (const Bytes & v, Instant now) const;
}; };
struct HumanKeyFile { struct HumanKeyFile {
vector <uint8_t> salt; Bytes salt;
Instant time_created; Instant time_created;
vector <uint8_t> pubkey; Bytes pubkey;
string machine_id; string machine_id;
// This doesn't fsync, so it's possible to lose the key due to a power outage // This doesn't fsync, so it's possible to lose the key due to a power outage
@ -47,20 +47,20 @@ namespace BareMinimumCrypto {
static optional <SigningKey> generate (const string & file_path, const string & passphrase); static optional <SigningKey> generate (const string & file_path, const string & passphrase);
vector <uint8_t> to_msgpack () const; Bytes to_msgpack () const;
static optional <HumanKeyFile> try_from_msgpack (const json & msg); static optional <HumanKeyFile> try_from_msgpack (const json & msg);
}; };
struct MachineKeyFile { struct MachineKeyFile {
vector <uint8_t> secretkey; Bytes secretkey;
Instant time_created; Instant time_created;
string machine_id; string machine_id;
static optional <SigningKey> generate (const string & file_path); static optional <SigningKey> generate (const string & file_path);
vector <uint8_t> pubkey () const; Bytes pubkey () const;
vector <uint8_t> to_msgpack () const; Bytes to_msgpack () const;
static optional <MachineKeyFile> try_from_msgpack (const json & msg); static optional <MachineKeyFile> try_from_msgpack (const json & msg);
}; };
} }

View File

@ -7,15 +7,15 @@
namespace BareMinimumCrypto { namespace BareMinimumCrypto {
using namespace std; using namespace std;
vector <uint8_t> copy_to_bytes (const string & s) { Bytes copy_to_bytes (const string & s) {
return vector <uint8_t> ((const uint8_t *)&s [0], (const uint8_t *)&s [s.size ()]); return Bytes ((const uint8_t *)&s [0], (const uint8_t *)&s [s.size ()]);
} }
string base64_encode (const vector <uint8_t> & v) { string base64_encode (const Bytes & v) {
return ::base64_encode (string_view ((const char *)v.data (), v.size ())); return ::base64_encode (string_view ((const char *)v.data (), v.size ()));
} }
optional <vector <uint8_t>> base64_decode (const string & s) { optional <Bytes> base64_decode (const string & s) {
try { try {
const auto decoded = ::base64_decode (s); const auto decoded = ::base64_decode (s);
return copy_to_bytes (decoded); return copy_to_bytes (decoded);
@ -33,7 +33,7 @@ namespace BareMinimumCrypto {
return 1; return 1;
} }
vector <uint8_t> v {1, 2, 3, 4, 5, 6}; Bytes v {1, 2, 3, 4, 5, 6};
const auto s = base64_encode (v); const auto s = base64_encode (v);
if (s != "AQIDBAUG") { if (s != "AQIDBAUG") {

View File

@ -8,11 +8,13 @@
namespace BareMinimumCrypto { namespace BareMinimumCrypto {
using namespace std; using namespace std;
vector <uint8_t> copy_to_bytes (const string & s); typedef vector <uint8_t> Bytes;
Bytes copy_to_bytes (const string & s);
// Not sure why the Base64 lib fails to provide this API // Not sure why the Base64 lib fails to provide this API
string base64_encode (const vector <uint8_t> & v); string base64_encode (const Bytes & v);
optional <vector <uint8_t>> base64_decode (const string & s); optional <Bytes> base64_decode (const string & s);
int test_base64 (); int test_base64 ();
} }