♻️ 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 ();
f.seekg (0, ifstream::beg);
vector <uint8_t> bytes;
Bytes bytes;
bytes.resize (len);
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)"
<< 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
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)"
<< 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
if (now.x < key.time_created.x) {
@ -166,6 +166,8 @@ int main (int argc, char ** argv) {
options.add_options ()
("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-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> ())
("test", "Run self-test")
("help", "Print usage")

View File

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

View File

@ -12,12 +12,12 @@
namespace BareMinimumCrypto::Receiver {
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;
}
optional <vector <uint8_t>> try_verify_signed_data (
const vector <uint8_t> & pubkey,
optional <Bytes> try_verify_signed_data (
const Bytes & pubkey,
const ExpiringSignature & sig,
Instant now
) {
@ -52,8 +52,8 @@ namespace BareMinimumCrypto::Receiver {
return payload;
}
optional <vector <uint8_t>> verify_signed_data (
const vector <uint8_t> & pubkey,
optional <Bytes> verify_signed_data (
const Bytes & pubkey,
const ExpiringSignature & sig,
Instant now
) {
@ -65,9 +65,9 @@ namespace BareMinimumCrypto::Receiver {
}
}
optional <vector <uint8_t>> try_verify_cert_and_data (
const vector <uint8_t> & root_pubkey,
const vector <uint8_t> & msgpack,
optional <Bytes> try_verify_cert_and_data (
const Bytes & root_pubkey,
const Bytes & msgpack,
Instant now
) {
const auto j = json::from_msgpack (msgpack);
@ -90,9 +90,9 @@ namespace BareMinimumCrypto::Receiver {
return verify_signed_data (subkey, data, now);
}
optional <vector <uint8_t>> verify_cert_and_data (
const vector <uint8_t> & root_pubkey,
const vector <uint8_t> & msgpack
optional <Bytes> verify_cert_and_data (
const Bytes & root_pubkey,
const Bytes & msgpack
) {
try {
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 {
using namespace std;
optional <vector <uint8_t>> verify_cert_and_data (
const vector <uint8_t> & root_pubkey,
typedef vector <uint8_t> Bytes;
optional <Bytes> verify_cert_and_data (
const Bytes & root_pubkey,
const ExpiringSignature & signed_cert,
const ExpiringSignature & signed_data
);
optional <vector <uint8_t>> verify_cert_and_data (
const vector <uint8_t> & root_pubkey,
const vector <uint8_t> & msgpack
optional <Bytes> verify_cert_and_data (
const Bytes & root_pubkey,
const Bytes & msgpack
);
}

View File

@ -18,7 +18,7 @@ namespace BareMinimumCrypto {
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 json j {
@ -35,7 +35,7 @@ namespace BareMinimumCrypto {
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 {
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 ());
}
}

View File

@ -15,13 +15,13 @@ namespace BareMinimumCrypto {
static optional <Sender> create (SigningKey k, ExpiringSignature c);
// 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:
SigningKey sender_key;
ExpiringSignature cert;
vector <uint8_t> try_sign (const vector <uint8_t> & data, Instant now) const;
optional <vector <uint8_t>> sign (const vector <uint8_t> & data, Instant now) const;
Bytes try_sign (const Bytes & data, Instant now) const;
optional <Bytes> sign (const Bytes & data, Instant now) const;
};
}

View File

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

View File

@ -17,28 +17,28 @@ namespace BareMinimumCrypto {
string get_machine_id ();
struct SigningKey {
vector <uint8_t> sk;
Bytes sk;
SigningKey ();
static optional <SigningKey> load_human_key_file (const string & file_path, const string & passphrase);
vector <uint8_t> pubkey () const;
vector <uint8_t> pub_to_msgpack () const;
Bytes pubkey () const;
Bytes pub_to_msgpack () const;
optional <ExpiringSignature> sign (
const vector <uint8_t> & payload,
const Bytes & payload,
TimeRange tr
) 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 {
vector <uint8_t> salt;
Bytes salt;
Instant time_created;
vector <uint8_t> pubkey;
Bytes pubkey;
string machine_id;
// 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);
vector <uint8_t> to_msgpack () const;
Bytes to_msgpack () const;
static optional <HumanKeyFile> try_from_msgpack (const json & msg);
};
struct MachineKeyFile {
vector <uint8_t> secretkey;
Bytes secretkey;
Instant time_created;
string machine_id;
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);
};
}

View File

@ -7,15 +7,15 @@
namespace BareMinimumCrypto {
using namespace std;
vector <uint8_t> copy_to_bytes (const string & s) {
return vector <uint8_t> ((const uint8_t *)&s [0], (const uint8_t *)&s [s.size ()]);
Bytes copy_to_bytes (const string & s) {
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 ()));
}
optional <vector <uint8_t>> base64_decode (const string & s) {
optional <Bytes> base64_decode (const string & s) {
try {
const auto decoded = ::base64_decode (s);
return copy_to_bytes (decoded);
@ -33,7 +33,7 @@ namespace BareMinimumCrypto {
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);
if (s != "AQIDBAUG") {

View File

@ -8,11 +8,13 @@
namespace BareMinimumCrypto {
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
string base64_encode (const vector <uint8_t> & v);
optional <vector <uint8_t>> base64_decode (const string & s);
string base64_encode (const Bytes & v);
optional <Bytes> base64_decode (const string & s);
int test_base64 ();
}