1 package com.atlassian.asap.core.keys.publickey;
2
3 import com.atlassian.asap.api.exception.CannotRetrieveKeyException;
4 import com.atlassian.asap.core.exception.PublicKeyNotFoundException;
5 import com.atlassian.asap.core.exception.PublicKeyRetrievalException;
6 import com.atlassian.asap.core.keys.KeyProvider;
7 import com.atlassian.asap.core.keys.KeyReader;
8 import com.atlassian.asap.core.validator.ValidatedKeyId;
9 import com.google.common.annotations.VisibleForTesting;
10 import com.google.common.base.Preconditions;
11 import org.slf4j.Logger;
12 import org.slf4j.LoggerFactory;
13
14 import java.io.IOException;
15 import java.io.InputStream;
16 import java.io.InputStreamReader;
17 import java.nio.charset.StandardCharsets;
18 import java.security.PublicKey;
19 import java.util.Objects;
20
21 import static com.atlassian.asap.core.keys.ClassPathUri.classPathUri;
22
23
24
25
26
27 public class ClasspathPublicKeyProvider implements KeyProvider<PublicKey> {
28 private static final Logger logger = LoggerFactory.getLogger(ClasspathPublicKeyProvider.class);
29
30 private final KeyReader keyReader;
31 private final String classpathBase;
32
33
34
35
36
37
38
39 public ClasspathPublicKeyProvider(String classpathBase, KeyReader keyReader) {
40 this.keyReader = Objects.requireNonNull(keyReader);
41 this.classpathBase = Objects.requireNonNull(classpathBase);
42 Preconditions.checkArgument(classpathBase.endsWith("/"), "Classpath prefix must end with a slash");
43 }
44
45 @Override
46 public PublicKey getKey(ValidatedKeyId validatedKeyId) throws CannotRetrieveKeyException {
47 String pathToKey = classpathBase + validatedKeyId.getKeyId();
48
49 logger.debug("Reading public key from classpath: {}", pathToKey);
50
51 try (InputStream inputStream = ClasspathPublicKeyProvider.class.getResourceAsStream(pathToKey)) {
52 if (inputStream == null) {
53 throw new PublicKeyNotFoundException(
54 "Public key not found in the classpath", validatedKeyId, classPathUri(pathToKey));
55 }
56 try (InputStreamReader reader = new InputStreamReader(inputStream, StandardCharsets.US_ASCII)) {
57 return keyReader.readPublicKey(reader);
58 }
59 } catch (IOException e) {
60 throw new PublicKeyRetrievalException(
61 "Error retrieving public key from classpath", e, validatedKeyId, classPathUri(pathToKey));
62 }
63 }
64
65 @VisibleForTesting
66 String getClasspathBase() {
67 return classpathBase;
68 }
69
70 @Override
71 public String toString() {
72 return this.getClass().getSimpleName();
73 }
74 }