Commit 1c82e9a4 authored by Russell Dickenson's avatar Russell Dickenson

Merge branch 'aqualls-x509-page-cleanup' into 'master'

Review X509 page for CTRT purposes

See merge request gitlab-org/gitlab!68792
parents 99e2f850 85e5d905
...@@ -5,78 +5,82 @@ info: "To determine the technical writer assigned to the Stage/Group associated ...@@ -5,78 +5,82 @@ info: "To determine the technical writer assigned to the Stage/Group associated
type: concepts, howto type: concepts, howto
--- ---
# Signing commits and tags with X.509 **(FREE)** # Sign commits and tags with X.509 certificates **(FREE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/17773) in GitLab 12.8. > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/17773) in GitLab 12.8.
[X.509](https://en.wikipedia.org/wiki/X.509) is a standard format for public key [X.509](https://en.wikipedia.org/wiki/X.509) is a standard format for public key
certificates issued by a public or private Public Key Infrastructure (PKI). certificates issued by a public or private Public Key Infrastructure (PKI).
Personal X.509 certificates are used for authentication or signing purposes Personal X.509 certificates are used for authentication or signing purposes
such as SMIME, but Git also supports signing of commits and tags such as S/MIME (Secure/Multipurpose Internet Mail Extensions).
with X.509 certificates in a similar way as with [GPG](../gpg_signed_commits/index.md). However, Git also supports signing of commits and tags with X.509 certificates in a
The main difference is the trust anchor which is the PKI for X.509 certificates similar way as with [GPG (GnuPG, or GNU Privacy Guard)](../gpg_signed_commits/index.md).
instead of a web of trust with GPG. The main difference is the way GitLab determines whether or not the developer's signature is trusted:
## How GitLab handles X.509 - For X.509, a root certificate authority is added to the GitLab trust store.
(A trust store is a repository of trusted security certificates.) Combined with
GitLab uses its own certificate store and therefore defines the trust chain. any required intermediate certificates in the signature, the developer's certificate
can be chained back to a trusted root certificate.
- For GPG, developers [add their GPG key](../gpg_signed_commits/index.md#adding-a-gpg-key-to-your-account)
to their account.
GitLab uses its own certificate store and therefore defines the
[trust chain](https://www.ssl.com/faqs/what-is-a-chain-of-trust/).
For a commit or tag to be *verified* by GitLab: For a commit or tag to be *verified* by GitLab:
- The signing certificate email must match a verified email address in GitLab. - The signing certificate email must match a verified email address in GitLab.
- The GitLab instance must be able to establish a full trust chain from the certificate - The GitLab instance must be able to establish a full [trust chain](https://www.ssl.com/faqs/what-is-a-chain-of-trust/)
in the signature to a trusted certificate in the GitLab certificate store. This chain from the certificate in the signature to a trusted certificate in the GitLab certificate store.
may include intermediate certificates supplied in the signature. Additional This chain may include intermediate certificates supplied in the signature. You may
certificates, such as the Certificate Authority root, need to add certificates, such as Certificate Authority root certificates,
[may need to be added to the GitLab certificate store](https://docs.gitlab.com/omnibus/settings/ssl.html#install-custom-public-certificates). [to the GitLab certificate store](https://docs.gitlab.com/omnibus/settings/ssl.html#install-custom-public-certificates).
- The signing time has to be within the time range of the [certificate validity](https://www.rfc-editor.org/rfc/rfc5280.html#section-4.1.2.5) - The signing time must be in the time range of the
[certificate validity](https://www.rfc-editor.org/rfc/rfc5280.html#section-4.1.2.5),
which is usually up to three years. which is usually up to three years.
- The signing time is equal or later than commit time. - The signing time is equal to, or later than, the commit time.
- If the status of a commit has already been determined and stored in the database,
[use the Rake task to re-check the status](../../../../raketasks/x509_signatures.md).
[Read more about this and detailed troubleshooting steps](#troubleshooting).
NOTE: If a commit's status has already been determined and stored in the database,
Certificate revocation lists are checked on a daily basis via background worker. use the Rake task [to re-check the status](../../../../raketasks/x509_signatures.md).
Refer to the [Troubleshooting section](#troubleshooting).
NOTE: GitLab checks certificate revocation lists on a daily basis with a background worker.
Self signed certificates without `authorityKeyIdentifier`,
`subjectKeyIdentifier`, and `crlDistributionPoints` are not supported. We
recommend using certificates from a PKI that are in line with
[RFC 5280](https://tools.ietf.org/html/rfc5280).
## Limitations ## Limitations
- Self-signed certificates without `authorityKeyIdentifier`,
`subjectKeyIdentifier`, and `crlDistributionPoints` are not supported. We
recommend using certificates from a PKI that are in line with
[RFC 5280](https://tools.ietf.org/html/rfc5280).
- If you have more than one email in the Subject Alternative Name list in - If you have more than one email in the Subject Alternative Name list in
your signing certificate, your signing certificate,
[only the first one is used to verify commits](https://gitlab.com/gitlab-org/gitlab/-/issues/336677). [only the first one is used to verify commits](https://gitlab.com/gitlab-org/gitlab/-/issues/336677).
- The `X509v3 Subject Key Identifier` (SKI) in the issuer certificate and the - The `X509v3 Subject Key Identifier` (SKI) in the issuer certificate and the
signing certificate signing certificate
[must be 40 characters long](https://gitlab.com/gitlab-org/gitlab/-/issues/332503). [must be 40 characters long](https://gitlab.com/gitlab-org/gitlab/-/issues/332503).
If your SKI is shorter, commits will not show as verified in GitLab, and If your SKI is shorter, commits don't show as verified in GitLab, and
short subject key identifiers may also short subject key identifiers may also
[cause errors when accessing the project](https://gitlab.com/gitlab-org/gitlab/-/issues/332464), [cause errors when accessing the project](https://gitlab.com/gitlab-org/gitlab/-/issues/332464),
such as 'An error occurred while loading commit signatures' and such as 'An error occurred while loading commit signatures' and
`HTTP 422 Unprocessable Entity` errors. `HTTP 422 Unprocessable Entity` errors.
## Obtaining an X.509 key pair ## Configure for signed commits
If your organization has Public Key Infrastructure (PKI), that PKI provides To sign your commits, tags, or both, you must:
an S/MIME key.
If you do not have an S/MIME key pair from a PKI, you can either create your 1. [Obtain an X.509 key pair](#obtain-an-x509-key-pair).
own self-signed one, or purchase one. MozillaZine keeps a nice collection 1. [Associate your X.509 certificate with Git](#associate-your-x509-certificate-with-git).
of [S/MIME-capable signing authorities](http://kb.mozillazine.org/Getting_an_SMIME_certificate) 1. [Sign and verify commits](#sign-and-verify-commits).
and some of them generate keys for free. 1. [Sign and verify tags](#sign-and-verify-tags).
## Associating your X.509 certificate with Git ### Obtain an X.509 key pair
To take advantage of X.509 signing, you need Git 2.19.0 or later. You can If your organization has Public Key Infrastructure (PKI), that PKI provides
check your Git version with: an S/MIME key. If you do not have an S/MIME key pair from a PKI, you can either
create your own self-signed pair, or purchase a pair.
```shell ### Associate your X.509 certificate with Git
git --version
``` To take advantage of X.509 signing, you need Git 2.19.0 or later. You can
check your Git version with the command `git --version`.
If you have the correct version, you can proceed to configure Git. If you have the correct version, you can proceed to configure Git.
...@@ -90,74 +94,73 @@ git config --global user.signingkey $signingkey ...@@ -90,74 +94,73 @@ git config --global user.signingkey $signingkey
git config --global gpg.format x509 git config --global gpg.format x509
``` ```
### Windows and MacOS #### Windows and macOS
Install [S/MIME Sign](https://github.com/github/smimesign) by downloading the To configure Windows or macOS:
installer or via `brew install smimesign` on MacOS.
Get the ID of your certificate with `smimesign --list-keys` and set your 1. Install [S/MIME Sign](https://github.com/github/smimesign) by either:
signing key `git config --global user.signingkey ID`, then configure X.509: - Downloading the installer.
- Running `brew install smimesign` on macOS.
1. Get the ID of your certificate by running `smimesign --list-keys`.
1. Set your signing key by running `git config --global user.signingkey ID`.
1. Configure X.509 with this command:
```shell ```shell
git config --global gpg.x509.program smimesign git config --global gpg.x509.program smimesign
git config --global gpg.format x509 git config --global gpg.format x509
``` ```
## Signing commits ### Sign and verify commits
After you have [associated your X.509 certificate with Git](#associating-your-x509-certificate-with-git) you After you have [associated your X.509 certificate with Git](#associate-your-x509-certificate-with-git) you
can start signing your commits: can sign your commits:
1. Commit like you used to, the only difference is the addition of the `-S` flag: 1. When you create a Git commit, add the `-S` flag:
```shell ```shell
git commit -S -m "feat: x509 signed commits" git commit -S -m "feat: x509 signed commits"
``` ```
1. Push to GitLab and check that your commits [are verified](#verifying-commits). 1. Push to GitLab, and check that your commits are verified with the `--show-signature` flag:
If you don't want to type the `-S` flag every time you commit, you can tell Git
to sign your commits automatically:
```shell
git config --global commit.gpgsign true
```
## Verifying commits ```shell
git log --show-signature
```
To verify that a commit is signed, you can use the `--show-signature` flag: 1. *If you don't want to type the `-S` flag every time you commit,* run this command
for Git to sign your commits every time:
```shell ```shell
git log --show-signature git config --global commit.gpgsign true
``` ```
## Signing tags ### Sign and verify tags
After you have [associated your X.509 certificate with Git](#associating-your-x509-certificate-with-git) you After you have [associated your X.509 certificate with Git](#associate-your-x509-certificate-with-git) you
can start signing your tags: can start signing your tags:
1. Tag like you used to, the only difference is the addition of the `-s` flag: 1. When you create a Git tag, add the `-s` flag:
```shell ```shell
git tag -s v1.1.1 -m "My signed tag" git tag -s v1.1.1 -m "My signed tag"
``` ```
1. Push to GitLab and check that your tags [are verified](#verifying-tags). 1. Push to GitLab and verify your tags are signed with this command:
If you don't want to type the `-s` flag every time you tag, you can tell Git ```shell
to sign your tags automatically: git tag --verify v1.1.1
```
```shell 1. *If you don't want to type the `-s` flag every time you tag,* run this command
git config --global tag.gpgsign true for Git to sign your tags each time:
```
## Verifying tags ```shell
git config --global tag.gpgsign true
```
To verify that a tag is signed, you can use the `--verify` flag: ## Resources
```shell - [Rake task for X.509 signatures](../../../../raketasks/x509_signatures.md)
git tag --verify v1.1.1
```
## Troubleshooting ## Troubleshooting
...@@ -175,13 +178,13 @@ sudo gitlab-rake gitlab:x509:update_signatures ...@@ -175,13 +178,13 @@ sudo gitlab-rake gitlab:x509:update_signatures
### Main verification checks ### Main verification checks
The code performs The code performs
[six key checks](https://gitlab.com/gitlab-org/gitlab/-/blob/v14.1.0-ee/lib/gitlab/x509/signature.rb#L33), [these key checks](https://gitlab.com/gitlab-org/gitlab/-/blob/v14.1.0-ee/lib/gitlab/x509/signature.rb#L33),
which all must return `verified`: which all must return `verified`:
- `x509_certificate.nil?` should be false. - `x509_certificate.nil?` should be false.
- `x509_certificate.revoked?` should be false. - `x509_certificate.revoked?` should be false.
- `verified_signature` should be true. - `verified_signature` should be true.
- `user.nil?`should be false. - `user.nil?` should be false.
- `user.verified_emails.include?(@email)` should be true. - `user.verified_emails.include?(@email)` should be true.
- `certificate_email == @email` should be true. - `certificate_email == @email` should be true.
...@@ -254,7 +257,7 @@ To investigate why a commit shows as `Unverified`: ...@@ -254,7 +257,7 @@ To investigate why a commit shows as `Unverified`:
``` ```
If the developer's email address is not the first one in the list, this check If the developer's email address is not the first one in the list, this check
will not work, and the commit will be `unverified`. fails, and the commit is marked `unverified`.
1. The email address on the commit must be associated with an account in GitLab. 1. The email address on the commit must be associated with an account in GitLab.
This check should return `false`: This check should return `false`:
...@@ -346,8 +349,12 @@ step of the previous [main verification checks](#main-verification-checks). ...@@ -346,8 +349,12 @@ step of the previous [main verification checks](#main-verification-checks).
Ensure any additional intermediate certificate(s) and the root certificate are added Ensure any additional intermediate certificate(s) and the root certificate are added
to the certificate store. For consistency with how certificate chains are built on to the certificate store. For consistency with how certificate chains are built on
web servers, Git clients that are signing commits should include the certificate web servers:
and all intermediate certificates in the signature, and the GitLab certificate
store should only contain the root. If you remove a root certificate from the GitLab - Git clients that are signing commits should include the certificate
and all intermediate certificates in the signature.
- The GitLab certificate store should only contain the root.
If you remove a root certificate from the GitLab
trust store, such as when it expires, commit signatures which chain back to that trust store, such as when it expires, commit signatures which chain back to that
root display as `unverified`. root display as `unverified`.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment