]> source.dussan.org Git - jgit.git/blob
61441959830355fcb0a6f3e97105c512afed58a7
[jgit.git] /
1 /*-
2  * Copyright (C) 2019, 2020 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.gpg.bc.internal;
11
12 import java.net.URISyntaxException;
13 import java.nio.file.Path;
14 import java.text.MessageFormat;
15
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;
24
25 /**
26  * Prompts for a passphrase and caches it until {@link #clear() cleared}.
27  * <p>
28  * Implements {@link AutoCloseable} so it can be used within a
29  * try-with-resources block.
30  * </p>
31  */
32 class BouncyCastleGpgKeyPassphrasePrompt implements AutoCloseable {
33
34         private Password passphrase;
35
36         private CredentialsProvider credentialsProvider;
37
38         public BouncyCastleGpgKeyPassphrasePrompt(
39                         CredentialsProvider credentialsProvider) {
40                 this.credentialsProvider = credentialsProvider;
41         }
42
43         /**
44          * Clears any cached passphrase
45          */
46         public void clear() {
47                 if (passphrase != null) {
48                         passphrase.clear();
49                         passphrase = null;
50                 }
51         }
52
53         @Override
54         public void close() {
55                 clear();
56         }
57
58         private URIish createURI(Path keyLocation) throws URISyntaxException {
59                 return new URIish(keyLocation.toUri().toString());
60         }
61
62         /**
63          * Prompts use for a passphrase unless one was cached from a previous
64          * prompt.
65          *
66          * @param keyFingerprint
67          *            the fingerprint to show to the user during prompting
68          * @param keyLocation
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
76          */
77         public char[] getPassphrase(byte[] keyFingerprint, Path keyLocation)
78                         throws PGPException, CanceledException, UnsupportedCredentialItem,
79                         URISyntaxException {
80                 if (passphrase == null) {
81                         passphrase = new Password(BCText.get().credentialPassphrase);
82                 }
83
84                 if (credentialsProvider == null) {
85                         throw new PGPException(BCText.get().gpgNoCredentialsProvider);
86                 }
87
88                 if (passphrase.getValue() == null
89                                 && !credentialsProvider.get(createURI(keyLocation),
90                                                 new InformationalMessage(
91                                                                 MessageFormat.format(BCText.get().gpgKeyInfo,
92                                                                                 Hex.toHexString(keyFingerprint))),
93                                                 passphrase)) {
94                         throw new CanceledException(BCText.get().gpgSigningCancelled);
95                 }
96                 return passphrase.getValue();
97         }
98
99         /**
100          * Determines whether a passphrase was already obtained.
101          *
102          * @return {@code true} if a passphrase is already set, {@code false}
103          *         otherwise
104          */
105         public boolean hasPassphrase() {
106                 return passphrase != null && passphrase.getValue() != null;
107         }
108 }