GpgSigner.java

  1. /*
  2.  * Copyright (C) 2018, 2022 Salesforce and others
  3.  *
  4.  * This program and the accompanying materials are made available under the
  5.  * terms of the Eclipse Distribution License v. 1.0 which is available at
  6.  * https://www.eclipse.org/org/documents/edl-v10.php.
  7.  *
  8.  * SPDX-License-Identifier: BSD-3-Clause
  9.  */
  10. package org.eclipse.jgit.lib;

  11. import java.util.Iterator;
  12. import java.util.ServiceConfigurationError;
  13. import java.util.ServiceLoader;

  14. import org.eclipse.jgit.annotations.NonNull;
  15. import org.eclipse.jgit.annotations.Nullable;
  16. import org.eclipse.jgit.api.errors.CanceledException;
  17. import org.eclipse.jgit.transport.CredentialsProvider;
  18. import org.slf4j.Logger;
  19. import org.slf4j.LoggerFactory;

  20. /**
  21.  * Creates GPG signatures for Git objects.
  22.  *
  23.  * @since 5.3
  24.  */
  25. public abstract class GpgSigner {

  26.     private static final Logger LOG = LoggerFactory.getLogger(GpgSigner.class);

  27.     private static class DefaultSigner {

  28.         private static volatile GpgSigner defaultSigner = loadGpgSigner();

  29.         private static GpgSigner loadGpgSigner() {
  30.             try {
  31.                 ServiceLoader<GpgSigner> loader = ServiceLoader
  32.                         .load(GpgSigner.class);
  33.                 Iterator<GpgSigner> iter = loader.iterator();
  34.                 if (iter.hasNext()) {
  35.                     return iter.next();
  36.                 }
  37.             } catch (ServiceConfigurationError e) {
  38.                 LOG.error(e.getMessage(), e);
  39.             }
  40.             return null;
  41.         }

  42.         private DefaultSigner() {
  43.             // No instantiation
  44.         }

  45.         public static GpgSigner getDefault() {
  46.             return defaultSigner;
  47.         }

  48.         public static void setDefault(GpgSigner signer) {
  49.             defaultSigner = signer;
  50.         }
  51.     }

  52.     /**
  53.      * Get the default signer, or <code>null</code>.
  54.      *
  55.      * @return the default signer, or <code>null</code>.
  56.      */
  57.     public static GpgSigner getDefault() {
  58.         return DefaultSigner.getDefault();
  59.     }

  60.     /**
  61.      * Set the default signer.
  62.      *
  63.      * @param signer
  64.      *            the new default signer, may be <code>null</code> to select no
  65.      *            default.
  66.      */
  67.     public static void setDefault(GpgSigner signer) {
  68.         DefaultSigner.setDefault(signer);
  69.     }

  70.     /**
  71.      * Signs the specified commit.
  72.      *
  73.      * <p>
  74.      * Implementors should obtain the payload for signing from the specified
  75.      * commit via {@link CommitBuilder#build()} and create a proper
  76.      * {@link GpgSignature}. The generated signature must be set on the
  77.      * specified {@code commit} (see
  78.      * {@link CommitBuilder#setGpgSignature(GpgSignature)}).
  79.      * </p>
  80.      * <p>
  81.      * Any existing signature on the commit must be discarded prior obtaining
  82.      * the payload via {@link CommitBuilder#build()}.
  83.      * </p>
  84.      *
  85.      * @param commit
  86.      *            the commit to sign (must not be <code>null</code> and must be
  87.      *            complete to allow proper calculation of payload)
  88.      * @param gpgSigningKey
  89.      *            the signing key to locate (passed as is to the GPG signing
  90.      *            tool as is; eg., value of <code>user.signingkey</code>)
  91.      * @param committer
  92.      *            the signing identity (to help with key lookup in case signing
  93.      *            key is not specified)
  94.      * @param credentialsProvider
  95.      *            provider to use when querying for signing key credentials (eg.
  96.      *            passphrase)
  97.      * @throws CanceledException
  98.      *             when signing was canceled (eg., user aborted when entering
  99.      *             passphrase)
  100.      */
  101.     public abstract void sign(@NonNull CommitBuilder commit,
  102.             @Nullable String gpgSigningKey, @NonNull PersonIdent committer,
  103.             CredentialsProvider credentialsProvider) throws CanceledException;

  104.     /**
  105.      * Indicates if a signing key is available for the specified committer
  106.      * and/or signing key.
  107.      *
  108.      * @param gpgSigningKey
  109.      *            the signing key to locate (passed as is to the GPG signing
  110.      *            tool as is; eg., value of <code>user.signingkey</code>)
  111.      * @param committer
  112.      *            the signing identity (to help with key lookup in case signing
  113.      *            key is not specified)
  114.      * @param credentialsProvider
  115.      *            provider to use when querying for signing key credentials (eg.
  116.      *            passphrase)
  117.      * @return <code>true</code> if a signing key is available,
  118.      *         <code>false</code> otherwise
  119.      * @throws CanceledException
  120.      *             when signing was canceled (eg., user aborted when entering
  121.      *             passphrase)
  122.      */
  123.     public abstract boolean canLocateSigningKey(@Nullable String gpgSigningKey,
  124.             @NonNull PersonIdent committer,
  125.             CredentialsProvider credentialsProvider) throws CanceledException;

  126. }