8#include <botan/asn1_obj.h>
10#include <botan/ber_dec.h>
11#include <botan/der_enc.h>
12#include <botan/internal/bit_ops.h>
13#include <botan/internal/fmt.h>
14#include <botan/internal/int_utils.h>
15#include <botan/internal/oid_map.h>
16#include <botan/internal/parsing.h>
17#include <botan/internal/stl_util.h>
26void oid_valid_check(std::span<const uint32_t> oid) {
29 BOTAN_ARG_CHECK(oid[1] <= 39 || oid[0] == 2,
"OID second arc too large");
36std::vector<uint32_t> parse_oid_str(std::string_view oid) {
39 std::vector<uint32_t> oid_elems;
44 return std::vector<uint32_t>();
58 }
catch(Invalid_Argument&) {
60 return std::vector<uint32_t>();
79 return std::optional(o);
105 oid_valid_check(m_id);
109 oid_valid_check(m_id);
116 if(!oid_str.empty()) {
117 m_id = parse_oid_str(oid_str);
118 oid_valid_check(m_id);
126 std::ostringstream out;
128 for(
size_t i = 0; i != m_id.size(); ++i) {
130 out << std::to_string(m_id[i]);
131 if(i != m_id.size() - 1) {
156 constexpr uint64_t mod = 0xffffffffffffffc5;
158 for(
auto id : m_id) {
159 hash = (hash * 257 + id) % mod;
161 return static_cast<size_t>(hash);
169 const std::vector<uint32_t>& oid2 =
b.get_components();
171 return std::lexicographical_compare(oid1.begin(), oid1.end(), oid2.begin(), oid2.end());
178 if(m_id.size() < 2) {
182 auto append = [](std::vector<uint8_t>& encoding, uint32_t z) {
184 encoding.push_back(
static_cast<uint8_t
>(z));
186 size_t z7 = (
high_bit(z) + 7 - 1) / 7;
188 for(
size_t j = 0; j != z7; ++j) {
189 uint8_t zp =
static_cast<uint8_t
>(z >> (7 * (z7 - j - 1)) & 0x7F);
195 encoding.push_back(zp);
200 std::vector<uint8_t> encoding;
205 append(encoding, first);
207 for(
size_t i = 2; i != m_id.size(); ++i) {
208 append(encoding, m_id[i]);
228 uint32_t
b = data.take_byte();
237 throw Decoding_Error(
"Leading zero byte in multibyte OID encoding");
245 const uint8_t next = data.take_byte();
246 const bool more = (next & 0x80);
247 const uint8_t value = next & 0x7F;
249 if((
b >> (32 - 7)) != 0) {
253 b = (
b << 7) | value;
265 std::vector<uint32_t> parts;
266 while(!data.
empty()) {
267 const uint32_t comp = consume(data);
272 const uint32_t root_arc = [](uint32_t b0) -> uint32_t {
282 parts.push_back(root_arc);
284 parts.push_back(comp - 40 * root_arc);
286 parts.push_back(comp);
#define BOTAN_ASSERT_NOMSG(expr)
#define BOTAN_ARG_CHECK(expr, msg)
BER_Object get_next_object()
std::span< const uint8_t > data() const
DER_Encoder & add_object(ASN1_Type type_tag, ASN1_Class class_tag, const uint8_t rep[], size_t length)
std::string oid2str(const OID &oid)
void add_oid(const OID &oid, std::string_view str)
static OID_Map & global_registry()
OID str2oid(std::string_view str)
void encode_into(DER_Encoder &) const override
std::string to_formatted_string() const
bool registered_oid() const
const std::vector< uint32_t > & get_components() const
static std::optional< OID > from_name(std::string_view name)
static void register_oid(const OID &oid, std::string_view name)
std::string human_name_or_empty() const
void decode_from(BER_Decoder &) override
std::string to_string() const
static OID from_string(std::string_view str)
uint32_t to_u32bit(std::string_view str_view)
constexpr std::optional< T > checked_add(T a, T b)
std::string fmt(std::string_view format, const T &... args)
bool operator<(const OID &a, const OID &b)
constexpr size_t high_bit(T n)
#define BOTAN_ASSERT_IS_SOME(v)