x509 / TLS signed commits: only the first email address in the subjectAltName list is used for verifying commits
Summary
Support is assisting a customer with x509 / TLS signed commits (GitLab team members can read more in the ticket)
While investigating the code, I noticed that certificate_email
does this:
175 get_certificate_extension('subjectAltName').split(',').each do |item|
176 if item.strip.start_with?("email")
177 email = item.split('email:')[1]
178 break
179 end
180 end
181
182 return if email.nil?
183
184 email
-
175
:subjectAltName
is a comma separated list that can contain zero, one, or 'n' entries of potentially multiple types, and the list is processed as a loop -
176
: as it loops over the list, entries which are not prefixedemail
are skipped -
177
: entries prefixedemail:
have that string stripped off -
178
: I understand thebreak
terminates.each do |item|
when anemail
is found, which would the first one in the list.
The problem is, I would anticipate that certificates can have multiple email addresses in them. I think this code should return them all (ie: a list/array) and then consumers of certificate_email
(example: if user.verified_emails.include?(@email) && certificate_email == @email
) should expect to be verifying if a given string (@email
) is in a list certificate_email
.
Companies with multiple top level domains for different brands may assign email addresses to staff across all domains, and staff might use any of them. Or, as a result if mergers and acquisitions, staff might be using the old company's email address plus an email address issued by the acquiring company.
I've looked through RFC5280 and can see no restriction around how many SANs of a particular flavour can appear in the list, including email
. The language sometimes uses singular and plural forms, but it does it for types which definitely appear 'n' times in certificates.
Example: gitlab.com
has multiple DNS:
entries.
X509v3 Subject Alternative Name:
DNS:gitlab.com, DNS:auth.gitlab.com, DNS:customers.gitlab.com, DNS:email.customers.gitlab.com, DNS:gprd.gitlab.com, DNS:www.gitlab.com
Steps to reproduce
Example Project
What is the current bug behavior?
Verification is going to fail just because a user isn't signing commits with the first email address in the X509v3 Subject Alternative Name
list.
What is the expected correct behavior?
All email addresses in the X509v3 Subject Alternative Name
are valid for that certificate and GitLab should support commits signed with any of them.
Relevant logs and/or screenshots
Output of checks
Results of GitLab environment info
Expand for output related to GitLab environment info
(For installations with omnibus-gitlab package run and paste the output of: `sudo gitlab-rake gitlab:env:info`) (For installations from source run and paste the output of: `sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production`)
Results of GitLab application Check
Expand for output related to the GitLab application check
(For installations with omnibus-gitlab package run and paste the output of:
sudo gitlab-rake gitlab:check SANITIZE=true
)(For installations from source run and paste the output of:
sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production SANITIZE=true
)(we will only investigate if the tests are passing)