S/MIME X509 verification of commits
## Problem to solve
<!-- What problem do we solve? -->
Signing Git commits using Public Key Infrastructure (PKI) using a public certificate authority or a corporate CA may be more convenient that GnuPG in enterprise environments. GitLab should implement support.
## Intended users
<!-- Who will use this feature? If known, include any of the following: types of users (e.g. Developer), personas, or specific company roles (e.g. Release Manager). It's okay to write "Unknown" and fill this field in later.
Personas can be found at https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/ -->
Developers, end consumers.
## Further details
<!-- Include use cases, benefits, and/or goals (contributes to our vision?) -->
At the moment on GitHub I am using X509 signing verification. This was introduced in GIT 2.19 as a option.
I would envision it be similar to the GPG verification, where user will tell GIT about their signing key and use a SMime client such as https://github.com/glennawatson/GitSMimeSign
```bash
git config --global gpg.x509.program gitsmimesign
git config --global gpg.format x509
```
The client will then based on an X509 certificate store sign the commit.
Then in the same UI you use for GPG verification, you would check the commit against a CA (such as the mozilla one which I believe GitHub do) and then show the Subject and Issuer subject of the certificate.
At the moment when I import projects over from GitHub they aren't showing my verified commits due to a lot of them being X509 S/Mime signed.
## Proposal
<!-- How are we going to solve the problem? Try to include the user journey! https://about.gitlab.com/handbook/journeys/#user-journey -->
I would use something like this
```ruby
require 'optparse'
require 'openssl'
include OpenSSL
options = ARGV.getopts("c:k:C:")
ca_path = options["C"]
data = $stdin.read
store = X509::Store.new
store.add_path(ca_path)
p7sig = PKCS7::read_smime(data)
if p7sig.verify([], store)
puts p7sig.data
end
```
This would read in the Mozilla CA and then verify the signature.
I mostly got the above sample from the OpenSSL ruby examples.
The verification tab would contain "Verified" with similar text as below, or "Unverified" if the signing details could not be verified against the certificate store.
The sample text would be:
```
This commit was signed with a verified signature.
username
FirstName
Certificate subject
CN Certificate Name
emailAddress user@email.address.com
Certificate issuer
CN GlobalSign PersonalSign 2 CA - SHA256 - G3
O GlobalSign nv-sa
```
## Permissions and Security
<!-- What permissions are required to perform the described actions? Are they consistent with the existing permissions as documented for users, groups, and projects as appropriate? Is the proposed behavior consistent between the UI, API, and other access methods (e.g. email replies)? -->
It would be consistent with the GPG existing permissions, it would read in the header details from GIT and run a verify against it.
## Documentation
<!-- See the Feature Change Documentation Workflow https://docs.gitlab.com/ee/development/documentation/feature-change-workflow.html
Add all known Documentation Requirements here, per https://docs.gitlab.com/ee/development/documentation/feature-change-workflow.html#documentation-requirements -->
You would need to add documentation similar to what GitHub has in regards to how to run a git smime signer/verify utility.
An example of their documentation is at https://help.github.com/en/enterprise/2.16/user/articles/telling-git-about-your-signing-key#telling-git-about-your-x509-key-1
## Testing
<!-- What risks does this change pose? How might it affect the quality of the product? What additional test coverage or changes to tests will be needed? Will it require cross-browser testing? See the test engineering process for further guidelines: https://about.gitlab.com/handbook/engineering/quality/guidelines/test-engineering/ -->
Potential extra performance hit. Time factor for verification.
## What does success look like, and how can we measure that?
<!-- Define both the success metrics and acceptance criteria. Note that success metrics indicate the desired business outcomes, while acceptance criteria indicate when the solution is working correctly. If there is no way to measure success, link to an issue that will implement a way to measure this. -->
## Links / references
issue