View Javadoc
1   /*
2    * Copyright (C) 2018, 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  
12  import java.util.Iterator;
13  import java.util.ServiceConfigurationError;
14  import java.util.ServiceLoader;
15  
16  import org.eclipse.jgit.annotations.NonNull;
17  import org.eclipse.jgit.annotations.Nullable;
18  import org.eclipse.jgit.api.errors.CanceledException;
19  import org.eclipse.jgit.transport.CredentialsProvider;
20  import org.slf4j.Logger;
21  import org.slf4j.LoggerFactory;
22  
23  /**
24   * Creates GPG signatures for Git objects.
25   *
26   * @since 5.3
27   */
28  public abstract class GpgSigner {
29  	private static final Logger LOG = LoggerFactory.getLogger(GpgSigner.class);
30  
31  	private static GpgSigner defaultSigner = loadGpgSigner();
32  
33  	private static GpgSigner loadGpgSigner() {
34  		try {
35  			ServiceLoader<GpgSigner> loader = ServiceLoader
36  					.load(GpgSigner.class);
37  			Iterator<GpgSigner> iter = loader.iterator();
38  			if (iter.hasNext()) {
39  				return iter.next();
40  			}
41  		} catch (ServiceConfigurationError e) {
42  			LOG.error(e.getMessage(), e);
43  		}
44  		return null;
45  	}
46  
47  	/**
48  	 * Get the default signer, or <code>null</code>.
49  	 *
50  	 * @return the default signer, or <code>null</code>.
51  	 */
52  	public static GpgSigner getDefault() {
53  		return defaultSigner;
54  	}
55  
56  	/**
57  	 * Set the default signer.
58  	 *
59  	 * @param signer
60  	 *            the new default signer, may be <code>null</code> to select no
61  	 *            default.
62  	 */
63  	public static void setDefault(GpgSigner signer) {
64  		GpgSigner.defaultSigner = signer;
65  	}
66  
67  	/**
68  	 * Signs the specified commit.
69  	 *
70  	 * <p>
71  	 * Implementors should obtain the payload for signing from the specified
72  	 * commit via {@link CommitBuilder#build()} and create a proper
73  	 * {@link GpgSignature}. The generated signature must be set on the
74  	 * specified {@code commit} (see
75  	 * {@link CommitBuilder#setGpgSignature(GpgSignature)}).
76  	 * </p>
77  	 * <p>
78  	 * Any existing signature on the commit must be discarded prior obtaining
79  	 * the payload via {@link CommitBuilder#build()}.
80  	 * </p>
81  	 *
82  	 * @param commit
83  	 *            the commit to sign (must not be <code>null</code> and must be
84  	 *            complete to allow proper calculation of payload)
85  	 * @param gpgSigningKey
86  	 *            the signing key to locate (passed as is to the GPG signing
87  	 *            tool as is; eg., value of <code>user.signingkey</code>)
88  	 * @param committer
89  	 *            the signing identity (to help with key lookup in case signing
90  	 *            key is not specified)
91  	 * @param credentialsProvider
92  	 *            provider to use when querying for signing key credentials (eg.
93  	 *            passphrase)
94  	 * @throws CanceledException
95  	 *             when signing was canceled (eg., user aborted when entering
96  	 *             passphrase)
97  	 */
98  	public abstract void sign(@NonNull CommitBuilder commit,
99  			@Nullable String gpgSigningKey, @NonNull PersonIdent committer,
100 			CredentialsProvider credentialsProvider) throws CanceledException;
101 
102 	/**
103 	 * Indicates if a signing key is available for the specified committer
104 	 * and/or signing key.
105 	 *
106 	 * @param gpgSigningKey
107 	 *            the signing key to locate (passed as is to the GPG signing
108 	 *            tool as is; eg., value of <code>user.signingkey</code>)
109 	 * @param committer
110 	 *            the signing identity (to help with key lookup in case signing
111 	 *            key is not specified)
112 	 * @param credentialsProvider
113 	 *            provider to use when querying for signing key credentials (eg.
114 	 *            passphrase)
115 	 * @return <code>true</code> if a signing key is available,
116 	 *         <code>false</code> otherwise
117 	 * @throws CanceledException
118 	 *             when signing was canceled (eg., user aborted when entering
119 	 *             passphrase)
120 	 */
121 	public abstract boolean canLocateSigningKey(@Nullable String gpgSigningKey,
122 			@NonNull PersonIdent committer,
123 			CredentialsProvider credentialsProvider) throws CanceledException;
124 
125 }