-
Notifications
You must be signed in to change notification settings - Fork 512
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
Support wildcard CNs in root leaf certificates #1088
Conversation
b481fb3
to
fb428da
Compare
// MatchCNToGun checks that the common name in a cert is valid for the given gun. | ||
// This allows wildcards as suffixes, e.g. `namespace/*` | ||
func MatchCNToGun(commonName, gun string) bool { | ||
wildcard := "*" |
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.
should this be a const?
fb428da
to
00a7cba
Compare
Glad you avoided One thought, should we require the |
// MatchCNToGun checks that the common name in a cert is valid for the given gun. | ||
// This allows wildcards as suffixes, e.g. `namespace/*` | ||
func MatchCNToGun(commonName, gun string) bool { | ||
const wildcard = "*" |
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 figured a const at probably package scope :-P This works too as far as giving us immutability though.
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.
figured the go compiler would do what I wanted here, didn't really verify though
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.
It probably will as far as optimization, I was thinking more along code organization.
Personally I think that's a little too restrictive; I was considering an organization using a wildcard cert for a subset of their packages, e.g. |
{"test/*/wild", "test/test/wild", false}, | ||
{"*/all", "test/all", false}, | ||
{"docker.com/*/*", "docker.com/notary/test", false}, | ||
{"*", "docker.com/any", 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.
can we add the following test cases:
CN: ""
, gun: *
, out: false
CN: *
, gun: ""
, out: true
CN: *abc*
, gun: "abc"
, out: false
(since we check against *abc
, no longer wildcarded)
CN: test/*/wild*
, gun: "test/test/wild"
, out: false
(since we check against test/*/wild
, no longer wildcarded)
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.
Out of curiosity, if the common name is **
, should we treat that as *
? If not, can we also add one more test?
CN: **
, gun: "docker.com/any"
, out: false
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.
Non-blocking: Since we're not actually checking any trust pinning here, do we need a CA+intermediate+leaf for this test? Might make the test a little shorter to just include the leaf.
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.
@cyli: good idea - I like treating **
as *
for now to keep things simple so that test would be great 👍
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 went ahead and switched TrimSuffix
to TrimRight
so that any number of trailing *
s will collapse down to 1.
func MatchCNToGun(commonName, gun string) bool { | ||
const wildcard = "*" | ||
if strings.HasSuffix(commonName, wildcard) { | ||
prefix := commonName[:len(commonName)-len(wildcard)] |
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.
nit style: I'd prefer using strings.TrimSuffix
instead of indexing directly
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.
Also, could we add a log debug to display which prefix we're comparing against?
My concern is if folks use something like prefix**
and expect matching against prefix
instead of prefix*
00a7cba
to
70d3da2
Compare
@@ -1299,3 +1299,193 @@ func TestValidateRootWithExpiredIntermediate(t *testing.T) { | |||
) | |||
require.Error(t, err, "failed to invalidate expired intermediate certificate") | |||
} | |||
|
|||
func TestCheckingWilcardCert(t *testing.T) { |
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.
nit: "TestCheckingWildcartCert"
d474056
to
764e056
Compare
Signed-off-by: Evan Cordell <cordell.evan@gmail.com>
764e056
to
dfa8a5b
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.
LGTM, thank you for picking this up @ecordell!
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.
LGTM! Thanks for adding this support, @ecordell!
How do I enable this feature? Today the root public key in the root.json file is a self-signed cert with CN == GUN. How do I use this such that the CN is a wildcard such as www.example.com/* ? |
@endophage - we are making the changes (actually already done, just testing now) as well as some others that you and I discussed. You should see a pull request in the next few days. Once this is in place, we are planning to work on CA pinning, and then moving trust pinning into DCT. Once that's all finished, we can work on getting generalizing the pkcs11 interface to support HSMs other than Yubikey :-) |
This adds support for explicit wildcard suffixes in root (leaf) certificates of the form
prefix*
.I considered doing something more flexible using
filepath.Match
but I think this more conservative form is safer and (probably) just as useful. It would be easy to change in the future if more flexibility (e.g.docker.io/*/test
) is needed.Note the wildcard
*
indicator is required to avoid accidentally using wildcard certs (e.g.docker.io/test
anddocker.io/test2
).Fixes #883
Possibly addresses #914 as well?