aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2018-03-21 10:28:26 -0400
committerJack Lloyd <[email protected]>2018-03-21 10:28:26 -0400
commitdbc51ba73c46f361753bd7d88828988d972a477e (patch)
treee59a14ce2b004417e7c0e665425fc0323a03d13c /src
parent2821d60c9c159851c3d236fcc2bdeafd2d733849 (diff)
parente2a0236d3c00b2a80ad22b8239e9752fb08f777e (diff)
Merge GH #1504 Store DN entries in a vector
Diffstat (limited to 'src')
-rw-r--r--src/lib/asn1/asn1_str.h2
-rw-r--r--src/lib/x509/name_constraint.cpp4
-rw-r--r--src/lib/x509/x509_dn.cpp105
-rw-r--r--src/lib/x509/x509_dn.h36
-rw-r--r--src/lib/x509/x509path.cpp3
5 files changed, 78 insertions, 72 deletions
diff --git a/src/lib/asn1/asn1_str.h b/src/lib/asn1/asn1_str.h
index 9a571561c..41dbd005c 100644
--- a/src/lib/asn1/asn1_str.h
+++ b/src/lib/asn1/asn1_str.h
@@ -26,6 +26,8 @@ class BOTAN_PUBLIC_API(2,0) ASN1_String final : public ASN1_Object
const std::string& value() const { return m_utf8_str; }
+ size_t size() const { return value().size(); }
+
bool empty() const { return m_utf8_str.empty(); }
std::string BOTAN_DEPRECATED("Use value() to get UTF-8 string instead")
diff --git a/src/lib/x509/name_constraint.cpp b/src/lib/x509/name_constraint.cpp
index 888291557..b64e04d29 100644
--- a/src/lib/x509/name_constraint.cpp
+++ b/src/lib/x509/name_constraint.cpp
@@ -190,14 +190,14 @@ bool GeneralName::matches_dn(const std::string& nam) const
bool ret = true;
size_t trys = 0;
- for(const std::pair<OID,std::string>& c: my_dn.get_attributes())
+ for(const auto& c: my_dn.dn_info())
{
auto i = attr.equal_range(c.first);
if(i.first != i.second)
{
trys += 1;
- ret = ret && (i.first->second == c.second);
+ ret = ret && (i.first->second == c.second.value());
}
}
diff --git a/src/lib/x509/x509_dn.cpp b/src/lib/x509/x509_dn.cpp
index 64c1c9a08..9eb509dab 100644
--- a/src/lib/x509/x509_dn.cpp
+++ b/src/lib/x509/x509_dn.cpp
@@ -1,6 +1,6 @@
/*
* X509_DN
-* (C) 1999-2007 Jack Lloyd
+* (C) 1999-2007,2018 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -17,24 +17,6 @@
namespace Botan {
/*
-* Create an X509_DN
-*/
-X509_DN::X509_DN(const std::multimap<OID, std::string>& args)
- {
- for(auto i = args.begin(); i != args.end(); ++i)
- add_attribute(i->first, i->second);
- }
-
-/*
-* Create an X509_DN
-*/
-X509_DN::X509_DN(const std::multimap<std::string, std::string>& args)
- {
- for(auto i = args.begin(); i != args.end(); ++i)
- add_attribute(OIDS::lookup(i->first), i->second);
- }
-
-/*
* Add an attribute to a X509_DN
*/
void X509_DN::add_attribute(const std::string& type,
@@ -43,11 +25,6 @@ void X509_DN::add_attribute(const std::string& type,
add_attribute(OIDS::lookup(type), str);
}
-void X509_DN::add_attribute(const OID& oid, const std::string& str)
- {
- add_attribute(oid, ASN1_String(str));
- }
-
/*
* Add an attribute to a X509_DN
*/
@@ -56,14 +33,7 @@ void X509_DN::add_attribute(const OID& oid, const ASN1_String& str)
if(str.empty())
return;
- auto range = m_dn_info.equal_range(oid);
- for(auto i = range.first; i != range.second; ++i)
- {
- if(i->second == str)
- return;
- }
-
- multimap_insert(m_dn_info, oid, str);
+ m_rdn.push_back(std::make_pair(oid, str));
m_dn_bits.clear();
}
@@ -73,8 +43,9 @@ void X509_DN::add_attribute(const OID& oid, const ASN1_String& str)
std::multimap<OID, std::string> X509_DN::get_attributes() const
{
std::multimap<OID, std::string> retval;
- for(auto i = m_dn_info.begin(); i != m_dn_info.end(); ++i)
- multimap_insert(retval, i->first, i->second.value());
+
+ for(auto& i : m_rdn)
+ multimap_insert(retval, i.first, i.second.value());
return retval;
}
@@ -84,13 +55,14 @@ std::multimap<OID, std::string> X509_DN::get_attributes() const
std::multimap<std::string, std::string> X509_DN::contents() const
{
std::multimap<std::string, std::string> retval;
- for(auto i = m_dn_info.begin(); i != m_dn_info.end(); ++i)
+
+ for(auto& i : m_rdn)
{
- std::string str_value = OIDS::oid2str(i->first);
+ std::string str_value = OIDS::oid2str(i.first);
if(str_value.empty())
- str_value = i->first.as_string();
- multimap_insert(retval, str_value, i->second.value());
+ str_value = i.first.as_string();
+ multimap_insert(retval, str_value, i.second.value());
}
return retval;
}
@@ -102,8 +74,13 @@ bool X509_DN::has_field(const std::string& attr) const
bool X509_DN::has_field(const OID& oid) const
{
- auto range = m_dn_info.equal_range(oid);
- return (range.first != range.second);
+ for(auto& i : m_rdn)
+ {
+ if(i.first == oid)
+ return true;
+ }
+
+ return false;
}
std::string X509_DN::get_first_attribute(const std::string& attr) const
@@ -114,9 +91,13 @@ std::string X509_DN::get_first_attribute(const std::string& attr) const
ASN1_String X509_DN::get_first_attribute(const OID& oid) const
{
- auto i = m_dn_info.lower_bound(oid);
- if(i != m_dn_info.end() && i->first == oid)
- return i->second;
+ for(auto& i : m_rdn)
+ {
+ if(i.first == oid)
+ {
+ return i.second;
+ }
+ }
return ASN1_String();
}
@@ -128,11 +109,16 @@ std::vector<std::string> X509_DN::get_attribute(const std::string& attr) const
{
const OID oid = OIDS::lookup(deref_info_field(attr));
- auto range = m_dn_info.equal_range(oid);
-
std::vector<std::string> values;
- for(auto i = range.first; i != range.second; ++i)
- values.push_back(i->second.value());
+
+ for(auto& i : m_rdn)
+ {
+ if(i.first == oid)
+ {
+ values.push_back(i.second.value());
+ }
+ }
+
return values;
}
@@ -227,7 +213,7 @@ void X509_DN::encode_into(DER_Encoder& der) const
}
else
{
- for(const auto& dn : m_dn_info)
+ for(const auto& dn : m_rdn)
{
der.start_cons(SET)
.start_cons(SEQUENCE)
@@ -263,10 +249,7 @@ void X509_DN::decode_from(BER_Decoder& source)
OID oid;
ASN1_String str;
- rdn.start_cons(SEQUENCE)
- .decode(oid)
- .decode(str)
- .end_cons();
+ rdn.start_cons(SEQUENCE).decode(oid).decode(str).end_cons();
add_attribute(oid, str);
}
@@ -277,8 +260,13 @@ void X509_DN::decode_from(BER_Decoder& source)
namespace {
-std::string to_short_form(const std::string& long_id)
+std::string to_short_form(const OID& oid)
{
+ const std::string long_id = OIDS::oid2str(oid);
+
+ if(long_id.empty())
+ return oid.to_string();
+
if(long_id == "X520.CommonName")
return "CN";
@@ -298,13 +286,12 @@ std::string to_short_form(const std::string& long_id)
std::ostream& operator<<(std::ostream& out, const X509_DN& dn)
{
- std::multimap<std::string, std::string> contents = dn.contents();
+ auto info = dn.dn_info();
- for(std::multimap<std::string, std::string>::const_iterator i = contents.begin();
- i != contents.end(); ++i)
+ for(size_t i = 0; i != info.size(); ++i)
{
- out << to_short_form(i->first) << "=\"";
- for(char c: i->second)
+ out << to_short_form(info[i].first) << "=\"";
+ for(char c : info[i].second.value())
{
if(c == '\\' || c == '\"')
{
@@ -314,7 +301,7 @@ std::ostream& operator<<(std::ostream& out, const X509_DN& dn)
}
out << "\"";
- if(std::next(i) != contents.end())
+ if(i + 1 < info.size())
{
out << ",";
}
diff --git a/src/lib/x509/x509_dn.h b/src/lib/x509/x509_dn.h
index c08bf9e7e..9d8beb0bf 100644
--- a/src/lib/x509/x509_dn.h
+++ b/src/lib/x509/x509_dn.h
@@ -12,6 +12,7 @@
#include <botan/asn1_obj.h>
#include <botan/asn1_oid.h>
#include <botan/asn1_str.h>
+#include <vector>
#include <map>
#include <iosfwd>
@@ -24,14 +25,22 @@ class BOTAN_PUBLIC_API(2,0) X509_DN final : public ASN1_Object
{
public:
X509_DN() = default;
- explicit X509_DN(const std::multimap<OID, std::string>& vals);
- explicit X509_DN(const std::multimap<std::string, std::string>& vals);
+
+ explicit X509_DN(const std::multimap<OID, std::string>& args)
+ {
+ for(auto i : args)
+ add_attribute(i.first, i.second);
+ }
+
+ explicit X509_DN(const std::multimap<std::string, std::string>& args)
+ {
+ for(auto i : args)
+ add_attribute(i.first, i.second);
+ }
void encode_into(class DER_Encoder&) const override;
void decode_from(class BER_Decoder&) override;
- const std::multimap<OID, ASN1_String>& dn_info() const { return m_dn_info; }
-
bool has_field(const OID& oid) const;
ASN1_String get_first_attribute(const OID& oid) const;
@@ -40,17 +49,24 @@ class BOTAN_PUBLIC_API(2,0) X509_DN final : public ASN1_Object
*/
const std::vector<uint8_t>& get_bits() const { return m_dn_bits; }
- bool empty() const { return m_dn_info.empty(); }
+ bool empty() const { return m_rdn.empty(); }
- bool has_field(const std::string& attr) const;
- std::vector<std::string> get_attribute(const std::string& attr) const;
- std::string get_first_attribute(const std::string& attr) const;
+ const std::vector<std::pair<OID,ASN1_String>>& dn_info() const { return m_rdn; }
std::multimap<OID, std::string> get_attributes() const;
std::multimap<std::string, std::string> contents() const;
+ bool has_field(const std::string& attr) const;
+ std::vector<std::string> get_attribute(const std::string& attr) const;
+ std::string get_first_attribute(const std::string& attr) const;
+
void add_attribute(const std::string& key, const std::string& val);
- void add_attribute(const OID& oid, const std::string& val);
+
+ void add_attribute(const OID& oid, const std::string& val)
+ {
+ add_attribute(oid, ASN1_String(val));
+ }
+
void add_attribute(const OID& oid, const ASN1_String& val);
static std::string deref_info_field(const std::string& key);
@@ -65,7 +81,7 @@ class BOTAN_PUBLIC_API(2,0) X509_DN final : public ASN1_Object
static size_t lookup_ub(const OID& oid);
private:
- std::multimap<OID, ASN1_String> m_dn_info;
+ std::vector<std::pair<OID,ASN1_String>> m_rdn;
std::vector<uint8_t> m_dn_bits;
};
diff --git a/src/lib/x509/x509path.cpp b/src/lib/x509/x509path.cpp
index f703bf028..e73fe12b6 100644
--- a/src/lib/x509/x509path.cpp
+++ b/src/lib/x509/x509path.cpp
@@ -92,7 +92,8 @@ PKIX::check_chain(const std::vector<std::shared_ptr<const X509_Certificate>>& ce
}
// Check the subject's DN components' length
- for(const auto& dn_pair : subject->subject_dn().get_attributes())
+
+ for(const auto& dn_pair : subject->subject_dn().dn_info())
{
const size_t dn_ub = X509_DN::lookup_ub(dn_pair.first);
// dn_pair = <OID,str>