-
Notifications
You must be signed in to change notification settings - Fork 5.5k
ssl: support wildcard matching for verify_subject_alt_name #1298
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
Changes from 4 commits
3ed769d
bef14f1
e4b97c7
ad7d440
c878f8b
9347913
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -209,7 +209,7 @@ bool ContextImpl::verifySubjectAltName(X509* cert, | |
| ASN1_STRING* str = altname->d.uniformResourceIdentifier; | ||
| char* crt_san = reinterpret_cast<char*>(ASN1_STRING_data(str)); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It just occurred to me that there is and then we could compare strings only if Sorry for not catching this yesterday!
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll fix this along with the problem mentioned below.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. a side question though, if we use
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that is correct. Optimally, You would just pass char* and length to the function, then still use strncmp (or compare if you can). At this point though let's just get something working that everyone agrees with. :)
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cool, I'll stick to the current way then
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ...it is. Feel free to ignore this. Alternatively, you could use
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. right. I'll pass |
||
| for (auto& config_san : subject_alt_names) { | ||
| if (config_san.compare(crt_san) == 0) { | ||
| if (uriMatch(config_san, crt_san)) { | ||
| verified = true; | ||
| break; | ||
| } | ||
|
|
@@ -223,6 +223,15 @@ bool ContextImpl::verifySubjectAltName(X509* cert, | |
| return verified; | ||
| } | ||
|
|
||
| bool ContextImpl::uriMatch(const std::string& uriPattern, const char* uri) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This whole function is low-level C instead of C++11. Please consider using
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes that would be much better. :)
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm confused but
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should use Previously, you were using
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. got it. Since my original
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: Maybe move this function after dNSNameMatch, to be consistent with the order in the .h file. |
||
| size_t pattern_len = uriPattern.length(); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: |
||
| if (pattern_len > 1 && uriPattern.substr(pattern_len - 2) == "/*") { | ||
| return strncmp(uriPattern.c_str(), uri, pattern_len - 1) == 0 && uri[pattern_len - 1]; | ||
| } | ||
|
|
||
| return uriPattern == uri; | ||
| } | ||
|
|
||
| bool ContextImpl::dNSNameMatch(const std::string& dNSName, const char* pattern) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry to bring this up ... I feel like how this function is called (line 203 in context_impl.cc) is not right. It should be: It makes sense to me that we support wildcard in config, not in certificates. Unfortunately I didn't notice this when I modified this function. This was unnoticed because we don't have integration tests, nor did we tell users this wildcard is supported.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @myidpt yes that make sense to me. Can we fix?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @myidpt @mattklein123 I can fix this and update the doc. So the SAN field, whether it's URI or DNS, should never contain a wildcard; and we allow configs to optionally use wildcard to match multiple SAN values.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you very much. Please also make sure the function signature (parameter naming&order) aligns with the uriMatch function :) |
||
| if (dNSName == pattern) { | ||
| return true; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,6 +30,21 @@ TEST_F(SslContextImplTest, TestdNSNameMatching) { | |
| EXPECT_FALSE(ContextImpl::dNSNameMatch("lyft.com", "")); | ||
| } | ||
|
|
||
| TEST_F(SslContextImplTest, TestURIMatch) { | ||
| EXPECT_TRUE(ContextImpl::uriMatch("spiffe://lyft.com/foo", "spiffe://lyft.com/foo")); | ||
| EXPECT_TRUE(ContextImpl::uriMatch("spiffe://lyft.com/*", "spiffe://lyft.com/foo")); | ||
| EXPECT_TRUE(ContextImpl::uriMatch("spiffe://lyft.com/foo/*", "spiffe://lyft.com/foo/bar")); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you also add test for:
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. will add |
||
| EXPECT_TRUE(ContextImpl::uriMatch("spiffe://lyft.com/*", "spiffe://lyft.com/foo/bar")); | ||
| EXPECT_FALSE(ContextImpl::uriMatch("spiffe://lyft.com/*", "spiffe://lyft.com/")); | ||
| EXPECT_FALSE(ContextImpl::uriMatch("spiffe://lyft.com/foo", "spiffe://lyft.com/foo/bar")); | ||
| EXPECT_FALSE(ContextImpl::uriMatch("spiffe://lyft.com/*", "")); | ||
| EXPECT_FALSE(ContextImpl::uriMatch("spiffe://lyft.com/*", "spiffe://lyft.net/foo")); | ||
| EXPECT_FALSE(ContextImpl::uriMatch("spiffe://lyft.com*", "spiffe://lyft.com/foo")); | ||
| EXPECT_FALSE(ContextImpl::uriMatch("spiffe://lyft.com/*", "spiffe://lyft.comfoo")); | ||
| EXPECT_FALSE(ContextImpl::uriMatch("*", "foo")); | ||
| EXPECT_FALSE(ContextImpl::uriMatch("f", "foo")); | ||
| } | ||
|
|
||
| TEST_F(SslContextImplTest, TestVerifySubjectAltNameDNSMatched) { | ||
| FILE* fp = fopen( | ||
| TestEnvironment::runfilesPath("test/common/ssl/test_data/san_dns_cert.pem").c_str(), "r"); | ||
|
|
@@ -52,6 +67,11 @@ TEST_F(SslContextImplTest, TestVerifySubjectAltNameURIMatched) { | |
| std::vector<std::string> verify_subject_alt_name_list = {"spiffe://lyft.com/fake-team", | ||
| "spiffe://lyft.com/test-team"}; | ||
| EXPECT_TRUE(ContextImpl::verifySubjectAltName(cert, verify_subject_alt_name_list)); | ||
|
|
||
| verify_subject_alt_name_list.clear(); | ||
| verify_subject_alt_name_list.push_back("spiffe://lyft.com/*"); | ||
| EXPECT_TRUE(ContextImpl::verifySubjectAltName(cert, verify_subject_alt_name_list)); | ||
|
|
||
| X509_free(cert); | ||
| fclose(fp); | ||
| } | ||
|
|
||
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.
Could you make it clear that this wildcard support is only for URI type SAN. And also for DNS type SAN, there's a wildcard support for "*.foo.com" style?