8#include <botan/pkix_types.h>
9#include <botan/der_enc.h>
10#include <botan/ber_dec.h>
11#include <botan/internal/stl_util.h>
22bool caseless_cmp(
char a,
char b)
24 return (std::tolower(
static_cast<unsigned char>(a)) ==
25 std::tolower(
static_cast<unsigned char>(b)));
30 return std::isspace(
static_cast<unsigned char>(c));
38bool x500_name_cmp(std::string_view name1, std::string_view name2)
40 auto p1 = name1.begin();
41 auto p2 = name2.begin();
43 while((p1 != name1.end()) && is_space(*p1)) ++p1;
44 while((p2 != name2.end()) && is_space(*p2)) ++p2;
46 while(p1 != name1.end() && p2 != name2.end())
53 while((p1 != name1.end()) && is_space(*p1)) ++p1;
54 while((p2 != name2.end()) && is_space(*p2)) ++p2;
56 if(p1 == name1.end() && p2 == name2.end())
58 if(p1 == name1.end() || p2 == name2.end())
62 if(!caseless_cmp(*p1, *p2))
68 while((p1 != name1.end()) && is_space(*p1)) ++p1;
69 while((p2 != name2.end()) && is_space(*p2)) ++p2;
71 if((p1 != name1.end()) || (p2 != name2.end()))
95 m_rdn.push_back(std::make_pair(oid, str));
104 std::multimap<OID, std::string> retval;
116 std::multimap<std::string, std::string> retval;
120 multimap_insert(retval, i.first.to_formatted_string(), i.second.value());
175 std::vector<std::string> values;
181 values.push_back(i.second.value());
193 if(info ==
"Name" || info ==
"CommonName" || info ==
"CN")
return "X520.CommonName";
194 if(info ==
"SerialNumber" || info ==
"SN")
return "X520.SerialNumber";
195 if(info ==
"Country" || info ==
"C")
return "X520.Country";
196 if(info ==
"Organization" || info ==
"O")
return "X520.Organization";
197 if(info ==
"Organizational Unit" || info ==
"OrgUnit" || info ==
"OU")
198 return "X520.OrganizationalUnit";
199 if(info ==
"Locality" || info ==
"L")
return "X520.Locality";
200 if(info ==
"State" || info ==
"Province" || info ==
"ST")
return "X520.State";
201 if(info ==
"Email")
return "RFC822";
202 return std::string(info);
213 if(attr1.size() != attr2.size())
return false;
215 auto p1 = attr1.begin();
216 auto p2 = attr2.begin();
220 if(p1 == attr1.end() && p2 == attr2.end())
222 if(p1 == attr1.end())
return false;
223 if(p2 == attr2.end())
return false;
224 if(p1->first != p2->first)
return false;
225 if(!x500_name_cmp(p1->second, p2->second))
238 return !(dn1 == dn2);
250 if(attr1.size() < attr2.size())
252 if(attr1.size() > attr2.size())
256 auto p1 = attr1.begin();
257 auto p2 = attr2.begin();
259 while(p1 != attr1.end() && p2 != attr2.end())
261 if(p1->first != p2->first)
263 return (p1->first < p2->first);
279 while(p1 != attr1.end() && p2 != attr2.end())
284 if(!x500_name_cmp(p1->second, p2->second))
288 return (p1->second < p2->second);
302 std::vector<uint8_t> result;
315 if(!m_dn_bits.empty())
325 for(
const auto& dn : m_rdn)
344 std::vector<uint8_t> bits;
378std::string to_short_form(
const OID& oid)
382 if(long_id ==
"X520.CommonName")
385 if(long_id ==
"X520.Country")
388 if(long_id ==
"X520.Organization")
391 if(long_id ==
"X520.OrganizationalUnit")
401 std::ostringstream out;
410 for(
size_t i = 0; i != info.size(); ++i)
412 out << to_short_form(info[i].first) <<
"=\"";
413 for(
char c : info[i].second.value())
415 if(c ==
'\\' || c ==
'\"')
423 if(i + 1 < info.size())
444 if(std::isspace(c) && key.empty())
446 else if(!std::isspace(c))
459 if(!std::isspace(c) && c !=
'=')
467 bool in_quotes =
false;
474 if(!in_quotes && !val.empty())
480 in_quotes = !in_quotes;
487 else if(c ==
',' && !in_quotes)
493 if(!key.empty() && !val.empty())
#define BOTAN_ASSERT_NOMSG(expr)
#define BOTAN_DEBUG_ASSERT(expr)
const std::string & value() const
BER_Decoder & decode(bool &out)
BER_Decoder start_sequence()
DER_Encoder & start_set()
DER_Encoder & start_sequence()
DER_Encoder & raw_bytes(const uint8_t val[], size_t len)
DER_Encoder & encode(bool b)
std::string to_formatted_string() const
static OID from_string(std::string_view str)
bool has_field(const OID &oid) const
void decode_from(BER_Decoder &) override
std::multimap< std::string, std::string > contents() const
void encode_into(DER_Encoder &) const override
std::vector< std::string > get_attribute(std::string_view attr) const
void add_attribute(std::string_view key, std::string_view val)
std::multimap< OID, std::string > get_attributes() const
ASN1_String get_first_attribute(const OID &oid) const
const std::vector< std::pair< OID, ASN1_String > > & dn_info() const
std::vector< uint8_t > DER_encode() const
std::string to_string() const
static std::string deref_info_field(std::string_view key)
bool operator<(const OID &a, const OID &b)
std::ostream & operator<<(std::ostream &out, const OID &oid)
bool operator!=(const AlgorithmIdentifier &a1, const AlgorithmIdentifier &a2)
bool operator==(const AlgorithmIdentifier &a1, const AlgorithmIdentifier &a2)
void multimap_insert(std::multimap< K, V > &multimap, const K &key, const V &value)
int operator>>(int fd, Pipe &pipe)