aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/lib/prov/tpm/info.txt1
-rw-r--r--src/lib/prov/tpm/uuid.h106
-rw-r--r--src/lib/utils/uuid/info.txt8
-rw-r--r--src/lib/utils/uuid/uuid.cpp82
-rw-r--r--src/lib/utils/uuid/uuid.h66
-rw-r--r--src/tests/test_utils.cpp73
6 files changed, 230 insertions, 106 deletions
diff --git a/src/lib/prov/tpm/info.txt b/src/lib/prov/tpm/info.txt
index 8ec00ba86..3993efc53 100644
--- a/src/lib/prov/tpm/info.txt
+++ b/src/lib/prov/tpm/info.txt
@@ -9,6 +9,7 @@ all -> tspi
</libs>
<requires>
+uuid
hash_id
rsa
rng
diff --git a/src/lib/prov/tpm/uuid.h b/src/lib/prov/tpm/uuid.h
deleted file mode 100644
index 2c89d45b4..000000000
--- a/src/lib/prov/tpm/uuid.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
-* UUID type
-* (C) 2015 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#ifndef BOTAN_UUID_H_
-#define BOTAN_UUID_H_
-
-#include <botan/secmem.h>
-#include <botan/hex.h>
-#include <sstream>
-
-namespace Botan {
-
-// TODO: move to util?
-class UUID final
- {
- public:
- // Represents an unassigned UUID object
- UUID() : m_uuid(0) {}
-
- UUID(RandomNumberGenerator& rng)
- {
- m_uuid.resize(16);
- rng.randomize(m_uuid.data(), m_uuid.size());
-
- // Mark as a random UUID (RFC 4122 sec 4.4)
- m_uuid[6] = 0x40 | (m_uuid[6] & 0x0F);
-
- // Set two reserved bits
- m_uuid[8] = 0xC0 | (m_uuid[8] & 0x3F);
- }
-
- UUID(const std::vector<uint8_t>& blob)
- {
- if(blob.size() != 16)
- {
- throw Invalid_Argument("Bad UUID blob " + hex_encode(blob));
- }
-
- m_uuid = blob;
- }
-
- UUID(const std::string& uuid_str)
- {
- if(uuid_str.size() != 36 ||
- uuid_str[8] != '-' ||
- uuid_str[14] != '-' ||
- uuid_str[19] != '-' ||
- uuid_str[24] != '-')
- {
- throw Invalid_Argument("Bad UUID '" + uuid_str + "'");
- }
-
- std::string just_hex;
- for(size_t i = 0; i != uuid_str.size(); ++i)
- {
- char c = uuid_str[i];
-
- if(c == '-')
- continue;
-
- just_hex += c;
- }
-
- m_uuid = hex_decode(just_hex);
-
- if(m_uuid.size() != 16)
- {
- throw Invalid_Argument("Bad UUID '" + uuid_str + "'");
- }
- }
-
-
- std::string to_string() const
- {
- std::string h = hex_encode(m_uuid);
-
- h.insert(8, "-");
- h.insert(14, "-");
- h.insert(19, "-");
- h.insert(24, "-");
-
- return h;
- }
-
- const std::vector<uint8_t>& binary_value() const { return m_uuid; }
-
- bool operator==(const UUID& other) const
- {
- return m_uuid == other.m_uuid;
- }
-
- bool operator!=(const UUID& other) const { return !(*this == other); }
-
- bool is_valid() const { return m_uuid.size() == 16; }
-
- private:
- std::vector<uint8_t> m_uuid;
- };
-
-}
-
-#endif
diff --git a/src/lib/utils/uuid/info.txt b/src/lib/utils/uuid/info.txt
new file mode 100644
index 000000000..b078146e8
--- /dev/null
+++ b/src/lib/utils/uuid/info.txt
@@ -0,0 +1,8 @@
+<defines>
+UUID -> 20180930
+</defines>
+
+<requires>
+rng
+hex
+</requires>
diff --git a/src/lib/utils/uuid/uuid.cpp b/src/lib/utils/uuid/uuid.cpp
new file mode 100644
index 000000000..c81cae665
--- /dev/null
+++ b/src/lib/utils/uuid/uuid.cpp
@@ -0,0 +1,82 @@
+/*
+* UUID type
+* (C) 2015,2018 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/uuid.h>
+#include <botan/rng.h>
+#include <botan/hex.h>
+#include <sstream>
+
+namespace Botan {
+
+UUID::UUID(RandomNumberGenerator& rng)
+ {
+ m_uuid.resize(16);
+ rng.randomize(m_uuid.data(), m_uuid.size());
+
+ // Mark as a random v4 UUID (RFC 4122 sec 4.4)
+ m_uuid[6] = 0x40 | (m_uuid[6] & 0x0F);
+
+ // Set reserved bits
+ m_uuid[8] = 0x80 | (m_uuid[8] & 0x3F);
+ }
+
+UUID::UUID(const std::vector<uint8_t>& blob)
+ {
+ if(blob.size() != 16)
+ {
+ throw Invalid_Argument("Bad UUID blob " + hex_encode(blob));
+ }
+
+ m_uuid = blob;
+ }
+
+UUID::UUID(const std::string& uuid_str)
+ {
+ if(uuid_str.size() != 36 ||
+ uuid_str[8] != '-' ||
+ uuid_str[13] != '-' ||
+ uuid_str[18] != '-' ||
+ uuid_str[23] != '-')
+ {
+ throw Invalid_Argument("Bad UUID '" + uuid_str + "'");
+ }
+
+ std::string just_hex;
+ for(size_t i = 0; i != uuid_str.size(); ++i)
+ {
+ char c = uuid_str[i];
+
+ if(c == '-')
+ continue;
+
+ just_hex += c;
+ }
+
+ m_uuid = hex_decode(just_hex);
+
+ if(m_uuid.size() != 16)
+ {
+ throw Invalid_Argument("Bad UUID '" + uuid_str + "'");
+ }
+ }
+
+std::string UUID::to_string() const
+ {
+ if(is_valid() == false)
+ throw Invalid_State("UUID object is empty cannot convert to string");
+
+ std::string h = hex_encode(m_uuid);
+
+ h.insert(8, "-");
+ h.insert(13, "-");
+ h.insert(18, "-");
+ h.insert(23, "-");
+
+ return h;
+ }
+
+}
diff --git a/src/lib/utils/uuid/uuid.h b/src/lib/utils/uuid/uuid.h
new file mode 100644
index 000000000..9d02fc2cd
--- /dev/null
+++ b/src/lib/utils/uuid/uuid.h
@@ -0,0 +1,66 @@
+/*
+* UUID type
+* (C) 2015,2018 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_UUID_H_
+#define BOTAN_UUID_H_
+
+#include <botan/types.h>
+#include <vector>
+
+namespace Botan {
+
+class RandomNumberGenerator;
+
+class BOTAN_UNSTABLE_API UUID final
+ {
+ public:
+ /**
+ * Create an uninitialized UUID object
+ */
+ UUID() : m_uuid() {}
+
+ /**
+ * Create a random UUID
+ */
+ UUID(RandomNumberGenerator& rng);
+
+ /**
+ * Load a UUID from a 16 byte vector
+ */
+ UUID(const std::vector<uint8_t>& blob);
+
+ UUID& operator=(const UUID& other) = default;
+ UUID(const UUID& other) = default;
+
+ /**
+ * Decode a UUID string
+ */
+ UUID(const std::string& uuid_str);
+
+ /**
+ * Convert the UUID to a string
+ */
+ std::string to_string() const;
+
+ const std::vector<uint8_t>& binary_value() const { return m_uuid; }
+
+ bool operator==(const UUID& other) const
+ {
+ return m_uuid == other.m_uuid;
+ }
+
+ bool operator!=(const UUID& other) const { return !(*this == other); }
+
+ bool is_valid() const { return m_uuid.size() == 16; }
+
+ private:
+ std::vector<uint8_t> m_uuid;
+ };
+
+}
+
+#endif
diff --git a/src/tests/test_utils.cpp b/src/tests/test_utils.cpp
index 5c231c2cd..5da910af6 100644
--- a/src/tests/test_utils.cpp
+++ b/src/tests/test_utils.cpp
@@ -30,6 +30,10 @@
#include <botan/internal/poly_dbl.h>
#endif
+#if defined(BOTAN_HAS_UUID)
+ #include <botan/uuid.h>
+#endif
+
namespace Botan_Tests {
namespace {
@@ -753,6 +757,75 @@ class CPUID_Tests final : public Test
BOTAN_REGISTER_TEST("cpuid", CPUID_Tests);
+#if defined(BOTAN_HAS_UUID)
+
+class UUID_Tests : public Test
+ {
+ public:
+ std::vector<Test::Result> run() override
+ {
+ Test::Result result("UUID");
+
+ const Botan::UUID empty_uuid;
+ const Botan::UUID random_uuid1(Test::rng());
+ const Botan::UUID random_uuid2(Test::rng());
+ const Botan::UUID loaded_uuid(std::vector<uint8_t>(16, 4));
+
+ result.test_throws("Cannot load wrong number of bytes", []() { Botan::UUID u(std::vector<uint8_t>(15)); });
+
+ result.test_eq("Empty UUID is empty", empty_uuid.is_valid(), false);
+ result.confirm("Empty UUID equals self", empty_uuid == empty_uuid);
+
+ result.test_throws("Empty UUID cannot become a string", [&]() { empty_uuid.to_string(); });
+
+ result.test_eq("Random UUID not empty", random_uuid1.is_valid(), true);
+ result.test_eq("Random UUID not empty", random_uuid2.is_valid(), true);
+
+ result.confirm("Random UUIDs are distinct", random_uuid1 != random_uuid2);
+ result.confirm("Random UUIDs not equal to empty", random_uuid1 != empty_uuid);
+
+ const std::string uuid4_str = loaded_uuid.to_string();
+ result.test_eq("String matches expected", uuid4_str, "04040404-0404-0404-0404-040404040404");
+
+ const std::string uuid_r1_str = random_uuid1.to_string();
+ result.confirm("UUID from string matches", Botan::UUID(uuid_r1_str) == random_uuid1);
+
+ class AllSame_RNG : public Botan::RandomNumberGenerator
+ {
+ public:
+ AllSame_RNG(uint8_t b) : m_val(b) {}
+
+ void randomize(uint8_t out[], size_t len) override
+ {
+ std::memset(out, m_val, len);
+ }
+
+ std::string name() const override { return "zeros"; }
+ bool accepts_input() const override { return false; }
+ void add_entropy(const uint8_t[], size_t) override {}
+ void clear() override {}
+ bool is_seeded() const override { return true; }
+ private:
+ uint8_t m_val;
+ };
+
+ AllSame_RNG zeros(0x00);
+ const Botan::UUID zero_uuid(zeros);
+ result.test_eq("Zero UUID matches expected", zero_uuid.to_string(), "00000000-0000-4000-8000-000000000000");
+
+ AllSame_RNG ones(0xFF);
+ const Botan::UUID ones_uuid(ones);
+ result.test_eq("Ones UUID matches expected", ones_uuid.to_string(), "FFFFFFFF-FFFF-4FFF-BFFF-FFFFFFFFFFFF");
+
+ return {result};
+ }
+
+ };
+
+BOTAN_REGISTER_TEST("uuid", UUID_Tests);
+
+#endif
+
}
}