2 * Copyright (C) 2019, 2020 Salesforce and others
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.
8 * SPDX-License-Identifier: BSD-3-Clause
10 package org.eclipse.jgit.gpg.bc.internal;
12 import java.net.URISyntaxException;
13 import java.nio.file.Path;
14 import java.text.MessageFormat;
16 import org.bouncycastle.openpgp.PGPException;
17 import org.bouncycastle.util.encoders.Hex;
18 import org.eclipse.jgit.api.errors.CanceledException;
19 import org.eclipse.jgit.errors.UnsupportedCredentialItem;
20 import org.eclipse.jgit.transport.CredentialItem.InformationalMessage;
21 import org.eclipse.jgit.transport.CredentialItem.Password;
22 import org.eclipse.jgit.transport.CredentialsProvider;
23 import org.eclipse.jgit.transport.URIish;
26 * Prompts for a passphrase and caches it until {@link #clear() cleared}.
28 * Implements {@link AutoCloseable} so it can be used within a
29 * try-with-resources block.
32 class BouncyCastleGpgKeyPassphrasePrompt implements AutoCloseable {
34 private Password passphrase;
36 private CredentialsProvider credentialsProvider;
38 public BouncyCastleGpgKeyPassphrasePrompt(
39 CredentialsProvider credentialsProvider) {
40 this.credentialsProvider = credentialsProvider;
44 * Clears any cached passphrase
47 if (passphrase != null) {
58 private URIish createURI(Path keyLocation) throws URISyntaxException {
59 return new URIish(keyLocation.toUri().toString());
63 * Prompts use for a passphrase unless one was cached from a previous
66 * @param keyFingerprint
67 * the fingerprint to show to the user during prompting
69 * the location the key was loaded from
70 * @return the passphrase (maybe <code>null</code>)
71 * @throws PGPException
72 * @throws CanceledException
73 * in case passphrase was not entered by user
74 * @throws URISyntaxException
75 * @throws UnsupportedCredentialItem
77 public char[] getPassphrase(byte[] keyFingerprint, Path keyLocation)
78 throws PGPException, CanceledException, UnsupportedCredentialItem,
80 if (passphrase == null) {
81 passphrase = new Password(BCText.get().credentialPassphrase);
84 if (credentialsProvider == null) {
85 throw new PGPException(BCText.get().gpgNoCredentialsProvider);
88 if (passphrase.getValue() == null
89 && !credentialsProvider.get(createURI(keyLocation),
90 new InformationalMessage(
91 MessageFormat.format(BCText.get().gpgKeyInfo,
92 Hex.toHexString(keyFingerprint))),
94 throw new CanceledException(BCText.get().gpgSigningCancelled);
96 return passphrase.getValue();
100 * Determines whether a passphrase was already obtained.
102 * @return {@code true} if a passphrase is already set, {@code false}
105 public boolean hasPassphrase() {
106 return passphrase != null && passphrase.getValue() != null;