View Javadoc

1   package com.atlassian.asap.core.keys.privatekey;
2   
3   import com.atlassian.asap.api.exception.CannotRetrieveKeyException;
4   import com.atlassian.asap.core.keys.KeyProvider;
5   import com.atlassian.asap.core.keys.KeyReader;
6   import com.atlassian.asap.core.validator.ValidatedKeyId;
7   
8   import java.io.StringReader;
9   import java.security.PrivateKey;
10  import java.util.Objects;
11  import java.util.Optional;
12  
13  /**
14   * Reads a single private key from a String. The key and the key identifier are construction arguments, and the
15   * provider only provides that particular key identifier. This provider can be used for private keys obtained from
16   * arbitrary sources, like an application-specific configuration file. If the key is provided via a classpath resource,
17   * or a file, or an environment variable, or a system property, then please use one of the specialised private key
18   * providers for those scenarios.
19   *
20   * <p>See also {@link DataUriKeyProvider}, which can be used for a similar purpose but only when the key is provided in
21   * the data URI format. {@link StringPrivateKeyProvider} also allows other formats, like PEM keys.
22   */
23  public class StringPrivateKeyProvider implements KeyProvider<PrivateKey> {
24      private final String keyId;
25      private final Optional<PrivateKey> privateKey;
26  
27      /**
28       * Creates an instance that provides a single key read from a String. It attempts to parse the key at construction
29       * time. If the key is not parseable, it will fail at retrieval time.
30       *
31       * @param keyReader the key reader to parse the key
32       * @param key the actual private key
33       * @param keyId the key identifier
34       */
35      public StringPrivateKeyProvider(KeyReader keyReader, String key, String keyId) {
36          this.keyId = Objects.requireNonNull(keyId);
37          this.privateKey = tryReadPrivateKey(keyReader, key);  // eagerly parse the key
38      }
39  
40      private static Optional<PrivateKey> tryReadPrivateKey(KeyReader keyReader, String key) {
41          try {
42              return Optional.of(keyReader.readPrivateKey(new StringReader(key)));
43          } catch (CannotRetrieveKeyException e) {
44              return Optional.empty();  // will fail later at retrieval time
45          }
46      }
47  
48      @Override
49      public PrivateKey getKey(ValidatedKeyId keyId) throws CannotRetrieveKeyException {
50          if (keyId.getKeyId().equals(this.keyId)) {
51              return privateKey.orElseThrow(() -> new CannotRetrieveKeyException("Cannot parse private key"));
52          } else {
53              throw new CannotRetrieveKeyException("Cannot find private key");
54          }
55      }
56  }