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 }