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 }