-
Notifications
You must be signed in to change notification settings - Fork 574
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Optimize name constraint matching #4047
Conversation
43a4c83
to
0b70811
Compare
a6ad2c2
to
deae034
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like your optimizations :)
src/lib/x509/name_constraint.cpp
Outdated
m_excluded_contains_unknown = false; | ||
for(const auto& c : m_permitted_subtrees) { | ||
if(c.base().is_unknown_type()) { | ||
m_excluded_contains_unknown = true; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
m_excluded_contains_unknown = false; | |
for(const auto& c : m_permitted_subtrees) { | |
if(c.base().is_unknown_type()) { | |
m_excluded_contains_unknown = true; | |
} | |
} | |
m_excluded_contains_unknown = false; | |
for(const auto& c : m_excluded_subtrees) { | |
if(c.base().is_unknown_type()) { | |
m_excluded_contains_unknown = true; | |
} | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😭
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed using a lambda
m_permitted_contains_unknown = contains_unknown(m_permitted_subtrees);
m_excluded_contains_unknown = contains_unknown(m_excluded_subtrees);
Previously name constraints flattened everything to a std::string and then parsed it back to the desired form during matching. This is slow. It also bounced through a std::function for each match, which has a surprisingly high overhead. This commit also removes some sketchy (untested, unused within library, unclear purpose) string constructors for GeneralName and GeneralSubtree. Technically a SemVer break but I'm pretty sure nobody uses these.
DNS is case insensitive and forcing the DNS name to lowercase means we don't have to tolower while comparing name constraints.
If we match on an excluded tree there is no reason to continue checking the remainder of the constraints.
f5d098f
to
6700358
Compare
If so we can immediately fail if the extension is critical. Also this allows returning early from is_permitted since we don't have to handle the case of looking for critical+unknown permitted subtrees, which otherwise would force us to scan (and match against) the entire list of permitted trees.
With the help of string_view we don't need to create any copies.
RFC 5280 states that minimum must be zero and maximum must be unset, so keeping the fixed values in memory isn't that helpful.
Previously name constraint matching worked by smashing all of the constraints and names into
std::string
, then parsing the values back out of the strings for each match attempt. This is all quite slow and needless. Instead store the names in their best form for matching in astd::variant
.