You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

BouncyCastleGpgKeyPassphrasePrompt.java 3.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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. import java.net.URISyntaxException;
  12. import java.nio.file.Path;
  13. import java.text.MessageFormat;
  14. import org.bouncycastle.openpgp.PGPException;
  15. import org.bouncycastle.util.encoders.Hex;
  16. import org.eclipse.jgit.api.errors.CanceledException;
  17. import org.eclipse.jgit.errors.UnsupportedCredentialItem;
  18. import org.eclipse.jgit.transport.CredentialItem.InformationalMessage;
  19. import org.eclipse.jgit.transport.CredentialItem.Password;
  20. import org.eclipse.jgit.transport.CredentialsProvider;
  21. import org.eclipse.jgit.transport.URIish;
  22. /**
  23. * Prompts for a passphrase and caches it until {@link #clear() cleared}.
  24. * <p>
  25. * Implements {@link AutoCloseable} so it can be used within a
  26. * try-with-resources block.
  27. * </p>
  28. */
  29. class BouncyCastleGpgKeyPassphrasePrompt implements AutoCloseable {
  30. private Password passphrase;
  31. private CredentialsProvider credentialsProvider;
  32. public BouncyCastleGpgKeyPassphrasePrompt(
  33. CredentialsProvider credentialsProvider) {
  34. this.credentialsProvider = credentialsProvider;
  35. }
  36. /**
  37. * Clears any cached passphrase
  38. */
  39. public void clear() {
  40. if (passphrase != null) {
  41. passphrase.clear();
  42. passphrase = null;
  43. }
  44. }
  45. @Override
  46. public void close() {
  47. clear();
  48. }
  49. private URIish createURI(Path keyLocation) throws URISyntaxException {
  50. return new URIish(keyLocation.toUri().toString());
  51. }
  52. /**
  53. * Prompts use for a passphrase unless one was cached from a previous
  54. * prompt.
  55. *
  56. * @param keyFingerprint
  57. * the fingerprint to show to the user during prompting
  58. * @param keyLocation
  59. * the location the key was loaded from
  60. * @return the passphrase (maybe <code>null</code>)
  61. * @throws PGPException
  62. * @throws CanceledException
  63. * in case passphrase was not entered by user
  64. * @throws URISyntaxException
  65. * @throws UnsupportedCredentialItem
  66. */
  67. public char[] getPassphrase(byte[] keyFingerprint, Path keyLocation)
  68. throws PGPException, CanceledException, UnsupportedCredentialItem,
  69. URISyntaxException {
  70. if (passphrase == null) {
  71. passphrase = new Password(BCText.get().credentialPassphrase);
  72. }
  73. if (credentialsProvider == null) {
  74. throw new PGPException(BCText.get().gpgNoCredentialsProvider);
  75. }
  76. if (passphrase.getValue() == null
  77. && !credentialsProvider.get(createURI(keyLocation),
  78. new InformationalMessage(
  79. MessageFormat.format(BCText.get().gpgKeyInfo,
  80. Hex.toHexString(keyFingerprint))),
  81. passphrase)) {
  82. throw new CanceledException(BCText.get().gpgSigningCancelled);
  83. }
  84. return passphrase.getValue();
  85. }
  86. /**
  87. * Determines whether a passphrase was already obtained.
  88. *
  89. * @return {@code true} if a passphrase is already set, {@code false}
  90. * otherwise
  91. */
  92. public boolean hasPassphrase() {
  93. return passphrase != null && passphrase.getValue() != null;
  94. }
  95. }