Using self-signed X.509 certificates for signed commits

Using self-signed X.509 certificates for signed commits

GitLab supports the use of signed commits using X.509 certificates. This tutorial creates a commit with a self signed X.509 certificate which is verified by the GDK. When complete the commit is displayed as verified on the commits page:

Verified Commit

To set up self-signed X.509 certificates for signed commits in GDK follow the steps below. The commands can be run from any empty directory in the MacOS home folder unless otherwise specified.

  1. Create a CA certificate
  2. Create an end-entity certificate
  3. Import keys into gpgsm and add to trustlist
  4. Set up GDK to use the CA certificate you generated
  5. Set up a project
  6. Cleaning up

Create a CA certificate

  1. Generate a 4069 bit CA certificate key file:

    openssl genrsa -out ca.key 4096
  2. Generate the CA certificate:

    openssl req \  -new \  -x509 \  -subj "/C=US/ST=California/L=San Francisco/O=GitLab/OU=dev/CN=gdk.test/emailAddress=root@gdk.test" \  -days 3650 \  -key ca.key \  -out ca.crt

Create an end-entity certificate

  1. Generate a 4096 bit Git key file:

    openssl genrsa -out git.key 4096
  2. Generate the end-entity certificate:

    openssl req \  -new \  -subj "/C=US/ST=California/L=San Francisco/O=GitLab/OU=dev/CN=gdk.test/emailAddress=root@gdk.test" \  -key git.key \  -out git.csr
  3. Add more fields to the certificate:

    openssl x509 -req -days 3650 -in git.csr -CA ca.crt -CAkey ca.key -extfile <(  echo "subjectAltName = DNS:gitlab.test,email:test@example.com,email:test2@example.com"; \  echo "keyUsage = critical,digitalSignature"  echo "subjectKeyIdentifier = hash"  echo "authorityKeyIdentifier = keyid"  echo "crlDistributionPoints=DNS:gitlab.test,URI:http://example.com/crl.pem" ) -set_serial 1 -out git.crt

Import keys into gpgsm and add to trustlist

  1. Export your Git key:

    openssl pkcs12 -export -inkey git.key -in git.crt -name test -out git.p12
  2. Export your CA key:

    openssl pkcs12 -export -inkey ca.key -in ca.crt -name test2 -out ca.p12
  3. Import your CA key into gpgsm:

    gpgsm --import ca.p12
  4. Import your Git key into gpgsm:

    gpgsm --import git.p12
  5. Add the SHA1 fingerprint for the last two keys in gpgsm --list-keys to ~/.gnupg/trustlist.txt:

    gpgsm --list-keys | grep 'sha1 fpr' | awk -F 'sha1 fpr: ' '{ print $2 " S relax" }' >> ~/.gnupg/trustlist.txt
  6. Suppress DirMngr checking for revoked certificates:

    echo "disable-crl-checks" >> ~/.gnupg/gpgsm.conf

Set up GDK to use the CA certificate you generated

  1. In the GDK root directory:

    echo "export SSL_CERT_FILE=<path-to-ca.crt>" >> env.runit
  2. Restart the GDK:

    gdk restart
  3. In a Rails console:

    Feature.enable(:x509_forced_cert_loading)

Set up a project

  1. Create a user with email test2@example.com.

  2. Create a project.

  3. Clone the project.

  4. Configure the Git client to sign commits:

    git config user.email test2@example.com git config user.signingkey $(gpgsm --list-keys | grep 'ID: ' | tail -n1 | awk -F': ' '{ print $2 }') git config gpg.program gpgsm git config gpg.format x509
  5. Restart gpg-agent:

    gpgconf --kill gpg-agent
  6. Make some changes and commit with signature:

    echo test > test && git add test && git commit -m "test" -S
  7. Push the changes.

  8. Look at the commits you just pushed in the GitLab UI (for example, http://gdk.test:3000/root/test-signatures/-/commits/<branch_name>). There should be a Verified badge next to the signed commit.

Cleaning up

Some of these configurations should be removed once testing is complete.

  1. Remove added keys from gpgsm:
    1. Run gpgsm --list-keys and find the last two key IDs.
    2. Delete each of them by running gpgsm --delete-keys <key ID>.
  2. Remove the two SHA1 fingerprint keys you added to ~/.gnupg/trustlist.txt.
  3. Remove ignoring the certificate revocation list (CRL) setting from gpgsm.conf:
    1. Delete disable-crl-checks from ~/.gnupg/gpgsm.conf.
  4. Remove SSL certificate file from GDK:
    1. Delete export SSL_CERT_FILE=path to ca.crt from env.runit.
    2. Restart the GDK: gdk restart.
Last updated on